Merge tag 'pinctrl-v4.1-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl
Pull pincontrol updates from Linus Walleij:
 "This is the bulk of pin control changes for the v4.1 development
  cycle.  Nothing really exciting this time: we basically added a few
  new drivers and subdrivers and stabilized them in linux-next.  Some
  cleanups too.  With sunrisepoint Intel has a real fine fully featured
  pin control driver for contemporary hardware, and the AMD driver is
  also for large deployments.  Most of the others are ARM devices.
  New drivers:
    - Intel Sunrisepoint
    - AMD KERNCZ GPIO
    - Broadcom Cygnus IOMUX
  New subdrivers:
    - Marvell MVEBU Armada 39x SoCs
    - Samsung Exynos 5433
    - nVidia Tegra 210
    - Mediatek MT8135
    - Mediatek MT8173
    - AMLogic Meson8b
    - Qualcomm PM8916
  On top of this cleanups and development history for the above drivers
  as issues were fixed after merging"
* tag 'pinctrl-v4.1-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl: (71 commits)
  pinctrl: sirf: move sgpio lock into state container
  pinctrl: Add support for PM8916 GPIO's and MPP's
  pinctrl: bcm2835: Fix support for threaded level triggered IRQs
  sh-pfc: r8a7790: add EtherAVB pin groups
  pinctrl: Document "function" + "pins" pinmux binding
  pinctrl: intel: Add Intel Sunrisepoint pin controller and GPIO support
  pinctrl: fsl: imx: Check for 0 config register
  pinctrl: Add support for Meson8b
  documentation: Extend pinctrl docs for Meson8b
  pinctrl: Cleanup Meson8 driver
  Fix inconsistent spinlock of AMD GPIO driver which can be recognized by static analysis tool smatch. Declare constant Variables with Sparse's suggestion.
  pinctrl: at91: convert __raw to endian agnostic IO
  pinctrl: constify of_device_id array
  pinctrl: pinconf-generic: add dt node names to error messages
  pinctrl: pinconf-generic: scan also referenced phandle node
  pinctrl: mvebu: add suspend/resume support to Armada XP pinctrl driver
  pinctrl: st: Display pin's function when printing pinctrl debug information
  pinctrl: st: Show correct pin direction also in GPIO mode
  pinctrl: st: Supply a GPIO get_direction() call-back
  pinctrl: st: Move st_get_pio_control() further up the source file
  ...
			
			
This commit is contained in:
		| @@ -0,0 +1,98 @@ | ||||
| Broadcom Cygnus GPIO/PINCONF Controller | ||||
|  | ||||
| Required properties: | ||||
|  | ||||
| - compatible: | ||||
|     Must be "brcm,cygnus-ccm-gpio", "brcm,cygnus-asiu-gpio", or | ||||
|     "brcm,cygnus-crmu-gpio" | ||||
|  | ||||
| - reg: | ||||
|     Define the base and range of the I/O address space that contains the Cygnus | ||||
| GPIO/PINCONF controller registers | ||||
|  | ||||
| - #gpio-cells: | ||||
|     Must be two. The first cell is the GPIO pin number (within the | ||||
| controller's pin space) and the second cell is used for the following: | ||||
|     bit[0]: polarity (0 for active high and 1 for active low) | ||||
|  | ||||
| - gpio-controller: | ||||
|     Specifies that the node is a GPIO controller | ||||
|  | ||||
| Optional properties: | ||||
|  | ||||
| - interrupts: | ||||
|     Interrupt ID | ||||
|  | ||||
| - interrupt-controller: | ||||
|     Specifies that the node is an interrupt controller | ||||
|  | ||||
| - pinmux: | ||||
|     Specifies the phandle to the IOMUX device, where pins can be individually | ||||
| muxed to GPIO | ||||
|  | ||||
| Supported generic PINCONF properties in child nodes: | ||||
|  | ||||
| - pins: | ||||
|     The list of pins (within the controller's own pin space) that properties | ||||
| in the node apply to. Pin names are "gpio-<pin>" | ||||
|  | ||||
| - bias-disable: | ||||
|     Disable pin bias | ||||
|  | ||||
| - bias-pull-up: | ||||
|     Enable internal pull up resistor | ||||
|  | ||||
| - bias-pull-down: | ||||
|     Enable internal pull down resistor | ||||
|  | ||||
| - drive-strength: | ||||
|     Valid drive strength values include 2, 4, 6, 8, 10, 12, 14, 16 (mA) | ||||
|  | ||||
| Example: | ||||
| 	gpio_ccm: gpio@1800a000 { | ||||
| 		compatible = "brcm,cygnus-ccm-gpio"; | ||||
| 		reg = <0x1800a000 0x50>, | ||||
| 		      <0x0301d164 0x20>; | ||||
| 		#gpio-cells = <2>; | ||||
| 		gpio-controller; | ||||
| 		interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>; | ||||
| 		interrupt-controller; | ||||
|  | ||||
| 		touch_pins: touch_pins { | ||||
| 			pwr: pwr { | ||||
| 				pins = "gpio-0"; | ||||
| 				drive-strength = <16>; | ||||
| 			}; | ||||
|  | ||||
| 			event: event { | ||||
| 				pins = "gpio-1"; | ||||
| 				bias-pull-up; | ||||
| 			}; | ||||
| 		}; | ||||
| 	}; | ||||
|  | ||||
| 	gpio_asiu: gpio@180a5000 { | ||||
| 		compatible = "brcm,cygnus-asiu-gpio"; | ||||
| 		reg = <0x180a5000 0x668>; | ||||
| 		#gpio-cells = <2>; | ||||
| 		gpio-controller; | ||||
| 		interrupts = <GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH>; | ||||
| 		interrupt-controller; | ||||
| 	}; | ||||
|  | ||||
| 	/* | ||||
| 	 * Touchscreen that uses the CCM GPIO 0 and 1 | ||||
| 	 */ | ||||
| 	tsc { | ||||
| 		... | ||||
| 		... | ||||
| 		gpio-pwr = <&gpio_ccm 0 0>; | ||||
| 		gpio-event = <&gpio_ccm 1 0>; | ||||
| 	}; | ||||
|  | ||||
| 	/* Bluetooth that uses the ASIU GPIO 5, with polarity inverted */ | ||||
| 	bluetooth { | ||||
| 		... | ||||
| 		... | ||||
| 		bcm,rfkill-bank-sel = <&gpio_asiu 5 1> | ||||
| 	} | ||||
							
								
								
									
										132
									
								
								Documentation/devicetree/bindings/pinctrl/brcm,cygnus-pinmux.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										132
									
								
								Documentation/devicetree/bindings/pinctrl/brcm,cygnus-pinmux.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,132 @@ | ||||
| Broadcom Cygnus IOMUX Controller | ||||
|  | ||||
| The Cygnus IOMUX controller supports group based mux configuration. In | ||||
| addition, certain pins can be muxed to GPIO function individually. | ||||
|  | ||||
| Required properties: | ||||
|  | ||||
| - compatible: | ||||
|     Must be "brcm,cygnus-pinmux" | ||||
|  | ||||
| - reg: | ||||
|     Define the base and range of the I/O address space that contains the Cygnus | ||||
| IOMUX registers | ||||
|  | ||||
| Properties in subnodes: | ||||
|  | ||||
| - function: | ||||
|     The mux function to select | ||||
|  | ||||
| - groups: | ||||
|     The list of groups to select with a given function | ||||
|  | ||||
| For more details, refer to | ||||
| Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt | ||||
|  | ||||
| For example: | ||||
|  | ||||
| 	pinmux: pinmux@0x0301d0c8 { | ||||
| 		compatible = "brcm,cygnus-pinmux"; | ||||
| 		reg = <0x0301d0c8 0x1b0>; | ||||
|  | ||||
| 		pinctrl-names = "default"; | ||||
| 		pinctrl-0 = <&i2s0_default>; | ||||
|  | ||||
| 		i2s0_default: i2s0_default { | ||||
| 			mux { | ||||
| 				function = "i2s0"; | ||||
| 				groups = "i2s0_0_grp", "i2s0_1_grp"; | ||||
| 			}; | ||||
| 		}; | ||||
| 	}; | ||||
|  | ||||
| List of supported functions and groups in Cygnus: | ||||
|  | ||||
| "i2s0": "i2s0_0_grp", "i2s0_1_grp" | ||||
|  | ||||
| "i2s1": "i2s1_0_grp", "i2s1_1_grp" | ||||
|  | ||||
| "i2s2": "i2s2_0_grp", "i2s2_1_grp", "i2s2_2_grp", "i2s2_3_grp", "i2s2_4_grp" | ||||
|  | ||||
| "spdif": "spdif_grp" | ||||
|  | ||||
| "pwm0": "pwm0_grp" | ||||
|  | ||||
| "pwm1": "pwm1_grp" | ||||
|  | ||||
| "pwm2": "pwm2_grp" | ||||
|  | ||||
| "pwm3": "pwm3_grp" | ||||
|  | ||||
| "pwm4": "pwm4_grp" | ||||
|  | ||||
| "pwm5": "pwm5_grp" | ||||
|  | ||||
| "key": "key0_grp", "key1_grp", "key2_grp", "key3_grp", "key4_grp", "key5_grp", | ||||
| "key6_grp", "key7_grp", "key8_grp", "key9_grp", "key10_grp", "key11_grp", | ||||
| "key12_grp", "key13_grp", "key14_grp", "key15_grp" | ||||
|  | ||||
| "audio_dte": "audio_dte0_grp", "audio_dte1_grp", "audio_dte2_grp", "audio_dte3_grp" | ||||
|  | ||||
| "smart_card0": "smart_card0_grp", "smart_card0_fcb_grp" | ||||
|  | ||||
| "smart_card1": "smart_card1_grp", "smart_card1_fcb_grp" | ||||
|  | ||||
| "spi0": "spi0_grp" | ||||
|  | ||||
| "spi1": "spi1_grp" | ||||
|  | ||||
| "spi2": "spi2_grp" | ||||
|  | ||||
| "spi3": "spi3_grp" | ||||
|  | ||||
| "spi4": "spi4_0_grp", "spi4_1_grp" | ||||
|  | ||||
| "spi5": "spi5_grp" | ||||
|  | ||||
| "sw_led0": "sw_led0_0_grp", "sw_led0_1_grp" | ||||
|  | ||||
| "sw_led1": "sw_led1_grp" | ||||
|  | ||||
| "sw_led2": "sw_led2_0_grp", "sw_led2_1_grp" | ||||
|  | ||||
| "d1w": "d1w_grp" | ||||
|  | ||||
| "lcd": "lcd_grp" | ||||
|  | ||||
| "sram": "sram_0_grp", "sram_1_grp" | ||||
|  | ||||
| "uart0": "uart0_grp" | ||||
|  | ||||
| "uart1": "uart1_grp", "uart1_dte_grp" | ||||
|  | ||||
| "uart2": "uart2_grp" | ||||
|  | ||||
| "uart3": "uart3_grp" | ||||
|  | ||||
| "uart4": "uart4_grp" | ||||
|  | ||||
| "qspi": "qspi_0_grp", "qspi_1_grp" | ||||
|  | ||||
| "nand": "nand_grp" | ||||
|  | ||||
| "sdio0": "sdio0_grp", "sdio0_cd_grp", "sdio0_mmc_grp" | ||||
|  | ||||
| "sdio1": "sdio1_data_0_grp", "sdio1_data_1_grp", "sdio1_cd_grp", | ||||
| "sdio1_led_grp", "sdio1_mmc_grp" | ||||
|  | ||||
| "can0": "can0_grp" | ||||
|  | ||||
| "can1": "can1_grp" | ||||
|  | ||||
| "cam": "cam_led_grp", "cam_0_grp", "cam_1_grp" | ||||
|  | ||||
| "bsc1": "bsc1_grp" | ||||
|  | ||||
| "pcie_clkreq": "pcie_clkreq_grp" | ||||
|  | ||||
| "usb0_oc": "usb0_oc_grp" | ||||
|  | ||||
| "usb1_oc": "usb1_oc_grp" | ||||
|  | ||||
| "usb2_oc": "usb2_oc_grp" | ||||
| @@ -0,0 +1,78 @@ | ||||
| * Marvell Armada 39x SoC pinctrl driver for mpp | ||||
|  | ||||
| Please refer to marvell,mvebu-pinctrl.txt in this directory for common binding | ||||
| part and usage. | ||||
|  | ||||
| Required properties: | ||||
| - compatible: "marvell,88f6920-pinctrl", "marvell,88f6928-pinctrl" | ||||
|   depending on the specific variant of the SoC being used. | ||||
| - reg: register specifier of MPP registers | ||||
|  | ||||
| Available mpp pins/groups and functions: | ||||
| Note: brackets (x) are not part of the mpp name for marvell,function and given | ||||
| only for more detailed description in this document. | ||||
|  | ||||
| name    pins    functions | ||||
| ================================================================================ | ||||
| mpp0	0	gpio, ua0(rxd) | ||||
| mpp1	1	gpio, ua0(txd) | ||||
| mpp2	2	gpio, i2c0(sck) | ||||
| mpp3	3	gpio, i2c0(sda) | ||||
| mpp4	4	gpio, ua1(txd), ua0(rts), smi(mdc) | ||||
| mpp5	5	gpio, ua1(rxd), ua0(cts), smi(mdio) | ||||
| mpp6	6	gpio, dev(cs3), xsmi(mdio) | ||||
| mpp7	7	gpio, dev(ad9), xsmi(mdc) | ||||
| mpp8	8	gpio, dev(ad10), ptp(trig) | ||||
| mpp9	9	gpio, dev(ad11), ptp(clk) | ||||
| mpp10	10	gpio, dev(ad12), ptp(event) | ||||
| mpp11	11	gpio, dev(ad13), led(clk) | ||||
| mpp12	12	gpio, pcie0(rstout), dev(ad14), led(stb) | ||||
| mpp13	13	gpio, dev(ad15), led(data) | ||||
| mpp14	14	gpio, m(vtt), dev(wen1), ua1(txd) | ||||
| mpp15	15	gpio, pcie0(rstout), spi0(mosi), i2c1(sck) | ||||
| mpp16	16	gpio, m(decc), spi0(miso), i2c1(sda) | ||||
| mpp17	17	gpio, ua1(rxd), spi0(sck), smi(mdio) | ||||
| mpp18	18	gpio, ua1(txd), spi0(cs0), i2c2(sck) | ||||
| mpp19	19	gpio, sata1(present) [1], ua0(cts), ua1(rxd), i2c2(sda) | ||||
| mpp20	20	gpio, sata0(present) [1], ua0(rts), ua1(txd), smi(mdc) | ||||
| mpp21	21	gpio, spi0(cs1), sata0(present) [1], sd(cmd), dev(bootcs), ge(rxd0) | ||||
| mpp22	22	gpio, spi0(mosi), dev(ad0) | ||||
| mpp23	23	gpio, spi0(sck), dev(ad2) | ||||
| mpp24	24	gpio, spi0(miso), ua0(cts), ua1(rxd), sd(d4), dev(readyn) | ||||
| mpp25	25	gpio, spi0(cs0), ua0(rts), ua1(txd), sd(d5), dev(cs0) | ||||
| mpp26	26	gpio, spi0(cs2), i2c1(sck), sd(d6), dev(cs1) | ||||
| mpp27	27	gpio, spi0(cs3), i2c1(sda), sd(d7), dev(cs2), ge(txclkout) | ||||
| mpp28	28	gpio, sd(clk), dev(ad5), ge(txd0) | ||||
| mpp29	29	gpio, dev(ale0), ge(txd1) | ||||
| mpp30	30	gpio, dev(oen), ge(txd2) | ||||
| mpp31	31	gpio, dev(ale1), ge(txd3) | ||||
| mpp32	32	gpio, dev(wen0), ge(txctl) | ||||
| mpp33	33	gpio, m(decc), dev(ad3) | ||||
| mpp34	34	gpio, dev(ad1) | ||||
| mpp35	35	gpio, ref(clk), dev(a1) | ||||
| mpp36	36	gpio, dev(a0) | ||||
| mpp37	37	gpio, sd(d3), dev(ad8), ge(rxclk) | ||||
| mpp38	38	gpio, ref(clk), sd(d0), dev(ad4), ge(rxd1) | ||||
| mpp39	39	gpio, i2c1(sck), ua0(cts), sd(d1), dev(a2), ge(rxd2) | ||||
| mpp40	40	gpio, i2c1(sda), ua0(rts), sd(d2), dev(ad6), ge(rxd3) | ||||
| mpp41	41	gpio, ua1(rxd), ua0(cts), spi1(cs3), dev(burstn), nd(rbn0), ge(rxctl) | ||||
| mpp42	42	gpio, ua1(txd), ua0(rts), dev(ad7) | ||||
| mpp43	43	gpio, pcie0(clkreq), m(vtt), m(decc), spi1(cs2), dev(clkout), nd(rbn1) | ||||
| mpp44	44	gpio, sata0(present) [1], sata1(present) [1], led(clk) | ||||
| mpp45	45	gpio, ref(clk), pcie0(rstout), ua1(rxd) | ||||
| mpp46	46	gpio, ref(clk), pcie0(rstout), ua1(txd), led(stb) | ||||
| mpp47	47	gpio, sata0(present) [1], sata1(present) [1], led(data) | ||||
| mpp48	48	gpio, sata0(present) [1], m(vtt), tdm(pclk) [1], audio(mclk) [1], sd(d4), pcie0(clkreq), ua1(txd) | ||||
| mpp49	49	gpio, tdm(fsync) [1], audio(lrclk) [1], sd(d5), ua2(rxd) | ||||
| mpp50	50	gpio, pcie0(rstout), tdm(drx) [1], audio(extclk) [1], sd(cmd), ua2(rxd) | ||||
| mpp51	51	gpio, tdm(dtx) [1], audio(sdo) [1], m(decc), ua2(txd) | ||||
| mpp52	52	gpio, pcie0(rstout), tdm(intn) [1], audio(sdi) [1], sd(d6), i2c3(sck) | ||||
| mpp53	53	gpio, sata1(present) [1], sata0(present) [1], tdm(rstn) [1], audio(bclk) [1], sd(d7), i2c3(sda) | ||||
| mpp54	54	gpio, sata0(present) [1], sata1(present) [1], pcie0(rstout), sd(d3), ua3(txd) | ||||
| mpp55	55	gpio, ua1(cts), spi1(cs1), sd(d0), ua1(rxd), ua3(rxd) | ||||
| mpp56	56	gpio, ua1(rts), m(decc), spi1(mosi), ua1(txd) | ||||
| mpp57	57	gpio, spi1(sck), sd(clk), ua1(txd) | ||||
| mpp58	58	gpio, i2c1(sck), pcie2(clkreq), spi1(miso), sd(d1), ua1(rxd) | ||||
| mpp59	59	gpio, pcie0(rstout), i2c1(sda), spi1(cs0), sd(d2) | ||||
|  | ||||
| [1]: only available on 88F6928 | ||||
| @@ -1,7 +1,7 @@ | ||||
| == Amlogic Meson pinmux controller == | ||||
|  | ||||
| Required properties for the root node: | ||||
|  - compatible: "amlogic,meson8-pinctrl" | ||||
|  - compatible: "amlogic,meson8-pinctrl" or "amlogic,meson8b-pinctrl" | ||||
|  - reg: address and size of registers controlling irq functionality | ||||
|  | ||||
| === GPIO sub-nodes === | ||||
|   | ||||
| @@ -0,0 +1,166 @@ | ||||
| NVIDIA Tegra210 pinmux controller | ||||
|  | ||||
| Required properties: | ||||
| - compatible: "nvidia,tegra210-pinmux" | ||||
| - reg: Should contain a list of base address and size pairs for: | ||||
|   - first entry: The APB_MISC_GP_*_PADCTRL registers (pad control) | ||||
|   - second entry: The PINMUX_AUX_* registers (pinmux) | ||||
|  | ||||
| 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 arbitrary 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. | ||||
|  | ||||
| See the TRM to determine which properties and values apply to each pin/group. | ||||
| Macro values for property values are defined in | ||||
| include/dt-binding/pinctrl/pinctrl-tegra.h. | ||||
|  | ||||
| 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. | ||||
| - 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,enable-input: Integer. Enable the pin's input path. | ||||
|     enable :TEGRA_PIN_ENABLE0 and | ||||
|     disable or output only: TEGRA_PIN_DISABLE. | ||||
| - nvidia,open-drain: Integer. | ||||
|     enable: TEGRA_PIN_ENABLE. | ||||
|     disable: TEGRA_PIN_DISABLE. | ||||
| - nvidia,lock: Integer. Lock the pin configuration against further changes | ||||
|     until reset. | ||||
|     enable: TEGRA_PIN_ENABLE. | ||||
|     disable: TEGRA_PIN_DISABLE. | ||||
| - nvidia,io-hv: Integer. Select high-voltage receivers. | ||||
|     normal: TEGRA_PIN_DISABLE | ||||
|     high: TEGRA_PIN_ENABLE | ||||
| - nvidia,high-speed-mode: Integer. Enable high speed mode the pins. | ||||
|     normal: TEGRA_PIN_DISABLE | ||||
|     high: TEGRA_PIN_ENABLE | ||||
| - nvidia,schmitt: Integer. Enables Schmitt Trigger on the input. | ||||
|     normal: TEGRA_PIN_DISABLE | ||||
|     high: TEGRA_PIN_ENABLE | ||||
| - nvidia,drive-type: Integer. Valid range 0...3. | ||||
| - 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. | ||||
|  | ||||
| Valid values for pin and group names (nvidia,pin) are: | ||||
|  | ||||
|   Mux groups: | ||||
|  | ||||
|     These correspond to Tegra PINMUX_AUX_* (pinmux) registers. Any property | ||||
|     that exists in those registers may be set for the following pin names. | ||||
|  | ||||
|     In Tegra210, many pins also have a dedicated APB_MISC_GP_*_PADCTRL | ||||
|     register. Where that is true, and property that exists in that register | ||||
|     may also be set on the following pin names. | ||||
|  | ||||
|     als_prox_int_px3, ap_ready_pv5, ap_wake_bt_ph3, ap_wake_nfc_ph7, | ||||
|     aud_mclk_pbb0, batt_bcl, bt_rst_ph4, bt_wake_ap_ph5, button_home_py1, | ||||
|     button_power_on_px5, button_slide_sw_py0, button_vol_down_px7, | ||||
|     button_vol_up_px6, cam1_mclk_ps0, cam1_pwdn_ps7, cam1_strobe_pt1, | ||||
|     cam2_mclk_ps1, cam2_pwdn_pt0, cam_af_en_ps5, cam_flash_en_ps6, | ||||
|     cam_i2c_scl_ps2, cam_i2c_sda_ps3, cam_rst_ps4cam_rst_ps4, clk_32k_in, | ||||
|     clk_32k_out_py5, clk_req, core_pwr_req, cpu_pwr_req, dap1_din_pb1, | ||||
|     dap1_dout_pb2, dap1_fs_pb0, dap1_sclk_pb3, dap2_din_paa2, dap2_dout_paa3, | ||||
|     dap2_fs_paa0, dap2_sclk_paa1, dap4_din_pj5, dap4_dout_pj6, dap4_fs_pj4, | ||||
|     dap4_sclk_pj7, dmic1_clk_pe0, dmic1_dat_pe1, dmic2_clk_pe2, dmic2_dat_pe3, | ||||
|     dmic3_clk_pe4, dmic3_dat_pe5, dp_hpd0_pcc6, dvfs_clk_pbb2, dvfs_pwm_pbb1, | ||||
|     gen1_i2c_scl_pj1, gen1_i2c_sda_pj0, gen2_i2c_scl_pj2, gen2_i2c_sda_pj3, | ||||
|     gen3_i2c_scl_pf0, gen3_i2c_sda_pf1, gpio_x1_aud_pbb3, gpio_x3_aud_pbb4, | ||||
|     gps_en_pi2, gps_rst_pi3, hdmi_cec_pcc0, hdmi_int_dp_hpd_pcc1, jtag_rtck, | ||||
|     lcd_bl_en_pv1, lcd_bl_pwm_pv0, lcd_gpio1_pv3, lcd_gpio2_pv4, lcd_rst_pv2, | ||||
|     lcd_te_py2, modem_wake_ap_px0, motion_int_px2, nfc_en_pi0, nfc_int_pi1, | ||||
|     pa6, pcc7, pe6, pe7, pex_l0_clkreq_n_pa1, pex_l0_rst_n_pa0, | ||||
|     pex_l1_clkreq_n_pa4, pex_l1_rst_n_pa3, pex_wake_n_pa2, ph6, pk0, pk1, pk2, | ||||
|     pk3, pk4, pk5, pk6, pk7, pl0, pl1, pwr_i2c_scl_py3, pwr_i2c_sda_py4, | ||||
|     pwr_int_n, pz0, pz1, pz2, pz3, pz4, pz5, qspi_cs_n_pee1, qspi_io0_pee2, | ||||
|     qspi_io1_pee3, qspi_io2_pee4, qspi_io3_pee5, qspi_sck_pee0, | ||||
|     sata_led_active_pa5, sdmmc1_clk_pm0, sdmmc1_cmd_pm1, sdmmc1_dat0_pm5, | ||||
|     sdmmc1_dat1_pm4, sdmmc1_dat2_pm3, sdmmc1_dat3_pm2, sdmmc3_clk_pp0, | ||||
|     sdmmc3_cmd_pp1, sdmmc3_dat0_pp5, sdmmc3_dat1_pp4, sdmmc3_dat2_pp3, | ||||
|     sdmmc3_dat3_pp2, shutdown, spdif_in_pcc3, spdif_out_pcc2, spi1_cs0_pc3, | ||||
|     spi1_cs1_pc4, spi1_miso_pc1, spi1_mosi_pc0, spi1_sck_pc2, spi2_cs0_pb7, | ||||
|     spi2_cs1_pdd0, spi2_miso_pb5, spi2_mosi_pb4, spi2_sck_pb6, spi4_cs0_pc6, | ||||
|     spi4_miso_pd0, spi4_mosi_pc7, spi4_sck_pc5, temp_alert_px4, touch_clk_pv7, | ||||
|     touch_int_px1, touch_rst_pv6, uart1_cts_pu3, uart1_rts_pu2, uart1_rx_pu1, | ||||
|     uart1_tx_pu0, uart2_cts_pg3, uart2_rts_pg2, uart2_rx_pg1, uart2_tx_pg0, | ||||
|     uart3_cts_pd4, uart3_rts_pd3, uart3_rx_pd2, uart3_tx_pd1, uart4_cts_pi7, | ||||
|     uart4_rts_pi6, uart4_rx_pi5, uart4_tx_pi4, usb_vbus_en0_pcc4, | ||||
|     usb_vbus_en1_pcc5, wifi_en_ph0, wifi_rst_ph1, wifi_wake_ap_ph2 | ||||
|  | ||||
|   Drive groups: | ||||
|  | ||||
|     These correspond to the Tegra APB_MISC_GP_*_PADCTRL (pad control) | ||||
|     registers. Note that where one of these registers controls a single pin | ||||
|     for which a PINMUX_AUX_* exists, see the list above for the pin name to | ||||
|     use when configuring the pinmux. | ||||
|  | ||||
|     pa6, pcc7, pe6, pe7, ph6, pk0, pk1, pk2, pk3, pk4, pk5, pk6, pk7, pl0, pl1, | ||||
|     pz0, pz1, pz2, pz3, pz4, pz5, sdmmc1, sdmmc2, sdmmc3, sdmmc4 | ||||
|  | ||||
| Valid values for nvidia,functions are: | ||||
|  | ||||
|     aud, bcl, blink, ccla, cec, cldvfs, clk, core, cpu, displaya, displayb, | ||||
|     dmic1, dmic2, dmic3, dp, dtv, extperiph3, i2c1, i2c2, i2c3, i2cpmu, i2cvi, | ||||
|     i2s1, i2s2, i2s3, i2s4a, i2s4b, i2s5a, i2s5b, iqc0, iqc1, jtag, pe, pe0, | ||||
|     pe1, pmi, pwm0, pwm1, pwm2, pwm3, qspi, rsvd0, rsvd1, rsvd2, rsvd3, sata, | ||||
|     sdmmc1, sdmmc3, shutdown, soc, sor0, sor1, spdif, spi1, spi2, spi3, spi4, | ||||
|     sys, touch, uart, uarta, uartb, uartc, uartd, usb, vgp1, vgp2, vgp3, vgp4, | ||||
|     vgp5, vgp6, vimclk, vimclk2 | ||||
|  | ||||
| Example: | ||||
|  | ||||
| 	pinmux: pinmux@70000800 { | ||||
| 		compatible = "nvidia,tegra210-pinmux"; | ||||
| 		reg = <0x0 0x700008d4 0x0 0x2a8>, /* Pad control registers */ | ||||
| 		      <0x0 0x70003000 0x0 0x1000>; /* Mux registers */ | ||||
|  | ||||
| 		pinctrl-names = "boot"; | ||||
| 		pinctrl-0 = <&state_boot>; | ||||
|  | ||||
| 		state_boot: pinmux { | ||||
| 			gen1_i2c_scl_pj1 { | ||||
| 				nvidia,pins = "gen1_i2c_scl_pj1", | ||||
| 				nvidia,function = "i2c1"; | ||||
| 				nvidia,pull = <TEGRA_PIN_PULL_NONE>; | ||||
| 				nvidia,tristate = <TEGRA_PIN_DISABLE>; | ||||
| 				nvidia,enable-input = <TEGRA_PIN_ENABLE>; | ||||
| 				nvidia,open-drain = <TEGRA_PIN_ENABLE>; | ||||
| 				nvidia,io-hv = <TEGRA_PIN_ENABLE>; | ||||
| 			}; | ||||
| 		}; | ||||
| 	}; | ||||
| }; | ||||
| @@ -38,7 +38,7 @@ 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 | ||||
| Each client device's own binding determines the set of states that 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. | ||||
| @@ -133,16 +133,27 @@ pin multiplexing nodes: | ||||
|  | ||||
| function		- the mux function to select | ||||
| groups			- the list of groups to select with this function | ||||
| 			  (either this or "pins" must be specified) | ||||
| pins			- the list of pins to select with this function (either | ||||
| 			  this or "groups" must be specified) | ||||
|  | ||||
| Example: | ||||
|  | ||||
| state_0_node_a { | ||||
| 	function = "uart0"; | ||||
| 	groups = "u0rxtx", "u0rtscts"; | ||||
| 	uart0 { | ||||
| 		function = "uart0"; | ||||
| 		groups = "u0rxtx", "u0rtscts"; | ||||
| 	}; | ||||
| }; | ||||
| state_1_node_a { | ||||
| 	function = "spi0"; | ||||
| 	groups = "spi0pins"; | ||||
| 	spi0 { | ||||
| 		function = "spi0"; | ||||
| 		groups = "spi0pins"; | ||||
| 	}; | ||||
| }; | ||||
| state_2_node_a { | ||||
| 	function = "i2c0"; | ||||
| 	pins = "mfio29", "mfio30"; | ||||
| }; | ||||
|  | ||||
| == Generic pin configuration node content == | ||||
| @@ -188,16 +199,22 @@ slew-rate		- set the slew rate | ||||
| For example: | ||||
|  | ||||
| state_0_node_a { | ||||
| 	pins = "GPIO0_AJ5", "GPIO2_AH4"; /* CTS+RXD */ | ||||
| 	bias-pull-up; | ||||
| 	cts_rxd { | ||||
| 		pins = "GPIO0_AJ5", "GPIO2_AH4"; /* CTS+RXD */ | ||||
| 		bias-pull-up; | ||||
| 	}; | ||||
| }; | ||||
| state_1_node_a { | ||||
| 	pins = "GPIO1_AJ3", "GPIO3_AH3"; /* RTS+TXD */ | ||||
| 	output-high; | ||||
| 	rts_txd { | ||||
| 		pins = "GPIO1_AJ3", "GPIO3_AH3"; /* RTS+TXD */ | ||||
| 		output-high; | ||||
| 	}; | ||||
| }; | ||||
| state_2_node_a { | ||||
| 	group = "foo-group"; | ||||
| 	bias-pull-up; | ||||
| 	foo { | ||||
| 		group = "foo-group"; | ||||
| 		bias-pull-up; | ||||
| 	}; | ||||
| }; | ||||
|  | ||||
| Some of the generic properties take arguments. For those that do, the | ||||
|   | ||||
							
								
								
									
										145
									
								
								Documentation/devicetree/bindings/pinctrl/pinctrl-mt65xx.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										145
									
								
								Documentation/devicetree/bindings/pinctrl/pinctrl-mt65xx.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,145 @@ | ||||
| * Mediatek MT65XX Pin Controller | ||||
|  | ||||
| The Mediatek's Pin controller is used to control SoC pins. | ||||
|  | ||||
| Required properties: | ||||
| - compatible: value should be either of the following. | ||||
|     (a) "mediatek,mt8135-pinctrl", compatible with mt8135 pinctrl. | ||||
| - mediatek,pctl-regmap: Should be a phandle of the syscfg node. | ||||
| - pins-are-numbered: Specify the subnodes are using numbered pinmux to | ||||
|   specify pins. | ||||
| - gpio-controller : Marks the device node as a gpio controller. | ||||
| - #gpio-cells: number of cells in GPIO specifier. Since the generic GPIO | ||||
|   binding is used, the amount of cells must be specified as 2. See the below | ||||
|   mentioned gpio binding representation for description of particular cells. | ||||
|  | ||||
| 	Eg: <&pio 6 0> | ||||
| 	<[phandle of the gpio controller node] | ||||
| 	[line number within the gpio controller] | ||||
| 	[flags]> | ||||
|  | ||||
| 	Values for gpio specifier: | ||||
| 	- Line number: is a value between 0 to 202. | ||||
| 	- Flags:  bit field of flags, as defined in <dt-bindings/gpio/gpio.h>. | ||||
|             Only the following flags are supported: | ||||
|             0 - GPIO_ACTIVE_HIGH | ||||
|             1 - GPIO_ACTIVE_LOW | ||||
| - reg: physicall address base for EINT registers | ||||
| - interrupt-controller: Marks the device node as an interrupt controller | ||||
| - #interrupt-cells: Should be two. | ||||
| - interrupts : The interrupt outputs from the controller. | ||||
|  | ||||
| Please refer to pinctrl-bindings.txt in this directory for details of the | ||||
| common pinctrl bindings used by client devices. | ||||
|  | ||||
| Subnode format | ||||
| A pinctrl node should contain at least one subnodes representing the | ||||
| pinctrl groups available on the machine. Each subnode will list the | ||||
| pins it needs, and how they should be configured, with regard to muxer | ||||
| configuration, pullups, drive strength, input enable/disable and input schmitt. | ||||
|  | ||||
|     node { | ||||
| 	pinmux = <PIN_NUMBER_PINMUX>; | ||||
| 	GENERIC_PINCONFIG; | ||||
|     }; | ||||
|  | ||||
| Required properties: | ||||
| - pinmux: integer array, represents gpio pin number and mux setting. | ||||
|     Supported pin number and mux varies for different SoCs, and are defined | ||||
|     as macros in boot/dts/<soc>-pinfunc.h directly. | ||||
|  | ||||
| Optional properties: | ||||
| - GENERIC_PINCONFIG: is the generic pinconfig options to use, bias-disable, | ||||
|     bias-pull-down, bias-pull-up, input-enable, input-disable, output-low, output-high, | ||||
|     input-schmitt-enable, input-schmitt-disable and drive-strength are valid. | ||||
|  | ||||
|     Some special pins have extra pull up strength, there are R0 and R1 pull-up | ||||
|     resistors available, but for user, it's only need to set R1R0 as 00, 01, 10 or 11. | ||||
|     So when config bias-pull-up, it support arguments for those special pins. | ||||
|     Some macros have been defined for this usage, such as MTK_PUPD_SET_R1R0_00. | ||||
|     See dt-bindings/pinctrl/mt65xx.h. | ||||
|  | ||||
|     When config drive-strength, it can support some arguments, such as | ||||
|     MTK_DRIVE_4mA, MTK_DRIVE_6mA, etc. See dt-bindings/pinctrl/mt65xx.h. | ||||
|  | ||||
| Examples: | ||||
|  | ||||
| #include "mt8135-pinfunc.h" | ||||
|  | ||||
| ... | ||||
| { | ||||
| 	syscfg_pctl_a: syscfg_pctl_a@10005000 { | ||||
| 		compatible = "mediatek,mt8135-pctl-a-syscfg", "syscon"; | ||||
| 		reg = <0 0x10005000 0 0x1000>; | ||||
| 	}; | ||||
|  | ||||
| 	syscfg_pctl_b: syscfg_pctl_b@1020C020 { | ||||
| 		compatible = "mediatek,mt8135-pctl-b-syscfg", "syscon"; | ||||
| 		reg = <0 0x1020C020 0 0x1000>; | ||||
| 	}; | ||||
|  | ||||
| 	pinctrl@01c20800 { | ||||
| 		compatible = "mediatek,mt8135-pinctrl"; | ||||
| 		reg = <0 0x1000B000 0 0x1000>; | ||||
| 		mediatek,pctl-regmap = <&syscfg_pctl_a &syscfg_pctl_b>; | ||||
| 		pins-are-numbered; | ||||
| 		gpio-controller; | ||||
| 		#gpio-cells = <2>; | ||||
| 		interrupt-controller; | ||||
| 		#interrupt-cells = <2>; | ||||
| 		interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>, | ||||
| 				<GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>, | ||||
| 				<GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>; | ||||
|  | ||||
| 		i2c0_pins_a: i2c0@0 { | ||||
| 			pins1 { | ||||
| 				pinmux = <MT8135_PIN_100_SDA0__FUNC_SDA0>, | ||||
| 					 <MT8135_PIN_101_SCL0__FUNC_SCL0>; | ||||
| 				bias-disable; | ||||
| 			}; | ||||
| 		}; | ||||
|  | ||||
| 		i2c1_pins_a: i2c1@0 { | ||||
| 			pins { | ||||
| 				pinmux = <MT8135_PIN_195_SDA1__FUNC_SDA1>, | ||||
| 					 <MT8135_PIN_196_SCL1__FUNC_SCL1>; | ||||
| 				bias-pull-up = <55>; | ||||
| 			}; | ||||
| 		}; | ||||
|  | ||||
| 		i2c2_pins_a: i2c2@0 { | ||||
| 			pins1 { | ||||
| 				pinmux = <MT8135_PIN_193_SDA2__FUNC_SDA2>; | ||||
| 				bias-pull-down; | ||||
| 			}; | ||||
|  | ||||
| 			pins2 { | ||||
| 				pinmux = <MT8135_PIN_49_WATCHDOG__FUNC_GPIO49>; | ||||
| 				bias-pull-up; | ||||
| 			}; | ||||
| 		}; | ||||
|  | ||||
| 		i2c3_pins_a: i2c3@0 { | ||||
| 			pins1 { | ||||
| 				pinmux = <MT8135_PIN_40_DAC_CLK__FUNC_GPIO40>, | ||||
| 					 <MT8135_PIN_41_DAC_WS__FUNC_GPIO41>; | ||||
| 				bias-pull-up = <55>; | ||||
| 			}; | ||||
|  | ||||
| 			pins2 { | ||||
| 				pinmux = <MT8135_PIN_35_SCL3__FUNC_SCL3>, | ||||
| 					 <MT8135_PIN_36_SDA3__FUNC_SDA3>; | ||||
| 				output-low; | ||||
| 				bias-pull-up = <55>; | ||||
| 			}; | ||||
|  | ||||
| 			pins3 { | ||||
| 				pinmux = <MT8135_PIN_57_JTCK__FUNC_GPIO57>, | ||||
| 					 <MT8135_PIN_60_JTDI__FUNC_JTDI>; | ||||
| 				drive-strength = <32>; | ||||
| 			}; | ||||
| 		}; | ||||
|  | ||||
| 		... | ||||
| 	} | ||||
| }; | ||||
| @@ -10,6 +10,7 @@ PMIC's from Qualcomm. | ||||
| 		    "qcom,pm8018-gpio" | ||||
| 		    "qcom,pm8038-gpio" | ||||
| 		    "qcom,pm8058-gpio" | ||||
| 		    "qcom,pm8916-gpio" | ||||
| 		    "qcom,pm8917-gpio" | ||||
| 		    "qcom,pm8921-gpio" | ||||
| 		    "qcom,pm8941-gpio" | ||||
| @@ -74,6 +75,7 @@ to specify in a pin configuration subnode: | ||||
| 		    gpio1-gpio6 for pm8018 | ||||
| 		    gpio1-gpio12 for pm8038 | ||||
| 		    gpio1-gpio40 for pm8058 | ||||
| 		    gpio1-gpio4 for pm8916 | ||||
| 		    gpio1-gpio38 for pm8917 | ||||
| 		    gpio1-gpio44 for pm8921 | ||||
| 		    gpio1-gpio36 for pm8941 | ||||
|   | ||||
| @@ -8,6 +8,7 @@ of PMIC's from Qualcomm. | ||||
| 	Value type: <string> | ||||
| 	Definition: Should contain one of: | ||||
| 		    "qcom,pm8841-mpp", | ||||
| 		    "qcom,pm8916-mpp", | ||||
| 		    "qcom,pm8941-mpp", | ||||
| 		    "qcom,pma8084-mpp", | ||||
|  | ||||
| @@ -67,6 +68,7 @@ to specify in a pin configuration subnode: | ||||
| 	Definition: List of MPP pins affected by the properties specified in | ||||
| 		    this subnode.  Valid pins are: | ||||
| 		    mpp1-mpp4 for pm8841 | ||||
| 		    mpp1-mpp4 for pm8916 | ||||
| 		    mpp1-mpp8 for pm8941 | ||||
| 		    mpp1-mpp4 for pma8084 | ||||
|  | ||||
|   | ||||
| @@ -72,7 +72,6 @@ static struct pinctrl_desc foo_desc = { | ||||
| 	.name = "foo", | ||||
| 	.pins = foo_pins, | ||||
| 	.npins = ARRAY_SIZE(foo_pins), | ||||
| 	.maxpin = 63, | ||||
| 	.owner = THIS_MODULE, | ||||
| }; | ||||
|  | ||||
| @@ -164,8 +163,8 @@ static const char *foo_get_group_name(struct pinctrl_dev *pctldev, | ||||
| } | ||||
|  | ||||
| static int foo_get_group_pins(struct pinctrl_dev *pctldev, unsigned selector, | ||||
| 			       unsigned ** const pins, | ||||
| 			       unsigned * const num_pins) | ||||
| 			       const unsigned **pins, | ||||
| 			       unsigned *num_pins) | ||||
| { | ||||
| 	*pins = (unsigned *) foo_groups[selector].pins; | ||||
| 	*num_pins = foo_groups[selector].num_pins; | ||||
| @@ -570,9 +569,8 @@ is possible to perform the requested mux setting, poke the hardware so that | ||||
| this happens. | ||||
|  | ||||
| Pinmux drivers are required to supply a few callback functions, some are | ||||
| optional. Usually the enable() and disable() functions are implemented, | ||||
| writing values into some certain registers to activate a certain mux setting | ||||
| for a certain pin. | ||||
| optional. Usually the set_mux() function is implemented, writing values into | ||||
| some certain registers to activate a certain mux setting for a certain pin. | ||||
|  | ||||
| A simple driver for the above example will work by setting bits 0, 1, 2, 3 or 4 | ||||
| into some register named MUX to select a certain function with a certain | ||||
| @@ -683,12 +681,12 @@ static const struct foo_pmx_func foo_functions[] = { | ||||
| 	}, | ||||
| }; | ||||
|  | ||||
| int foo_get_functions_count(struct pinctrl_dev *pctldev) | ||||
| static int foo_get_functions_count(struct pinctrl_dev *pctldev) | ||||
| { | ||||
| 	return ARRAY_SIZE(foo_functions); | ||||
| } | ||||
|  | ||||
| const char *foo_get_fname(struct pinctrl_dev *pctldev, unsigned selector) | ||||
| static const char *foo_get_fname(struct pinctrl_dev *pctldev, unsigned selector) | ||||
| { | ||||
| 	return foo_functions[selector].name; | ||||
| } | ||||
| @@ -702,7 +700,7 @@ static int foo_get_groups(struct pinctrl_dev *pctldev, unsigned selector, | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| int foo_set_mux(struct pinctrl_dev *pctldev, unsigned selector, | ||||
| static int foo_set_mux(struct pinctrl_dev *pctldev, unsigned selector, | ||||
| 		unsigned group) | ||||
| { | ||||
| 	u8 regbit = (1 << selector + group); | ||||
| @@ -711,7 +709,7 @@ int foo_set_mux(struct pinctrl_dev *pctldev, unsigned selector, | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| struct pinmux_ops foo_pmxops = { | ||||
| static struct pinmux_ops foo_pmxops = { | ||||
| 	.get_functions_count = foo_get_functions_count, | ||||
| 	.get_function_name = foo_get_fname, | ||||
| 	.get_function_groups = foo_get_groups, | ||||
| @@ -1266,7 +1264,7 @@ The semantics of the pinctrl APIs are: | ||||
|  | ||||
| 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 | ||||
| the associated pins, whereas select_state pass on to the pin controller | ||||
| driver which takes care of activating and/or deactivating the mux setting by | ||||
| quickly poking some registers. | ||||
|  | ||||
| @@ -1363,8 +1361,9 @@ function, but with different named in the mapping as described under | ||||
| "Advanced mapping" above. So that for an SPI device, we have two states named | ||||
| "pos-A" and "pos-B". | ||||
|  | ||||
| This snippet first muxes the function in the pins defined by group A, enables | ||||
| it, disables and releases it, and muxes it in on the pins defined by group B: | ||||
| This snippet first initializes a state object for both groups (in foo_probe()), | ||||
| then muxes the function in the pins defined by group A, and finally muxes it in | ||||
| on the pins defined by group B: | ||||
|  | ||||
| #include <linux/pinctrl/consumer.h> | ||||
|  | ||||
|   | ||||
| @@ -67,23 +67,20 @@ config PINCTRL_AT91 | ||||
| 	help | ||||
| 	  Say Y here to enable the at91 pinctrl driver | ||||
|  | ||||
| config PINCTRL_BCM2835 | ||||
| 	bool | ||||
| 	select PINMUX | ||||
| 	select PINCONF | ||||
|  | ||||
| config PINCTRL_BCM281XX | ||||
| 	bool "Broadcom BCM281xx pinctrl driver" | ||||
| 	depends on OF && (ARCH_BCM_MOBILE || COMPILE_TEST) | ||||
| 	select PINMUX | ||||
| config PINCTRL_AMD | ||||
| 	bool "AMD GPIO pin control" | ||||
| 	depends on GPIOLIB | ||||
| 	select GPIOLIB_IRQCHIP | ||||
| 	select PINCONF | ||||
| 	select GENERIC_PINCONF | ||||
| 	select REGMAP_MMIO | ||||
| 	help | ||||
| 	  Say Y here to support Broadcom BCM281xx pinctrl driver, which is used | ||||
| 	  for the BCM281xx SoC family, including BCM11130, BCM11140, BCM11351, | ||||
| 	  BCM28145, and BCM28155 SoCs.  This driver requires the pinctrl | ||||
| 	  framework.  GPIO is provided by a separate GPIO driver. | ||||
| 	  driver for memory mapped GPIO functionality on AMD platforms | ||||
| 	  (x86 or arm).Most pins are usually muxed to some other | ||||
| 	  functionality by firmware,so only a small amount is available | ||||
| 	  for gpio use. | ||||
|  | ||||
| 	  Requires ACPI/FDT device enumeration code to set up a platform | ||||
| 	  device. | ||||
|  | ||||
| config PINCTRL_LANTIQ | ||||
| 	bool | ||||
| @@ -154,6 +151,10 @@ config PINCTRL_TEGRA124 | ||||
| 	bool | ||||
| 	select PINCTRL_TEGRA | ||||
|  | ||||
| config PINCTRL_TEGRA210 | ||||
| 	bool | ||||
| 	select PINCTRL_TEGRA | ||||
|  | ||||
| config PINCTRL_TEGRA_XUSB | ||||
| 	def_bool y if ARCH_TEGRA | ||||
| 	select GENERIC_PHY | ||||
| @@ -207,6 +208,7 @@ config PINCTRL_ZYNQ | ||||
| 	help | ||||
| 	  This selectes the pinctrl driver for Xilinx Zynq. | ||||
|  | ||||
| source "drivers/pinctrl/bcm/Kconfig" | ||||
| source "drivers/pinctrl/berlin/Kconfig" | ||||
| source "drivers/pinctrl/freescale/Kconfig" | ||||
| source "drivers/pinctrl/intel/Kconfig" | ||||
| @@ -218,6 +220,7 @@ source "drivers/pinctrl/sh-pfc/Kconfig" | ||||
| source "drivers/pinctrl/spear/Kconfig" | ||||
| source "drivers/pinctrl/sunxi/Kconfig" | ||||
| source "drivers/pinctrl/vt8500/Kconfig" | ||||
| source "drivers/pinctrl/mediatek/Kconfig" | ||||
|  | ||||
| config PINCTRL_XWAY | ||||
| 	bool | ||||
|   | ||||
| @@ -14,8 +14,7 @@ obj-$(CONFIG_PINCTRL_AS3722)	+= pinctrl-as3722.o | ||||
| obj-$(CONFIG_PINCTRL_BF54x)	+= pinctrl-adi2-bf54x.o | ||||
| obj-$(CONFIG_PINCTRL_BF60x)	+= pinctrl-adi2-bf60x.o | ||||
| obj-$(CONFIG_PINCTRL_AT91)	+= pinctrl-at91.o | ||||
| obj-$(CONFIG_PINCTRL_BCM2835)	+= pinctrl-bcm2835.o | ||||
| obj-$(CONFIG_PINCTRL_BCM281XX)	+= pinctrl-bcm281xx.o | ||||
| obj-$(CONFIG_PINCTRL_AMD)	+= pinctrl-amd.o | ||||
| obj-$(CONFIG_PINCTRL_FALCON)	+= pinctrl-falcon.o | ||||
| obj-$(CONFIG_PINCTRL_MESON)	+= meson/ | ||||
| obj-$(CONFIG_PINCTRL_PALMAS)	+= pinctrl-palmas.o | ||||
| @@ -27,6 +26,7 @@ obj-$(CONFIG_PINCTRL_TEGRA20)	+= pinctrl-tegra20.o | ||||
| obj-$(CONFIG_PINCTRL_TEGRA30)	+= pinctrl-tegra30.o | ||||
| obj-$(CONFIG_PINCTRL_TEGRA114)	+= pinctrl-tegra114.o | ||||
| obj-$(CONFIG_PINCTRL_TEGRA124)	+= pinctrl-tegra124.o | ||||
| obj-$(CONFIG_PINCTRL_TEGRA210)	+= pinctrl-tegra210.o | ||||
| obj-$(CONFIG_PINCTRL_TEGRA_XUSB)	+= pinctrl-tegra-xusb.o | ||||
| obj-$(CONFIG_PINCTRL_TZ1090)	+= pinctrl-tz1090.o | ||||
| obj-$(CONFIG_PINCTRL_TZ1090_PDC)	+= pinctrl-tz1090-pdc.o | ||||
| @@ -38,6 +38,7 @@ obj-$(CONFIG_PINCTRL_TB10X)	+= pinctrl-tb10x.o | ||||
| obj-$(CONFIG_PINCTRL_ST) 	+= pinctrl-st.o | ||||
| obj-$(CONFIG_PINCTRL_ZYNQ)	+= pinctrl-zynq.o | ||||
|  | ||||
| obj-$(CONFIG_ARCH_BCM)		+= bcm/ | ||||
| obj-$(CONFIG_ARCH_BERLIN)	+= berlin/ | ||||
| obj-y				+= freescale/ | ||||
| obj-$(CONFIG_X86)		+= intel/ | ||||
| @@ -49,3 +50,4 @@ obj-$(CONFIG_PINCTRL_SH_PFC)	+= sh-pfc/ | ||||
| obj-$(CONFIG_PLAT_SPEAR)	+= spear/ | ||||
| obj-$(CONFIG_ARCH_SUNXI)	+= sunxi/ | ||||
| obj-$(CONFIG_ARCH_VT8500)	+= vt8500/ | ||||
| obj-$(CONFIG_ARCH_MEDIATEK)	+= mediatek/ | ||||
|   | ||||
							
								
								
									
										56
									
								
								drivers/pinctrl/bcm/Kconfig
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								drivers/pinctrl/bcm/Kconfig
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,56 @@ | ||||
| # | ||||
| # Broadcom pinctrl drivers | ||||
| # | ||||
|  | ||||
| config PINCTRL_BCM281XX | ||||
| 	bool "Broadcom BCM281xx pinctrl driver" | ||||
| 	depends on OF && (ARCH_BCM_MOBILE || COMPILE_TEST) | ||||
| 	select PINMUX | ||||
| 	select PINCONF | ||||
| 	select GENERIC_PINCONF | ||||
| 	select REGMAP_MMIO | ||||
| 	help | ||||
| 	  Say Y here to support Broadcom BCM281xx pinctrl driver, which is used | ||||
| 	  for the BCM281xx SoC family, including BCM11130, BCM11140, BCM11351, | ||||
| 	  BCM28145, and BCM28155 SoCs.  This driver requires the pinctrl | ||||
| 	  framework.  GPIO is provided by a separate GPIO driver. | ||||
|  | ||||
| config PINCTRL_BCM2835 | ||||
| 	bool | ||||
| 	select PINMUX | ||||
| 	select PINCONF | ||||
|  | ||||
| config PINCTRL_CYGNUS_GPIO | ||||
| 	bool "Broadcom Cygnus GPIO (with PINCONF) driver" | ||||
| 	depends on OF_GPIO && ARCH_BCM_CYGNUS | ||||
| 	select GPIOLIB_IRQCHIP | ||||
| 	select PINCONF | ||||
| 	select GENERIC_PINCONF | ||||
| 	default ARCH_BCM_CYGNUS | ||||
| 	help | ||||
| 	  Say yes here to enable the Broadcom Cygnus GPIO driver. | ||||
|  | ||||
| 	  The Broadcom Cygnus SoC has 3 GPIO controllers including the ASIU | ||||
| 	  GPIO controller (ASIU), the chipCommonG GPIO controller (CCM), and | ||||
| 	  the always-ON GPIO controller (CRMU/AON). All 3 GPIO controllers are | ||||
| 	  supported by this driver. | ||||
|  | ||||
| 	  All 3 Cygnus GPIO controllers support basic PINCONF functions such | ||||
| 	  as bias pull up, pull down, and drive strength configurations, when | ||||
| 	  these pins are muxed to GPIO. | ||||
|  | ||||
| 	  Pins from the ASIU GPIO can be individually muxed to GPIO function, | ||||
| 	  through interaction with the Cygnus IOMUX controller. | ||||
|  | ||||
| config PINCTRL_CYGNUS_MUX | ||||
| 	bool "Broadcom Cygnus IOMUX driver" | ||||
| 	depends on (ARCH_BCM_CYGNUS || COMPILE_TEST) | ||||
| 	select PINMUX | ||||
| 	select GENERIC_PINCONF | ||||
| 	default ARCH_BCM_CYGNUS | ||||
| 	help | ||||
| 	  Say yes here to enable the Broadcom Cygnus IOMUX driver. | ||||
|  | ||||
| 	  The Broadcom Cygnus IOMUX driver supports group based IOMUX | ||||
| 	  configuration, with the exception that certain individual pins | ||||
| 	  can be overrided to GPIO function | ||||
							
								
								
									
										6
									
								
								drivers/pinctrl/bcm/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								drivers/pinctrl/bcm/Makefile
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,6 @@ | ||||
| # Broadcom pinctrl support | ||||
|  | ||||
| obj-$(CONFIG_PINCTRL_BCM281XX)		+= pinctrl-bcm281xx.o | ||||
| obj-$(CONFIG_PINCTRL_BCM2835)		+= pinctrl-bcm2835.o | ||||
| obj-$(CONFIG_PINCTRL_CYGNUS_GPIO)	+= pinctrl-cygnus-gpio.o | ||||
| obj-$(CONFIG_PINCTRL_CYGNUS_MUX)	+= pinctrl-cygnus-mux.o | ||||
| @@ -21,8 +21,8 @@ | ||||
| #include <linux/pinctrl/pinconf-generic.h> | ||||
| #include <linux/regmap.h> | ||||
| #include <linux/slab.h> | ||||
| #include "core.h" | ||||
| #include "pinctrl-utils.h" | ||||
| #include "../core.h" | ||||
| #include "../pinctrl-utils.h" | ||||
| 
 | ||||
| /* BCM281XX Pin Control Registers Definitions */ | ||||
| 
 | ||||
| @@ -403,15 +403,7 @@ static irqreturn_t bcm2835_gpio_irq_handler(int irq, void *dev_id) | ||||
| 		gpio = (32 * bank) + offset; | ||||
| 		type = pc->irq_type[gpio]; | ||||
| 
 | ||||
| 		/* ack edge triggered IRQs immediately */ | ||||
| 		if (!(type & IRQ_TYPE_LEVEL_MASK)) | ||||
| 			bcm2835_gpio_set_bit(pc, GPEDS0, gpio); | ||||
| 
 | ||||
| 		generic_handle_irq(irq_linear_revmap(pc->irq_domain, gpio)); | ||||
| 
 | ||||
| 		/* ack level triggered IRQ after handling them */ | ||||
| 		if (type & IRQ_TYPE_LEVEL_MASK) | ||||
| 			bcm2835_gpio_set_bit(pc, GPEDS0, gpio); | ||||
| 	} | ||||
| 	return events ? IRQ_HANDLED : IRQ_NONE; | ||||
| } | ||||
| @@ -591,16 +583,32 @@ static int bcm2835_gpio_irq_set_type(struct irq_data *data, unsigned int type) | ||||
| 	else | ||||
| 		ret = __bcm2835_gpio_irq_set_type_disabled(pc, gpio, type); | ||||
| 
 | ||||
| 	if (type & IRQ_TYPE_EDGE_BOTH) | ||||
| 		__irq_set_handler_locked(data->irq, handle_edge_irq); | ||||
| 	else | ||||
| 		__irq_set_handler_locked(data->irq, handle_level_irq); | ||||
| 
 | ||||
| 	spin_unlock_irqrestore(&pc->irq_lock[bank], flags); | ||||
| 
 | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| static void bcm2835_gpio_irq_ack(struct irq_data *data) | ||||
| { | ||||
| 	struct bcm2835_pinctrl *pc = irq_data_get_irq_chip_data(data); | ||||
| 	unsigned gpio = irqd_to_hwirq(data); | ||||
| 
 | ||||
| 	bcm2835_gpio_set_bit(pc, GPEDS0, gpio); | ||||
| } | ||||
| 
 | ||||
| static struct irq_chip bcm2835_gpio_irq_chip = { | ||||
| 	.name = MODULE_NAME, | ||||
| 	.irq_enable = bcm2835_gpio_irq_enable, | ||||
| 	.irq_disable = bcm2835_gpio_irq_disable, | ||||
| 	.irq_set_type = bcm2835_gpio_irq_set_type, | ||||
| 	.irq_ack = bcm2835_gpio_irq_ack, | ||||
| 	.irq_mask = bcm2835_gpio_irq_disable, | ||||
| 	.irq_unmask = bcm2835_gpio_irq_enable, | ||||
| }; | ||||
| 
 | ||||
| static int bcm2835_pctl_get_groups_count(struct pinctrl_dev *pctldev) | ||||
| @@ -977,7 +985,7 @@ static int bcm2835_pinctrl_probe(struct platform_device *pdev) | ||||
| 		int irq = irq_create_mapping(pc->irq_domain, i); | ||||
| 		irq_set_lockdep_class(irq, &gpio_lock_class); | ||||
| 		irq_set_chip_and_handler(irq, &bcm2835_gpio_irq_chip, | ||||
| 				handle_simple_irq); | ||||
| 				handle_level_irq); | ||||
| 		irq_set_chip_data(irq, pc); | ||||
| 		set_irq_flags(irq, IRQF_VALID); | ||||
| 	} | ||||
| @@ -1051,7 +1059,7 @@ static int bcm2835_pinctrl_remove(struct platform_device *pdev) | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static struct of_device_id bcm2835_pinctrl_match[] = { | ||||
| static const struct of_device_id bcm2835_pinctrl_match[] = { | ||||
| 	{ .compatible = "brcm,bcm2835-gpio" }, | ||||
| 	{} | ||||
| }; | ||||
							
								
								
									
										907
									
								
								drivers/pinctrl/bcm/pinctrl-cygnus-gpio.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										907
									
								
								drivers/pinctrl/bcm/pinctrl-cygnus-gpio.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,907 @@ | ||||
| /* | ||||
|  * Copyright (C) 2014-2015 Broadcom Corporation | ||||
|  * | ||||
|  * 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 version 2. | ||||
|  * | ||||
|  * This program is distributed "as is" WITHOUT ANY WARRANTY of any | ||||
|  * kind, whether express or implied; without even the implied warranty | ||||
|  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * This file contains the Broadcom Cygnus GPIO driver that supports 3 | ||||
|  * GPIO controllers on Cygnus including the ASIU GPIO controller, the | ||||
|  * chipCommonG GPIO controller, and the always-on GPIO controller. Basic | ||||
|  * PINCONF such as bias pull up/down, and drive strength are also supported | ||||
|  * in this driver. | ||||
|  * | ||||
|  * Pins from the ASIU GPIO can be individually muxed to GPIO function, | ||||
|  * through the interaction with the Cygnus IOMUX controller | ||||
|  */ | ||||
|  | ||||
| #include <linux/kernel.h> | ||||
| #include <linux/slab.h> | ||||
| #include <linux/interrupt.h> | ||||
| #include <linux/io.h> | ||||
| #include <linux/gpio.h> | ||||
| #include <linux/ioport.h> | ||||
| #include <linux/of_device.h> | ||||
| #include <linux/of_irq.h> | ||||
| #include <linux/pinctrl/pinctrl.h> | ||||
| #include <linux/pinctrl/pinmux.h> | ||||
| #include <linux/pinctrl/pinconf.h> | ||||
| #include <linux/pinctrl/pinconf-generic.h> | ||||
|  | ||||
| #include "../pinctrl-utils.h" | ||||
|  | ||||
| #define CYGNUS_GPIO_DATA_IN_OFFSET   0x00 | ||||
| #define CYGNUS_GPIO_DATA_OUT_OFFSET  0x04 | ||||
| #define CYGNUS_GPIO_OUT_EN_OFFSET    0x08 | ||||
| #define CYGNUS_GPIO_IN_TYPE_OFFSET   0x0c | ||||
| #define CYGNUS_GPIO_INT_DE_OFFSET    0x10 | ||||
| #define CYGNUS_GPIO_INT_EDGE_OFFSET  0x14 | ||||
| #define CYGNUS_GPIO_INT_MSK_OFFSET   0x18 | ||||
| #define CYGNUS_GPIO_INT_STAT_OFFSET  0x1c | ||||
| #define CYGNUS_GPIO_INT_MSTAT_OFFSET 0x20 | ||||
| #define CYGNUS_GPIO_INT_CLR_OFFSET   0x24 | ||||
| #define CYGNUS_GPIO_PAD_RES_OFFSET   0x34 | ||||
| #define CYGNUS_GPIO_RES_EN_OFFSET    0x38 | ||||
|  | ||||
| /* drive strength control for ASIU GPIO */ | ||||
| #define CYGNUS_GPIO_ASIU_DRV0_CTRL_OFFSET 0x58 | ||||
|  | ||||
| /* drive strength control for CCM/CRMU (AON) GPIO */ | ||||
| #define CYGNUS_GPIO_DRV0_CTRL_OFFSET  0x00 | ||||
|  | ||||
| #define GPIO_BANK_SIZE 0x200 | ||||
| #define NGPIOS_PER_BANK 32 | ||||
| #define GPIO_BANK(pin) ((pin) / NGPIOS_PER_BANK) | ||||
|  | ||||
| #define CYGNUS_GPIO_REG(pin, reg) (GPIO_BANK(pin) * GPIO_BANK_SIZE + (reg)) | ||||
| #define CYGNUS_GPIO_SHIFT(pin) ((pin) % NGPIOS_PER_BANK) | ||||
|  | ||||
| #define GPIO_DRV_STRENGTH_BIT_SHIFT  20 | ||||
| #define GPIO_DRV_STRENGTH_BITS       3 | ||||
| #define GPIO_DRV_STRENGTH_BIT_MASK   ((1 << GPIO_DRV_STRENGTH_BITS) - 1) | ||||
|  | ||||
| /* | ||||
|  * Cygnus GPIO core | ||||
|  * | ||||
|  * @dev: pointer to device | ||||
|  * @base: I/O register base for Cygnus GPIO controller | ||||
|  * @io_ctrl: I/O register base for certain type of Cygnus GPIO controller that | ||||
|  * has the PINCONF support implemented outside of the GPIO block | ||||
|  * @lock: lock to protect access to I/O registers | ||||
|  * @gc: GPIO chip | ||||
|  * @num_banks: number of GPIO banks, each bank supports up to 32 GPIOs | ||||
|  * @pinmux_is_supported: flag to indicate this GPIO controller contains pins | ||||
|  * that can be individually muxed to GPIO | ||||
|  * @pctl: pointer to pinctrl_dev | ||||
|  * @pctldesc: pinctrl descriptor | ||||
|  */ | ||||
| struct cygnus_gpio { | ||||
| 	struct device *dev; | ||||
|  | ||||
| 	void __iomem *base; | ||||
| 	void __iomem *io_ctrl; | ||||
|  | ||||
| 	spinlock_t lock; | ||||
|  | ||||
| 	struct gpio_chip gc; | ||||
| 	unsigned num_banks; | ||||
|  | ||||
| 	bool pinmux_is_supported; | ||||
|  | ||||
| 	struct pinctrl_dev *pctl; | ||||
| 	struct pinctrl_desc pctldesc; | ||||
| }; | ||||
|  | ||||
| static inline struct cygnus_gpio *to_cygnus_gpio(struct gpio_chip *gc) | ||||
| { | ||||
| 	return container_of(gc, struct cygnus_gpio, gc); | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * Mapping from PINCONF pins to GPIO pins is 1-to-1 | ||||
|  */ | ||||
| static inline unsigned cygnus_pin_to_gpio(unsigned pin) | ||||
| { | ||||
| 	return pin; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  *  cygnus_set_bit - set or clear one bit (corresponding to the GPIO pin) in a | ||||
|  *  Cygnus GPIO register | ||||
|  * | ||||
|  *  @cygnus_gpio: Cygnus GPIO device | ||||
|  *  @reg: register offset | ||||
|  *  @gpio: GPIO pin | ||||
|  *  @set: set or clear | ||||
|  */ | ||||
| static inline void cygnus_set_bit(struct cygnus_gpio *chip, unsigned int reg, | ||||
| 				  unsigned gpio, bool set) | ||||
| { | ||||
| 	unsigned int offset = CYGNUS_GPIO_REG(gpio, reg); | ||||
| 	unsigned int shift = CYGNUS_GPIO_SHIFT(gpio); | ||||
| 	u32 val; | ||||
|  | ||||
| 	val = readl(chip->base + offset); | ||||
| 	if (set) | ||||
| 		val |= BIT(shift); | ||||
| 	else | ||||
| 		val &= ~BIT(shift); | ||||
| 	writel(val, chip->base + offset); | ||||
| } | ||||
|  | ||||
| static inline bool cygnus_get_bit(struct cygnus_gpio *chip, unsigned int reg, | ||||
| 				  unsigned gpio) | ||||
| { | ||||
| 	unsigned int offset = CYGNUS_GPIO_REG(gpio, reg); | ||||
| 	unsigned int shift = CYGNUS_GPIO_SHIFT(gpio); | ||||
|  | ||||
| 	return !!(readl(chip->base + offset) & BIT(shift)); | ||||
| } | ||||
|  | ||||
| static void cygnus_gpio_irq_handler(unsigned int irq, struct irq_desc *desc) | ||||
| { | ||||
| 	struct gpio_chip *gc = irq_desc_get_handler_data(desc); | ||||
| 	struct cygnus_gpio *chip = to_cygnus_gpio(gc); | ||||
| 	struct irq_chip *irq_chip = irq_desc_get_chip(desc); | ||||
| 	int i, bit; | ||||
|  | ||||
| 	chained_irq_enter(irq_chip, desc); | ||||
|  | ||||
| 	/* go through the entire GPIO banks and handle all interrupts */ | ||||
| 	for (i = 0; i < chip->num_banks; i++) { | ||||
| 		unsigned long val = readl(chip->base + (i * GPIO_BANK_SIZE) + | ||||
| 					  CYGNUS_GPIO_INT_MSTAT_OFFSET); | ||||
|  | ||||
| 		for_each_set_bit(bit, &val, NGPIOS_PER_BANK) { | ||||
| 			unsigned pin = NGPIOS_PER_BANK * i + bit; | ||||
| 			int child_irq = irq_find_mapping(gc->irqdomain, pin); | ||||
|  | ||||
| 			/* | ||||
| 			 * Clear the interrupt before invoking the | ||||
| 			 * handler, so we do not leave any window | ||||
| 			 */ | ||||
| 			writel(BIT(bit), chip->base + (i * GPIO_BANK_SIZE) + | ||||
| 			       CYGNUS_GPIO_INT_CLR_OFFSET); | ||||
|  | ||||
| 			generic_handle_irq(child_irq); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	chained_irq_exit(irq_chip, desc); | ||||
| } | ||||
|  | ||||
|  | ||||
| static void cygnus_gpio_irq_ack(struct irq_data *d) | ||||
| { | ||||
| 	struct gpio_chip *gc = irq_data_get_irq_chip_data(d); | ||||
| 	struct cygnus_gpio *chip = to_cygnus_gpio(gc); | ||||
| 	unsigned gpio = d->hwirq; | ||||
| 	unsigned int offset = CYGNUS_GPIO_REG(gpio, | ||||
| 			CYGNUS_GPIO_INT_CLR_OFFSET); | ||||
| 	unsigned int shift = CYGNUS_GPIO_SHIFT(gpio); | ||||
| 	u32 val = BIT(shift); | ||||
|  | ||||
| 	writel(val, chip->base + offset); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  *  cygnus_gpio_irq_set_mask - mask/unmask a GPIO interrupt | ||||
|  * | ||||
|  *  @d: IRQ chip data | ||||
|  *  @unmask: mask/unmask GPIO interrupt | ||||
|  */ | ||||
| static void cygnus_gpio_irq_set_mask(struct irq_data *d, bool unmask) | ||||
| { | ||||
| 	struct gpio_chip *gc = irq_data_get_irq_chip_data(d); | ||||
| 	struct cygnus_gpio *chip = to_cygnus_gpio(gc); | ||||
| 	unsigned gpio = d->hwirq; | ||||
|  | ||||
| 	cygnus_set_bit(chip, CYGNUS_GPIO_INT_MSK_OFFSET, gpio, unmask); | ||||
| } | ||||
|  | ||||
| static void cygnus_gpio_irq_mask(struct irq_data *d) | ||||
| { | ||||
| 	struct gpio_chip *gc = irq_data_get_irq_chip_data(d); | ||||
| 	struct cygnus_gpio *chip = to_cygnus_gpio(gc); | ||||
| 	unsigned long flags; | ||||
|  | ||||
| 	spin_lock_irqsave(&chip->lock, flags); | ||||
| 	cygnus_gpio_irq_set_mask(d, false); | ||||
| 	spin_unlock_irqrestore(&chip->lock, flags); | ||||
| } | ||||
|  | ||||
| static void cygnus_gpio_irq_unmask(struct irq_data *d) | ||||
| { | ||||
| 	struct gpio_chip *gc = irq_data_get_irq_chip_data(d); | ||||
| 	struct cygnus_gpio *chip = to_cygnus_gpio(gc); | ||||
| 	unsigned long flags; | ||||
|  | ||||
| 	spin_lock_irqsave(&chip->lock, flags); | ||||
| 	cygnus_gpio_irq_set_mask(d, true); | ||||
| 	spin_unlock_irqrestore(&chip->lock, flags); | ||||
| } | ||||
|  | ||||
| static int cygnus_gpio_irq_set_type(struct irq_data *d, unsigned int type) | ||||
| { | ||||
| 	struct gpio_chip *gc = irq_data_get_irq_chip_data(d); | ||||
| 	struct cygnus_gpio *chip = to_cygnus_gpio(gc); | ||||
| 	unsigned gpio = d->hwirq; | ||||
| 	bool level_triggered = false; | ||||
| 	bool dual_edge = false; | ||||
| 	bool rising_or_high = false; | ||||
| 	unsigned long flags; | ||||
|  | ||||
| 	switch (type & IRQ_TYPE_SENSE_MASK) { | ||||
| 	case IRQ_TYPE_EDGE_RISING: | ||||
| 		rising_or_high = true; | ||||
| 		break; | ||||
|  | ||||
| 	case IRQ_TYPE_EDGE_FALLING: | ||||
| 		break; | ||||
|  | ||||
| 	case IRQ_TYPE_EDGE_BOTH: | ||||
| 		dual_edge = true; | ||||
| 		break; | ||||
|  | ||||
| 	case IRQ_TYPE_LEVEL_HIGH: | ||||
| 		level_triggered = true; | ||||
| 		rising_or_high = true; | ||||
| 		break; | ||||
|  | ||||
| 	case IRQ_TYPE_LEVEL_LOW: | ||||
| 		level_triggered = true; | ||||
| 		break; | ||||
|  | ||||
| 	default: | ||||
| 		dev_err(chip->dev, "invalid GPIO IRQ type 0x%x\n", | ||||
| 			type); | ||||
| 		return -EINVAL; | ||||
| 	} | ||||
|  | ||||
| 	spin_lock_irqsave(&chip->lock, flags); | ||||
| 	cygnus_set_bit(chip, CYGNUS_GPIO_IN_TYPE_OFFSET, gpio, | ||||
| 		       level_triggered); | ||||
| 	cygnus_set_bit(chip, CYGNUS_GPIO_INT_DE_OFFSET, gpio, dual_edge); | ||||
| 	cygnus_set_bit(chip, CYGNUS_GPIO_INT_EDGE_OFFSET, gpio, | ||||
| 		       rising_or_high); | ||||
| 	spin_unlock_irqrestore(&chip->lock, flags); | ||||
|  | ||||
| 	dev_dbg(chip->dev, | ||||
| 		"gpio:%u level_triggered:%d dual_edge:%d rising_or_high:%d\n", | ||||
| 		gpio, level_triggered, dual_edge, rising_or_high); | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static struct irq_chip cygnus_gpio_irq_chip = { | ||||
| 	.name = "bcm-cygnus-gpio", | ||||
| 	.irq_ack = cygnus_gpio_irq_ack, | ||||
| 	.irq_mask = cygnus_gpio_irq_mask, | ||||
| 	.irq_unmask = cygnus_gpio_irq_unmask, | ||||
| 	.irq_set_type = cygnus_gpio_irq_set_type, | ||||
| }; | ||||
|  | ||||
| /* | ||||
|  * Request the Cygnus IOMUX pinmux controller to mux individual pins to GPIO | ||||
|  */ | ||||
| static int cygnus_gpio_request(struct gpio_chip *gc, unsigned offset) | ||||
| { | ||||
| 	struct cygnus_gpio *chip = to_cygnus_gpio(gc); | ||||
| 	unsigned gpio = gc->base + offset; | ||||
|  | ||||
| 	/* not all Cygnus GPIO pins can be muxed individually */ | ||||
| 	if (!chip->pinmux_is_supported) | ||||
| 		return 0; | ||||
|  | ||||
| 	return pinctrl_request_gpio(gpio); | ||||
| } | ||||
|  | ||||
| static void cygnus_gpio_free(struct gpio_chip *gc, unsigned offset) | ||||
| { | ||||
| 	struct cygnus_gpio *chip = to_cygnus_gpio(gc); | ||||
| 	unsigned gpio = gc->base + offset; | ||||
|  | ||||
| 	if (!chip->pinmux_is_supported) | ||||
| 		return; | ||||
|  | ||||
| 	pinctrl_free_gpio(gpio); | ||||
| } | ||||
|  | ||||
| static int cygnus_gpio_direction_input(struct gpio_chip *gc, unsigned gpio) | ||||
| { | ||||
| 	struct cygnus_gpio *chip = to_cygnus_gpio(gc); | ||||
| 	unsigned long flags; | ||||
|  | ||||
| 	spin_lock_irqsave(&chip->lock, flags); | ||||
| 	cygnus_set_bit(chip, CYGNUS_GPIO_OUT_EN_OFFSET, gpio, false); | ||||
| 	spin_unlock_irqrestore(&chip->lock, flags); | ||||
|  | ||||
| 	dev_dbg(chip->dev, "gpio:%u set input\n", gpio); | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int cygnus_gpio_direction_output(struct gpio_chip *gc, unsigned gpio, | ||||
| 					int val) | ||||
| { | ||||
| 	struct cygnus_gpio *chip = to_cygnus_gpio(gc); | ||||
| 	unsigned long flags; | ||||
|  | ||||
| 	spin_lock_irqsave(&chip->lock, flags); | ||||
| 	cygnus_set_bit(chip, CYGNUS_GPIO_OUT_EN_OFFSET, gpio, true); | ||||
| 	cygnus_set_bit(chip, CYGNUS_GPIO_DATA_OUT_OFFSET, gpio, !!(val)); | ||||
| 	spin_unlock_irqrestore(&chip->lock, flags); | ||||
|  | ||||
| 	dev_dbg(chip->dev, "gpio:%u set output, value:%d\n", gpio, val); | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static void cygnus_gpio_set(struct gpio_chip *gc, unsigned gpio, int val) | ||||
| { | ||||
| 	struct cygnus_gpio *chip = to_cygnus_gpio(gc); | ||||
| 	unsigned long flags; | ||||
|  | ||||
| 	spin_lock_irqsave(&chip->lock, flags); | ||||
| 	cygnus_set_bit(chip, CYGNUS_GPIO_DATA_OUT_OFFSET, gpio, !!(val)); | ||||
| 	spin_unlock_irqrestore(&chip->lock, flags); | ||||
|  | ||||
| 	dev_dbg(chip->dev, "gpio:%u set, value:%d\n", gpio, val); | ||||
| } | ||||
|  | ||||
| static int cygnus_gpio_get(struct gpio_chip *gc, unsigned gpio) | ||||
| { | ||||
| 	struct cygnus_gpio *chip = to_cygnus_gpio(gc); | ||||
| 	unsigned int offset = CYGNUS_GPIO_REG(gpio, | ||||
| 					      CYGNUS_GPIO_DATA_IN_OFFSET); | ||||
| 	unsigned int shift = CYGNUS_GPIO_SHIFT(gpio); | ||||
|  | ||||
| 	return !!(readl(chip->base + offset) & BIT(shift)); | ||||
| } | ||||
|  | ||||
| static int cygnus_get_groups_count(struct pinctrl_dev *pctldev) | ||||
| { | ||||
| 	return 1; | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * Only one group: "gpio_grp", since this local pinctrl device only performs | ||||
|  * GPIO specific PINCONF configurations | ||||
|  */ | ||||
| static const char *cygnus_get_group_name(struct pinctrl_dev *pctldev, | ||||
| 					 unsigned selector) | ||||
| { | ||||
| 	return "gpio_grp"; | ||||
| } | ||||
|  | ||||
| static const struct pinctrl_ops cygnus_pctrl_ops = { | ||||
| 	.get_groups_count = cygnus_get_groups_count, | ||||
| 	.get_group_name = cygnus_get_group_name, | ||||
| 	.dt_node_to_map = pinconf_generic_dt_node_to_map_pin, | ||||
| 	.dt_free_map = pinctrl_utils_dt_free_map, | ||||
| }; | ||||
|  | ||||
| static int cygnus_gpio_set_pull(struct cygnus_gpio *chip, unsigned gpio, | ||||
| 				bool disable, bool pull_up) | ||||
| { | ||||
| 	unsigned long flags; | ||||
|  | ||||
| 	spin_lock_irqsave(&chip->lock, flags); | ||||
|  | ||||
| 	if (disable) { | ||||
| 		cygnus_set_bit(chip, CYGNUS_GPIO_RES_EN_OFFSET, gpio, false); | ||||
| 	} else { | ||||
| 		cygnus_set_bit(chip, CYGNUS_GPIO_PAD_RES_OFFSET, gpio, | ||||
| 			       pull_up); | ||||
| 		cygnus_set_bit(chip, CYGNUS_GPIO_RES_EN_OFFSET, gpio, true); | ||||
| 	} | ||||
|  | ||||
| 	spin_unlock_irqrestore(&chip->lock, flags); | ||||
|  | ||||
| 	dev_dbg(chip->dev, "gpio:%u set pullup:%d\n", gpio, pull_up); | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static void cygnus_gpio_get_pull(struct cygnus_gpio *chip, unsigned gpio, | ||||
| 				 bool *disable, bool *pull_up) | ||||
| { | ||||
| 	unsigned long flags; | ||||
|  | ||||
| 	spin_lock_irqsave(&chip->lock, flags); | ||||
| 	*disable = !cygnus_get_bit(chip, CYGNUS_GPIO_RES_EN_OFFSET, gpio); | ||||
| 	*pull_up = cygnus_get_bit(chip, CYGNUS_GPIO_PAD_RES_OFFSET, gpio); | ||||
| 	spin_unlock_irqrestore(&chip->lock, flags); | ||||
| } | ||||
|  | ||||
| static int cygnus_gpio_set_strength(struct cygnus_gpio *chip, unsigned gpio, | ||||
| 				    unsigned strength) | ||||
| { | ||||
| 	void __iomem *base; | ||||
| 	unsigned int i, offset, shift; | ||||
| 	u32 val; | ||||
| 	unsigned long flags; | ||||
|  | ||||
| 	/* make sure drive strength is supported */ | ||||
| 	if (strength < 2 ||  strength > 16 || (strength % 2)) | ||||
| 		return -ENOTSUPP; | ||||
|  | ||||
| 	if (chip->io_ctrl) { | ||||
| 		base = chip->io_ctrl; | ||||
| 		offset = CYGNUS_GPIO_DRV0_CTRL_OFFSET; | ||||
| 	} else { | ||||
| 		base = chip->base; | ||||
| 		offset = CYGNUS_GPIO_REG(gpio, | ||||
| 					 CYGNUS_GPIO_ASIU_DRV0_CTRL_OFFSET); | ||||
| 	} | ||||
|  | ||||
| 	shift = CYGNUS_GPIO_SHIFT(gpio); | ||||
|  | ||||
| 	dev_dbg(chip->dev, "gpio:%u set drive strength:%d mA\n", gpio, | ||||
| 		strength); | ||||
|  | ||||
| 	spin_lock_irqsave(&chip->lock, flags); | ||||
| 	strength = (strength / 2) - 1; | ||||
| 	for (i = 0; i < GPIO_DRV_STRENGTH_BITS; i++) { | ||||
| 		val = readl(base + offset); | ||||
| 		val &= ~BIT(shift); | ||||
| 		val |= ((strength >> i) & 0x1) << shift; | ||||
| 		writel(val, base + offset); | ||||
| 		offset += 4; | ||||
| 	} | ||||
| 	spin_unlock_irqrestore(&chip->lock, flags); | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int cygnus_gpio_get_strength(struct cygnus_gpio *chip, unsigned gpio, | ||||
| 				    u16 *strength) | ||||
| { | ||||
| 	void __iomem *base; | ||||
| 	unsigned int i, offset, shift; | ||||
| 	u32 val; | ||||
| 	unsigned long flags; | ||||
|  | ||||
| 	if (chip->io_ctrl) { | ||||
| 		base = chip->io_ctrl; | ||||
| 		offset = CYGNUS_GPIO_DRV0_CTRL_OFFSET; | ||||
| 	} else { | ||||
| 		base = chip->base; | ||||
| 		offset = CYGNUS_GPIO_REG(gpio, | ||||
| 					 CYGNUS_GPIO_ASIU_DRV0_CTRL_OFFSET); | ||||
| 	} | ||||
|  | ||||
| 	shift = CYGNUS_GPIO_SHIFT(gpio); | ||||
|  | ||||
| 	spin_lock_irqsave(&chip->lock, flags); | ||||
| 	*strength = 0; | ||||
| 	for (i = 0; i < GPIO_DRV_STRENGTH_BITS; i++) { | ||||
| 		val = readl(base + offset) & BIT(shift); | ||||
| 		val >>= shift; | ||||
| 		*strength += (val << i); | ||||
| 		offset += 4; | ||||
| 	} | ||||
|  | ||||
| 	/* convert to mA */ | ||||
| 	*strength = (*strength + 1) * 2; | ||||
| 	spin_unlock_irqrestore(&chip->lock, flags); | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int cygnus_pin_config_get(struct pinctrl_dev *pctldev, unsigned pin, | ||||
| 				 unsigned long *config) | ||||
| { | ||||
| 	struct cygnus_gpio *chip = pinctrl_dev_get_drvdata(pctldev); | ||||
| 	enum pin_config_param param = pinconf_to_config_param(*config); | ||||
| 	unsigned gpio = cygnus_pin_to_gpio(pin); | ||||
| 	u16 arg; | ||||
| 	bool disable, pull_up; | ||||
| 	int ret; | ||||
|  | ||||
| 	switch (param) { | ||||
| 	case PIN_CONFIG_BIAS_DISABLE: | ||||
| 		cygnus_gpio_get_pull(chip, gpio, &disable, &pull_up); | ||||
| 		if (disable) | ||||
| 			return 0; | ||||
| 		else | ||||
| 			return -EINVAL; | ||||
|  | ||||
| 	case PIN_CONFIG_BIAS_PULL_UP: | ||||
| 		cygnus_gpio_get_pull(chip, gpio, &disable, &pull_up); | ||||
| 		if (!disable && pull_up) | ||||
| 			return 0; | ||||
| 		else | ||||
| 			return -EINVAL; | ||||
|  | ||||
| 	case PIN_CONFIG_BIAS_PULL_DOWN: | ||||
| 		cygnus_gpio_get_pull(chip, gpio, &disable, &pull_up); | ||||
| 		if (!disable && !pull_up) | ||||
| 			return 0; | ||||
| 		else | ||||
| 			return -EINVAL; | ||||
|  | ||||
| 	case PIN_CONFIG_DRIVE_STRENGTH: | ||||
| 		ret = cygnus_gpio_get_strength(chip, gpio, &arg); | ||||
| 		if (ret) | ||||
| 			return ret; | ||||
| 		else | ||||
| 			*config = pinconf_to_config_packed(param, arg); | ||||
|  | ||||
| 		return 0; | ||||
|  | ||||
| 	default: | ||||
| 		return -ENOTSUPP; | ||||
| 	} | ||||
|  | ||||
| 	return -ENOTSUPP; | ||||
| } | ||||
|  | ||||
| static int cygnus_pin_config_set(struct pinctrl_dev *pctldev, unsigned pin, | ||||
| 				 unsigned long *configs, unsigned num_configs) | ||||
| { | ||||
| 	struct cygnus_gpio *chip = pinctrl_dev_get_drvdata(pctldev); | ||||
| 	enum pin_config_param param; | ||||
| 	u16 arg; | ||||
| 	unsigned i, gpio = cygnus_pin_to_gpio(pin); | ||||
| 	int ret = -ENOTSUPP; | ||||
|  | ||||
| 	for (i = 0; i < num_configs; i++) { | ||||
| 		param = pinconf_to_config_param(configs[i]); | ||||
| 		arg = pinconf_to_config_argument(configs[i]); | ||||
|  | ||||
| 		switch (param) { | ||||
| 		case PIN_CONFIG_BIAS_DISABLE: | ||||
| 			ret = cygnus_gpio_set_pull(chip, gpio, true, false); | ||||
| 			if (ret < 0) | ||||
| 				goto out; | ||||
| 			break; | ||||
|  | ||||
| 		case PIN_CONFIG_BIAS_PULL_UP: | ||||
| 			ret = cygnus_gpio_set_pull(chip, gpio, false, true); | ||||
| 			if (ret < 0) | ||||
| 				goto out; | ||||
| 			break; | ||||
|  | ||||
| 		case PIN_CONFIG_BIAS_PULL_DOWN: | ||||
| 			ret = cygnus_gpio_set_pull(chip, gpio, false, false); | ||||
| 			if (ret < 0) | ||||
| 				goto out; | ||||
| 			break; | ||||
|  | ||||
| 		case PIN_CONFIG_DRIVE_STRENGTH: | ||||
| 			ret = cygnus_gpio_set_strength(chip, gpio, arg); | ||||
| 			if (ret < 0) | ||||
| 				goto out; | ||||
| 			break; | ||||
|  | ||||
| 		default: | ||||
| 			dev_err(chip->dev, "invalid configuration\n"); | ||||
| 			return -ENOTSUPP; | ||||
| 		} | ||||
| 	} /* for each config */ | ||||
|  | ||||
| out: | ||||
| 	return ret; | ||||
| } | ||||
|  | ||||
| static const struct pinconf_ops cygnus_pconf_ops = { | ||||
| 	.is_generic = true, | ||||
| 	.pin_config_get = cygnus_pin_config_get, | ||||
| 	.pin_config_set = cygnus_pin_config_set, | ||||
| }; | ||||
|  | ||||
| /* | ||||
|  * Map a GPIO in the local gpio_chip pin space to a pin in the Cygnus IOMUX | ||||
|  * pinctrl pin space | ||||
|  */ | ||||
| struct cygnus_gpio_pin_range { | ||||
| 	unsigned offset; | ||||
| 	unsigned pin_base; | ||||
| 	unsigned num_pins; | ||||
| }; | ||||
|  | ||||
| #define CYGNUS_PINRANGE(o, p, n) { .offset = o, .pin_base = p, .num_pins = n } | ||||
|  | ||||
| /* | ||||
|  * Pin mapping table for mapping local GPIO pins to Cygnus IOMUX pinctrl pins | ||||
|  */ | ||||
| static const struct cygnus_gpio_pin_range cygnus_gpio_pintable[] = { | ||||
| 	CYGNUS_PINRANGE(0, 42, 1), | ||||
| 	CYGNUS_PINRANGE(1, 44, 3), | ||||
| 	CYGNUS_PINRANGE(4, 48, 1), | ||||
| 	CYGNUS_PINRANGE(5, 50, 3), | ||||
| 	CYGNUS_PINRANGE(8, 126, 1), | ||||
| 	CYGNUS_PINRANGE(9, 155, 1), | ||||
| 	CYGNUS_PINRANGE(10, 152, 1), | ||||
| 	CYGNUS_PINRANGE(11, 154, 1), | ||||
| 	CYGNUS_PINRANGE(12, 153, 1), | ||||
| 	CYGNUS_PINRANGE(13, 127, 3), | ||||
| 	CYGNUS_PINRANGE(16, 140, 1), | ||||
| 	CYGNUS_PINRANGE(17, 145, 7), | ||||
| 	CYGNUS_PINRANGE(24, 130, 10), | ||||
| 	CYGNUS_PINRANGE(34, 141, 4), | ||||
| 	CYGNUS_PINRANGE(38, 54, 1), | ||||
| 	CYGNUS_PINRANGE(39, 56, 3), | ||||
| 	CYGNUS_PINRANGE(42, 60, 3), | ||||
| 	CYGNUS_PINRANGE(45, 64, 3), | ||||
| 	CYGNUS_PINRANGE(48, 68, 2), | ||||
| 	CYGNUS_PINRANGE(50, 84, 6), | ||||
| 	CYGNUS_PINRANGE(56, 94, 6), | ||||
| 	CYGNUS_PINRANGE(62, 72, 1), | ||||
| 	CYGNUS_PINRANGE(63, 70, 1), | ||||
| 	CYGNUS_PINRANGE(64, 80, 1), | ||||
| 	CYGNUS_PINRANGE(65, 74, 3), | ||||
| 	CYGNUS_PINRANGE(68, 78, 1), | ||||
| 	CYGNUS_PINRANGE(69, 82, 1), | ||||
| 	CYGNUS_PINRANGE(70, 156, 17), | ||||
| 	CYGNUS_PINRANGE(87, 104, 12), | ||||
| 	CYGNUS_PINRANGE(99, 102, 2), | ||||
| 	CYGNUS_PINRANGE(101, 90, 4), | ||||
| 	CYGNUS_PINRANGE(105, 116, 10), | ||||
| 	CYGNUS_PINRANGE(123, 11, 1), | ||||
| 	CYGNUS_PINRANGE(124, 38, 4), | ||||
| 	CYGNUS_PINRANGE(128, 43, 1), | ||||
| 	CYGNUS_PINRANGE(129, 47, 1), | ||||
| 	CYGNUS_PINRANGE(130, 49, 1), | ||||
| 	CYGNUS_PINRANGE(131, 53, 1), | ||||
| 	CYGNUS_PINRANGE(132, 55, 1), | ||||
| 	CYGNUS_PINRANGE(133, 59, 1), | ||||
| 	CYGNUS_PINRANGE(134, 63, 1), | ||||
| 	CYGNUS_PINRANGE(135, 67, 1), | ||||
| 	CYGNUS_PINRANGE(136, 71, 1), | ||||
| 	CYGNUS_PINRANGE(137, 73, 1), | ||||
| 	CYGNUS_PINRANGE(138, 77, 1), | ||||
| 	CYGNUS_PINRANGE(139, 79, 1), | ||||
| 	CYGNUS_PINRANGE(140, 81, 1), | ||||
| 	CYGNUS_PINRANGE(141, 83, 1), | ||||
| 	CYGNUS_PINRANGE(142, 10, 1) | ||||
| }; | ||||
|  | ||||
| /* | ||||
|  * The Cygnus IOMUX controller mainly supports group based mux configuration, | ||||
|  * but certain pins can be muxed to GPIO individually. Only the ASIU GPIO | ||||
|  * controller can support this, so it's an optional configuration | ||||
|  * | ||||
|  * Return -ENODEV means no support and that's fine | ||||
|  */ | ||||
| static int cygnus_gpio_pinmux_add_range(struct cygnus_gpio *chip) | ||||
| { | ||||
| 	struct device_node *node = chip->dev->of_node; | ||||
| 	struct device_node *pinmux_node; | ||||
| 	struct platform_device *pinmux_pdev; | ||||
| 	struct gpio_chip *gc = &chip->gc; | ||||
| 	int i, ret = 0; | ||||
|  | ||||
| 	/* parse DT to find the phandle to the pinmux controller */ | ||||
| 	pinmux_node = of_parse_phandle(node, "pinmux", 0); | ||||
| 	if (!pinmux_node) | ||||
| 		return -ENODEV; | ||||
|  | ||||
| 	pinmux_pdev = of_find_device_by_node(pinmux_node); | ||||
| 	/* no longer need the pinmux node */ | ||||
| 	of_node_put(pinmux_node); | ||||
| 	if (!pinmux_pdev) { | ||||
| 		dev_err(chip->dev, "failed to get pinmux device\n"); | ||||
| 		return -EINVAL; | ||||
| 	} | ||||
|  | ||||
| 	/* now need to create the mapping between local GPIO and PINMUX pins */ | ||||
| 	for (i = 0; i < ARRAY_SIZE(cygnus_gpio_pintable); i++) { | ||||
| 		ret = gpiochip_add_pin_range(gc, dev_name(&pinmux_pdev->dev), | ||||
| 					     cygnus_gpio_pintable[i].offset, | ||||
| 					     cygnus_gpio_pintable[i].pin_base, | ||||
| 					     cygnus_gpio_pintable[i].num_pins); | ||||
| 		if (ret) { | ||||
| 			dev_err(chip->dev, "unable to add GPIO pin range\n"); | ||||
| 			goto err_put_device; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	chip->pinmux_is_supported = true; | ||||
|  | ||||
| 	/* no need for pinmux_pdev device reference anymore */ | ||||
| 	put_device(&pinmux_pdev->dev); | ||||
| 	return 0; | ||||
|  | ||||
| err_put_device: | ||||
| 	put_device(&pinmux_pdev->dev); | ||||
| 	gpiochip_remove_pin_ranges(gc); | ||||
| 	return ret; | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * Cygnus GPIO controller supports some PINCONF related configurations such as | ||||
|  * pull up, pull down, and drive strength, when the pin is configured to GPIO | ||||
|  * | ||||
|  * Here a local pinctrl device is created with simple 1-to-1 pin mapping to the | ||||
|  * local GPIO pins | ||||
|  */ | ||||
| static int cygnus_gpio_register_pinconf(struct cygnus_gpio *chip) | ||||
| { | ||||
| 	struct pinctrl_desc *pctldesc = &chip->pctldesc; | ||||
| 	struct pinctrl_pin_desc *pins; | ||||
| 	struct gpio_chip *gc = &chip->gc; | ||||
| 	int i; | ||||
|  | ||||
| 	pins = devm_kcalloc(chip->dev, gc->ngpio, sizeof(*pins), GFP_KERNEL); | ||||
| 	if (!pins) | ||||
| 		return -ENOMEM; | ||||
|  | ||||
| 	for (i = 0; i < gc->ngpio; i++) { | ||||
| 		pins[i].number = i; | ||||
| 		pins[i].name = devm_kasprintf(chip->dev, GFP_KERNEL, | ||||
| 					      "gpio-%d", i); | ||||
| 		if (!pins[i].name) | ||||
| 			return -ENOMEM; | ||||
| 	} | ||||
|  | ||||
| 	pctldesc->name = dev_name(chip->dev); | ||||
| 	pctldesc->pctlops = &cygnus_pctrl_ops; | ||||
| 	pctldesc->pins = pins; | ||||
| 	pctldesc->npins = gc->ngpio; | ||||
| 	pctldesc->confops = &cygnus_pconf_ops; | ||||
|  | ||||
| 	chip->pctl = pinctrl_register(pctldesc, chip->dev, chip); | ||||
| 	if (!chip->pctl) { | ||||
| 		dev_err(chip->dev, "unable to register pinctrl device\n"); | ||||
| 		return -EINVAL; | ||||
| 	} | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static void cygnus_gpio_unregister_pinconf(struct cygnus_gpio *chip) | ||||
| { | ||||
| 	if (chip->pctl) | ||||
| 		pinctrl_unregister(chip->pctl); | ||||
| } | ||||
|  | ||||
| struct cygnus_gpio_data { | ||||
| 	unsigned num_gpios; | ||||
| }; | ||||
|  | ||||
| static const struct cygnus_gpio_data cygnus_cmm_gpio_data = { | ||||
| 	.num_gpios = 24, | ||||
| }; | ||||
|  | ||||
| static const struct cygnus_gpio_data cygnus_asiu_gpio_data = { | ||||
| 	.num_gpios = 146, | ||||
| }; | ||||
|  | ||||
| static const struct cygnus_gpio_data cygnus_crmu_gpio_data = { | ||||
| 	.num_gpios = 6, | ||||
| }; | ||||
|  | ||||
| static const struct of_device_id cygnus_gpio_of_match[] = { | ||||
| 	{ | ||||
| 		.compatible = "brcm,cygnus-ccm-gpio", | ||||
| 		.data = &cygnus_cmm_gpio_data, | ||||
| 	}, | ||||
| 	{ | ||||
| 		.compatible = "brcm,cygnus-asiu-gpio", | ||||
| 		.data = &cygnus_asiu_gpio_data, | ||||
| 	}, | ||||
| 	{ | ||||
| 		.compatible = "brcm,cygnus-crmu-gpio", | ||||
| 		.data = &cygnus_crmu_gpio_data, | ||||
| 	} | ||||
| }; | ||||
|  | ||||
| static int cygnus_gpio_probe(struct platform_device *pdev) | ||||
| { | ||||
| 	struct device *dev = &pdev->dev; | ||||
| 	struct resource *res; | ||||
| 	struct cygnus_gpio *chip; | ||||
| 	struct gpio_chip *gc; | ||||
| 	u32 ngpios; | ||||
| 	int irq, ret; | ||||
| 	const struct of_device_id *match; | ||||
| 	const struct cygnus_gpio_data *gpio_data; | ||||
|  | ||||
| 	match = of_match_device(cygnus_gpio_of_match, dev); | ||||
| 	if (!match) | ||||
| 		return -ENODEV; | ||||
| 	gpio_data = match->data; | ||||
| 	ngpios = gpio_data->num_gpios; | ||||
|  | ||||
| 	chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL); | ||||
| 	if (!chip) | ||||
| 		return -ENOMEM; | ||||
|  | ||||
| 	chip->dev = dev; | ||||
| 	platform_set_drvdata(pdev, chip); | ||||
|  | ||||
| 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||||
| 	chip->base = devm_ioremap_resource(dev, res); | ||||
| 	if (IS_ERR(chip->base)) { | ||||
| 		dev_err(dev, "unable to map I/O memory\n"); | ||||
| 		return PTR_ERR(chip->base); | ||||
| 	} | ||||
|  | ||||
| 	res = platform_get_resource(pdev, IORESOURCE_MEM, 1); | ||||
| 	if (res) { | ||||
| 		chip->io_ctrl = devm_ioremap_resource(dev, res); | ||||
| 		if (IS_ERR(chip->io_ctrl)) { | ||||
| 			dev_err(dev, "unable to map I/O memory\n"); | ||||
| 			return PTR_ERR(chip->io_ctrl); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	spin_lock_init(&chip->lock); | ||||
|  | ||||
| 	gc = &chip->gc; | ||||
| 	gc->base = -1; | ||||
| 	gc->ngpio = ngpios; | ||||
| 	chip->num_banks = (ngpios + NGPIOS_PER_BANK - 1) / NGPIOS_PER_BANK; | ||||
| 	gc->label = dev_name(dev); | ||||
| 	gc->dev = dev; | ||||
| 	gc->of_node = dev->of_node; | ||||
| 	gc->request = cygnus_gpio_request; | ||||
| 	gc->free = cygnus_gpio_free; | ||||
| 	gc->direction_input = cygnus_gpio_direction_input; | ||||
| 	gc->direction_output = cygnus_gpio_direction_output; | ||||
| 	gc->set = cygnus_gpio_set; | ||||
| 	gc->get = cygnus_gpio_get; | ||||
|  | ||||
| 	ret = gpiochip_add(gc); | ||||
| 	if (ret < 0) { | ||||
| 		dev_err(dev, "unable to add GPIO chip\n"); | ||||
| 		return ret; | ||||
| 	} | ||||
|  | ||||
| 	ret = cygnus_gpio_pinmux_add_range(chip); | ||||
| 	if (ret && ret != -ENODEV) { | ||||
| 		dev_err(dev, "unable to add GPIO pin range\n"); | ||||
| 		goto err_rm_gpiochip; | ||||
| 	} | ||||
|  | ||||
| 	ret = cygnus_gpio_register_pinconf(chip); | ||||
| 	if (ret) { | ||||
| 		dev_err(dev, "unable to register pinconf\n"); | ||||
| 		goto err_rm_gpiochip; | ||||
| 	} | ||||
|  | ||||
| 	/* optional GPIO interrupt support */ | ||||
| 	irq = platform_get_irq(pdev, 0); | ||||
| 	if (irq) { | ||||
| 		ret = gpiochip_irqchip_add(gc, &cygnus_gpio_irq_chip, 0, | ||||
| 					   handle_simple_irq, IRQ_TYPE_NONE); | ||||
| 		if (ret) { | ||||
| 			dev_err(dev, "no GPIO irqchip\n"); | ||||
| 			goto err_unregister_pinconf; | ||||
| 		} | ||||
|  | ||||
| 		gpiochip_set_chained_irqchip(gc, &cygnus_gpio_irq_chip, irq, | ||||
| 					     cygnus_gpio_irq_handler); | ||||
| 	} | ||||
|  | ||||
| 	return 0; | ||||
|  | ||||
| err_unregister_pinconf: | ||||
| 	cygnus_gpio_unregister_pinconf(chip); | ||||
|  | ||||
| err_rm_gpiochip: | ||||
| 	gpiochip_remove(gc); | ||||
|  | ||||
| 	return ret; | ||||
| } | ||||
|  | ||||
| static struct platform_driver cygnus_gpio_driver = { | ||||
| 	.driver = { | ||||
| 		.name = "cygnus-gpio", | ||||
| 		.of_match_table = cygnus_gpio_of_match, | ||||
| 	}, | ||||
| 	.probe = cygnus_gpio_probe, | ||||
| }; | ||||
|  | ||||
| static int __init cygnus_gpio_init(void) | ||||
| { | ||||
| 	return platform_driver_probe(&cygnus_gpio_driver, cygnus_gpio_probe); | ||||
| } | ||||
| arch_initcall_sync(cygnus_gpio_init); | ||||
							
								
								
									
										1022
									
								
								drivers/pinctrl/bcm/pinctrl-cygnus-mux.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1022
									
								
								drivers/pinctrl/bcm/pinctrl-cygnus-mux.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -542,10 +542,13 @@ static int imx_pinctrl_parse_groups(struct device_node *np, | ||||
| 		struct imx_pin_reg *pin_reg; | ||||
| 		struct imx_pin *pin = &grp->pins[i]; | ||||
|  | ||||
| 		if (info->flags & SHARE_MUX_CONF_REG) | ||||
| 		if (info->flags & SHARE_MUX_CONF_REG) { | ||||
| 			conf_reg = mux_reg; | ||||
| 		else | ||||
| 		} else { | ||||
| 			conf_reg = be32_to_cpu(*list++); | ||||
| 			if (!conf_reg) | ||||
| 				conf_reg = -1; | ||||
| 		} | ||||
|  | ||||
| 		pin_id = mux_reg ? mux_reg / 4 : conf_reg / 4; | ||||
| 		pin_reg = &info->pin_regs[pin_id]; | ||||
| @@ -645,7 +648,7 @@ int imx_pinctrl_probe(struct platform_device *pdev, | ||||
| { | ||||
| 	struct imx_pinctrl *ipctl; | ||||
| 	struct resource *res; | ||||
| 	int ret; | ||||
| 	int ret, i; | ||||
|  | ||||
| 	if (!info || !info->pins || !info->npins) { | ||||
| 		dev_err(&pdev->dev, "wrong pinctrl info\n"); | ||||
| @@ -662,7 +665,11 @@ int imx_pinctrl_probe(struct platform_device *pdev, | ||||
| 				      info->npins, GFP_KERNEL); | ||||
| 	if (!info->pin_regs) | ||||
| 		return -ENOMEM; | ||||
| 	memset(info->pin_regs, 0xff, sizeof(*info->pin_regs) * info->npins); | ||||
|  | ||||
| 	for (i = 0; i < info->npins; i++) { | ||||
| 		info->pin_regs[i].mux_reg = -1; | ||||
| 		info->pin_regs[i].conf_reg = -1; | ||||
| 	} | ||||
|  | ||||
| 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||||
| 	ipctl->base = devm_ioremap_resource(&pdev->dev, res); | ||||
|   | ||||
| @@ -302,7 +302,7 @@ static struct imx_pinctrl_soc_info vf610_pinctrl_info = { | ||||
| 	.flags = SHARE_MUX_CONF_REG, | ||||
| }; | ||||
|  | ||||
| static struct of_device_id vf610_pinctrl_of_match[] = { | ||||
| static const struct of_device_id vf610_pinctrl_of_match[] = { | ||||
| 	{ .compatible = "fsl,vf610-iomuxc", }, | ||||
| 	{ /* sentinel */ } | ||||
| }; | ||||
|   | ||||
| @@ -25,3 +25,20 @@ config PINCTRL_CHERRYVIEW | ||||
| 	help | ||||
| 	  Cherryview/Braswell pinctrl driver provides an interface that | ||||
| 	  allows configuring of SoC pins and using them as GPIOs. | ||||
|  | ||||
| config PINCTRL_INTEL | ||||
| 	tristate | ||||
| 	select PINMUX | ||||
| 	select PINCONF | ||||
| 	select GENERIC_PINCONF | ||||
| 	select GPIOLIB | ||||
| 	select GPIOLIB_IRQCHIP | ||||
|  | ||||
| config PINCTRL_SUNRISEPOINT | ||||
| 	tristate "Intel Sunrisepoint pinctrl and GPIO driver" | ||||
| 	depends on ACPI | ||||
| 	select PINCTRL_INTEL | ||||
| 	help | ||||
| 	  Sunrisepoint is the PCH of Intel Skylake. This pinctrl driver | ||||
| 	  provides an interface that allows configuring of PCH pins and | ||||
| 	  using them as GPIOs. | ||||
|   | ||||
| @@ -2,3 +2,5 @@ | ||||
|  | ||||
| obj-$(CONFIG_PINCTRL_BAYTRAIL)		+= pinctrl-baytrail.o | ||||
| obj-$(CONFIG_PINCTRL_CHERRYVIEW)	+= pinctrl-cherryview.o | ||||
| obj-$(CONFIG_PINCTRL_INTEL)		+= pinctrl-intel.o | ||||
| obj-$(CONFIG_PINCTRL_SUNRISEPOINT)	+= pinctrl-sunrisepoint.o | ||||
|   | ||||
							
								
								
									
										1149
									
								
								drivers/pinctrl/intel/pinctrl-intel.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1149
									
								
								drivers/pinctrl/intel/pinctrl-intel.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										128
									
								
								drivers/pinctrl/intel/pinctrl-intel.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										128
									
								
								drivers/pinctrl/intel/pinctrl-intel.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,128 @@ | ||||
| /* | ||||
|  * Core pinctrl/GPIO driver for Intel GPIO controllers | ||||
|  * | ||||
|  * Copyright (C) 2015, Intel Corporation | ||||
|  * Authors: Mathias Nyman <mathias.nyman@linux.intel.com> | ||||
|  *          Mika Westerberg <mika.westerberg@linux.intel.com> | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License version 2 as | ||||
|  * published by the Free Software Foundation. | ||||
|  */ | ||||
|  | ||||
| #ifndef PINCTRL_INTEL_H | ||||
| #define PINCTRL_INTEL_H | ||||
|  | ||||
| struct pinctrl_pin_desc; | ||||
| struct platform_device; | ||||
| struct device; | ||||
|  | ||||
| /** | ||||
|  * struct intel_pingroup - Description about group of pins | ||||
|  * @name: Name of the groups | ||||
|  * @pins: All pins in this group | ||||
|  * @npins: Number of pins in this groups | ||||
|  * @mode: Native mode in which the group is muxed out @pins | ||||
|  */ | ||||
| struct intel_pingroup { | ||||
| 	const char *name; | ||||
| 	const unsigned *pins; | ||||
| 	size_t npins; | ||||
| 	unsigned short mode; | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * struct intel_function - Description about a function | ||||
|  * @name: Name of the function | ||||
|  * @groups: An array of groups for this function | ||||
|  * @ngroups: Number of groups in @groups | ||||
|  */ | ||||
| struct intel_function { | ||||
| 	const char *name; | ||||
| 	const char * const *groups; | ||||
| 	size_t ngroups; | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * struct intel_community - Intel pin community description | ||||
|  * @barno: MMIO BAR number where registers for this community reside | ||||
|  * @padown_offset: Register offset of PAD_OWN register from @regs. If %0 | ||||
|  *                 then there is no support for owner. | ||||
|  * @padcfglock_offset: Register offset of PADCFGLOCK from @regs. If %0 then | ||||
|  *                     locking is not supported. | ||||
|  * @hostown_offset: Register offset of HOSTSW_OWN from @regs. If %0 then it | ||||
|  *                  is assumed that the host owns the pin (rather than | ||||
|  *                  ACPI). | ||||
|  * @ie_offset: Register offset of GPI_IE from @regs. | ||||
|  * @pin_base: Starting pin of pins in this community | ||||
|  * @npins: Number of pins in this community | ||||
|  * @regs: Community specific common registers (reserved for core driver) | ||||
|  * @pad_regs: Community specific pad registers (reserved for core driver) | ||||
|  * @ngpps: Number of groups (hw groups) in this community (reserved for | ||||
|  *         core driver) | ||||
|  */ | ||||
| struct intel_community { | ||||
| 	unsigned barno; | ||||
| 	unsigned padown_offset; | ||||
| 	unsigned padcfglock_offset; | ||||
| 	unsigned hostown_offset; | ||||
| 	unsigned ie_offset; | ||||
| 	unsigned pin_base; | ||||
| 	size_t npins; | ||||
| 	void __iomem *regs; | ||||
| 	void __iomem *pad_regs; | ||||
| 	size_t ngpps; | ||||
| }; | ||||
|  | ||||
| #define PIN_GROUP(n, p, m)			\ | ||||
| 	{					\ | ||||
| 		.name = (n),			\ | ||||
| 		.pins = (p),			\ | ||||
| 		.npins = ARRAY_SIZE((p)),	\ | ||||
| 		.mode = (m),			\ | ||||
| 	} | ||||
|  | ||||
| #define FUNCTION(n, g)				\ | ||||
| 	{					\ | ||||
| 		.name = (n),			\ | ||||
| 		.groups = (g),			\ | ||||
| 		.ngroups = ARRAY_SIZE((g)),	\ | ||||
| 	} | ||||
|  | ||||
| /** | ||||
|  * struct intel_pinctrl_soc_data - Intel pin controller per-SoC configuration | ||||
|  * @uid: ACPI _UID for the probe driver use if needed | ||||
|  * @pins: Array if pins this pinctrl controls | ||||
|  * @npins: Number of pins in the array | ||||
|  * @groups: Array of pin groups | ||||
|  * @ngroups: Number of groups in the array | ||||
|  * @functions: Array of functions | ||||
|  * @nfunctions: Number of functions in the array | ||||
|  * @communities: Array of communities this pinctrl handles | ||||
|  * @ncommunities: Number of communities in the array | ||||
|  * | ||||
|  * The @communities is used as a template by the core driver. It will make | ||||
|  * copy of all communities and fill in rest of the information. | ||||
|  */ | ||||
| struct intel_pinctrl_soc_data { | ||||
| 	const char *uid; | ||||
| 	const struct pinctrl_pin_desc *pins; | ||||
| 	size_t npins; | ||||
| 	const struct intel_pingroup *groups; | ||||
| 	size_t ngroups; | ||||
| 	const struct intel_function *functions; | ||||
| 	size_t nfunctions; | ||||
| 	const struct intel_community *communities; | ||||
| 	size_t ncommunities; | ||||
| }; | ||||
|  | ||||
| int intel_pinctrl_probe(struct platform_device *pdev, | ||||
| 			const struct intel_pinctrl_soc_data *soc_data); | ||||
| int intel_pinctrl_remove(struct platform_device *pdev); | ||||
|  | ||||
| #ifdef CONFIG_PM_SLEEP | ||||
| int intel_pinctrl_suspend(struct device *dev); | ||||
| int intel_pinctrl_resume(struct device *dev); | ||||
| #endif | ||||
|  | ||||
| #endif /* PINCTRL_INTEL_H */ | ||||
							
								
								
									
										336
									
								
								drivers/pinctrl/intel/pinctrl-sunrisepoint.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										336
									
								
								drivers/pinctrl/intel/pinctrl-sunrisepoint.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,336 @@ | ||||
| /* | ||||
|  * Intel Sunrisepoint PCH pinctrl/GPIO driver | ||||
|  * | ||||
|  * Copyright (C) 2015, Intel Corporation | ||||
|  * Authors: Mathias Nyman <mathias.nyman@linux.intel.com> | ||||
|  *          Mika Westerberg <mika.westerberg@linux.intel.com> | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License version 2 as | ||||
|  * published by the Free Software Foundation. | ||||
|  */ | ||||
|  | ||||
| #include <linux/acpi.h> | ||||
| #include <linux/module.h> | ||||
| #include <linux/platform_device.h> | ||||
| #include <linux/pm.h> | ||||
| #include <linux/pinctrl/pinctrl.h> | ||||
|  | ||||
| #include "pinctrl-intel.h" | ||||
|  | ||||
| #define SPT_PAD_OWN	0x020 | ||||
| #define SPT_PADCFGLOCK	0x0a0 | ||||
| #define SPT_HOSTSW_OWN	0x0d0 | ||||
| #define SPT_GPI_IE	0x120 | ||||
|  | ||||
| #define SPT_COMMUNITY(b, s, e)				\ | ||||
| 	{						\ | ||||
| 		.barno = (b),				\ | ||||
| 		.padown_offset = SPT_PAD_OWN,		\ | ||||
| 		.padcfglock_offset = SPT_PADCFGLOCK,	\ | ||||
| 		.hostown_offset = SPT_HOSTSW_OWN,	\ | ||||
| 		.ie_offset = SPT_GPI_IE,		\ | ||||
| 		.pin_base = (s),			\ | ||||
| 		.npins = ((e) - (s) + 1),		\ | ||||
| 	} | ||||
|  | ||||
| /* Sunrisepoint-LP */ | ||||
| static const struct pinctrl_pin_desc sptlp_pins[] = { | ||||
| 	/* GPP_A */ | ||||
| 	PINCTRL_PIN(0, "RCINB"), | ||||
| 	PINCTRL_PIN(1, "LAD_0"), | ||||
| 	PINCTRL_PIN(2, "LAD_1"), | ||||
| 	PINCTRL_PIN(3, "LAD_2"), | ||||
| 	PINCTRL_PIN(4, "LAD_3"), | ||||
| 	PINCTRL_PIN(5, "LFRAMEB"), | ||||
| 	PINCTRL_PIN(6, "SERIQ"), | ||||
| 	PINCTRL_PIN(7, "PIRQAB"), | ||||
| 	PINCTRL_PIN(8, "CLKRUNB"), | ||||
| 	PINCTRL_PIN(9, "CLKOUT_LPC_0"), | ||||
| 	PINCTRL_PIN(10, "CLKOUT_LPC_1"), | ||||
| 	PINCTRL_PIN(11, "PMEB"), | ||||
| 	PINCTRL_PIN(12, "BM_BUSYB"), | ||||
| 	PINCTRL_PIN(13, "SUSWARNB_SUS_PWRDNACK"), | ||||
| 	PINCTRL_PIN(14, "SUS_STATB"), | ||||
| 	PINCTRL_PIN(15, "SUSACKB"), | ||||
| 	PINCTRL_PIN(16, "SD_1P8_SEL"), | ||||
| 	PINCTRL_PIN(17, "SD_PWR_EN_B"), | ||||
| 	PINCTRL_PIN(18, "ISH_GP_0"), | ||||
| 	PINCTRL_PIN(19, "ISH_GP_1"), | ||||
| 	PINCTRL_PIN(20, "ISH_GP_2"), | ||||
| 	PINCTRL_PIN(21, "ISH_GP_3"), | ||||
| 	PINCTRL_PIN(22, "ISH_GP_4"), | ||||
| 	PINCTRL_PIN(23, "ISH_GP_5"), | ||||
| 	/* GPP_B */ | ||||
| 	PINCTRL_PIN(24, "CORE_VID_0"), | ||||
| 	PINCTRL_PIN(25, "CORE_VID_1"), | ||||
| 	PINCTRL_PIN(26, "VRALERTB"), | ||||
| 	PINCTRL_PIN(27, "CPU_GP_2"), | ||||
| 	PINCTRL_PIN(28, "CPU_GP_3"), | ||||
| 	PINCTRL_PIN(29, "SRCCLKREQB_0"), | ||||
| 	PINCTRL_PIN(30, "SRCCLKREQB_1"), | ||||
| 	PINCTRL_PIN(31, "SRCCLKREQB_2"), | ||||
| 	PINCTRL_PIN(32, "SRCCLKREQB_3"), | ||||
| 	PINCTRL_PIN(33, "SRCCLKREQB_4"), | ||||
| 	PINCTRL_PIN(34, "SRCCLKREQB_5"), | ||||
| 	PINCTRL_PIN(35, "EXT_PWR_GATEB"), | ||||
| 	PINCTRL_PIN(36, "SLP_S0B"), | ||||
| 	PINCTRL_PIN(37, "PLTRSTB"), | ||||
| 	PINCTRL_PIN(38, "SPKR"), | ||||
| 	PINCTRL_PIN(39, "GSPI0_CSB"), | ||||
| 	PINCTRL_PIN(40, "GSPI0_CLK"), | ||||
| 	PINCTRL_PIN(41, "GSPI0_MISO"), | ||||
| 	PINCTRL_PIN(42, "GSPI0_MOSI"), | ||||
| 	PINCTRL_PIN(43, "GSPI1_CSB"), | ||||
| 	PINCTRL_PIN(44, "GSPI1_CLK"), | ||||
| 	PINCTRL_PIN(45, "GSPI1_MISO"), | ||||
| 	PINCTRL_PIN(46, "GSPI1_MOSI"), | ||||
| 	PINCTRL_PIN(47, "SML1ALERTB"), | ||||
| 	/* GPP_C */ | ||||
| 	PINCTRL_PIN(48, "SMBCLK"), | ||||
| 	PINCTRL_PIN(49, "SMBDATA"), | ||||
| 	PINCTRL_PIN(50, "SMBALERTB"), | ||||
| 	PINCTRL_PIN(51, "SML0CLK"), | ||||
| 	PINCTRL_PIN(52, "SML0DATA"), | ||||
| 	PINCTRL_PIN(53, "SML0ALERTB"), | ||||
| 	PINCTRL_PIN(54, "SML1CLK"), | ||||
| 	PINCTRL_PIN(55, "SML1DATA"), | ||||
| 	PINCTRL_PIN(56, "UART0_RXD"), | ||||
| 	PINCTRL_PIN(57, "UART0_TXD"), | ||||
| 	PINCTRL_PIN(58, "UART0_RTSB"), | ||||
| 	PINCTRL_PIN(59, "UART0_CTSB"), | ||||
| 	PINCTRL_PIN(60, "UART1_RXD"), | ||||
| 	PINCTRL_PIN(61, "UART1_TXD"), | ||||
| 	PINCTRL_PIN(62, "UART1_RTSB"), | ||||
| 	PINCTRL_PIN(63, "UART1_CTSB"), | ||||
| 	PINCTRL_PIN(64, "I2C0_SDA"), | ||||
| 	PINCTRL_PIN(65, "I2C0_SCL"), | ||||
| 	PINCTRL_PIN(66, "I2C1_SDA"), | ||||
| 	PINCTRL_PIN(67, "I2C1_SCL"), | ||||
| 	PINCTRL_PIN(68, "UART2_RXD"), | ||||
| 	PINCTRL_PIN(69, "UART2_TXD"), | ||||
| 	PINCTRL_PIN(70, "UART2_RTSB"), | ||||
| 	PINCTRL_PIN(71, "UART2_CTSB"), | ||||
| 	/* GPP_D */ | ||||
| 	PINCTRL_PIN(72, "SPI1_CSB"), | ||||
| 	PINCTRL_PIN(73, "SPI1_CLK"), | ||||
| 	PINCTRL_PIN(74, "SPI1_MISO_IO_1"), | ||||
| 	PINCTRL_PIN(75, "SPI1_MOSI_IO_0"), | ||||
| 	PINCTRL_PIN(76, "FLASHTRIG"), | ||||
| 	PINCTRL_PIN(77, "ISH_I2C0_SDA"), | ||||
| 	PINCTRL_PIN(78, "ISH_I2C0_SCL"), | ||||
| 	PINCTRL_PIN(79, "ISH_I2C1_SDA"), | ||||
| 	PINCTRL_PIN(80, "ISH_I2C1_SCL"), | ||||
| 	PINCTRL_PIN(81, "ISH_SPI_CSB"), | ||||
| 	PINCTRL_PIN(82, "ISH_SPI_CLK"), | ||||
| 	PINCTRL_PIN(83, "ISH_SPI_MISO"), | ||||
| 	PINCTRL_PIN(84, "ISH_SPI_MOSI"), | ||||
| 	PINCTRL_PIN(85, "ISH_UART0_RXD"), | ||||
| 	PINCTRL_PIN(86, "ISH_UART0_TXD"), | ||||
| 	PINCTRL_PIN(87, "ISH_UART0_RTSB"), | ||||
| 	PINCTRL_PIN(88, "ISH_UART0_CTSB"), | ||||
| 	PINCTRL_PIN(89, "DMIC_CLK_1"), | ||||
| 	PINCTRL_PIN(90, "DMIC_DATA_1"), | ||||
| 	PINCTRL_PIN(91, "DMIC_CLK_0"), | ||||
| 	PINCTRL_PIN(92, "DMIC_DATA_0"), | ||||
| 	PINCTRL_PIN(93, "SPI1_IO_2"), | ||||
| 	PINCTRL_PIN(94, "SPI1_IO_3"), | ||||
| 	PINCTRL_PIN(95, "SSP_MCLK"), | ||||
| 	/* GPP_E */ | ||||
| 	PINCTRL_PIN(96, "SATAXPCIE_0"), | ||||
| 	PINCTRL_PIN(97, "SATAXPCIE_1"), | ||||
| 	PINCTRL_PIN(98, "SATAXPCIE_2"), | ||||
| 	PINCTRL_PIN(99, "CPU_GP_0"), | ||||
| 	PINCTRL_PIN(100, "SATA_DEVSLP_0"), | ||||
| 	PINCTRL_PIN(101, "SATA_DEVSLP_1"), | ||||
| 	PINCTRL_PIN(102, "SATA_DEVSLP_2"), | ||||
| 	PINCTRL_PIN(103, "CPU_GP_1"), | ||||
| 	PINCTRL_PIN(104, "SATA_LEDB"), | ||||
| 	PINCTRL_PIN(105, "USB2_OCB_0"), | ||||
| 	PINCTRL_PIN(106, "USB2_OCB_1"), | ||||
| 	PINCTRL_PIN(107, "USB2_OCB_2"), | ||||
| 	PINCTRL_PIN(108, "USB2_OCB_3"), | ||||
| 	PINCTRL_PIN(109, "DDSP_HPD_0"), | ||||
| 	PINCTRL_PIN(110, "DDSP_HPD_1"), | ||||
| 	PINCTRL_PIN(111, "DDSP_HPD_2"), | ||||
| 	PINCTRL_PIN(112, "DDSP_HPD_3"), | ||||
| 	PINCTRL_PIN(113, "EDP_HPD"), | ||||
| 	PINCTRL_PIN(114, "DDPB_CTRLCLK"), | ||||
| 	PINCTRL_PIN(115, "DDPB_CTRLDATA"), | ||||
| 	PINCTRL_PIN(116, "DDPC_CTRLCLK"), | ||||
| 	PINCTRL_PIN(117, "DDPC_CTRLDATA"), | ||||
| 	PINCTRL_PIN(118, "DDPD_CTRLCLK"), | ||||
| 	PINCTRL_PIN(119, "DDPD_CTRLDATA"), | ||||
| 	/* GPP_F */ | ||||
| 	PINCTRL_PIN(120, "SSP2_SCLK"), | ||||
| 	PINCTRL_PIN(121, "SSP2_SFRM"), | ||||
| 	PINCTRL_PIN(122, "SSP2_TXD"), | ||||
| 	PINCTRL_PIN(123, "SSP2_RXD"), | ||||
| 	PINCTRL_PIN(124, "I2C2_SDA"), | ||||
| 	PINCTRL_PIN(125, "I2C2_SCL"), | ||||
| 	PINCTRL_PIN(126, "I2C3_SDA"), | ||||
| 	PINCTRL_PIN(127, "I2C3_SCL"), | ||||
| 	PINCTRL_PIN(128, "I2C4_SDA"), | ||||
| 	PINCTRL_PIN(129, "I2C4_SCL"), | ||||
| 	PINCTRL_PIN(130, "I2C5_SDA"), | ||||
| 	PINCTRL_PIN(131, "I2C5_SCL"), | ||||
| 	PINCTRL_PIN(132, "EMMC_CMD"), | ||||
| 	PINCTRL_PIN(133, "EMMC_DATA_0"), | ||||
| 	PINCTRL_PIN(134, "EMMC_DATA_1"), | ||||
| 	PINCTRL_PIN(135, "EMMC_DATA_2"), | ||||
| 	PINCTRL_PIN(136, "EMMC_DATA_3"), | ||||
| 	PINCTRL_PIN(137, "EMMC_DATA_4"), | ||||
| 	PINCTRL_PIN(138, "EMMC_DATA_5"), | ||||
| 	PINCTRL_PIN(139, "EMMC_DATA_6"), | ||||
| 	PINCTRL_PIN(140, "EMMC_DATA_7"), | ||||
| 	PINCTRL_PIN(141, "EMMC_RCLK"), | ||||
| 	PINCTRL_PIN(142, "EMMC_CLK"), | ||||
| 	PINCTRL_PIN(143, "GPP_F_23"), | ||||
| 	/* GPP_G */ | ||||
| 	PINCTRL_PIN(144, "SD_CMD"), | ||||
| 	PINCTRL_PIN(145, "SD_DATA_0"), | ||||
| 	PINCTRL_PIN(146, "SD_DATA_1"), | ||||
| 	PINCTRL_PIN(147, "SD_DATA_2"), | ||||
| 	PINCTRL_PIN(148, "SD_DATA_3"), | ||||
| 	PINCTRL_PIN(149, "SD_CDB"), | ||||
| 	PINCTRL_PIN(150, "SD_CLK"), | ||||
| 	PINCTRL_PIN(151, "SD_WP"), | ||||
| }; | ||||
|  | ||||
| static const unsigned sptlp_spi0_pins[] = { 39, 40, 41, 42 }; | ||||
| static const unsigned sptlp_spi1_pins[] = { 43, 44, 45, 46 }; | ||||
| static const unsigned sptlp_uart0_pins[] = { 56, 57, 58, 59 }; | ||||
| static const unsigned sptlp_uart1_pins[] = { 60, 61, 62, 63 }; | ||||
| static const unsigned sptlp_uart2_pins[] = { 68, 69, 71, 71 }; | ||||
| static const unsigned sptlp_i2c0_pins[] = { 64, 65 }; | ||||
| static const unsigned sptlp_i2c1_pins[] = { 66, 67 }; | ||||
| static const unsigned sptlp_i2c2_pins[] = { 124, 125 }; | ||||
| static const unsigned sptlp_i2c3_pins[] = { 126, 127 }; | ||||
| static const unsigned sptlp_i2c4_pins[] = { 128, 129 }; | ||||
| static const unsigned sptlp_i2c4b_pins[] = { 85, 86 }; | ||||
| static const unsigned sptlp_i2c5_pins[] = { 130, 131 }; | ||||
| static const unsigned sptlp_ssp2_pins[] = { 120, 121, 122, 123 }; | ||||
| static const unsigned sptlp_emmc_pins[] = { | ||||
| 	132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, | ||||
| }; | ||||
| static const unsigned sptlp_sd_pins[] = { | ||||
| 	144, 145, 146, 147, 148, 149, 150, 151, | ||||
| }; | ||||
|  | ||||
| static const struct intel_pingroup sptlp_groups[] = { | ||||
| 	PIN_GROUP("spi0_grp", sptlp_spi0_pins, 1), | ||||
| 	PIN_GROUP("spi1_grp", sptlp_spi1_pins, 1), | ||||
| 	PIN_GROUP("uart0_grp", sptlp_uart0_pins, 1), | ||||
| 	PIN_GROUP("uart1_grp", sptlp_uart1_pins, 1), | ||||
| 	PIN_GROUP("uart2_grp", sptlp_uart2_pins, 1), | ||||
| 	PIN_GROUP("i2c0_grp", sptlp_i2c0_pins, 1), | ||||
| 	PIN_GROUP("i2c1_grp", sptlp_i2c1_pins, 1), | ||||
| 	PIN_GROUP("i2c2_grp", sptlp_i2c2_pins, 1), | ||||
| 	PIN_GROUP("i2c3_grp", sptlp_i2c3_pins, 1), | ||||
| 	PIN_GROUP("i2c4_grp", sptlp_i2c4_pins, 1), | ||||
| 	PIN_GROUP("i2c4b_grp", sptlp_i2c4b_pins, 3), | ||||
| 	PIN_GROUP("i2c5_grp", sptlp_i2c5_pins, 1), | ||||
| 	PIN_GROUP("ssp2_grp", sptlp_ssp2_pins, 1), | ||||
| 	PIN_GROUP("emmc_grp", sptlp_emmc_pins, 1), | ||||
| 	PIN_GROUP("sd_grp", sptlp_sd_pins, 1), | ||||
| }; | ||||
|  | ||||
| static const char * const sptlp_spi0_groups[] = { "spi0_grp" }; | ||||
| static const char * const sptlp_spi1_groups[] = { "spi0_grp" }; | ||||
| static const char * const sptlp_uart0_groups[] = { "uart0_grp" }; | ||||
| static const char * const sptlp_uart1_groups[] = { "uart1_grp" }; | ||||
| static const char * const sptlp_uart2_groups[] = { "uart2_grp" }; | ||||
| static const char * const sptlp_i2c0_groups[] = { "i2c0_grp" }; | ||||
| static const char * const sptlp_i2c1_groups[] = { "i2c1_grp" }; | ||||
| static const char * const sptlp_i2c2_groups[] = { "i2c2_grp" }; | ||||
| static const char * const sptlp_i2c3_groups[] = { "i2c3_grp" }; | ||||
| static const char * const sptlp_i2c4_groups[] = { "i2c4_grp", "i2c4b_grp" }; | ||||
| static const char * const sptlp_i2c5_groups[] = { "i2c5_grp" }; | ||||
| static const char * const sptlp_ssp2_groups[] = { "ssp2_grp" }; | ||||
| static const char * const sptlp_emmc_groups[] = { "emmc_grp" }; | ||||
| static const char * const sptlp_sd_groups[] = { "sd_grp" }; | ||||
|  | ||||
| static const struct intel_function sptlp_functions[] = { | ||||
| 	FUNCTION("spi0", sptlp_spi0_groups), | ||||
| 	FUNCTION("spi1", sptlp_spi1_groups), | ||||
| 	FUNCTION("uart0", sptlp_uart0_groups), | ||||
| 	FUNCTION("uart1", sptlp_uart1_groups), | ||||
| 	FUNCTION("uart2", sptlp_uart2_groups), | ||||
| 	FUNCTION("i2c0", sptlp_i2c0_groups), | ||||
| 	FUNCTION("i2c1", sptlp_i2c1_groups), | ||||
| 	FUNCTION("i2c2", sptlp_i2c2_groups), | ||||
| 	FUNCTION("i2c3", sptlp_i2c3_groups), | ||||
| 	FUNCTION("i2c4", sptlp_i2c4_groups), | ||||
| 	FUNCTION("i2c5", sptlp_i2c5_groups), | ||||
| 	FUNCTION("ssp2", sptlp_ssp2_groups), | ||||
| 	FUNCTION("emmc", sptlp_emmc_groups), | ||||
| 	FUNCTION("sd", sptlp_sd_groups), | ||||
| }; | ||||
|  | ||||
| static const struct intel_community sptlp_communities[] = { | ||||
| 	SPT_COMMUNITY(0, 0, 47), | ||||
| 	SPT_COMMUNITY(1, 48, 119), | ||||
| 	SPT_COMMUNITY(2, 120, 151), | ||||
| }; | ||||
|  | ||||
| static const struct intel_pinctrl_soc_data sptlp_soc_data = { | ||||
| 	.pins = sptlp_pins, | ||||
| 	.npins = ARRAY_SIZE(sptlp_pins), | ||||
| 	.groups = sptlp_groups, | ||||
| 	.ngroups = ARRAY_SIZE(sptlp_groups), | ||||
| 	.functions = sptlp_functions, | ||||
| 	.nfunctions = ARRAY_SIZE(sptlp_functions), | ||||
| 	.communities = sptlp_communities, | ||||
| 	.ncommunities = ARRAY_SIZE(sptlp_communities), | ||||
| }; | ||||
|  | ||||
| static const struct acpi_device_id spt_pinctrl_acpi_match[] = { | ||||
| 	{ "INT344B", (kernel_ulong_t)&sptlp_soc_data }, | ||||
| 	{ } | ||||
| }; | ||||
| MODULE_DEVICE_TABLE(acpi, spt_pinctrl_acpi_match); | ||||
|  | ||||
| static int spt_pinctrl_probe(struct platform_device *pdev) | ||||
| { | ||||
| 	const struct intel_pinctrl_soc_data *soc_data; | ||||
| 	const struct acpi_device_id *id; | ||||
|  | ||||
| 	id = acpi_match_device(spt_pinctrl_acpi_match, &pdev->dev); | ||||
| 	if (!id || !id->driver_data) | ||||
| 		return -ENODEV; | ||||
|  | ||||
| 	soc_data = (const struct intel_pinctrl_soc_data *)id->driver_data; | ||||
| 	return intel_pinctrl_probe(pdev, soc_data); | ||||
| } | ||||
|  | ||||
| static const struct dev_pm_ops spt_pinctrl_pm_ops = { | ||||
| 	SET_LATE_SYSTEM_SLEEP_PM_OPS(intel_pinctrl_suspend, | ||||
| 				     intel_pinctrl_resume) | ||||
| }; | ||||
|  | ||||
| static struct platform_driver spt_pinctrl_driver = { | ||||
| 	.probe = spt_pinctrl_probe, | ||||
| 	.remove = intel_pinctrl_remove, | ||||
| 	.driver = { | ||||
| 		.name = "sunrisepoint-pinctrl", | ||||
| 		.acpi_match_table = spt_pinctrl_acpi_match, | ||||
| 		.pm = &spt_pinctrl_pm_ops, | ||||
| 	}, | ||||
| }; | ||||
|  | ||||
| static int __init spt_pinctrl_init(void) | ||||
| { | ||||
| 	return platform_driver_register(&spt_pinctrl_driver); | ||||
| } | ||||
| subsys_initcall(spt_pinctrl_init); | ||||
|  | ||||
| static void __exit spt_pinctrl_exit(void) | ||||
| { | ||||
| 	platform_driver_unregister(&spt_pinctrl_driver); | ||||
| } | ||||
| module_exit(spt_pinctrl_exit); | ||||
|  | ||||
| MODULE_AUTHOR("Mathias Nyman <mathias.nyman@linux.intel.com>"); | ||||
| MODULE_AUTHOR("Mika Westerberg <mika.westerberg@linux.intel.com>"); | ||||
| MODULE_DESCRIPTION("Intel Sunrisepoint PCH pinctrl/GPIO driver"); | ||||
| MODULE_LICENSE("GPL v2"); | ||||
							
								
								
									
										23
									
								
								drivers/pinctrl/mediatek/Kconfig
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								drivers/pinctrl/mediatek/Kconfig
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,23 @@ | ||||
| if ARCH_MEDIATEK || COMPILE_TEST | ||||
|  | ||||
| config PINCTRL_MTK_COMMON | ||||
| 	bool | ||||
| 	select PINMUX | ||||
| 	select GENERIC_PINCONF | ||||
| 	select GPIOLIB | ||||
| 	select OF_GPIO | ||||
|  | ||||
| # For ARMv7 SoCs | ||||
| config PINCTRL_MT8135 | ||||
| 	bool "Mediatek MT8135 pin control" if COMPILE_TEST && !MACH_MT8135 | ||||
| 	default MACH_MT8135 | ||||
| 	select PINCTRL_MTK_COMMON | ||||
|  | ||||
| # For ARMv8 SoCs | ||||
| config PINCTRL_MT8173 | ||||
| 	bool "Mediatek MT8173 pin control" | ||||
| 	depends on ARM64 || COMPILE_TEST | ||||
| 	default ARM64 && ARCH_MEDIATEK | ||||
| 	select PINCTRL_MTK_COMMON | ||||
|  | ||||
| endif | ||||
							
								
								
									
										6
									
								
								drivers/pinctrl/mediatek/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								drivers/pinctrl/mediatek/Makefile
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,6 @@ | ||||
| # Core | ||||
| obj-$(CONFIG_PINCTRL_MTK_COMMON)	+= pinctrl-mtk-common.o | ||||
|  | ||||
| # SoC Drivers | ||||
| obj-$(CONFIG_PINCTRL_MT8135)		+= pinctrl-mt8135.o | ||||
| obj-$(CONFIG_PINCTRL_MT8173)		+= pinctrl-mt8173.o | ||||
							
								
								
									
										376
									
								
								drivers/pinctrl/mediatek/pinctrl-mt8135.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										376
									
								
								drivers/pinctrl/mediatek/pinctrl-mt8135.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,376 @@ | ||||
| /* | ||||
|  * Copyright (c) 2014 MediaTek Inc. | ||||
|  * Author: Hongzhou.Yang <hongzhou.yang@mediatek.com> | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License version 2 as | ||||
|  * published by the Free Software Foundation. | ||||
|  * | ||||
|  * This program is distributed in the hope that 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. | ||||
|  */ | ||||
|  | ||||
| #include <linux/module.h> | ||||
| #include <linux/platform_device.h> | ||||
| #include <linux/of.h> | ||||
| #include <linux/of_device.h> | ||||
| #include <linux/pinctrl/pinctrl.h> | ||||
| #include <linux/regmap.h> | ||||
| #include <dt-bindings/pinctrl/mt65xx.h> | ||||
|  | ||||
| #include "pinctrl-mtk-common.h" | ||||
| #include "pinctrl-mtk-mt8135.h" | ||||
|  | ||||
| #define DRV_BASE1				0x500 | ||||
| #define DRV_BASE2				0x510 | ||||
| #define PUPD_BASE1				0x400 | ||||
| #define PUPD_BASE2				0x450 | ||||
| #define R0_BASE1				0x4d0 | ||||
| #define R1_BASE1				0x200 | ||||
| #define R1_BASE2				0x250 | ||||
|  | ||||
| struct mtk_spec_pull_set { | ||||
| 	unsigned int pin; | ||||
| 	unsigned int pupd_offset; | ||||
| 	unsigned char pupd_bit; | ||||
| 	unsigned int r0_offset; | ||||
| 	unsigned char r0_bit; | ||||
| 	unsigned int r1_offset; | ||||
| 	unsigned char r1_bit; | ||||
| }; | ||||
|  | ||||
| #define SPEC_PULL(_pin, _pupd_offset, _pupd_bit, _r0_offset, \ | ||||
| 	_r0_bit, _r1_offset, _r1_bit)	\ | ||||
| 	{	\ | ||||
| 		.pin = _pin,	\ | ||||
| 		.pupd_offset = _pupd_offset,	\ | ||||
| 		.pupd_bit = _pupd_bit,	\ | ||||
| 		.r0_offset = _r0_offset, \ | ||||
| 		.r0_bit = _r0_bit, \ | ||||
| 		.r1_offset = _r1_offset, \ | ||||
| 		.r1_bit = _r1_bit, \ | ||||
| 	} | ||||
|  | ||||
| static const struct mtk_drv_group_desc mt8135_drv_grp[] =  { | ||||
| 	/* E8E4E2 2/4/6/8/10/12/14/16 */ | ||||
| 	MTK_DRV_GRP(2, 16, 0, 2, 2), | ||||
| 	/* E8E4  4/8/12/16 */ | ||||
| 	MTK_DRV_GRP(4, 16, 1, 2, 4), | ||||
| 	/* E4E2  2/4/6/8 */ | ||||
| 	MTK_DRV_GRP(2, 8, 0, 1, 2), | ||||
| 	/* E16E8E4 4/8/12/16/20/24/28/32 */ | ||||
| 	MTK_DRV_GRP(4, 32, 0, 2, 4) | ||||
| }; | ||||
|  | ||||
| static const struct mtk_pin_drv_grp mt8135_pin_drv[] = { | ||||
| 	MTK_PIN_DRV_GRP(0, DRV_BASE1, 0, 0), | ||||
| 	MTK_PIN_DRV_GRP(1, DRV_BASE1, 0, 0), | ||||
| 	MTK_PIN_DRV_GRP(2, DRV_BASE1, 0, 0), | ||||
| 	MTK_PIN_DRV_GRP(3, DRV_BASE1, 0, 0), | ||||
| 	MTK_PIN_DRV_GRP(4, DRV_BASE1, 4, 0), | ||||
| 	MTK_PIN_DRV_GRP(5, DRV_BASE1, 8, 0), | ||||
| 	MTK_PIN_DRV_GRP(6, DRV_BASE1, 0, 0), | ||||
| 	MTK_PIN_DRV_GRP(7, DRV_BASE1, 0, 0), | ||||
| 	MTK_PIN_DRV_GRP(8, DRV_BASE1, 0, 0), | ||||
| 	MTK_PIN_DRV_GRP(9, DRV_BASE1, 0, 0), | ||||
|  | ||||
| 	MTK_PIN_DRV_GRP(10, DRV_BASE1, 12, 1), | ||||
| 	MTK_PIN_DRV_GRP(11, DRV_BASE1, 12, 1), | ||||
| 	MTK_PIN_DRV_GRP(12, DRV_BASE1, 12, 1), | ||||
| 	MTK_PIN_DRV_GRP(13, DRV_BASE1, 12, 1), | ||||
| 	MTK_PIN_DRV_GRP(14, DRV_BASE1, 12, 1), | ||||
| 	MTK_PIN_DRV_GRP(15, DRV_BASE1, 12, 1), | ||||
| 	MTK_PIN_DRV_GRP(16, DRV_BASE1, 12, 1), | ||||
| 	MTK_PIN_DRV_GRP(17, DRV_BASE1, 16, 1), | ||||
| 	MTK_PIN_DRV_GRP(18, DRV_BASE1, 16, 1), | ||||
| 	MTK_PIN_DRV_GRP(19, DRV_BASE1, 16, 1), | ||||
| 	MTK_PIN_DRV_GRP(20, DRV_BASE1, 16, 1), | ||||
| 	MTK_PIN_DRV_GRP(21, DRV_BASE1, 16, 1), | ||||
| 	MTK_PIN_DRV_GRP(22, DRV_BASE1, 16, 1), | ||||
| 	MTK_PIN_DRV_GRP(23, DRV_BASE1, 16, 1), | ||||
| 	MTK_PIN_DRV_GRP(24, DRV_BASE1, 16, 1), | ||||
| 	MTK_PIN_DRV_GRP(33, DRV_BASE1, 24, 1), | ||||
| 	MTK_PIN_DRV_GRP(34, DRV_BASE2, 12, 2), | ||||
| 	MTK_PIN_DRV_GRP(37, DRV_BASE2, 20, 1), | ||||
| 	MTK_PIN_DRV_GRP(38, DRV_BASE2, 20, 1), | ||||
| 	MTK_PIN_DRV_GRP(39, DRV_BASE2, 20, 1), | ||||
| 	MTK_PIN_DRV_GRP(40, DRV_BASE2, 24, 1), | ||||
| 	MTK_PIN_DRV_GRP(41, DRV_BASE2, 24, 1), | ||||
| 	MTK_PIN_DRV_GRP(42, DRV_BASE2, 24, 1), | ||||
| 	MTK_PIN_DRV_GRP(43, DRV_BASE2, 28, 1), | ||||
| 	MTK_PIN_DRV_GRP(44, DRV_BASE2, 28, 1), | ||||
| 	MTK_PIN_DRV_GRP(45, DRV_BASE2, 28, 1), | ||||
| 	MTK_PIN_DRV_GRP(46, DRV_BASE2, 28, 1), | ||||
| 	MTK_PIN_DRV_GRP(47, DRV_BASE2, 28, 1), | ||||
|  | ||||
| 	MTK_PIN_DRV_GRP(49, DRV_BASE2+0x10, 0, 1), | ||||
| 	MTK_PIN_DRV_GRP(50, DRV_BASE2+0x10, 4, 1), | ||||
| 	MTK_PIN_DRV_GRP(51, DRV_BASE2+0x10, 8, 1), | ||||
| 	MTK_PIN_DRV_GRP(52, DRV_BASE2+0x10, 12, 2), | ||||
| 	MTK_PIN_DRV_GRP(53, DRV_BASE2+0x10, 16, 1), | ||||
| 	MTK_PIN_DRV_GRP(54, DRV_BASE2+0x10, 20, 1), | ||||
| 	MTK_PIN_DRV_GRP(55, DRV_BASE2+0x10, 24, 1), | ||||
| 	MTK_PIN_DRV_GRP(56, DRV_BASE2+0x10, 28, 1), | ||||
|  | ||||
| 	MTK_PIN_DRV_GRP(57, DRV_BASE2+0x20, 0, 1), | ||||
| 	MTK_PIN_DRV_GRP(58, DRV_BASE2+0x20, 0, 1), | ||||
| 	MTK_PIN_DRV_GRP(59, DRV_BASE2+0x20, 0, 1), | ||||
| 	MTK_PIN_DRV_GRP(60, DRV_BASE2+0x20, 0, 1), | ||||
| 	MTK_PIN_DRV_GRP(61, DRV_BASE2+0x20, 0, 1), | ||||
| 	MTK_PIN_DRV_GRP(62, DRV_BASE2+0x20, 0, 1), | ||||
| 	MTK_PIN_DRV_GRP(63, DRV_BASE2+0x20, 4, 1), | ||||
| 	MTK_PIN_DRV_GRP(64, DRV_BASE2+0x20, 8, 1), | ||||
| 	MTK_PIN_DRV_GRP(65, DRV_BASE2+0x20, 12, 1), | ||||
| 	MTK_PIN_DRV_GRP(66, DRV_BASE2+0x20, 16, 1), | ||||
| 	MTK_PIN_DRV_GRP(67, DRV_BASE2+0x20, 20, 1), | ||||
| 	MTK_PIN_DRV_GRP(68, DRV_BASE2+0x20, 24, 1), | ||||
| 	MTK_PIN_DRV_GRP(69, DRV_BASE2+0x20, 28, 1), | ||||
|  | ||||
| 	MTK_PIN_DRV_GRP(70, DRV_BASE2+0x30, 0, 1), | ||||
| 	MTK_PIN_DRV_GRP(71, DRV_BASE2+0x30, 4, 1), | ||||
| 	MTK_PIN_DRV_GRP(72, DRV_BASE2+0x30, 8, 1), | ||||
| 	MTK_PIN_DRV_GRP(73, DRV_BASE2+0x30, 12, 1), | ||||
| 	MTK_PIN_DRV_GRP(74, DRV_BASE2+0x30, 16, 1), | ||||
| 	MTK_PIN_DRV_GRP(75, DRV_BASE2+0x30, 20, 1), | ||||
| 	MTK_PIN_DRV_GRP(76, DRV_BASE2+0x30, 24, 1), | ||||
| 	MTK_PIN_DRV_GRP(77, DRV_BASE2+0x30, 28, 3), | ||||
| 	MTK_PIN_DRV_GRP(78, DRV_BASE2+0x30, 28, 3), | ||||
|  | ||||
| 	MTK_PIN_DRV_GRP(79, DRV_BASE2+0x40, 0, 3), | ||||
| 	MTK_PIN_DRV_GRP(80, DRV_BASE2+0x40, 4, 3), | ||||
|  | ||||
| 	MTK_PIN_DRV_GRP(81, DRV_BASE2+0x30, 28, 3), | ||||
| 	MTK_PIN_DRV_GRP(82, DRV_BASE2+0x30, 28, 3), | ||||
|  | ||||
| 	MTK_PIN_DRV_GRP(83, DRV_BASE2+0x40, 8, 3), | ||||
| 	MTK_PIN_DRV_GRP(84, DRV_BASE2+0x40, 8, 3), | ||||
| 	MTK_PIN_DRV_GRP(85, DRV_BASE2+0x40, 12, 3), | ||||
| 	MTK_PIN_DRV_GRP(86, DRV_BASE2+0x40, 16, 3), | ||||
| 	MTK_PIN_DRV_GRP(87, DRV_BASE2+0x40, 8, 3), | ||||
| 	MTK_PIN_DRV_GRP(88, DRV_BASE2+0x40, 8, 3), | ||||
|  | ||||
| 	MTK_PIN_DRV_GRP(89, DRV_BASE2+0x50, 12, 0), | ||||
| 	MTK_PIN_DRV_GRP(90, DRV_BASE2+0x50, 12, 0), | ||||
| 	MTK_PIN_DRV_GRP(91, DRV_BASE2+0x50, 12, 0), | ||||
| 	MTK_PIN_DRV_GRP(92, DRV_BASE2+0x50, 12, 0), | ||||
| 	MTK_PIN_DRV_GRP(93, DRV_BASE2+0x50, 12, 0), | ||||
| 	MTK_PIN_DRV_GRP(94, DRV_BASE2+0x50, 12, 0), | ||||
| 	MTK_PIN_DRV_GRP(95, DRV_BASE2+0x50, 12, 0), | ||||
|  | ||||
| 	MTK_PIN_DRV_GRP(96, DRV_BASE1+0xb0, 28, 0), | ||||
|  | ||||
| 	MTK_PIN_DRV_GRP(97, DRV_BASE2+0x50, 12, 0), | ||||
| 	MTK_PIN_DRV_GRP(98, DRV_BASE2+0x50, 16, 0), | ||||
| 	MTK_PIN_DRV_GRP(99, DRV_BASE2+0x50, 20, 1), | ||||
| 	MTK_PIN_DRV_GRP(102, DRV_BASE2+0x50, 24, 1), | ||||
| 	MTK_PIN_DRV_GRP(103, DRV_BASE2+0x50, 28, 1), | ||||
|  | ||||
|  | ||||
| 	MTK_PIN_DRV_GRP(104, DRV_BASE2+0x60, 0, 1), | ||||
| 	MTK_PIN_DRV_GRP(105, DRV_BASE2+0x60, 4, 1), | ||||
| 	MTK_PIN_DRV_GRP(106, DRV_BASE2+0x60, 4, 1), | ||||
| 	MTK_PIN_DRV_GRP(107, DRV_BASE2+0x60, 4, 1), | ||||
| 	MTK_PIN_DRV_GRP(108, DRV_BASE2+0x60, 4, 1), | ||||
| 	MTK_PIN_DRV_GRP(109, DRV_BASE2+0x60, 8, 2), | ||||
| 	MTK_PIN_DRV_GRP(110, DRV_BASE2+0x60, 12, 2), | ||||
| 	MTK_PIN_DRV_GRP(111, DRV_BASE2+0x60, 16, 2), | ||||
| 	MTK_PIN_DRV_GRP(112, DRV_BASE2+0x60, 20, 2), | ||||
| 	MTK_PIN_DRV_GRP(113, DRV_BASE2+0x60, 24, 2), | ||||
| 	MTK_PIN_DRV_GRP(114, DRV_BASE2+0x60, 28, 2), | ||||
|  | ||||
| 	MTK_PIN_DRV_GRP(115, DRV_BASE2+0x70, 0, 2), | ||||
| 	MTK_PIN_DRV_GRP(116, DRV_BASE2+0x70, 4, 2), | ||||
| 	MTK_PIN_DRV_GRP(117, DRV_BASE2+0x70, 8, 2), | ||||
| 	MTK_PIN_DRV_GRP(118, DRV_BASE2+0x70, 12, 2), | ||||
| 	MTK_PIN_DRV_GRP(119, DRV_BASE2+0x70, 16, 2), | ||||
| 	MTK_PIN_DRV_GRP(120, DRV_BASE2+0x70, 20, 2), | ||||
|  | ||||
| 	MTK_PIN_DRV_GRP(181, DRV_BASE1+0xa0, 12, 1), | ||||
| 	MTK_PIN_DRV_GRP(182, DRV_BASE1+0xa0, 16, 1), | ||||
| 	MTK_PIN_DRV_GRP(183, DRV_BASE1+0xa0, 20, 1), | ||||
| 	MTK_PIN_DRV_GRP(184, DRV_BASE1+0xa0, 24, 1), | ||||
| 	MTK_PIN_DRV_GRP(185, DRV_BASE1+0xa0, 28, 1), | ||||
|  | ||||
| 	MTK_PIN_DRV_GRP(186, DRV_BASE1+0xb0, 0, 2), | ||||
| 	MTK_PIN_DRV_GRP(187, DRV_BASE1+0xb0, 0, 2), | ||||
| 	MTK_PIN_DRV_GRP(188, DRV_BASE1+0xb0, 0, 2), | ||||
| 	MTK_PIN_DRV_GRP(189, DRV_BASE1+0xb0, 0, 2), | ||||
| 	MTK_PIN_DRV_GRP(190, DRV_BASE1+0xb0, 4, 1), | ||||
| 	MTK_PIN_DRV_GRP(191, DRV_BASE1+0xb0, 8, 1), | ||||
| 	MTK_PIN_DRV_GRP(192, DRV_BASE1+0xb0, 12, 1), | ||||
|  | ||||
| 	MTK_PIN_DRV_GRP(197, DRV_BASE1+0xb0, 16, 0), | ||||
| 	MTK_PIN_DRV_GRP(198, DRV_BASE1+0xb0, 16, 0), | ||||
| 	MTK_PIN_DRV_GRP(199, DRV_BASE1+0xb0, 20, 0), | ||||
| 	MTK_PIN_DRV_GRP(200, DRV_BASE1+0xb0, 24, 0), | ||||
| 	MTK_PIN_DRV_GRP(201, DRV_BASE1+0xb0, 16, 0), | ||||
| 	MTK_PIN_DRV_GRP(202, DRV_BASE1+0xb0, 16, 0) | ||||
| }; | ||||
|  | ||||
| static const struct mtk_spec_pull_set spec_pupd[] = { | ||||
| 	SPEC_PULL(0, PUPD_BASE1, 0, R0_BASE1, 9, R1_BASE1, 0), | ||||
| 	SPEC_PULL(1, PUPD_BASE1, 1, R0_BASE1, 8, R1_BASE1, 1), | ||||
| 	SPEC_PULL(2, PUPD_BASE1, 2, R0_BASE1, 7, R1_BASE1, 2), | ||||
| 	SPEC_PULL(3, PUPD_BASE1, 3, R0_BASE1, 6, R1_BASE1, 3), | ||||
| 	SPEC_PULL(4, PUPD_BASE1, 4, R0_BASE1, 1, R1_BASE1, 4), | ||||
| 	SPEC_PULL(5, PUPD_BASE1, 5, R0_BASE1, 0, R1_BASE1, 5), | ||||
| 	SPEC_PULL(6, PUPD_BASE1, 6, R0_BASE1, 5, R1_BASE1, 6), | ||||
| 	SPEC_PULL(7, PUPD_BASE1, 7, R0_BASE1, 4, R1_BASE1, 7), | ||||
| 	SPEC_PULL(8, PUPD_BASE1, 8, R0_BASE1, 3, R1_BASE1, 8), | ||||
| 	SPEC_PULL(9, PUPD_BASE1, 9, R0_BASE1, 2, R1_BASE1, 9), | ||||
| 	SPEC_PULL(89, PUPD_BASE2, 9, R0_BASE1, 18, R1_BASE2, 9), | ||||
| 	SPEC_PULL(90, PUPD_BASE2, 10, R0_BASE1, 19, R1_BASE2, 10), | ||||
| 	SPEC_PULL(91, PUPD_BASE2, 11, R0_BASE1, 23, R1_BASE2, 11), | ||||
| 	SPEC_PULL(92, PUPD_BASE2, 12, R0_BASE1, 24, R1_BASE2, 12), | ||||
| 	SPEC_PULL(93, PUPD_BASE2, 13, R0_BASE1, 25, R1_BASE2, 13), | ||||
| 	SPEC_PULL(94, PUPD_BASE2, 14, R0_BASE1, 22, R1_BASE2, 14), | ||||
| 	SPEC_PULL(95, PUPD_BASE2, 15, R0_BASE1, 20, R1_BASE2, 15), | ||||
| 	SPEC_PULL(96, PUPD_BASE2+0x10, 0, R0_BASE1, 16, R1_BASE2+0x10, 0), | ||||
| 	SPEC_PULL(97, PUPD_BASE2+0x10, 1, R0_BASE1, 21, R1_BASE2+0x10, 1), | ||||
| 	SPEC_PULL(98, PUPD_BASE2+0x10, 2, R0_BASE1, 17, R1_BASE2+0x10, 2), | ||||
| 	SPEC_PULL(197, PUPD_BASE1+0xc0, 5, R0_BASE1, 13, R1_BASE2+0xc0, 5), | ||||
| 	SPEC_PULL(198, PUPD_BASE2+0xc0, 6, R0_BASE1, 14, R1_BASE2+0xc0, 6), | ||||
| 	SPEC_PULL(199, PUPD_BASE2+0xc0, 7, R0_BASE1, 11, R1_BASE2+0xc0, 7), | ||||
| 	SPEC_PULL(200, PUPD_BASE2+0xc0, 8, R0_BASE1, 10, R1_BASE2+0xc0, 8), | ||||
| 	SPEC_PULL(201, PUPD_BASE2+0xc0, 9, R0_BASE1, 13, R1_BASE2+0xc0, 9), | ||||
| 	SPEC_PULL(202, PUPD_BASE2+0xc0, 10, R0_BASE1, 12, R1_BASE2+0xc0, 10) | ||||
| }; | ||||
|  | ||||
| static int spec_pull_set(struct regmap *regmap, unsigned int pin, | ||||
| 		unsigned char align, bool isup, unsigned int r1r0) | ||||
| { | ||||
| 	unsigned int i; | ||||
| 	unsigned int reg_pupd, reg_set_r0, reg_set_r1; | ||||
| 	unsigned int reg_rst_r0, reg_rst_r1; | ||||
| 	bool find = false; | ||||
|  | ||||
| 	for (i = 0; i < ARRAY_SIZE(spec_pupd); i++) { | ||||
| 		if (pin == spec_pupd[i].pin) { | ||||
| 			find = true; | ||||
| 			break; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if (!find) | ||||
| 		return -EINVAL; | ||||
|  | ||||
| 	if (isup) | ||||
| 		reg_pupd = spec_pupd[i].pupd_offset + align; | ||||
| 	else | ||||
| 		reg_pupd = spec_pupd[i].pupd_offset + (align << 1); | ||||
|  | ||||
| 	regmap_write(regmap, reg_pupd, spec_pupd[i].pupd_bit); | ||||
|  | ||||
| 	reg_set_r0 = spec_pupd[i].r0_offset + align; | ||||
| 	reg_rst_r0 = spec_pupd[i].r0_offset + (align << 1); | ||||
| 	reg_set_r1 = spec_pupd[i].r1_offset + align; | ||||
| 	reg_rst_r1 = spec_pupd[i].r1_offset + (align << 1); | ||||
|  | ||||
| 	switch (r1r0) { | ||||
| 	case MTK_PUPD_SET_R1R0_00: | ||||
| 		regmap_write(regmap, reg_rst_r0, spec_pupd[i].r0_bit); | ||||
| 		regmap_write(regmap, reg_rst_r1, spec_pupd[i].r1_bit); | ||||
| 		break; | ||||
| 	case MTK_PUPD_SET_R1R0_01: | ||||
| 		regmap_write(regmap, reg_set_r0, spec_pupd[i].r0_bit); | ||||
| 		regmap_write(regmap, reg_rst_r1, spec_pupd[i].r1_bit); | ||||
| 		break; | ||||
| 	case MTK_PUPD_SET_R1R0_10: | ||||
| 		regmap_write(regmap, reg_rst_r0, spec_pupd[i].r0_bit); | ||||
| 		regmap_write(regmap, reg_set_r1, spec_pupd[i].r1_bit); | ||||
| 		break; | ||||
| 	case MTK_PUPD_SET_R1R0_11: | ||||
| 		regmap_write(regmap, reg_set_r0, spec_pupd[i].r0_bit); | ||||
| 		regmap_write(regmap, reg_set_r1, spec_pupd[i].r1_bit); | ||||
| 		break; | ||||
| 	default: | ||||
| 		return -EINVAL; | ||||
| 	} | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static const struct mtk_pinctrl_devdata mt8135_pinctrl_data = { | ||||
| 	.pins = mtk_pins_mt8135, | ||||
| 	.npins = ARRAY_SIZE(mtk_pins_mt8135), | ||||
| 	.grp_desc = mt8135_drv_grp, | ||||
| 	.n_grp_cls = ARRAY_SIZE(mt8135_drv_grp), | ||||
| 	.pin_drv_grp = mt8135_pin_drv, | ||||
| 	.n_pin_drv_grps = ARRAY_SIZE(mt8135_pin_drv), | ||||
| 	.spec_pull_set = spec_pull_set, | ||||
| 	.dir_offset = 0x0000, | ||||
| 	.ies_offset = 0x0100, | ||||
| 	.pullen_offset = 0x0200, | ||||
| 	.smt_offset = 0x0300, | ||||
| 	.pullsel_offset = 0x0400, | ||||
| 	.invser_offset = 0x0600, | ||||
| 	.dout_offset = 0x0800, | ||||
| 	.din_offset = 0x0A00, | ||||
| 	.pinmux_offset = 0x0C00, | ||||
| 	.type1_start = 34, | ||||
| 	.type1_end = 149, | ||||
| 	.port_shf = 4, | ||||
| 	.port_mask = 0xf, | ||||
| 	.port_align = 4, | ||||
| 	.chip_type = MTK_CHIP_TYPE_BASE, | ||||
| 	.eint_offsets = { | ||||
| 		.name = "mt8135_eint", | ||||
| 		.stat      = 0x000, | ||||
| 		.ack       = 0x040, | ||||
| 		.mask      = 0x080, | ||||
| 		.mask_set  = 0x0c0, | ||||
| 		.mask_clr  = 0x100, | ||||
| 		.sens      = 0x140, | ||||
| 		.sens_set  = 0x180, | ||||
| 		.sens_clr  = 0x1c0, | ||||
| 		.soft      = 0x200, | ||||
| 		.soft_set  = 0x240, | ||||
| 		.soft_clr  = 0x280, | ||||
| 		.pol       = 0x300, | ||||
| 		.pol_set   = 0x340, | ||||
| 		.pol_clr   = 0x380, | ||||
| 		.dom_en    = 0x400, | ||||
| 		.dbnc_ctrl = 0x500, | ||||
| 		.dbnc_set  = 0x600, | ||||
| 		.dbnc_clr  = 0x700, | ||||
| 		.port_mask = 7, | ||||
| 		.ports     = 6, | ||||
| 	}, | ||||
| 	.ap_num = 192, | ||||
| 	.db_cnt = 16, | ||||
| }; | ||||
|  | ||||
| static int mt8135_pinctrl_probe(struct platform_device *pdev) | ||||
| { | ||||
| 	return mtk_pctrl_init(pdev, &mt8135_pinctrl_data); | ||||
| } | ||||
|  | ||||
| static const struct of_device_id mt8135_pctrl_match[] = { | ||||
| 	{ | ||||
| 		.compatible = "mediatek,mt8135-pinctrl", | ||||
| 	}, | ||||
| 	{ } | ||||
| }; | ||||
| MODULE_DEVICE_TABLE(of, mt8135_pctrl_match); | ||||
|  | ||||
| static struct platform_driver mtk_pinctrl_driver = { | ||||
| 	.probe = mt8135_pinctrl_probe, | ||||
| 	.driver = { | ||||
| 		.name = "mediatek-mt8135-pinctrl", | ||||
| 		.owner = THIS_MODULE, | ||||
| 		.of_match_table = mt8135_pctrl_match, | ||||
| 	}, | ||||
| }; | ||||
|  | ||||
| static int __init mtk_pinctrl_init(void) | ||||
| { | ||||
| 	return platform_driver_register(&mtk_pinctrl_driver); | ||||
| } | ||||
|  | ||||
| module_init(mtk_pinctrl_init); | ||||
|  | ||||
| MODULE_LICENSE("GPL"); | ||||
| MODULE_DESCRIPTION("MediaTek Pinctrl Driver"); | ||||
| MODULE_AUTHOR("Hongzhou Yang <hongzhou.yang@mediatek.com>"); | ||||
							
								
								
									
										455
									
								
								drivers/pinctrl/mediatek/pinctrl-mt8173.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										455
									
								
								drivers/pinctrl/mediatek/pinctrl-mt8173.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,455 @@ | ||||
| /* | ||||
|  * Copyright (c) 2014-2015 MediaTek Inc. | ||||
|  * Author: Hongzhou.Yang <hongzhou.yang@mediatek.com> | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License version 2 as | ||||
|  * published by the Free Software Foundation. | ||||
|  * | ||||
|  * This program is distributed in the hope that 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. | ||||
|  */ | ||||
|  | ||||
| #include <linux/module.h> | ||||
| #include <linux/platform_device.h> | ||||
| #include <linux/of.h> | ||||
| #include <linux/of_device.h> | ||||
| #include <linux/pinctrl/pinctrl.h> | ||||
| #include <linux/regmap.h> | ||||
| #include <dt-bindings/pinctrl/mt65xx.h> | ||||
|  | ||||
| #include "pinctrl-mtk-common.h" | ||||
| #include "pinctrl-mtk-mt8173.h" | ||||
|  | ||||
| #define DRV_BASE				0xb00 | ||||
|  | ||||
| /** | ||||
|  * struct mtk_pin_ies_smt_set - For special pins' ies and smt setting. | ||||
|  * @start: The start pin number of those special pins. | ||||
|  * @end: The end pin number of those special pins. | ||||
|  * @offset: The offset of special setting register. | ||||
|  * @bit: The bit of special setting register. | ||||
|  */ | ||||
| struct mtk_pin_ies_smt_set { | ||||
| 	unsigned int start; | ||||
| 	unsigned int end; | ||||
| 	unsigned int offset; | ||||
| 	unsigned char bit; | ||||
| }; | ||||
|  | ||||
| #define MTK_PIN_IES_SMT_SET(_start, _end, _offset, _bit)	\ | ||||
| 	{	\ | ||||
| 		.start = _start,	\ | ||||
| 		.end = _end,	\ | ||||
| 		.bit = _bit,	\ | ||||
| 		.offset = _offset,	\ | ||||
| 	} | ||||
|  | ||||
| /** | ||||
|  * struct mtk_pin_spec_pupd_set - For special pins' pull up/down setting. | ||||
|  * @pin: The pin number. | ||||
|  * @offset: The offset of special pull up/down setting register. | ||||
|  * @pupd_bit: The pull up/down bit in this register. | ||||
|  * @r0_bit: The r0 bit of pull resistor. | ||||
|  * @r1_bit: The r1 bit of pull resistor. | ||||
|  */ | ||||
| struct mtk_pin_spec_pupd_set { | ||||
| 	unsigned int pin; | ||||
| 	unsigned int offset; | ||||
| 	unsigned char pupd_bit; | ||||
| 	unsigned char r1_bit; | ||||
| 	unsigned char r0_bit; | ||||
| }; | ||||
|  | ||||
| #define MTK_PIN_PUPD_SPEC(_pin, _offset, _pupd, _r1, _r0)	\ | ||||
| 	{	\ | ||||
| 		.pin = _pin,	\ | ||||
| 		.offset = _offset,	\ | ||||
| 		.pupd_bit = _pupd,	\ | ||||
| 		.r1_bit = _r1,		\ | ||||
| 		.r0_bit = _r0,		\ | ||||
| 	} | ||||
|  | ||||
| static const struct mtk_pin_spec_pupd_set mt8173_spec_pupd[] = { | ||||
| 	MTK_PIN_PUPD_SPEC(119, 0xe00, 2, 1, 0),  /* KROW0 */ | ||||
| 	MTK_PIN_PUPD_SPEC(120, 0xe00, 6, 5, 4),  /* KROW1 */ | ||||
| 	MTK_PIN_PUPD_SPEC(121, 0xe00, 10, 9, 8), /* KROW2 */ | ||||
| 	MTK_PIN_PUPD_SPEC(122, 0xe10, 2, 1, 0),  /* KCOL0 */ | ||||
| 	MTK_PIN_PUPD_SPEC(123, 0xe10, 6, 5, 4),  /* KCOL1 */ | ||||
| 	MTK_PIN_PUPD_SPEC(124, 0xe10, 10, 9, 8), /* KCOL2 */ | ||||
|  | ||||
| 	MTK_PIN_PUPD_SPEC(67, 0xd10, 2, 1, 0),   /* ms0 DS */ | ||||
| 	MTK_PIN_PUPD_SPEC(68, 0xd00, 2, 1, 0),   /* ms0 RST */ | ||||
| 	MTK_PIN_PUPD_SPEC(66, 0xc10, 2, 1, 0),   /* ms0 cmd */ | ||||
| 	MTK_PIN_PUPD_SPEC(65, 0xc00, 2, 1, 0),   /* ms0 clk */ | ||||
| 	MTK_PIN_PUPD_SPEC(57, 0xc20, 2, 1, 0),   /* ms0 data0 */ | ||||
| 	MTK_PIN_PUPD_SPEC(58, 0xc20, 2, 1, 0),   /* ms0 data1 */ | ||||
| 	MTK_PIN_PUPD_SPEC(59, 0xc20, 2, 1, 0),   /* ms0 data2 */ | ||||
| 	MTK_PIN_PUPD_SPEC(60, 0xc20, 2, 1, 0),   /* ms0 data3 */ | ||||
| 	MTK_PIN_PUPD_SPEC(61, 0xc20, 2, 1, 0),   /* ms0 data4 */ | ||||
| 	MTK_PIN_PUPD_SPEC(62, 0xc20, 2, 1, 0),   /* ms0 data5 */ | ||||
| 	MTK_PIN_PUPD_SPEC(63, 0xc20, 2, 1, 0),   /* ms0 data6 */ | ||||
| 	MTK_PIN_PUPD_SPEC(64, 0xc20, 2, 1, 0),   /* ms0 data7 */ | ||||
|  | ||||
| 	MTK_PIN_PUPD_SPEC(78, 0xc50, 2, 1, 0),    /* ms1 cmd */ | ||||
| 	MTK_PIN_PUPD_SPEC(73, 0xd20, 2, 1, 0),    /* ms1 dat0 */ | ||||
| 	MTK_PIN_PUPD_SPEC(74, 0xd20, 6, 5, 4),    /* ms1 dat1 */ | ||||
| 	MTK_PIN_PUPD_SPEC(75, 0xd20, 10, 9, 8),   /* ms1 dat2 */ | ||||
| 	MTK_PIN_PUPD_SPEC(76, 0xd20, 14, 13, 12), /* ms1 dat3 */ | ||||
| 	MTK_PIN_PUPD_SPEC(77, 0xc40, 2, 1, 0),    /* ms1 clk */ | ||||
|  | ||||
| 	MTK_PIN_PUPD_SPEC(100, 0xd40, 2, 1, 0),    /* ms2 dat0 */ | ||||
| 	MTK_PIN_PUPD_SPEC(101, 0xd40, 6, 5, 4),    /* ms2 dat1 */ | ||||
| 	MTK_PIN_PUPD_SPEC(102, 0xd40, 10, 9, 8),   /* ms2 dat2 */ | ||||
| 	MTK_PIN_PUPD_SPEC(103, 0xd40, 14, 13, 12), /* ms2 dat3 */ | ||||
| 	MTK_PIN_PUPD_SPEC(104, 0xc80, 2, 1, 0),    /* ms2 clk */ | ||||
| 	MTK_PIN_PUPD_SPEC(105, 0xc90, 2, 1, 0),    /* ms2 cmd */ | ||||
|  | ||||
| 	MTK_PIN_PUPD_SPEC(22, 0xd60, 2, 1, 0),    /* ms3 dat0 */ | ||||
| 	MTK_PIN_PUPD_SPEC(23, 0xd60, 6, 5, 4),    /* ms3 dat1 */ | ||||
| 	MTK_PIN_PUPD_SPEC(24, 0xd60, 10, 9, 8),   /* ms3 dat2 */ | ||||
| 	MTK_PIN_PUPD_SPEC(25, 0xd60, 14, 13, 12), /* ms3 dat3 */ | ||||
| 	MTK_PIN_PUPD_SPEC(26, 0xcc0, 2, 1, 0),    /* ms3 clk */ | ||||
| 	MTK_PIN_PUPD_SPEC(27, 0xcd0, 2, 1, 0)     /* ms3 cmd */ | ||||
| }; | ||||
|  | ||||
| static int spec_pull_set(struct regmap *regmap, unsigned int pin, | ||||
| 		unsigned char align, bool isup, unsigned int r1r0) | ||||
| { | ||||
| 	unsigned int i; | ||||
| 	unsigned int reg_pupd, reg_set, reg_rst; | ||||
| 	unsigned int bit_pupd, bit_r0, bit_r1; | ||||
| 	const struct mtk_pin_spec_pupd_set *spec_pupd_pin; | ||||
| 	bool find = false; | ||||
|  | ||||
| 	for (i = 0; i < ARRAY_SIZE(mt8173_spec_pupd); i++) { | ||||
| 		if (pin == mt8173_spec_pupd[i].pin) { | ||||
| 			find = true; | ||||
| 			break; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if (!find) | ||||
| 		return -EINVAL; | ||||
|  | ||||
| 	spec_pupd_pin = mt8173_spec_pupd + i; | ||||
| 	reg_set = spec_pupd_pin->offset + align; | ||||
| 	reg_rst = spec_pupd_pin->offset + (align << 1); | ||||
|  | ||||
| 	if (isup) | ||||
| 		reg_pupd = reg_rst; | ||||
| 	else | ||||
| 		reg_pupd = reg_set; | ||||
|  | ||||
| 	bit_pupd = BIT(spec_pupd_pin->pupd_bit); | ||||
| 	regmap_write(regmap, reg_pupd, bit_pupd); | ||||
|  | ||||
| 	bit_r0 = BIT(spec_pupd_pin->r0_bit); | ||||
| 	bit_r1 = BIT(spec_pupd_pin->r1_bit); | ||||
|  | ||||
| 	switch (r1r0) { | ||||
| 	case MTK_PUPD_SET_R1R0_00: | ||||
| 		regmap_write(regmap, reg_rst, bit_r0); | ||||
| 		regmap_write(regmap, reg_rst, bit_r1); | ||||
| 		break; | ||||
| 	case MTK_PUPD_SET_R1R0_01: | ||||
| 		regmap_write(regmap, reg_set, bit_r0); | ||||
| 		regmap_write(regmap, reg_rst, bit_r1); | ||||
| 		break; | ||||
| 	case MTK_PUPD_SET_R1R0_10: | ||||
| 		regmap_write(regmap, reg_rst, bit_r0); | ||||
| 		regmap_write(regmap, reg_set, bit_r1); | ||||
| 		break; | ||||
| 	case MTK_PUPD_SET_R1R0_11: | ||||
| 		regmap_write(regmap, reg_set, bit_r0); | ||||
| 		regmap_write(regmap, reg_set, bit_r1); | ||||
| 		break; | ||||
| 	default: | ||||
| 		return -EINVAL; | ||||
| 	} | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static const struct mtk_pin_ies_smt_set mt8173_ies_smt_set[] = { | ||||
| 	MTK_PIN_IES_SMT_SET(0, 4, 0x930, 1), | ||||
| 	MTK_PIN_IES_SMT_SET(5, 9, 0x930, 2), | ||||
| 	MTK_PIN_IES_SMT_SET(10, 13, 0x930, 10), | ||||
| 	MTK_PIN_IES_SMT_SET(14, 15, 0x940, 10), | ||||
| 	MTK_PIN_IES_SMT_SET(16, 16, 0x930, 0), | ||||
| 	MTK_PIN_IES_SMT_SET(17, 17, 0x950, 2), | ||||
| 	MTK_PIN_IES_SMT_SET(18, 21, 0x940, 3), | ||||
| 	MTK_PIN_IES_SMT_SET(29, 32, 0x930, 3), | ||||
| 	MTK_PIN_IES_SMT_SET(33, 33, 0x930, 4), | ||||
| 	MTK_PIN_IES_SMT_SET(34, 36, 0x930, 5), | ||||
| 	MTK_PIN_IES_SMT_SET(37, 38, 0x930, 6), | ||||
| 	MTK_PIN_IES_SMT_SET(39, 39, 0x930, 7), | ||||
| 	MTK_PIN_IES_SMT_SET(40, 41, 0x930, 9), | ||||
| 	MTK_PIN_IES_SMT_SET(42, 42, 0x940, 0), | ||||
| 	MTK_PIN_IES_SMT_SET(43, 44, 0x930, 11), | ||||
| 	MTK_PIN_IES_SMT_SET(45, 46, 0x930, 12), | ||||
| 	MTK_PIN_IES_SMT_SET(57, 64, 0xc20, 13), | ||||
| 	MTK_PIN_IES_SMT_SET(65, 65, 0xc10, 13), | ||||
| 	MTK_PIN_IES_SMT_SET(66, 66, 0xc00, 13), | ||||
| 	MTK_PIN_IES_SMT_SET(67, 67, 0xd10, 13), | ||||
| 	MTK_PIN_IES_SMT_SET(68, 68, 0xd00, 13), | ||||
| 	MTK_PIN_IES_SMT_SET(69, 72, 0x940, 14), | ||||
| 	MTK_PIN_IES_SMT_SET(73, 76, 0xc60, 13), | ||||
| 	MTK_PIN_IES_SMT_SET(77, 77, 0xc40, 13), | ||||
| 	MTK_PIN_IES_SMT_SET(78, 78, 0xc50, 13), | ||||
| 	MTK_PIN_IES_SMT_SET(79, 82, 0x940, 15), | ||||
| 	MTK_PIN_IES_SMT_SET(83, 83, 0x950, 0), | ||||
| 	MTK_PIN_IES_SMT_SET(84, 85, 0x950, 1), | ||||
| 	MTK_PIN_IES_SMT_SET(86, 91, 0x950, 2), | ||||
| 	MTK_PIN_IES_SMT_SET(92, 92, 0x930, 13), | ||||
| 	MTK_PIN_IES_SMT_SET(93, 95, 0x930, 14), | ||||
| 	MTK_PIN_IES_SMT_SET(96, 99, 0x930, 15), | ||||
| 	MTK_PIN_IES_SMT_SET(100, 103, 0xca0, 13), | ||||
| 	MTK_PIN_IES_SMT_SET(104, 104, 0xc80, 13), | ||||
| 	MTK_PIN_IES_SMT_SET(105, 105, 0xc90, 13), | ||||
| 	MTK_PIN_IES_SMT_SET(106, 107, 0x940, 4), | ||||
| 	MTK_PIN_IES_SMT_SET(108, 112, 0x940, 1), | ||||
| 	MTK_PIN_IES_SMT_SET(113, 116, 0x940, 2), | ||||
| 	MTK_PIN_IES_SMT_SET(117, 118, 0x940, 5), | ||||
| 	MTK_PIN_IES_SMT_SET(119, 124, 0x940, 6), | ||||
| 	MTK_PIN_IES_SMT_SET(125, 126, 0x940, 7), | ||||
| 	MTK_PIN_IES_SMT_SET(127, 127, 0x940, 0), | ||||
| 	MTK_PIN_IES_SMT_SET(128, 128, 0x950, 8), | ||||
| 	MTK_PIN_IES_SMT_SET(129, 130, 0x950, 9), | ||||
| 	MTK_PIN_IES_SMT_SET(131, 132, 0x950, 8), | ||||
| 	MTK_PIN_IES_SMT_SET(133, 134, 0x910, 8) | ||||
| }; | ||||
|  | ||||
| static int spec_ies_smt_set(struct regmap *regmap, unsigned int pin, | ||||
| 		unsigned char align, int value) | ||||
| { | ||||
| 	unsigned int i, reg_addr, bit; | ||||
| 	bool find = false; | ||||
|  | ||||
| 	for (i = 0; i < ARRAY_SIZE(mt8173_ies_smt_set); i++) { | ||||
| 		if (pin >= mt8173_ies_smt_set[i].start && | ||||
| 				pin <= mt8173_ies_smt_set[i].end) { | ||||
| 			find = true; | ||||
| 			break; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if (!find) | ||||
| 		return -EINVAL; | ||||
|  | ||||
| 	if (value) | ||||
| 		reg_addr = mt8173_ies_smt_set[i].offset + align; | ||||
| 	else | ||||
| 		reg_addr = mt8173_ies_smt_set[i].offset + (align << 1); | ||||
|  | ||||
| 	bit = BIT(mt8173_ies_smt_set[i].bit); | ||||
| 	regmap_write(regmap, reg_addr, bit); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static const struct mtk_drv_group_desc mt8173_drv_grp[] =  { | ||||
| 	/* 0E4E8SR 4/8/12/16 */ | ||||
| 	MTK_DRV_GRP(4, 16, 1, 2, 4), | ||||
| 	/* 0E2E4SR  2/4/6/8 */ | ||||
| 	MTK_DRV_GRP(2, 8, 1, 2, 2), | ||||
| 	/* E8E4E2  2/4/6/8/10/12/14/16 */ | ||||
| 	MTK_DRV_GRP(2, 16, 0, 2, 2) | ||||
| }; | ||||
|  | ||||
| static const struct mtk_pin_drv_grp mt8173_pin_drv[] = { | ||||
| 	MTK_PIN_DRV_GRP(0, DRV_BASE+0x20, 12, 0), | ||||
| 	MTK_PIN_DRV_GRP(1, DRV_BASE+0x20, 12, 0), | ||||
| 	MTK_PIN_DRV_GRP(2, DRV_BASE+0x20, 12, 0), | ||||
| 	MTK_PIN_DRV_GRP(3, DRV_BASE+0x20, 12, 0), | ||||
| 	MTK_PIN_DRV_GRP(4, DRV_BASE+0x20, 12, 0), | ||||
| 	MTK_PIN_DRV_GRP(5, DRV_BASE+0x30, 0, 0), | ||||
| 	MTK_PIN_DRV_GRP(6, DRV_BASE+0x30, 0, 0), | ||||
| 	MTK_PIN_DRV_GRP(7, DRV_BASE+0x30, 0, 0), | ||||
| 	MTK_PIN_DRV_GRP(8, DRV_BASE+0x30, 0, 0), | ||||
| 	MTK_PIN_DRV_GRP(9, DRV_BASE+0x30, 0, 0), | ||||
| 	MTK_PIN_DRV_GRP(10, DRV_BASE+0x30, 4, 1), | ||||
| 	MTK_PIN_DRV_GRP(11, DRV_BASE+0x30, 4, 1), | ||||
| 	MTK_PIN_DRV_GRP(12, DRV_BASE+0x30, 4, 1), | ||||
| 	MTK_PIN_DRV_GRP(13, DRV_BASE+0x30, 4, 1), | ||||
| 	MTK_PIN_DRV_GRP(14, DRV_BASE+0x40, 8, 1), | ||||
| 	MTK_PIN_DRV_GRP(15, DRV_BASE+0x40, 8, 1), | ||||
| 	MTK_PIN_DRV_GRP(16, DRV_BASE, 8, 1), | ||||
| 	MTK_PIN_DRV_GRP(17, 0xce0, 8, 2), | ||||
| 	MTK_PIN_DRV_GRP(22, 0xce0, 8, 2), | ||||
| 	MTK_PIN_DRV_GRP(23, 0xce0, 8, 2), | ||||
| 	MTK_PIN_DRV_GRP(24, 0xce0, 8, 2), | ||||
| 	MTK_PIN_DRV_GRP(25, 0xce0, 8, 2), | ||||
| 	MTK_PIN_DRV_GRP(26, 0xcc0, 8, 2), | ||||
| 	MTK_PIN_DRV_GRP(27, 0xcd0, 8, 2), | ||||
| 	MTK_PIN_DRV_GRP(28, 0xd70, 8, 2), | ||||
| 	MTK_PIN_DRV_GRP(29, DRV_BASE+0x80, 12, 1), | ||||
| 	MTK_PIN_DRV_GRP(30, DRV_BASE+0x80, 12, 1), | ||||
| 	MTK_PIN_DRV_GRP(31, DRV_BASE+0x80, 12, 1), | ||||
| 	MTK_PIN_DRV_GRP(32, DRV_BASE+0x80, 12, 1), | ||||
| 	MTK_PIN_DRV_GRP(33, DRV_BASE+0x10, 12, 1), | ||||
| 	MTK_PIN_DRV_GRP(34, DRV_BASE+0x10, 8, 1), | ||||
| 	MTK_PIN_DRV_GRP(35, DRV_BASE+0x10, 8, 1), | ||||
| 	MTK_PIN_DRV_GRP(36, DRV_BASE+0x10, 8, 1), | ||||
| 	MTK_PIN_DRV_GRP(37, DRV_BASE+0x10, 4, 1), | ||||
| 	MTK_PIN_DRV_GRP(38, DRV_BASE+0x10, 4, 1), | ||||
| 	MTK_PIN_DRV_GRP(39, DRV_BASE+0x20, 0, 0), | ||||
| 	MTK_PIN_DRV_GRP(40, DRV_BASE+0x20, 8, 0), | ||||
| 	MTK_PIN_DRV_GRP(41, DRV_BASE+0x20, 8, 0), | ||||
| 	MTK_PIN_DRV_GRP(42, DRV_BASE+0x50, 8, 1), | ||||
| 	MTK_PIN_DRV_GRP(57, 0xc20, 8, 2), | ||||
| 	MTK_PIN_DRV_GRP(58, 0xc20, 8, 2), | ||||
| 	MTK_PIN_DRV_GRP(59, 0xc20, 8, 2), | ||||
| 	MTK_PIN_DRV_GRP(60, 0xc20, 8, 2), | ||||
| 	MTK_PIN_DRV_GRP(61, 0xc20, 8, 2), | ||||
| 	MTK_PIN_DRV_GRP(62, 0xc20, 8, 2), | ||||
| 	MTK_PIN_DRV_GRP(63, 0xc20, 8, 2), | ||||
| 	MTK_PIN_DRV_GRP(64, 0xc20, 8, 2), | ||||
| 	MTK_PIN_DRV_GRP(65, 0xc00, 8, 2), | ||||
| 	MTK_PIN_DRV_GRP(66, 0xc10, 8, 2), | ||||
| 	MTK_PIN_DRV_GRP(67, 0xd10, 8, 2), | ||||
| 	MTK_PIN_DRV_GRP(68, 0xd00, 8, 2), | ||||
| 	MTK_PIN_DRV_GRP(69, DRV_BASE+0x80, 0, 1), | ||||
| 	MTK_PIN_DRV_GRP(70, DRV_BASE+0x80, 0, 1), | ||||
| 	MTK_PIN_DRV_GRP(71, DRV_BASE+0x80, 0, 1), | ||||
| 	MTK_PIN_DRV_GRP(72, DRV_BASE+0x80, 0, 1), | ||||
| 	MTK_PIN_DRV_GRP(73, 0xc60, 8, 2), | ||||
| 	MTK_PIN_DRV_GRP(74, 0xc60, 8, 2), | ||||
| 	MTK_PIN_DRV_GRP(75, 0xc60, 8, 2), | ||||
| 	MTK_PIN_DRV_GRP(76, 0xc60, 8, 2), | ||||
| 	MTK_PIN_DRV_GRP(77, 0xc40, 8, 2), | ||||
| 	MTK_PIN_DRV_GRP(78, 0xc50, 8, 2), | ||||
| 	MTK_PIN_DRV_GRP(79, DRV_BASE+0x70, 12, 1), | ||||
| 	MTK_PIN_DRV_GRP(80, DRV_BASE+0x70, 12, 1), | ||||
| 	MTK_PIN_DRV_GRP(81, DRV_BASE+0x70, 12, 1), | ||||
| 	MTK_PIN_DRV_GRP(82, DRV_BASE+0x70, 12, 1), | ||||
| 	MTK_PIN_DRV_GRP(83, DRV_BASE, 4, 1), | ||||
| 	MTK_PIN_DRV_GRP(84, DRV_BASE, 0, 1), | ||||
| 	MTK_PIN_DRV_GRP(85, DRV_BASE, 0, 1), | ||||
| 	MTK_PIN_DRV_GRP(85, DRV_BASE+0x60, 8, 1), | ||||
| 	MTK_PIN_DRV_GRP(86, DRV_BASE+0x60, 8, 1), | ||||
| 	MTK_PIN_DRV_GRP(87, DRV_BASE+0x60, 8, 1), | ||||
| 	MTK_PIN_DRV_GRP(88, DRV_BASE+0x60, 8, 1), | ||||
| 	MTK_PIN_DRV_GRP(89, DRV_BASE+0x60, 8, 1), | ||||
| 	MTK_PIN_DRV_GRP(90, DRV_BASE+0x60, 8, 1), | ||||
| 	MTK_PIN_DRV_GRP(91, DRV_BASE+0x60, 8, 1), | ||||
| 	MTK_PIN_DRV_GRP(92, DRV_BASE+0x60, 4, 0), | ||||
| 	MTK_PIN_DRV_GRP(93, DRV_BASE+0x60, 0, 0), | ||||
| 	MTK_PIN_DRV_GRP(94, DRV_BASE+0x60, 0, 0), | ||||
| 	MTK_PIN_DRV_GRP(95, DRV_BASE+0x60, 0, 0), | ||||
| 	MTK_PIN_DRV_GRP(96, DRV_BASE+0x80, 8, 1), | ||||
| 	MTK_PIN_DRV_GRP(97, DRV_BASE+0x80, 8, 1), | ||||
| 	MTK_PIN_DRV_GRP(98, DRV_BASE+0x80, 8, 1), | ||||
| 	MTK_PIN_DRV_GRP(99, DRV_BASE+0x80, 8, 1), | ||||
| 	MTK_PIN_DRV_GRP(100, 0xca0, 8, 2), | ||||
| 	MTK_PIN_DRV_GRP(101, 0xca0, 8, 2), | ||||
| 	MTK_PIN_DRV_GRP(102, 0xca0, 8, 2), | ||||
| 	MTK_PIN_DRV_GRP(103, 0xca0, 8, 2), | ||||
| 	MTK_PIN_DRV_GRP(104, 0xc80, 8, 2), | ||||
| 	MTK_PIN_DRV_GRP(105, 0xc90, 8, 2), | ||||
| 	MTK_PIN_DRV_GRP(108, DRV_BASE+0x50, 0, 1), | ||||
| 	MTK_PIN_DRV_GRP(109, DRV_BASE+0x50, 0, 1), | ||||
| 	MTK_PIN_DRV_GRP(110, DRV_BASE+0x50, 0, 1), | ||||
| 	MTK_PIN_DRV_GRP(111, DRV_BASE+0x50, 0, 1), | ||||
| 	MTK_PIN_DRV_GRP(112, DRV_BASE+0x50, 0, 1), | ||||
| 	MTK_PIN_DRV_GRP(113, DRV_BASE+0x80, 4, 1), | ||||
| 	MTK_PIN_DRV_GRP(114, DRV_BASE+0x80, 4, 1), | ||||
| 	MTK_PIN_DRV_GRP(115, DRV_BASE+0x80, 4, 1), | ||||
| 	MTK_PIN_DRV_GRP(116, DRV_BASE+0x80, 4, 1), | ||||
| 	MTK_PIN_DRV_GRP(117, DRV_BASE+0x90, 0, 1), | ||||
| 	MTK_PIN_DRV_GRP(118, DRV_BASE+0x90, 0, 1), | ||||
| 	MTK_PIN_DRV_GRP(119, DRV_BASE+0x50, 4, 1), | ||||
| 	MTK_PIN_DRV_GRP(120, DRV_BASE+0x50, 4, 1), | ||||
| 	MTK_PIN_DRV_GRP(121, DRV_BASE+0x50, 4, 1), | ||||
| 	MTK_PIN_DRV_GRP(122, DRV_BASE+0x50, 4, 1), | ||||
| 	MTK_PIN_DRV_GRP(123, DRV_BASE+0x50, 4, 1), | ||||
| 	MTK_PIN_DRV_GRP(124, DRV_BASE+0x50, 4, 1), | ||||
| 	MTK_PIN_DRV_GRP(125, DRV_BASE+0x30, 12, 1), | ||||
| 	MTK_PIN_DRV_GRP(126, DRV_BASE+0x30, 12, 1), | ||||
| 	MTK_PIN_DRV_GRP(127, DRV_BASE+0x50, 8, 1), | ||||
| 	MTK_PIN_DRV_GRP(128, DRV_BASE+0x40, 0, 1), | ||||
| 	MTK_PIN_DRV_GRP(129, DRV_BASE+0x40, 0, 1), | ||||
| 	MTK_PIN_DRV_GRP(130, DRV_BASE+0x40, 0, 1), | ||||
| 	MTK_PIN_DRV_GRP(131, DRV_BASE+0x40, 0, 1), | ||||
| 	MTK_PIN_DRV_GRP(132, DRV_BASE+0x40, 0, 1) | ||||
| }; | ||||
|  | ||||
| static const struct mtk_pinctrl_devdata mt8173_pinctrl_data = { | ||||
| 	.pins = mtk_pins_mt8173, | ||||
| 	.npins = ARRAY_SIZE(mtk_pins_mt8173), | ||||
| 	.grp_desc = mt8173_drv_grp, | ||||
| 	.n_grp_cls = ARRAY_SIZE(mt8173_drv_grp), | ||||
| 	.pin_drv_grp = mt8173_pin_drv, | ||||
| 	.n_pin_drv_grps = ARRAY_SIZE(mt8173_pin_drv), | ||||
| 	.spec_pull_set = spec_pull_set, | ||||
| 	.spec_ies_smt_set = spec_ies_smt_set, | ||||
| 	.dir_offset = 0x0000, | ||||
| 	.pullen_offset = 0x0100, | ||||
| 	.pullsel_offset = 0x0200, | ||||
| 	.dout_offset = 0x0400, | ||||
| 	.din_offset = 0x0500, | ||||
| 	.pinmux_offset = 0x0600, | ||||
| 	.type1_start = 135, | ||||
| 	.type1_end = 135, | ||||
| 	.port_shf = 4, | ||||
| 	.port_mask = 0xf, | ||||
| 	.port_align = 4, | ||||
| 	.eint_offsets = { | ||||
| 		.name = "mt8173_eint", | ||||
| 		.stat      = 0x000, | ||||
| 		.ack       = 0x040, | ||||
| 		.mask      = 0x080, | ||||
| 		.mask_set  = 0x0c0, | ||||
| 		.mask_clr  = 0x100, | ||||
| 		.sens      = 0x140, | ||||
| 		.sens_set  = 0x180, | ||||
| 		.sens_clr  = 0x1c0, | ||||
| 		.soft      = 0x200, | ||||
| 		.soft_set  = 0x240, | ||||
| 		.soft_clr  = 0x280, | ||||
| 		.pol       = 0x300, | ||||
| 		.pol_set   = 0x340, | ||||
| 		.pol_clr   = 0x380, | ||||
| 		.dom_en    = 0x400, | ||||
| 		.dbnc_ctrl = 0x500, | ||||
| 		.dbnc_set  = 0x600, | ||||
| 		.dbnc_clr  = 0x700, | ||||
| 		.port_mask = 7, | ||||
| 		.ports     = 6, | ||||
| 	}, | ||||
| 	.ap_num = 224, | ||||
| 	.db_cnt = 16, | ||||
| }; | ||||
|  | ||||
| static int mt8173_pinctrl_probe(struct platform_device *pdev) | ||||
| { | ||||
| 	return mtk_pctrl_init(pdev, &mt8173_pinctrl_data); | ||||
| } | ||||
|  | ||||
| static const struct of_device_id mt8173_pctrl_match[] = { | ||||
| 	{ | ||||
| 		.compatible = "mediatek,mt8173-pinctrl", | ||||
| 	}, | ||||
| 	{ } | ||||
| }; | ||||
| MODULE_DEVICE_TABLE(of, mt8173_pctrl_match); | ||||
|  | ||||
| static struct platform_driver mtk_pinctrl_driver = { | ||||
| 	.probe = mt8173_pinctrl_probe, | ||||
| 	.driver = { | ||||
| 		.name = "mediatek-mt8173-pinctrl", | ||||
| 		.of_match_table = mt8173_pctrl_match, | ||||
| 	}, | ||||
| }; | ||||
|  | ||||
| static int __init mtk_pinctrl_init(void) | ||||
| { | ||||
| 	return platform_driver_register(&mtk_pinctrl_driver); | ||||
| } | ||||
|  | ||||
| module_init(mtk_pinctrl_init); | ||||
|  | ||||
| MODULE_LICENSE("GPL v2"); | ||||
| MODULE_DESCRIPTION("MediaTek Pinctrl Driver"); | ||||
| MODULE_AUTHOR("Hongzhou Yang <hongzhou.yang@mediatek.com>"); | ||||
							
								
								
									
										1257
									
								
								drivers/pinctrl/mediatek/pinctrl-mtk-common.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1257
									
								
								drivers/pinctrl/mediatek/pinctrl-mtk-common.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										229
									
								
								drivers/pinctrl/mediatek/pinctrl-mtk-common.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										229
									
								
								drivers/pinctrl/mediatek/pinctrl-mtk-common.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,229 @@ | ||||
| /* | ||||
|  * Copyright (c) 2014 MediaTek Inc. | ||||
|  * Author: Hongzhou.Yang <hongzhou.yang@mediatek.com> | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License version 2 as | ||||
|  * published by the Free Software Foundation. | ||||
|  * | ||||
|  * This program is distributed in the hope that 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. | ||||
|  */ | ||||
|  | ||||
| #ifndef __PINCTRL_MTK_COMMON_H | ||||
| #define __PINCTRL_MTK_COMMON_H | ||||
|  | ||||
| #include <linux/pinctrl/pinctrl.h> | ||||
| #include <linux/regmap.h> | ||||
|  | ||||
| #define NO_EINT_SUPPORT    255 | ||||
| #define MTK_CHIP_TYPE_BASE     0 | ||||
| #define MTK_CHIP_TYPE_PMIC     1 | ||||
| #define MT_EDGE_SENSITIVE           0 | ||||
| #define MT_LEVEL_SENSITIVE          1 | ||||
| #define EINT_DBNC_SET_DBNC_BITS     4 | ||||
| #define EINT_DBNC_RST_BIT           (0x1 << 1) | ||||
| #define EINT_DBNC_SET_EN            (0x1 << 0) | ||||
|  | ||||
| struct mtk_desc_function { | ||||
| 	const char *name; | ||||
| 	unsigned char muxval; | ||||
| }; | ||||
|  | ||||
| struct mtk_desc_eint { | ||||
| 	unsigned char eintmux; | ||||
| 	unsigned char eintnum; | ||||
| }; | ||||
|  | ||||
| struct mtk_desc_pin { | ||||
| 	struct pinctrl_pin_desc	pin; | ||||
| 	const char *chip; | ||||
| 	const struct mtk_desc_eint eint; | ||||
| 	const struct mtk_desc_function	*functions; | ||||
| }; | ||||
|  | ||||
| #define MTK_PIN(_pin, _pad, _chip, _eint, ...)		\ | ||||
| 	{							\ | ||||
| 		.pin = _pin,					\ | ||||
| 		.chip = _chip,					\ | ||||
| 		.eint = _eint,					\ | ||||
| 		.functions = (struct mtk_desc_function[]){	\ | ||||
| 			__VA_ARGS__, { } },			\ | ||||
| 	} | ||||
|  | ||||
| #define MTK_EINT_FUNCTION(_eintmux, _eintnum)				\ | ||||
| 	{							\ | ||||
| 		.eintmux = _eintmux,					\ | ||||
| 		.eintnum = _eintnum,					\ | ||||
| 	} | ||||
|  | ||||
| #define MTK_FUNCTION(_val, _name)				\ | ||||
| 	{							\ | ||||
| 		.muxval = _val,					\ | ||||
| 		.name = _name,					\ | ||||
| 	} | ||||
|  | ||||
| #define SET_ADDR(x, y)  (x + (y->devdata->port_align)) | ||||
| #define CLR_ADDR(x, y)  (x + (y->devdata->port_align << 1)) | ||||
|  | ||||
| struct mtk_pinctrl_group { | ||||
| 	const char	*name; | ||||
| 	unsigned long	config; | ||||
| 	unsigned	pin; | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * struct mtk_drv_group_desc - Provide driving group data. | ||||
|  * @max_drv: The maximum current of this group. | ||||
|  * @min_drv: The minimum current of this group. | ||||
|  * @low_bit: The lowest bit of this group. | ||||
|  * @high_bit: The highest bit of this group. | ||||
|  * @step: The step current of this group. | ||||
|  */ | ||||
| struct mtk_drv_group_desc { | ||||
| 	unsigned char min_drv; | ||||
| 	unsigned char max_drv; | ||||
| 	unsigned char low_bit; | ||||
| 	unsigned char high_bit; | ||||
| 	unsigned char step; | ||||
| }; | ||||
|  | ||||
| #define MTK_DRV_GRP(_min, _max, _low, _high, _step)	\ | ||||
| 	{	\ | ||||
| 		.min_drv = _min,	\ | ||||
| 		.max_drv = _max,	\ | ||||
| 		.low_bit = _low,	\ | ||||
| 		.high_bit = _high,	\ | ||||
| 		.step = _step,		\ | ||||
| 	} | ||||
|  | ||||
| /** | ||||
|  * struct mtk_pin_drv_grp - Provide each pin driving info. | ||||
|  * @pin: The pin number. | ||||
|  * @offset: The offset of driving register for this pin. | ||||
|  * @bit: The bit of driving register for this pin. | ||||
|  * @grp: The group for this pin belongs to. | ||||
|  */ | ||||
| struct mtk_pin_drv_grp { | ||||
| 	unsigned int pin; | ||||
| 	unsigned int offset; | ||||
| 	unsigned char bit; | ||||
| 	unsigned char grp; | ||||
| }; | ||||
|  | ||||
| #define MTK_PIN_DRV_GRP(_pin, _offset, _bit, _grp)	\ | ||||
| 	{	\ | ||||
| 		.pin = _pin,	\ | ||||
| 		.offset = _offset,	\ | ||||
| 		.bit = _bit,	\ | ||||
| 		.grp = _grp,	\ | ||||
| 	} | ||||
|  | ||||
| struct mtk_eint_offsets { | ||||
| 	const char *name; | ||||
| 	unsigned int  stat; | ||||
| 	unsigned int  ack; | ||||
| 	unsigned int  mask; | ||||
| 	unsigned int  mask_set; | ||||
| 	unsigned int  mask_clr; | ||||
| 	unsigned int  sens; | ||||
| 	unsigned int  sens_set; | ||||
| 	unsigned int  sens_clr; | ||||
| 	unsigned int  soft; | ||||
| 	unsigned int  soft_set; | ||||
| 	unsigned int  soft_clr; | ||||
| 	unsigned int  pol; | ||||
| 	unsigned int  pol_set; | ||||
| 	unsigned int  pol_clr; | ||||
| 	unsigned int  dom_en; | ||||
| 	unsigned int  dbnc_ctrl; | ||||
| 	unsigned int  dbnc_set; | ||||
| 	unsigned int  dbnc_clr; | ||||
| 	u8  port_mask; | ||||
| 	u8  ports; | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * struct mtk_pinctrl_devdata - Provide HW GPIO related data. | ||||
|  * @pins: An array describing all pins the pin controller affects. | ||||
|  * @npins: The number of entries in @pins. | ||||
|  * | ||||
|  * @grp_desc: The driving group info. | ||||
|  * @pin_drv_grp: The driving group for all pins. | ||||
|  * @spec_pull_set: Each SoC may have special pins for pull up/down setting, | ||||
|  *  these pins' pull setting are very different, they have separate pull | ||||
|  *  up/down bit, R0 and R1 resistor bit, so they need special pull setting. | ||||
|  *  If special setting is success, this should return 0, otherwise it should | ||||
|  *  return non-zero value. | ||||
|  * @spec_ies_smt_set: Some pins are irregular, their input enable and smt | ||||
|  * control register are discontinuous, but they are mapping together. That | ||||
|  * means when user set smt, input enable is set at the same time. So they | ||||
|  * also need special control. If special control is success, this should | ||||
|  * return 0, otherwise return non-zero value. | ||||
|  * | ||||
|  * @dir_offset: The direction register offset. | ||||
|  * @pullen_offset: The pull-up/pull-down enable register offset. | ||||
|  * @pinmux_offset: The pinmux register offset. | ||||
|  * | ||||
|  * @type1_start: Some chips have two base addresses for pull select register, | ||||
|  *  that means some pins use the first address and others use the second. This | ||||
|  *  member record the start of pin number to use the second address. | ||||
|  * @type1_end: The end of pin number to use the second address. | ||||
|  * | ||||
|  * @port_shf: The shift between two registers. | ||||
|  * @port_mask: The mask of register. | ||||
|  * @port_align: Provide clear register and set register step. | ||||
|  */ | ||||
| struct mtk_pinctrl_devdata { | ||||
| 	const struct mtk_desc_pin	*pins; | ||||
| 	unsigned int				npins; | ||||
| 	const struct mtk_drv_group_desc	*grp_desc; | ||||
| 	unsigned int	n_grp_cls; | ||||
| 	const struct mtk_pin_drv_grp	*pin_drv_grp; | ||||
| 	unsigned int	n_pin_drv_grps; | ||||
| 	int (*spec_pull_set)(struct regmap *reg, unsigned int pin, | ||||
| 			unsigned char align, bool isup, unsigned int arg); | ||||
| 	int (*spec_ies_smt_set)(struct regmap *reg, unsigned int pin, | ||||
| 			unsigned char align, int value); | ||||
| 	unsigned int dir_offset; | ||||
| 	unsigned int ies_offset; | ||||
| 	unsigned int smt_offset; | ||||
| 	unsigned int pullen_offset; | ||||
| 	unsigned int pullsel_offset; | ||||
| 	unsigned int drv_offset; | ||||
| 	unsigned int invser_offset; | ||||
| 	unsigned int dout_offset; | ||||
| 	unsigned int din_offset; | ||||
| 	unsigned int pinmux_offset; | ||||
| 	unsigned short type1_start; | ||||
| 	unsigned short type1_end; | ||||
| 	unsigned char  port_shf; | ||||
| 	unsigned char  port_mask; | ||||
| 	unsigned char  port_align; | ||||
| 	unsigned char	chip_type; | ||||
| 	struct mtk_eint_offsets eint_offsets; | ||||
| 	unsigned int	ap_num; | ||||
| 	unsigned int	db_cnt; | ||||
| }; | ||||
|  | ||||
| struct mtk_pinctrl { | ||||
| 	struct regmap	*regmap1; | ||||
| 	struct regmap	*regmap2; | ||||
| 	struct device           *dev; | ||||
| 	struct gpio_chip	*chip; | ||||
| 	struct mtk_pinctrl_group	*groups; | ||||
| 	unsigned			ngroups; | ||||
| 	const char          **grp_names; | ||||
| 	struct pinctrl_dev      *pctl_dev; | ||||
| 	const struct mtk_pinctrl_devdata  *devdata; | ||||
| 	void __iomem		*eint_reg_base; | ||||
| 	struct irq_domain	*domain; | ||||
| 	int			*eint_dual_edges; | ||||
| }; | ||||
|  | ||||
| int mtk_pctrl_init(struct platform_device *pdev, | ||||
| 		const struct mtk_pinctrl_devdata *data); | ||||
|  | ||||
| #endif /* __PINCTRL_MTK_COMMON_H */ | ||||
							
								
								
									
										2114
									
								
								drivers/pinctrl/mediatek/pinctrl-mtk-mt8135.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2114
									
								
								drivers/pinctrl/mediatek/pinctrl-mtk-mt8135.h
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1226
									
								
								drivers/pinctrl/mediatek/pinctrl-mtk-mt8173.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1226
									
								
								drivers/pinctrl/mediatek/pinctrl-mtk-mt8173.h
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -1,2 +1,2 @@ | ||||
| obj-y	+= pinctrl-meson8.o | ||||
| obj-y	+= pinctrl-meson8.o pinctrl-meson8b.o | ||||
| obj-y	+= pinctrl-meson.o | ||||
|   | ||||
| @@ -13,8 +13,9 @@ | ||||
|  | ||||
| /* | ||||
|  * The available pins are organized in banks (A,B,C,D,E,X,Y,Z,AO, | ||||
|  * BOOT,CARD for meson6 and X,Y,DV,H,Z,AO,BOOT,CARD for meson8) and | ||||
|  * each bank has a variable number of pins. | ||||
|  * BOOT,CARD for meson6, X,Y,DV,H,Z,AO,BOOT,CARD for meson8 and | ||||
|  * X,Y,DV,H,AO,BOOT,CARD,DIF for meson8b) and each bank has a | ||||
|  * variable number of pins. | ||||
|  * | ||||
|  * The AO bank is special because it belongs to the Always-On power | ||||
|  * domain which can't be powered off; the bank also uses a set of | ||||
| @@ -544,6 +545,10 @@ static const struct of_device_id meson_pinctrl_dt_match[] = { | ||||
| 		.compatible = "amlogic,meson8-pinctrl", | ||||
| 		.data = &meson8_pinctrl_data, | ||||
| 	}, | ||||
| 	{ | ||||
| 		.compatible = "amlogic,meson8b-pinctrl", | ||||
| 		.data = &meson8b_pinctrl_data, | ||||
| 	}, | ||||
| 	{ }, | ||||
| }; | ||||
| MODULE_DEVICE_TABLE(of, meson_pinctrl_dt_match); | ||||
|   | ||||
| @@ -155,6 +155,8 @@ struct meson_pinctrl { | ||||
| 	struct meson_domain *domains; | ||||
| }; | ||||
|  | ||||
| #define PIN(x, b)	(b + x) | ||||
|  | ||||
| #define GROUP(grp, r, b)						\ | ||||
| 	{								\ | ||||
| 		.name = #grp,						\ | ||||
| @@ -165,10 +167,10 @@ struct meson_pinctrl { | ||||
| 		.domain = 0,						\ | ||||
| 	 } | ||||
|  | ||||
| #define GPIO_GROUP(gpio)						\ | ||||
| #define GPIO_GROUP(gpio, b)						\ | ||||
| 	{								\ | ||||
| 		.name = #gpio,						\ | ||||
| 		.pins = (const unsigned int[]){ PIN_ ## gpio},		\ | ||||
| 		.pins = (const unsigned int[]){ PIN(gpio, b) },		\ | ||||
| 		.num_pins = 1,						\ | ||||
| 		.is_gpio = true,					\ | ||||
| 	 } | ||||
| @@ -204,6 +206,7 @@ struct meson_pinctrl { | ||||
| 		},							\ | ||||
| 	 } | ||||
|  | ||||
| #define MESON_PIN(x) PINCTRL_PIN(PIN_ ## x, #x) | ||||
| #define MESON_PIN(x, b) PINCTRL_PIN(PIN(x, b), #x) | ||||
|  | ||||
| extern struct meson_pinctrl_data meson8_pinctrl_data; | ||||
| extern struct meson_pinctrl_data meson8b_pinctrl_data; | ||||
|   | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										899
									
								
								drivers/pinctrl/meson/pinctrl-meson8b.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										899
									
								
								drivers/pinctrl/meson/pinctrl-meson8b.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,899 @@ | ||||
| /* | ||||
|  * Pin controller and GPIO driver for Amlogic Meson8b. | ||||
|  * | ||||
|  * Copyright (C) 2015 Endless Mobile, Inc. | ||||
|  * Author: Carlo Caione <carlo@endlessm.com> | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License | ||||
|  * version 2 as published by the Free Software Foundation. | ||||
|  * | ||||
|  * 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 <dt-bindings/gpio/meson8b-gpio.h> | ||||
| #include "pinctrl-meson.h" | ||||
|  | ||||
| #define AO_OFF	130 | ||||
|  | ||||
| static const struct pinctrl_pin_desc meson8b_pins[] = { | ||||
| 	MESON_PIN(GPIOX_0, 0), | ||||
| 	MESON_PIN(GPIOX_1, 0), | ||||
| 	MESON_PIN(GPIOX_2, 0), | ||||
| 	MESON_PIN(GPIOX_3, 0), | ||||
| 	MESON_PIN(GPIOX_4, 0), | ||||
| 	MESON_PIN(GPIOX_5, 0), | ||||
| 	MESON_PIN(GPIOX_6, 0), | ||||
| 	MESON_PIN(GPIOX_7, 0), | ||||
| 	MESON_PIN(GPIOX_8, 0), | ||||
| 	MESON_PIN(GPIOX_9, 0), | ||||
| 	MESON_PIN(GPIOX_10, 0), | ||||
| 	MESON_PIN(GPIOX_11, 0), | ||||
| 	MESON_PIN(GPIOX_16, 0), | ||||
| 	MESON_PIN(GPIOX_17, 0), | ||||
| 	MESON_PIN(GPIOX_18, 0), | ||||
| 	MESON_PIN(GPIOX_19, 0), | ||||
| 	MESON_PIN(GPIOX_20, 0), | ||||
| 	MESON_PIN(GPIOX_21, 0), | ||||
|  | ||||
| 	MESON_PIN(GPIOY_0, 0), | ||||
| 	MESON_PIN(GPIOY_1, 0), | ||||
| 	MESON_PIN(GPIOY_3, 0), | ||||
| 	MESON_PIN(GPIOY_6, 0), | ||||
| 	MESON_PIN(GPIOY_7, 0), | ||||
| 	MESON_PIN(GPIOY_8, 0), | ||||
| 	MESON_PIN(GPIOY_9, 0), | ||||
| 	MESON_PIN(GPIOY_10, 0), | ||||
| 	MESON_PIN(GPIOY_11, 0), | ||||
| 	MESON_PIN(GPIOY_12, 0), | ||||
| 	MESON_PIN(GPIOY_13, 0), | ||||
| 	MESON_PIN(GPIOY_14, 0), | ||||
|  | ||||
| 	MESON_PIN(GPIODV_9, 0), | ||||
| 	MESON_PIN(GPIODV_24, 0), | ||||
| 	MESON_PIN(GPIODV_25, 0), | ||||
| 	MESON_PIN(GPIODV_26, 0), | ||||
| 	MESON_PIN(GPIODV_27, 0), | ||||
| 	MESON_PIN(GPIODV_28, 0), | ||||
| 	MESON_PIN(GPIODV_29, 0), | ||||
|  | ||||
| 	MESON_PIN(GPIOH_0, 0), | ||||
| 	MESON_PIN(GPIOH_1, 0), | ||||
| 	MESON_PIN(GPIOH_2, 0), | ||||
| 	MESON_PIN(GPIOH_3, 0), | ||||
| 	MESON_PIN(GPIOH_4, 0), | ||||
| 	MESON_PIN(GPIOH_5, 0), | ||||
| 	MESON_PIN(GPIOH_6, 0), | ||||
| 	MESON_PIN(GPIOH_7, 0), | ||||
| 	MESON_PIN(GPIOH_8, 0), | ||||
| 	MESON_PIN(GPIOH_9, 0), | ||||
|  | ||||
| 	MESON_PIN(CARD_0, 0), | ||||
| 	MESON_PIN(CARD_1, 0), | ||||
| 	MESON_PIN(CARD_2, 0), | ||||
| 	MESON_PIN(CARD_3, 0), | ||||
| 	MESON_PIN(CARD_4, 0), | ||||
| 	MESON_PIN(CARD_5, 0), | ||||
| 	MESON_PIN(CARD_6, 0), | ||||
|  | ||||
| 	MESON_PIN(BOOT_0, 0), | ||||
| 	MESON_PIN(BOOT_1, 0), | ||||
| 	MESON_PIN(BOOT_2, 0), | ||||
| 	MESON_PIN(BOOT_3, 0), | ||||
| 	MESON_PIN(BOOT_4, 0), | ||||
| 	MESON_PIN(BOOT_5, 0), | ||||
| 	MESON_PIN(BOOT_6, 0), | ||||
| 	MESON_PIN(BOOT_7, 0), | ||||
| 	MESON_PIN(BOOT_8, 0), | ||||
| 	MESON_PIN(BOOT_9, 0), | ||||
| 	MESON_PIN(BOOT_10, 0), | ||||
| 	MESON_PIN(BOOT_11, 0), | ||||
| 	MESON_PIN(BOOT_12, 0), | ||||
| 	MESON_PIN(BOOT_13, 0), | ||||
| 	MESON_PIN(BOOT_14, 0), | ||||
| 	MESON_PIN(BOOT_15, 0), | ||||
| 	MESON_PIN(BOOT_16, 0), | ||||
| 	MESON_PIN(BOOT_17, 0), | ||||
| 	MESON_PIN(BOOT_18, 0), | ||||
|  | ||||
| 	MESON_PIN(DIF_0_P, 0), | ||||
| 	MESON_PIN(DIF_0_N, 0), | ||||
| 	MESON_PIN(DIF_1_P, 0), | ||||
| 	MESON_PIN(DIF_1_N, 0), | ||||
| 	MESON_PIN(DIF_2_P, 0), | ||||
| 	MESON_PIN(DIF_2_N, 0), | ||||
| 	MESON_PIN(DIF_3_P, 0), | ||||
| 	MESON_PIN(DIF_3_N, 0), | ||||
| 	MESON_PIN(DIF_4_P, 0), | ||||
| 	MESON_PIN(DIF_4_N, 0), | ||||
|  | ||||
| 	MESON_PIN(GPIOAO_0, AO_OFF), | ||||
| 	MESON_PIN(GPIOAO_1, AO_OFF), | ||||
| 	MESON_PIN(GPIOAO_2, AO_OFF), | ||||
| 	MESON_PIN(GPIOAO_3, AO_OFF), | ||||
| 	MESON_PIN(GPIOAO_4, AO_OFF), | ||||
| 	MESON_PIN(GPIOAO_5, AO_OFF), | ||||
| 	MESON_PIN(GPIOAO_6, AO_OFF), | ||||
| 	MESON_PIN(GPIOAO_7, AO_OFF), | ||||
| 	MESON_PIN(GPIOAO_8, AO_OFF), | ||||
| 	MESON_PIN(GPIOAO_9, AO_OFF), | ||||
| 	MESON_PIN(GPIOAO_10, AO_OFF), | ||||
| 	MESON_PIN(GPIOAO_11, AO_OFF), | ||||
| 	MESON_PIN(GPIOAO_12, AO_OFF), | ||||
| 	MESON_PIN(GPIOAO_13, AO_OFF), | ||||
| 	MESON_PIN(GPIO_BSD_EN, AO_OFF), | ||||
| 	MESON_PIN(GPIO_TEST_N, AO_OFF), | ||||
| }; | ||||
|  | ||||
| /* bank X */ | ||||
| static const unsigned int sd_d0_a_pins[]	= { PIN(GPIOX_0, 0) }; | ||||
| static const unsigned int sd_d1_a_pins[]	= { PIN(GPIOX_1, 0) }; | ||||
| static const unsigned int sd_d2_a_pins[]	= { PIN(GPIOX_2, 0) }; | ||||
| static const unsigned int sd_d3_a_pins[]	= { PIN(GPIOX_3, 0) }; | ||||
| static const unsigned int sdxc_d0_0_a_pins[]	= { PIN(GPIOX_4, 0) }; | ||||
| static const unsigned int sdxc_d47_a_pins[]	= { PIN(GPIOX_4, 0), PIN(GPIOX_5, 0), | ||||
| 						    PIN(GPIOX_6, 0), PIN(GPIOX_7, 0) }; | ||||
| static const unsigned int sdxc_d13_0_a_pins[]	= { PIN(GPIOX_5, 0), PIN(GPIOX_6, 0), | ||||
| 						    PIN(GPIOX_7, 0) }; | ||||
| static const unsigned int sd_clk_a_pins[]	= { PIN(GPIOX_8, 0) }; | ||||
| static const unsigned int sd_cmd_a_pins[]	= { PIN(GPIOX_9, 0) }; | ||||
| static const unsigned int xtal_32k_out_pins[]	= { PIN(GPIOX_10, 0) }; | ||||
| static const unsigned int xtal_24m_out_pins[]	= { PIN(GPIOX_11, 0) }; | ||||
| static const unsigned int uart_tx_b0_pins[]	= { PIN(GPIOX_16, 0) }; | ||||
| static const unsigned int uart_rx_b0_pins[]	= { PIN(GPIOX_17, 0) }; | ||||
| static const unsigned int uart_cts_b0_pins[]	= { PIN(GPIOX_18, 0) }; | ||||
| static const unsigned int uart_rts_b0_pins[]	= { PIN(GPIOX_19, 0) }; | ||||
|  | ||||
| static const unsigned int sdxc_d0_1_a_pins[]	= { PIN(GPIOX_0, 0) }; | ||||
| static const unsigned int sdxc_d13_1_a_pins[]	= { PIN(GPIOX_1, 0), PIN(GPIOX_2, 0), | ||||
| 						    PIN(GPIOX_3, 0) }; | ||||
| static const unsigned int pcm_out_a_pins[]	= { PIN(GPIOX_4, 0) }; | ||||
| static const unsigned int pcm_in_a_pins[]	= { PIN(GPIOX_5, 0) }; | ||||
| static const unsigned int pcm_fs_a_pins[]	= { PIN(GPIOX_6, 0) }; | ||||
| static const unsigned int pcm_clk_a_pins[]	= { PIN(GPIOX_7, 0) }; | ||||
| static const unsigned int sdxc_clk_a_pins[]	= { PIN(GPIOX_8, 0) }; | ||||
| static const unsigned int sdxc_cmd_a_pins[]	= { PIN(GPIOX_9, 0) }; | ||||
| static const unsigned int pwm_vs_0_pins[]	= { PIN(GPIOX_10, 0) }; | ||||
| static const unsigned int pwm_e_pins[]		= { PIN(GPIOX_10, 0) }; | ||||
| static const unsigned int pwm_vs_1_pins[]	= { PIN(GPIOX_11, 0) }; | ||||
|  | ||||
| static const unsigned int uart_tx_a_pins[]	= { PIN(GPIOX_4, 0) }; | ||||
| static const unsigned int uart_rx_a_pins[]	= { PIN(GPIOX_5, 0) }; | ||||
| static const unsigned int uart_cts_a_pins[]	= { PIN(GPIOX_6, 0) }; | ||||
| static const unsigned int uart_rts_a_pins[]	= { PIN(GPIOX_7, 0) }; | ||||
| static const unsigned int uart_tx_b1_pins[]	= { PIN(GPIOX_8, 0) }; | ||||
| static const unsigned int uart_rx_b1_pins[]	= { PIN(GPIOX_9, 0) }; | ||||
| static const unsigned int uart_cts_b1_pins[]	= { PIN(GPIOX_10, 0) }; | ||||
| static const unsigned int uart_rts_b1_pins[]	= { PIN(GPIOX_20, 0) }; | ||||
|  | ||||
| static const unsigned int iso7816_0_clk_pins[]	= { PIN(GPIOX_6, 0) }; | ||||
| static const unsigned int iso7816_0_data_pins[]	= { PIN(GPIOX_7, 0) }; | ||||
| static const unsigned int spi_sclk_0_pins[]	= { PIN(GPIOX_8, 0) }; | ||||
| static const unsigned int spi_miso_0_pins[]	= { PIN(GPIOX_9, 0) }; | ||||
| static const unsigned int spi_mosi_0_pins[]	= { PIN(GPIOX_10, 0) }; | ||||
| static const unsigned int iso7816_det_pins[]	= { PIN(GPIOX_16, 0) }; | ||||
| static const unsigned int iso7816_reset_pins[]	= { PIN(GPIOX_17, 0) }; | ||||
| static const unsigned int iso7816_1_clk_pins[]	= { PIN(GPIOX_18, 0) }; | ||||
| static const unsigned int iso7816_1_data_pins[]	= { PIN(GPIOX_19, 0) }; | ||||
| static const unsigned int spi_ss0_0_pins[]	= { PIN(GPIOX_20, 0) }; | ||||
|  | ||||
| static const unsigned int tsin_clk_b_pins[]	= { PIN(GPIOX_8, 0) }; | ||||
| static const unsigned int tsin_sop_b_pins[]	= { PIN(GPIOX_9, 0) }; | ||||
| static const unsigned int tsin_d0_b_pins[]	= { PIN(GPIOX_10, 0) }; | ||||
| static const unsigned int pwm_b_pins[]		= { PIN(GPIOX_11, 0) }; | ||||
| static const unsigned int i2c_sda_d0_pins[]	= { PIN(GPIOX_16, 0) }; | ||||
| static const unsigned int i2c_sck_d0_pins[]	= { PIN(GPIOX_17, 0) }; | ||||
| static const unsigned int tsin_d_valid_b_pins[] = { PIN(GPIOX_20, 0) }; | ||||
|  | ||||
| /* bank Y */ | ||||
| static const unsigned int tsin_d_valid_a_pins[] = { PIN(GPIOY_0, 0) }; | ||||
| static const unsigned int tsin_sop_a_pins[]	= { PIN(GPIOY_1, 0) }; | ||||
| static const unsigned int tsin_d17_a_pins[]	= { PIN(GPIOY_6, 0), PIN(GPIOY_7, 0), | ||||
| 						    PIN(GPIOY_10, 0), PIN(GPIOY_11, 0), | ||||
| 						    PIN(GPIOY_12, 0), PIN(GPIOY_13, 0), | ||||
| 						    PIN(GPIOY_14, 0) }; | ||||
| static const unsigned int tsin_clk_a_pins[]	= { PIN(GPIOY_8, 0) }; | ||||
| static const unsigned int tsin_d0_a_pins[]	= { PIN(GPIOY_9, 0) }; | ||||
|  | ||||
| static const unsigned int spdif_out_0_pins[]	= { PIN(GPIOY_3, 0) }; | ||||
|  | ||||
| static const unsigned int xtal_24m_pins[]	= { PIN(GPIOY_3, 0) }; | ||||
| static const unsigned int iso7816_2_clk_pins[]	= { PIN(GPIOY_13, 0) }; | ||||
| static const unsigned int iso7816_2_data_pins[] = { PIN(GPIOY_14, 0) }; | ||||
|  | ||||
| /* bank DV */ | ||||
| static const unsigned int pwm_d_pins[]		= { PIN(GPIODV_28, 0) }; | ||||
| static const unsigned int pwm_c0_pins[]		= { PIN(GPIODV_29, 0) }; | ||||
|  | ||||
| static const unsigned int pwm_vs_2_pins[]	= { PIN(GPIODV_9, 0) }; | ||||
| static const unsigned int pwm_vs_3_pins[]	= { PIN(GPIODV_28, 0) }; | ||||
| static const unsigned int pwm_vs_4_pins[]	= { PIN(GPIODV_29, 0) }; | ||||
|  | ||||
| static const unsigned int xtal24_out_pins[]	= { PIN(GPIODV_29, 0) }; | ||||
|  | ||||
| static const unsigned int uart_tx_c_pins[]	= { PIN(GPIODV_24, 0) }; | ||||
| static const unsigned int uart_rx_c_pins[]	= { PIN(GPIODV_25, 0) }; | ||||
| static const unsigned int uart_cts_c_pins[]	= { PIN(GPIODV_26, 0) }; | ||||
| static const unsigned int uart_rts_c_pins[]	= { PIN(GPIODV_27, 0) }; | ||||
|  | ||||
| static const unsigned int pwm_c1_pins[]		= { PIN(GPIODV_9, 0) }; | ||||
|  | ||||
| static const unsigned int i2c_sda_a_pins[]	= { PIN(GPIODV_24, 0) }; | ||||
| static const unsigned int i2c_sck_a_pins[]	= { PIN(GPIODV_25, 0) }; | ||||
| static const unsigned int i2c_sda_b0_pins[]	= { PIN(GPIODV_26, 0) }; | ||||
| static const unsigned int i2c_sck_b0_pins[]	= { PIN(GPIODV_27, 0) }; | ||||
| static const unsigned int i2c_sda_c0_pins[]	= { PIN(GPIODV_28, 0) }; | ||||
| static const unsigned int i2c_sck_c0_pins[]	= { PIN(GPIODV_29, 0) }; | ||||
|  | ||||
| /* bank H */ | ||||
| static const unsigned int hdmi_hpd_pins[]	= { PIN(GPIOH_0, 0) }; | ||||
| static const unsigned int hdmi_sda_pins[]	= { PIN(GPIOH_1, 0) }; | ||||
| static const unsigned int hdmi_scl_pins[]	= { PIN(GPIOH_2, 0) }; | ||||
| static const unsigned int hdmi_cec_0_pins[]	= { PIN(GPIOH_3, 0) }; | ||||
| static const unsigned int eth_txd1_0_pins[]	= { PIN(GPIOH_5, 0) }; | ||||
| static const unsigned int eth_txd0_0_pins[]	= { PIN(GPIOH_6, 0) }; | ||||
| static const unsigned int clk_24m_out_pins[]	= { PIN(GPIOH_9, 0) }; | ||||
|  | ||||
| static const unsigned int spi_ss1_pins[]	= { PIN(GPIOH_0, 0) }; | ||||
| static const unsigned int spi_ss2_pins[]	= { PIN(GPIOH_1, 0) }; | ||||
| static const unsigned int spi_ss0_1_pins[]	= { PIN(GPIOH_3, 0) }; | ||||
| static const unsigned int spi_miso_1_pins[]	= { PIN(GPIOH_4, 0) }; | ||||
| static const unsigned int spi_mosi_1_pins[]	= { PIN(GPIOH_5, 0) }; | ||||
| static const unsigned int spi_sclk_1_pins[]	= { PIN(GPIOH_6, 0) }; | ||||
|  | ||||
| static const unsigned int eth_txd3_pins[]	= { PIN(GPIOH_7, 0) }; | ||||
| static const unsigned int eth_txd2_pins[]	= { PIN(GPIOH_8, 0) }; | ||||
| static const unsigned int eth_tx_clk_pins[]	= { PIN(GPIOH_9, 0) }; | ||||
|  | ||||
| static const unsigned int i2c_sda_b1_pins[]	= { PIN(GPIOH_3, 0) }; | ||||
| static const unsigned int i2c_sck_b1_pins[]	= { PIN(GPIOH_4, 0) }; | ||||
| static const unsigned int i2c_sda_c1_pins[]	= { PIN(GPIOH_5, 0) }; | ||||
| static const unsigned int i2c_sck_c1_pins[]	= { PIN(GPIOH_6, 0) }; | ||||
| static const unsigned int i2c_sda_d1_pins[]	= { PIN(GPIOH_7, 0) }; | ||||
| static const unsigned int i2c_sck_d1_pins[]	= { PIN(GPIOH_8, 0) }; | ||||
|  | ||||
| /* bank BOOT */ | ||||
| static const unsigned int nand_io_pins[]	= { PIN(BOOT_0, 0), PIN(BOOT_1, 0), | ||||
| 						    PIN(BOOT_2, 0), PIN(BOOT_3, 0), | ||||
| 						    PIN(BOOT_4, 0), PIN(BOOT_5, 0), | ||||
| 						    PIN(BOOT_6, 0), PIN(BOOT_7, 0) }; | ||||
| static const unsigned int nand_io_ce0_pins[]	= { PIN(BOOT_8, 0) }; | ||||
| static const unsigned int nand_io_ce1_pins[]	= { PIN(BOOT_9, 0) }; | ||||
| static const unsigned int nand_io_rb0_pins[]	= { PIN(BOOT_10, 0) }; | ||||
| static const unsigned int nand_ale_pins[]	= { PIN(BOOT_11, 0) }; | ||||
| static const unsigned int nand_cle_pins[]	= { PIN(BOOT_12, 0) }; | ||||
| static const unsigned int nand_wen_clk_pins[]	= { PIN(BOOT_13, 0) }; | ||||
| static const unsigned int nand_ren_clk_pins[]	= { PIN(BOOT_14, 0) }; | ||||
| static const unsigned int nand_dqs_0_pins[]	= { PIN(BOOT_15, 0) }; | ||||
| static const unsigned int nand_dqs_1_pins[]	= { PIN(BOOT_18, 0) }; | ||||
|  | ||||
| static const unsigned int sdxc_d0_c_pins[]	= { PIN(BOOT_0, 0)}; | ||||
| static const unsigned int sdxc_d13_c_pins[]	= { PIN(BOOT_1, 0), PIN(BOOT_2, 0), | ||||
| 						    PIN(BOOT_3, 0) }; | ||||
| static const unsigned int sdxc_d47_c_pins[]	= { PIN(BOOT_4, 0), PIN(BOOT_5, 0), | ||||
| 						    PIN(BOOT_6, 0), PIN(BOOT_7, 0) }; | ||||
| static const unsigned int sdxc_clk_c_pins[]	= { PIN(BOOT_8, 0) }; | ||||
| static const unsigned int sdxc_cmd_c_pins[]	= { PIN(BOOT_10, 0) }; | ||||
| static const unsigned int nor_d_pins[]		= { PIN(BOOT_11, 0) }; | ||||
| static const unsigned int nor_q_pins[]		= { PIN(BOOT_12, 0) }; | ||||
| static const unsigned int nor_c_pins[]		= { PIN(BOOT_13, 0) }; | ||||
| static const unsigned int nor_cs_pins[]		= { PIN(BOOT_18, 0) }; | ||||
|  | ||||
| static const unsigned int sd_d0_c_pins[]	= { PIN(BOOT_0, 0) }; | ||||
| static const unsigned int sd_d1_c_pins[]	= { PIN(BOOT_1, 0) }; | ||||
| static const unsigned int sd_d2_c_pins[]	= { PIN(BOOT_2, 0) }; | ||||
| static const unsigned int sd_d3_c_pins[]	= { PIN(BOOT_3, 0) }; | ||||
| static const unsigned int sd_cmd_c_pins[]	= { PIN(BOOT_8, 0) }; | ||||
| static const unsigned int sd_clk_c_pins[]	= { PIN(BOOT_10, 0) }; | ||||
|  | ||||
| /* bank CARD */ | ||||
| static const unsigned int sd_d1_b_pins[]	= { PIN(CARD_0, 0) }; | ||||
| static const unsigned int sd_d0_b_pins[]	= { PIN(CARD_1, 0) }; | ||||
| static const unsigned int sd_clk_b_pins[]	= { PIN(CARD_2, 0) }; | ||||
| static const unsigned int sd_cmd_b_pins[]	= { PIN(CARD_3, 0) }; | ||||
| static const unsigned int sd_d3_b_pins[]	= { PIN(CARD_4, 0) }; | ||||
| static const unsigned int sd_d2_b_pins[]	= { PIN(CARD_5, 0) }; | ||||
|  | ||||
| static const unsigned int sdxc_d13_b_pins[]	= { PIN(CARD_0, 0), PIN(CARD_4, 0), | ||||
| 						    PIN(CARD_5, 0) }; | ||||
| static const unsigned int sdxc_d0_b_pins[]	= { PIN(CARD_1, 0) }; | ||||
| static const unsigned int sdxc_clk_b_pins[]	= { PIN(CARD_2, 0) }; | ||||
| static const unsigned int sdxc_cmd_b_pins[]	= { PIN(CARD_3, 0) }; | ||||
|  | ||||
| /* bank AO */ | ||||
| static const unsigned int uart_tx_ao_a_pins[]	= { PIN(GPIOAO_0, AO_OFF) }; | ||||
| static const unsigned int uart_rx_ao_a_pins[]	= { PIN(GPIOAO_1, AO_OFF) }; | ||||
| static const unsigned int uart_cts_ao_a_pins[]	= { PIN(GPIOAO_2, AO_OFF) }; | ||||
| static const unsigned int uart_rts_ao_a_pins[]	= { PIN(GPIOAO_3, AO_OFF) }; | ||||
| static const unsigned int i2c_mst_sck_ao_pins[] = { PIN(GPIOAO_4, AO_OFF) }; | ||||
| static const unsigned int i2c_mst_sda_ao_pins[] = { PIN(GPIOAO_5, AO_OFF) }; | ||||
| static const unsigned int clk_32k_in_out_pins[]	= { PIN(GPIOAO_6, AO_OFF) }; | ||||
| static const unsigned int remote_input_pins[]	= { PIN(GPIOAO_7, AO_OFF) }; | ||||
| static const unsigned int hdmi_cec_1_pins[]	= { PIN(GPIOAO_12, AO_OFF) }; | ||||
| static const unsigned int ir_blaster_pins[]	= { PIN(GPIOAO_13, AO_OFF) }; | ||||
|  | ||||
| static const unsigned int pwm_c2_pins[]		= { PIN(GPIOAO_3, AO_OFF) }; | ||||
| static const unsigned int i2c_sck_ao_pins[]	= { PIN(GPIOAO_4, AO_OFF) }; | ||||
| static const unsigned int i2c_sda_ao_pins[]	= { PIN(GPIOAO_5, AO_OFF) }; | ||||
| static const unsigned int ir_remote_out_pins[]	= { PIN(GPIOAO_7, AO_OFF) }; | ||||
| static const unsigned int i2s_am_clk_out_pins[]	= { PIN(GPIOAO_8, AO_OFF) }; | ||||
| static const unsigned int i2s_ao_clk_out_pins[]	= { PIN(GPIOAO_9, AO_OFF) }; | ||||
| static const unsigned int i2s_lr_clk_out_pins[]	= { PIN(GPIOAO_10, AO_OFF) }; | ||||
| static const unsigned int i2s_out_01_pins[]	= { PIN(GPIOAO_11, AO_OFF) }; | ||||
|  | ||||
| static const unsigned int uart_tx_ao_b0_pins[]	= { PIN(GPIOAO_0, AO_OFF) }; | ||||
| static const unsigned int uart_rx_ao_b0_pins[]	= { PIN(GPIOAO_1, AO_OFF) }; | ||||
| static const unsigned int uart_cts_ao_b_pins[]	= { PIN(GPIOAO_2, AO_OFF) }; | ||||
| static const unsigned int uart_rts_ao_b_pins[]	= { PIN(GPIOAO_3, AO_OFF) }; | ||||
| static const unsigned int uart_tx_ao_b1_pins[]	= { PIN(GPIOAO_4, AO_OFF) }; | ||||
| static const unsigned int uart_rx_ao_b1_pins[]	= { PIN(GPIOAO_5, AO_OFF) }; | ||||
| static const unsigned int spdif_out_1_pins[]	= { PIN(GPIOAO_6, AO_OFF) }; | ||||
|  | ||||
| static const unsigned int i2s_in_ch01_pins[]	= { PIN(GPIOAO_6, AO_OFF) }; | ||||
| static const unsigned int i2s_ao_clk_in_pins[]	= { PIN(GPIOAO_9, AO_OFF) }; | ||||
| static const unsigned int i2s_lr_clk_in_pins[]	= { PIN(GPIOAO_10, AO_OFF) }; | ||||
|  | ||||
| /* bank DIF */ | ||||
| static const unsigned int eth_rxd1_pins[]	= { PIN(DIF_0_P, 0) }; | ||||
| static const unsigned int eth_rxd0_pins[]	= { PIN(DIF_0_N, 0) }; | ||||
| static const unsigned int eth_rx_dv_pins[]	= { PIN(DIF_1_P, 0) }; | ||||
| static const unsigned int eth_rx_clk_pins[]	= { PIN(DIF_1_N, 0) }; | ||||
| static const unsigned int eth_txd0_1_pins[]	= { PIN(DIF_2_P, 0) }; | ||||
| static const unsigned int eth_txd1_1_pins[]	= { PIN(DIF_2_N, 0) }; | ||||
| static const unsigned int eth_tx_en_pins[]	= { PIN(DIF_3_P, 0) }; | ||||
| static const unsigned int eth_ref_clk_pins[]	= { PIN(DIF_3_N, 0) }; | ||||
| static const unsigned int eth_mdc_pins[]	= { PIN(DIF_4_P, 0) }; | ||||
| static const unsigned int eth_mdio_en_pins[]	= { PIN(DIF_4_N, 0) }; | ||||
|  | ||||
| static struct meson_pmx_group meson8b_groups[] = { | ||||
| 	GPIO_GROUP(GPIOX_0, 0), | ||||
| 	GPIO_GROUP(GPIOX_1, 0), | ||||
| 	GPIO_GROUP(GPIOX_2, 0), | ||||
| 	GPIO_GROUP(GPIOX_3, 0), | ||||
| 	GPIO_GROUP(GPIOX_4, 0), | ||||
| 	GPIO_GROUP(GPIOX_5, 0), | ||||
| 	GPIO_GROUP(GPIOX_6, 0), | ||||
| 	GPIO_GROUP(GPIOX_7, 0), | ||||
| 	GPIO_GROUP(GPIOX_8, 0), | ||||
| 	GPIO_GROUP(GPIOX_9, 0), | ||||
| 	GPIO_GROUP(GPIOX_10, 0), | ||||
| 	GPIO_GROUP(GPIOX_11, 0), | ||||
| 	GPIO_GROUP(GPIOX_16, 0), | ||||
| 	GPIO_GROUP(GPIOX_17, 0), | ||||
| 	GPIO_GROUP(GPIOX_18, 0), | ||||
| 	GPIO_GROUP(GPIOX_19, 0), | ||||
| 	GPIO_GROUP(GPIOX_20, 0), | ||||
| 	GPIO_GROUP(GPIOX_21, 0), | ||||
|  | ||||
| 	GPIO_GROUP(GPIOY_0, 0), | ||||
| 	GPIO_GROUP(GPIOY_1, 0), | ||||
| 	GPIO_GROUP(GPIOY_3, 0), | ||||
| 	GPIO_GROUP(GPIOY_6, 0), | ||||
| 	GPIO_GROUP(GPIOY_7, 0), | ||||
| 	GPIO_GROUP(GPIOY_8, 0), | ||||
| 	GPIO_GROUP(GPIOY_9, 0), | ||||
| 	GPIO_GROUP(GPIOY_10, 0), | ||||
| 	GPIO_GROUP(GPIOY_11, 0), | ||||
| 	GPIO_GROUP(GPIOY_12, 0), | ||||
| 	GPIO_GROUP(GPIOY_13, 0), | ||||
| 	GPIO_GROUP(GPIOY_14, 0), | ||||
|  | ||||
| 	GPIO_GROUP(GPIODV_9, 0), | ||||
| 	GPIO_GROUP(GPIODV_24, 0), | ||||
| 	GPIO_GROUP(GPIODV_25, 0), | ||||
| 	GPIO_GROUP(GPIODV_26, 0), | ||||
| 	GPIO_GROUP(GPIODV_27, 0), | ||||
| 	GPIO_GROUP(GPIODV_28, 0), | ||||
| 	GPIO_GROUP(GPIODV_29, 0), | ||||
|  | ||||
| 	GPIO_GROUP(GPIOH_0, 0), | ||||
| 	GPIO_GROUP(GPIOH_1, 0), | ||||
| 	GPIO_GROUP(GPIOH_2, 0), | ||||
| 	GPIO_GROUP(GPIOH_3, 0), | ||||
| 	GPIO_GROUP(GPIOH_4, 0), | ||||
| 	GPIO_GROUP(GPIOH_5, 0), | ||||
| 	GPIO_GROUP(GPIOH_6, 0), | ||||
| 	GPIO_GROUP(GPIOH_7, 0), | ||||
| 	GPIO_GROUP(GPIOH_8, 0), | ||||
| 	GPIO_GROUP(GPIOH_9, 0), | ||||
|  | ||||
| 	GPIO_GROUP(DIF_0_P, 0), | ||||
| 	GPIO_GROUP(DIF_0_N, 0), | ||||
| 	GPIO_GROUP(DIF_1_P, 0), | ||||
| 	GPIO_GROUP(DIF_1_N, 0), | ||||
| 	GPIO_GROUP(DIF_2_P, 0), | ||||
| 	GPIO_GROUP(DIF_2_N, 0), | ||||
| 	GPIO_GROUP(DIF_3_P, 0), | ||||
| 	GPIO_GROUP(DIF_3_N, 0), | ||||
| 	GPIO_GROUP(DIF_4_P, 0), | ||||
| 	GPIO_GROUP(DIF_4_N, 0), | ||||
|  | ||||
| 	GPIO_GROUP(GPIOAO_0, AO_OFF), | ||||
| 	GPIO_GROUP(GPIOAO_1, AO_OFF), | ||||
| 	GPIO_GROUP(GPIOAO_2, AO_OFF), | ||||
| 	GPIO_GROUP(GPIOAO_3, AO_OFF), | ||||
| 	GPIO_GROUP(GPIOAO_4, AO_OFF), | ||||
| 	GPIO_GROUP(GPIOAO_5, AO_OFF), | ||||
| 	GPIO_GROUP(GPIOAO_6, AO_OFF), | ||||
| 	GPIO_GROUP(GPIOAO_7, AO_OFF), | ||||
| 	GPIO_GROUP(GPIOAO_8, AO_OFF), | ||||
| 	GPIO_GROUP(GPIOAO_9, AO_OFF), | ||||
| 	GPIO_GROUP(GPIOAO_10, AO_OFF), | ||||
| 	GPIO_GROUP(GPIOAO_11, AO_OFF), | ||||
| 	GPIO_GROUP(GPIOAO_12, AO_OFF), | ||||
| 	GPIO_GROUP(GPIOAO_13, AO_OFF), | ||||
| 	GPIO_GROUP(GPIO_BSD_EN, AO_OFF), | ||||
| 	GPIO_GROUP(GPIO_TEST_N, AO_OFF), | ||||
|  | ||||
| 	/* bank X */ | ||||
| 	GROUP(sd_d0_a,		8,	5), | ||||
| 	GROUP(sd_d1_a,		8,	4), | ||||
| 	GROUP(sd_d2_a,		8,	3), | ||||
| 	GROUP(sd_d3_a,		8,	2), | ||||
| 	GROUP(sdxc_d0_0_a,	5,	29), | ||||
| 	GROUP(sdxc_d47_a,	5,	12), | ||||
| 	GROUP(sdxc_d13_0_a,	5,	28), | ||||
| 	GROUP(sd_clk_a,		8,	1), | ||||
| 	GROUP(sd_cmd_a,		8,	0), | ||||
| 	GROUP(xtal_32k_out,	3,	22), | ||||
| 	GROUP(xtal_24m_out,	3,	20), | ||||
| 	GROUP(uart_tx_b0,	4,	9), | ||||
| 	GROUP(uart_rx_b0,	4,	8), | ||||
| 	GROUP(uart_cts_b0,	4,	7), | ||||
| 	GROUP(uart_rts_b0,	4,	6), | ||||
| 	GROUP(sdxc_d0_1_a,	5,	14), | ||||
| 	GROUP(sdxc_d13_1_a,	5,	13), | ||||
| 	GROUP(pcm_out_a,	3,	30), | ||||
| 	GROUP(pcm_in_a,		3,	29), | ||||
| 	GROUP(pcm_fs_a,		3,	28), | ||||
| 	GROUP(pcm_clk_a,	3,	27), | ||||
| 	GROUP(sdxc_clk_a,	5,	11), | ||||
| 	GROUP(sdxc_cmd_a,	5,	10), | ||||
| 	GROUP(pwm_vs_0,		7,	31), | ||||
| 	GROUP(pwm_e,		9,	19), | ||||
| 	GROUP(pwm_vs_1,		7,	30), | ||||
| 	GROUP(uart_tx_a,	4,	17), | ||||
| 	GROUP(uart_rx_a,	4,	16), | ||||
| 	GROUP(uart_cts_a,	4,	15), | ||||
| 	GROUP(uart_rts_a,	4,	14), | ||||
| 	GROUP(uart_tx_b1,	6,	19), | ||||
| 	GROUP(uart_rx_b1,	6,	18), | ||||
| 	GROUP(uart_cts_b1,	6,	17), | ||||
| 	GROUP(uart_rts_b1,	6,	16), | ||||
| 	GROUP(iso7816_0_clk,	5,	9), | ||||
| 	GROUP(iso7816_0_data,	5,	8), | ||||
| 	GROUP(spi_sclk_0,	4,	22), | ||||
| 	GROUP(spi_miso_0,	4,	24), | ||||
| 	GROUP(spi_mosi_0,	4,	23), | ||||
| 	GROUP(iso7816_det,	4,	21), | ||||
| 	GROUP(iso7816_reset,	4,	20), | ||||
| 	GROUP(iso7816_1_clk,	4,	19), | ||||
| 	GROUP(iso7816_1_data,	4,	18), | ||||
| 	GROUP(spi_ss0_0,	4,	25), | ||||
| 	GROUP(tsin_clk_b,	3,	6), | ||||
| 	GROUP(tsin_sop_b,	3,	7), | ||||
| 	GROUP(tsin_d0_b,	3,	8), | ||||
| 	GROUP(pwm_b,		2,	3), | ||||
| 	GROUP(i2c_sda_d0,	4,	5), | ||||
| 	GROUP(i2c_sck_d0,	4,	4), | ||||
| 	GROUP(tsin_d_valid_b,	3,	9), | ||||
|  | ||||
| 	/* bank Y */ | ||||
| 	GROUP(tsin_d_valid_a,	3,	2), | ||||
| 	GROUP(tsin_sop_a,	3,	1), | ||||
| 	GROUP(tsin_d17_a,	3,	5), | ||||
| 	GROUP(tsin_clk_a,	3,	0), | ||||
| 	GROUP(tsin_d0_a,	3,	4), | ||||
| 	GROUP(spdif_out_0,	1,	7), | ||||
| 	GROUP(xtal_24m,		3,	18), | ||||
| 	GROUP(iso7816_2_clk,	5,	7), | ||||
| 	GROUP(iso7816_2_data,	5,	6), | ||||
|  | ||||
| 	/* bank DV */ | ||||
| 	GROUP(pwm_d,		3,	26), | ||||
| 	GROUP(pwm_c0,		3,	25), | ||||
| 	GROUP(pwm_vs_2,		7,	28), | ||||
| 	GROUP(pwm_vs_3,		7,	27), | ||||
| 	GROUP(pwm_vs_4,		7,	26), | ||||
| 	GROUP(xtal24_out,	7,	25), | ||||
| 	GROUP(uart_tx_c,	6,	23), | ||||
| 	GROUP(uart_rx_c,	6,	22), | ||||
| 	GROUP(uart_cts_c,	6,	21), | ||||
| 	GROUP(uart_rts_c,	6,	20), | ||||
| 	GROUP(pwm_c1,		3,	24), | ||||
| 	GROUP(i2c_sda_a,	9,	31), | ||||
| 	GROUP(i2c_sck_a,	9,	30), | ||||
| 	GROUP(i2c_sda_b0,	9,	29), | ||||
| 	GROUP(i2c_sck_b0,	9,	28), | ||||
| 	GROUP(i2c_sda_c0,	9,	27), | ||||
| 	GROUP(i2c_sck_c0,	9,	26), | ||||
|  | ||||
| 	/* bank H */ | ||||
| 	GROUP(hdmi_hpd,		1,	26), | ||||
| 	GROUP(hdmi_sda,		1,	25), | ||||
| 	GROUP(hdmi_scl,		1,	24), | ||||
| 	GROUP(hdmi_cec_0,	1,	23), | ||||
| 	GROUP(eth_txd1_0,	7,	21), | ||||
| 	GROUP(eth_txd0_0,	7,	20), | ||||
| 	GROUP(clk_24m_out,	4,	1), | ||||
| 	GROUP(spi_ss1,		8,	11), | ||||
| 	GROUP(spi_ss2,		8,	12), | ||||
| 	GROUP(spi_ss0_1,	9,	13), | ||||
| 	GROUP(spi_miso_1,	9,	12), | ||||
| 	GROUP(spi_mosi_1,	9,	11), | ||||
| 	GROUP(spi_sclk_1,	9,	10), | ||||
| 	GROUP(eth_txd3,		6,	13), | ||||
| 	GROUP(eth_txd2,		6,	12), | ||||
| 	GROUP(eth_tx_clk,	6,	11), | ||||
| 	GROUP(i2c_sda_b1,	5,	27), | ||||
| 	GROUP(i2c_sck_b1,	5,	26), | ||||
| 	GROUP(i2c_sda_c1,	5,	25), | ||||
| 	GROUP(i2c_sck_c1,	5,	24), | ||||
| 	GROUP(i2c_sda_d1,	4,	3), | ||||
| 	GROUP(i2c_sck_d1,	4,	2), | ||||
|  | ||||
| 	/* bank BOOT */ | ||||
| 	GROUP(nand_io,		2,	26), | ||||
| 	GROUP(nand_io_ce0,	2,	25), | ||||
| 	GROUP(nand_io_ce1,	2,	24), | ||||
| 	GROUP(nand_io_rb0,	2,	17), | ||||
| 	GROUP(nand_ale,		2,	21), | ||||
| 	GROUP(nand_cle,		2,	20), | ||||
| 	GROUP(nand_wen_clk,	2,	19), | ||||
| 	GROUP(nand_ren_clk,	2,	18), | ||||
| 	GROUP(nand_dqs_0,	2,	27), | ||||
| 	GROUP(nand_dqs_1,	2,	28), | ||||
| 	GROUP(sdxc_d0_c,	4,	30), | ||||
| 	GROUP(sdxc_d13_c,	4,	29), | ||||
| 	GROUP(sdxc_d47_c,	4,	28), | ||||
| 	GROUP(sdxc_clk_c,	7,	19), | ||||
| 	GROUP(sdxc_cmd_c,	7,	18), | ||||
| 	GROUP(nor_d,		5,	1), | ||||
| 	GROUP(nor_q,		5,	3), | ||||
| 	GROUP(nor_c,		5,	2), | ||||
| 	GROUP(nor_cs,		5,	0), | ||||
| 	GROUP(sd_d0_c,		6,	29), | ||||
| 	GROUP(sd_d1_c,		6,	28), | ||||
| 	GROUP(sd_d2_c,		6,	27), | ||||
| 	GROUP(sd_d3_c,		6,	26), | ||||
| 	GROUP(sd_cmd_c,		6,	30), | ||||
| 	GROUP(sd_clk_c,		6,	31), | ||||
|  | ||||
| 	/* bank CARD */ | ||||
| 	GROUP(sd_d1_b,		2,	14), | ||||
| 	GROUP(sd_d0_b,		2,	15), | ||||
| 	GROUP(sd_clk_b,		2,	11), | ||||
| 	GROUP(sd_cmd_b,		2,	10), | ||||
| 	GROUP(sd_d3_b,		2,	12), | ||||
| 	GROUP(sd_d2_b,		2,	13), | ||||
| 	GROUP(sdxc_d13_b,	2,	6), | ||||
| 	GROUP(sdxc_d0_b,	2,	7), | ||||
| 	GROUP(sdxc_clk_b,	2,	5), | ||||
| 	GROUP(sdxc_cmd_b,	2,	4), | ||||
|  | ||||
| 	/* bank AO */ | ||||
| 	GROUP(uart_tx_ao_a,	0,	12), | ||||
| 	GROUP(uart_rx_ao_a,	0,	11), | ||||
| 	GROUP(uart_cts_ao_a,	0,	10), | ||||
| 	GROUP(uart_rts_ao_a,	0,	9), | ||||
| 	GROUP(i2c_mst_sck_ao,	0,	6), | ||||
| 	GROUP(i2c_mst_sda_ao,	0,	5), | ||||
| 	GROUP(clk_32k_in_out,	0,	18), | ||||
| 	GROUP(remote_input,	0,	0), | ||||
| 	GROUP(hdmi_cec_1,	0,	17), | ||||
| 	GROUP(ir_blaster,	0,	31), | ||||
| 	GROUP(pwm_c2,		0,	22), | ||||
| 	GROUP(i2c_sck_ao,	0,	2), | ||||
| 	GROUP(i2c_sda_ao,	0,	1), | ||||
| 	GROUP(ir_remote_out,	0,	21), | ||||
| 	GROUP(i2s_am_clk_out,	0,	30), | ||||
| 	GROUP(i2s_ao_clk_out,	0,	29), | ||||
| 	GROUP(i2s_lr_clk_out,	0,	28), | ||||
| 	GROUP(i2s_out_01,	0,	27), | ||||
| 	GROUP(uart_tx_ao_b0,	0,	26), | ||||
| 	GROUP(uart_rx_ao_b0,	0,	25), | ||||
| 	GROUP(uart_cts_ao_b,	0,	8), | ||||
| 	GROUP(uart_rts_ao_b,	0,	7), | ||||
| 	GROUP(uart_tx_ao_b1,	0,	24), | ||||
| 	GROUP(uart_rx_ao_b1,	0,	23), | ||||
| 	GROUP(spdif_out_1,	0,	16), | ||||
| 	GROUP(i2s_in_ch01,	0,	13), | ||||
| 	GROUP(i2s_ao_clk_in,	0,	15), | ||||
| 	GROUP(i2s_lr_clk_in,	0,	14), | ||||
|  | ||||
| 	/* bank DIF */ | ||||
| 	GROUP(eth_rxd1,		6,	0), | ||||
| 	GROUP(eth_rxd0,		6,	1), | ||||
| 	GROUP(eth_rx_dv,	6,	2), | ||||
| 	GROUP(eth_rx_clk,	6,	3), | ||||
| 	GROUP(eth_txd0_1,	6,	4), | ||||
| 	GROUP(eth_txd1_1,	6,	5), | ||||
| 	GROUP(eth_tx_en,	6,	0), | ||||
| 	GROUP(eth_ref_clk,	6,	8), | ||||
| 	GROUP(eth_mdc,		6,	9), | ||||
| 	GROUP(eth_mdio_en,	6,	10), | ||||
| }; | ||||
|  | ||||
| static const char * const gpio_groups[] = { | ||||
| 	"GPIOX_0", "GPIOX_1", "GPIOX_2", "GPIOX_3", "GPIOX_4", | ||||
| 	"GPIOX_5", "GPIOX_6", "GPIOX_7", "GPIOX_8", "GPIOX_9", | ||||
| 	"GPIOX_10", "GPIOX_11", "GPIOX_16", "GPIOX_17", "GPIOX_18", | ||||
| 	"GPIOX_19", "GPIOX_20", "GPIOX_21", | ||||
|  | ||||
| 	"GPIOY_0", "GPIOY_1", "GPIOY_3", "GPIOY_6", "GPIOY_7", | ||||
| 	"GPIOY_8", "GPIOY_9", "GPIOY_10", "GPIOY_11", "GPIOY_12", | ||||
| 	"GPIOY_13", "GPIOY_14", | ||||
|  | ||||
| 	"GPIODV_9", "GPIODV_24", "GPIODV_25", "GPIODV_26", | ||||
| 	"GPIODV_27", "GPIODV_28", "GPIODV_29", | ||||
|  | ||||
| 	"GPIOH_0", "GPIOH_1", "GPIOH_2", "GPIOH_3", "GPIOH_4", | ||||
| 	"GPIOH_5", "GPIOH_6", "GPIOH_7", "GPIOH_8", "GPIOH_9", | ||||
|  | ||||
| 	"CARD_0", "CARD_1", "CARD_2", "CARD_3", "CARD_4", | ||||
| 	"CARD_5", "CARD_6", | ||||
|  | ||||
| 	"BOOT_0", "BOOT_1", "BOOT_2", "BOOT_3", "BOOT_4", | ||||
| 	"BOOT_5", "BOOT_6", "BOOT_7", "BOOT_8", "BOOT_9", | ||||
| 	"BOOT_10", "BOOT_11", "BOOT_12", "BOOT_13", "BOOT_14", | ||||
| 	"BOOT_15", "BOOT_16", "BOOT_17", "BOOT_18", | ||||
|  | ||||
| 	"GPIOAO_0", "GPIOAO_1", "GPIOAO_2", "GPIOAO_3", | ||||
| 	"GPIOAO_4", "GPIOAO_5", "GPIOAO_6", "GPIOAO_7", | ||||
| 	"GPIOAO_8", "GPIOAO_9", "GPIOAO_10", "GPIOAO_11", | ||||
| 	"GPIOAO_12", "GPIOAO_13", "GPIO_BSD_EN", "GPIO_TEST_N", | ||||
|  | ||||
| 	"DIF_0_P", "DIF_0_N", "DIF_1_P", "DIF_1_N", | ||||
| 	"DIF_2_P", "DIF_2_N", "DIF_3_P", "DIF_3_N", | ||||
| 	"DIF_4_P", "DIF_4_N" | ||||
| }; | ||||
|  | ||||
| static const char * const sd_a_groups[] = { | ||||
| 	"sd_d0_a", "sd_d1_a", "sd_d2_a", "sd_d3_a", "sd_clk_a", | ||||
| 	"sd_cmd_a" | ||||
| }; | ||||
|  | ||||
| static const char * const sdxc_a_groups[] = { | ||||
| 	"sdxc_d0_0_a", "sdxc_d13_0_a", "sdxc_d47_a", "sdxc_clk_a", | ||||
| 	"sdxc_cmd_a", "sdxc_d0_1_a", "sdxc_d0_13_1_a" | ||||
| }; | ||||
|  | ||||
| static const char * const pcm_a_groups[] = { | ||||
| 	"pcm_out_a", "pcm_in_a", "pcm_fs_a", "pcm_clk_a" | ||||
| }; | ||||
|  | ||||
| static const char * const uart_a_groups[] = { | ||||
| 	"uart_tx_a", "uart_rx_a", "uart_cts_a", "uart_rts_a" | ||||
| }; | ||||
|  | ||||
| static const char * const uart_b_groups[] = { | ||||
| 	"uart_tx_b0", "uart_rx_b0", "uart_cts_b0", "uart_rts_b0", | ||||
| 	"uart_tx_b1", "uart_rx_b1", "uart_cts_b1", "uart_rts_b1" | ||||
| }; | ||||
|  | ||||
| static const char * const iso7816_groups[] = { | ||||
| 	"iso7816_det", "iso7816_reset", "iso7816_0_clk", "iso7816_0_data", | ||||
| 	"iso7816_1_clk", "iso7816_1_data", "iso7816_2_clk", "iso7816_2_data" | ||||
| }; | ||||
|  | ||||
| static const char * const i2c_d_groups[] = { | ||||
| 	"i2c_sda_d0", "i2c_sck_d0", "i2c_sda_d1", "i2c_sck_d1" | ||||
| }; | ||||
|  | ||||
| static const char * const xtal_groups[] = { | ||||
| 	"xtal_32k_out", "xtal_24m_out", "xtal_24m", "xtal24_out" | ||||
| }; | ||||
|  | ||||
| static const char * const uart_c_groups[] = { | ||||
| 	"uart_tx_c", "uart_rx_c", "uart_cts_c", "uart_rts_c" | ||||
| }; | ||||
|  | ||||
| static const char * const i2c_c_groups[] = { | ||||
| 	"i2c_sda_c0", "i2c_sck_c0", "i2c_sda_c1", "i2c_sck_c1" | ||||
| }; | ||||
|  | ||||
| static const char * const hdmi_groups[] = { | ||||
| 	"hdmi_hpd", "hdmi_sda", "hdmi_scl", "hdmi_cec_0", | ||||
| 	"hdmi_cec_1" | ||||
| }; | ||||
|  | ||||
| static const char * const spi_groups[] = { | ||||
| 	"spi_ss0_0", "spi_miso_0", "spi_mosi_0", "spi_sclk_0", | ||||
| 	"spi_ss0_1", "spi_ss1", "spi_sclk_1", "spi_mosi_1", | ||||
| 	"spi_miso_1", "spi_ss2" | ||||
| }; | ||||
|  | ||||
| static const char * const ethernet_groups[] = { | ||||
| 	"eth_tx_clk", "eth_tx_en", "eth_txd1_0", "eth_txd1_1", | ||||
| 	"eth_txd0_0", "eth_txd0_1", "eth_rx_clk", "eth_rx_dv", | ||||
| 	"eth_rxd1", "eth_rxd0", "eth_mdio_en", "eth_mdc", "eth_ref_clk", | ||||
| 	"eth_txd2", "eth_txd3" | ||||
| }; | ||||
|  | ||||
| static const char * const i2c_a_groups[] = { | ||||
| 	"i2c_sda_a", "i2c_sck_a", | ||||
| }; | ||||
|  | ||||
| static const char * const i2c_b_groups[] = { | ||||
| 	"i2c_sda_b0", "i2c_sck_b0", "i2c_sda_b1", "i2c_sck_b1" | ||||
| }; | ||||
|  | ||||
| static const char * const sd_c_groups[] = { | ||||
| 	"sd_d0_c", "sd_d1_c", "sd_d2_c", "sd_d3_c", | ||||
| 	"sd_cmd_c", "sd_clk_c" | ||||
| }; | ||||
|  | ||||
| static const char * const sdxc_c_groups[] = { | ||||
| 	"sdxc_d0_c", "sdxc_d13_c", "sdxc_d47_c", "sdxc_cmd_c", | ||||
| 	"sdxc_clk_c" | ||||
| }; | ||||
|  | ||||
| static const char * const nand_groups[] = { | ||||
| 	"nand_io", "nand_io_ce0", "nand_io_ce1", | ||||
| 	"nand_io_rb0", "nand_ale", "nand_cle", | ||||
| 	"nand_wen_clk", "nand_ren_clk", "nand_dqs0", | ||||
| 	"nand_dqs1" | ||||
| }; | ||||
|  | ||||
| static const char * const nor_groups[] = { | ||||
| 	"nor_d", "nor_q", "nor_c", "nor_cs" | ||||
| }; | ||||
|  | ||||
| static const char * const sd_b_groups[] = { | ||||
| 	"sd_d1_b", "sd_d0_b", "sd_clk_b", "sd_cmd_b", | ||||
| 	"sd_d3_b", "sd_d2_b" | ||||
| }; | ||||
|  | ||||
| static const char * const sdxc_b_groups[] = { | ||||
| 	"sdxc_d13_b", "sdxc_d0_b", "sdxc_clk_b", "sdxc_cmd_b" | ||||
| }; | ||||
|  | ||||
| static const char * const uart_ao_groups[] = { | ||||
| 	"uart_tx_ao_a", "uart_rx_ao_a", "uart_cts_ao_a", "uart_rts_ao_a" | ||||
| }; | ||||
|  | ||||
| static const char * const remote_groups[] = { | ||||
| 	"remote_input", "ir_blaster", "ir_remote_out" | ||||
| }; | ||||
|  | ||||
| static const char * const i2c_slave_ao_groups[] = { | ||||
| 	"i2c_sck_ao", "i2c_sda_ao" | ||||
| }; | ||||
|  | ||||
| static const char * const uart_ao_b_groups[] = { | ||||
| 	"uart_tx_ao_b0", "uart_rx_ao_b0", "uart_tx_ao_b1", "uart_rx_ao_b1", | ||||
| 	"uart_cts_ao_b", "uart_rts_ao_b" | ||||
| }; | ||||
|  | ||||
| static const char * const i2c_mst_ao_groups[] = { | ||||
| 	"i2c_mst_sck_ao", "i2c_mst_sda_ao" | ||||
| }; | ||||
|  | ||||
| static const char * const clk_groups[] = { | ||||
| 	"clk_24m_out", "clk_32k_in_out" | ||||
| }; | ||||
|  | ||||
| static const char * const spdif_groups[] = { | ||||
| 	"spdif_out_1", "spdif_out_0" | ||||
| }; | ||||
|  | ||||
| static const char * const i2s_groups[] = { | ||||
| 	"i2s_am_clk_out", "i2s_ao_clk_out", "i2s_lr_clk_out", | ||||
| 	"i2s_out_01", "i2s_in_ch01", "i2s_ao_clk_in", | ||||
| 	"i2s_lr_clk_in" | ||||
| }; | ||||
|  | ||||
| static const char * const pwm_b_groups[] = { | ||||
| 	"pwm_b" | ||||
| }; | ||||
|  | ||||
| static const char * const pwm_c_groups[] = { | ||||
| 	"pwm_c0", "pwm_c1", "pwm_c2" | ||||
| }; | ||||
|  | ||||
| static const char * const pwm_d_groups[] = { | ||||
| 	"pwm_d" | ||||
| }; | ||||
|  | ||||
| static const char * const pwm_e_groups[] = { | ||||
| 	"pwm_e" | ||||
| }; | ||||
|  | ||||
| static const char * const pwm_vs_groups[] = { | ||||
| 	"pwm_vs_0", "pwm_vs_1", "pwm_vs_2", | ||||
| 	"pwm_vs_3", "pwm_vs_4" | ||||
| }; | ||||
|  | ||||
| static const char * const tsin_a_groups[] = { | ||||
| 	"tsin_d0_a", "tsin_d17_a", "tsin_clk_a", "tsin_sop_a", | ||||
| 	"tsin_d_valid_a" | ||||
| }; | ||||
|  | ||||
| static const char * const tsin_b_groups[] = { | ||||
| 	"tsin_d0_b", "tsin_clk_b", "tsin_sop_b", "tsin_d_valid_b" | ||||
| }; | ||||
|  | ||||
| static struct meson_pmx_func meson8b_functions[] = { | ||||
| 	FUNCTION(gpio), | ||||
| 	FUNCTION(sd_a), | ||||
| 	FUNCTION(sdxc_a), | ||||
| 	FUNCTION(pcm_a), | ||||
| 	FUNCTION(uart_a), | ||||
| 	FUNCTION(uart_b), | ||||
| 	FUNCTION(iso7816), | ||||
| 	FUNCTION(i2c_d), | ||||
| 	FUNCTION(xtal), | ||||
| 	FUNCTION(uart_c), | ||||
| 	FUNCTION(i2c_c), | ||||
| 	FUNCTION(hdmi), | ||||
| 	FUNCTION(spi), | ||||
| 	FUNCTION(ethernet), | ||||
| 	FUNCTION(i2c_a), | ||||
| 	FUNCTION(i2c_b), | ||||
| 	FUNCTION(sd_c), | ||||
| 	FUNCTION(sdxc_c), | ||||
| 	FUNCTION(nand), | ||||
| 	FUNCTION(nor), | ||||
| 	FUNCTION(sd_b), | ||||
| 	FUNCTION(sdxc_b), | ||||
| 	FUNCTION(uart_ao), | ||||
| 	FUNCTION(remote), | ||||
| 	FUNCTION(i2c_slave_ao), | ||||
| 	FUNCTION(uart_ao_b), | ||||
| 	FUNCTION(i2c_mst_ao), | ||||
| 	FUNCTION(clk), | ||||
| 	FUNCTION(spdif), | ||||
| 	FUNCTION(i2s), | ||||
| 	FUNCTION(pwm_b), | ||||
| 	FUNCTION(pwm_c), | ||||
| 	FUNCTION(pwm_d), | ||||
| 	FUNCTION(pwm_e), | ||||
| 	FUNCTION(pwm_vs), | ||||
| 	FUNCTION(tsin_a), | ||||
| 	FUNCTION(tsin_b), | ||||
| }; | ||||
|  | ||||
| static struct meson_bank meson8b_banks[] = { | ||||
| 	/*   name    first                      last                   pullen  pull    dir     out     in  */ | ||||
| 	BANK("X",    PIN(GPIOX_0, 0),		PIN(GPIOX_21, 0),      4,  0,  4,  0,  0,  0,  1,  0,  2,  0), | ||||
| 	BANK("Y",    PIN(GPIOY_0, 0),		PIN(GPIOY_14, 0),      3,  0,  3,  0,  3,  0,  4,  0,  5,  0), | ||||
| 	BANK("DV",   PIN(GPIODV_9, 0),		PIN(GPIODV_29, 0),     0,  0,  0,  0,  7,  0,  8,  0,  9,  0), | ||||
| 	BANK("H",    PIN(GPIOH_0, 0),		PIN(GPIOH_9, 0),       1, 16,  1, 16,  9, 19, 10, 19, 11, 19), | ||||
| 	BANK("CARD", PIN(CARD_0, 0),		PIN(CARD_6, 0),        2, 20,  2, 20,  0, 22,  1, 22,  2, 22), | ||||
| 	BANK("BOOT", PIN(BOOT_0, 0),		PIN(BOOT_18, 0),       2,  0,  2,  0,  9,  0, 10,  0, 11,  0), | ||||
| 	BANK("DIF",  PIN(DIF_0_P, 0),		PIN(DIF_4_N, 0),       5,  8,  5,  8, 12, 12, 13, 12, 14, 12), | ||||
| }; | ||||
|  | ||||
| static struct meson_bank meson8b_ao_banks[] = { | ||||
| 	/*   name    first                  last                      pullen  pull    dir     out     in  */ | ||||
| 	BANK("AO",   PIN(GPIOAO_0, AO_OFF), PIN(GPIO_TEST_N, AO_OFF), 0,  0,  0, 16,  0,  0,  0, 16,  1,  0), | ||||
| }; | ||||
|  | ||||
| static struct meson_domain_data meson8b_domain_data[] = { | ||||
| 	{ | ||||
| 		.name		= "banks", | ||||
| 		.banks		= meson8b_banks, | ||||
| 		.num_banks	= ARRAY_SIZE(meson8b_banks), | ||||
| 		.pin_base	= 0, | ||||
| 		.num_pins	= 83, | ||||
| 	}, | ||||
| 	{ | ||||
| 		.name		= "ao-bank", | ||||
| 		.banks		= meson8b_ao_banks, | ||||
| 		.num_banks	= ARRAY_SIZE(meson8b_ao_banks), | ||||
| 		.pin_base	= 83, | ||||
| 		.num_pins	= 16, | ||||
| 	}, | ||||
| }; | ||||
|  | ||||
| struct meson_pinctrl_data meson8b_pinctrl_data = { | ||||
| 	.pins		= meson8b_pins, | ||||
| 	.groups		= meson8b_groups, | ||||
| 	.funcs		= meson8b_functions, | ||||
| 	.domain_data	= meson8b_domain_data, | ||||
| 	.num_pins	= ARRAY_SIZE(meson8b_pins), | ||||
| 	.num_groups	= ARRAY_SIZE(meson8b_groups), | ||||
| 	.num_funcs	= ARRAY_SIZE(meson8b_functions), | ||||
| 	.num_domains	= ARRAY_SIZE(meson8b_domain_data), | ||||
| }; | ||||
| @@ -26,6 +26,10 @@ config PINCTRL_ARMADA_38X | ||||
| 	bool | ||||
| 	select PINCTRL_MVEBU | ||||
|  | ||||
| config PINCTRL_ARMADA_39X | ||||
| 	bool | ||||
| 	select PINCTRL_MVEBU | ||||
|  | ||||
| config PINCTRL_ARMADA_XP | ||||
| 	bool | ||||
| 	select PINCTRL_MVEBU | ||||
|   | ||||
| @@ -4,5 +4,6 @@ obj-$(CONFIG_PINCTRL_KIRKWOOD)	+= pinctrl-kirkwood.o | ||||
| obj-$(CONFIG_PINCTRL_ARMADA_370) += pinctrl-armada-370.o | ||||
| obj-$(CONFIG_PINCTRL_ARMADA_375) += pinctrl-armada-375.o | ||||
| obj-$(CONFIG_PINCTRL_ARMADA_38X) += pinctrl-armada-38x.o | ||||
| obj-$(CONFIG_PINCTRL_ARMADA_39X) += pinctrl-armada-39x.o | ||||
| obj-$(CONFIG_PINCTRL_ARMADA_XP)  += pinctrl-armada-xp.o | ||||
| obj-$(CONFIG_PINCTRL_ORION)  += pinctrl-orion.o | ||||
|   | ||||
| @@ -379,7 +379,7 @@ static struct mvebu_mpp_mode mv88f6710_mpp_modes[] = { | ||||
|  | ||||
| static struct mvebu_pinctrl_soc_info armada_370_pinctrl_info; | ||||
|  | ||||
| static struct of_device_id armada_370_pinctrl_of_match[] = { | ||||
| static const struct of_device_id armada_370_pinctrl_of_match[] = { | ||||
| 	{ .compatible = "marvell,mv88f6710-pinctrl" }, | ||||
| 	{ }, | ||||
| }; | ||||
|   | ||||
| @@ -399,7 +399,7 @@ static struct mvebu_mpp_mode mv88f6720_mpp_modes[] = { | ||||
|  | ||||
| static struct mvebu_pinctrl_soc_info armada_375_pinctrl_info; | ||||
|  | ||||
| static struct of_device_id armada_375_pinctrl_of_match[] = { | ||||
| static const struct of_device_id armada_375_pinctrl_of_match[] = { | ||||
| 	{ .compatible = "marvell,mv88f6720-pinctrl" }, | ||||
| 	{ }, | ||||
| }; | ||||
|   | ||||
| @@ -389,7 +389,7 @@ static struct mvebu_mpp_mode armada_38x_mpp_modes[] = { | ||||
|  | ||||
| static struct mvebu_pinctrl_soc_info armada_38x_pinctrl_info; | ||||
|  | ||||
| static struct of_device_id armada_38x_pinctrl_of_match[] = { | ||||
| static const struct of_device_id armada_38x_pinctrl_of_match[] = { | ||||
| 	{ | ||||
| 		.compatible = "marvell,mv88f6810-pinctrl", | ||||
| 		.data       = (void *) V_88F6810, | ||||
|   | ||||
							
								
								
									
										432
									
								
								drivers/pinctrl/mvebu/pinctrl-armada-39x.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										432
									
								
								drivers/pinctrl/mvebu/pinctrl-armada-39x.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,432 @@ | ||||
| /* | ||||
|  * Marvell Armada 39x pinctrl driver based on mvebu pinctrl core | ||||
|  * | ||||
|  * Copyright (C) 2015 Marvell | ||||
|  * | ||||
|  * Thomas Petazzoni <thomas.petazzoni@free-electrons.com> | ||||
|  * | ||||
|  * 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/platform_device.h> | ||||
| #include <linux/of.h> | ||||
| #include <linux/of_device.h> | ||||
| #include <linux/pinctrl/pinctrl.h> | ||||
|  | ||||
| #include "pinctrl-mvebu.h" | ||||
|  | ||||
| static void __iomem *mpp_base; | ||||
|  | ||||
| static int armada_39x_mpp_ctrl_get(unsigned pid, unsigned long *config) | ||||
| { | ||||
| 	return default_mpp_ctrl_get(mpp_base, pid, config); | ||||
| } | ||||
|  | ||||
| static int armada_39x_mpp_ctrl_set(unsigned pid, unsigned long config) | ||||
| { | ||||
| 	return default_mpp_ctrl_set(mpp_base, pid, config); | ||||
| } | ||||
|  | ||||
| enum { | ||||
| 	V_88F6920 = BIT(0), | ||||
| 	V_88F6928 = BIT(1), | ||||
| 	V_88F6920_PLUS = (V_88F6920 | V_88F6928), | ||||
| }; | ||||
|  | ||||
| static struct mvebu_mpp_mode armada_39x_mpp_modes[] = { | ||||
| 	MPP_MODE(0, | ||||
| 		 MPP_VAR_FUNCTION(0, "gpio",    NULL,       V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(1, "ua0",     "rxd",      V_88F6920_PLUS)), | ||||
| 	MPP_MODE(1, | ||||
| 		 MPP_VAR_FUNCTION(0, "gpio",    NULL,       V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(1, "ua0",     "txd",      V_88F6920_PLUS)), | ||||
| 	MPP_MODE(2, | ||||
| 		 MPP_VAR_FUNCTION(0, "gpio",    NULL,       V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(1, "i2c0",    "sck",      V_88F6920_PLUS)), | ||||
| 	MPP_MODE(3, | ||||
| 		 MPP_VAR_FUNCTION(0, "gpio",    NULL,       V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(1, "i2c0",    "sda",      V_88F6920_PLUS)), | ||||
| 	MPP_MODE(4, | ||||
| 		 MPP_VAR_FUNCTION(0, "gpio",    NULL,       V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(2, "ua1",     "txd",      V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(3, "ua0",     "rts",      V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(7, "smi",     "mdc",      V_88F6920_PLUS)), | ||||
| 	MPP_MODE(5, | ||||
| 		 MPP_VAR_FUNCTION(0, "gpio",    NULL,       V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(2, "ua1",     "rxd",      V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(3, "ua0",     "cts",      V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(7, "smi",     "mdio",     V_88F6920_PLUS)), | ||||
| 	MPP_MODE(6, | ||||
| 		 MPP_VAR_FUNCTION(0, "gpio",    NULL,       V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(5, "dev",     "cs3",      V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(7, "xsmi",    "mdio",     V_88F6920_PLUS)), | ||||
| 	MPP_MODE(7, | ||||
| 		 MPP_VAR_FUNCTION(0, "gpio",    NULL,       V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(5, "dev",     "ad9",      V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(7, "xsmi",    "mdc",      V_88F6920_PLUS)), | ||||
| 	MPP_MODE(8, | ||||
| 		 MPP_VAR_FUNCTION(0, "gpio",    NULL,       V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(5, "dev",     "ad10",     V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(7, "ptp",     "trig",     V_88F6920_PLUS)), | ||||
| 	MPP_MODE(9, | ||||
| 		 MPP_VAR_FUNCTION(0, "gpio",    NULL,       V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(5, "dev",     "ad11",     V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(7, "ptp",     "clk",      V_88F6920_PLUS)), | ||||
| 	MPP_MODE(10, | ||||
| 		 MPP_VAR_FUNCTION(0, "gpio",    NULL,       V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(5, "dev",     "ad12",     V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(7, "ptp",     "event",    V_88F6920_PLUS)), | ||||
| 	MPP_MODE(11, | ||||
| 		 MPP_VAR_FUNCTION(0, "gpio",    NULL,       V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(5, "dev",     "ad13",     V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(7, "led",     "clk",      V_88F6920_PLUS)), | ||||
| 	MPP_MODE(12, | ||||
| 		 MPP_VAR_FUNCTION(0, "gpio",    NULL,       V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(2, "pcie0",   "rstout",   V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(5, "dev",     "ad14",     V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(7, "led",     "stb",      V_88F6920_PLUS)), | ||||
| 	MPP_MODE(13, | ||||
| 		 MPP_VAR_FUNCTION(0, "gpio",    NULL,       V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(5, "dev",     "ad15",     V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(7, "led",     "data",     V_88F6920_PLUS)), | ||||
| 	MPP_MODE(14, | ||||
| 		 MPP_VAR_FUNCTION(0, "gpio",    NULL,       V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(3, "m",       "vtt",      V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(5, "dev",     "wen1",     V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(7, "ua1",     "txd",      V_88F6920_PLUS)), | ||||
| 	MPP_MODE(15, | ||||
| 		 MPP_VAR_FUNCTION(0, "gpio",    NULL,       V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(3, "pcie0",   "rstout",   V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(4, "spi0",    "mosi",     V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(7, "i2c1",    "sck",      V_88F6920_PLUS)), | ||||
| 	MPP_MODE(16, | ||||
| 		 MPP_VAR_FUNCTION(0, "gpio",    NULL,       V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(3, "m",       "decc",     V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(4, "spi0",    "miso",     V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(7, "i2c1",    "sda",      V_88F6920_PLUS)), | ||||
| 	MPP_MODE(17, | ||||
| 		 MPP_VAR_FUNCTION(0, "gpio",    NULL,       V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(3, "ua1",     "rxd",      V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(4, "spi0",    "sck",      V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(7, "smi",     "mdio",     V_88F6920_PLUS)), | ||||
| 	MPP_MODE(18, | ||||
| 		 MPP_VAR_FUNCTION(0, "gpio",    NULL,       V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(3, "ua1",     "txd",      V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(4, "spi0",    "cs0",      V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(7, "i2c2",    "sck",      V_88F6920_PLUS)), | ||||
| 	MPP_MODE(19, | ||||
| 		 MPP_VAR_FUNCTION(0, "gpio",    NULL,       V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(4, "sata1",   "present",  V_88F6928), | ||||
| 		 MPP_VAR_FUNCTION(5, "ua0",     "cts",      V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(6, "ua1",     "rxd",      V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(7, "i2c2",    "sda",      V_88F6920_PLUS)), | ||||
| 	MPP_MODE(20, | ||||
| 		 MPP_VAR_FUNCTION(0, "gpio",    NULL,       V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(4, "sata0",   "present",  V_88F6928), | ||||
| 		 MPP_VAR_FUNCTION(5, "ua0",     "rts",      V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(6, "ua1",     "txd",      V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(7, "smi",     "mdc",      V_88F6920_PLUS)), | ||||
| 	MPP_MODE(21, | ||||
| 		 MPP_VAR_FUNCTION(0, "gpio",    NULL,       V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(1, "spi0",    "cs1",      V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(3, "sata0",   "present",  V_88F6928), | ||||
| 		 MPP_VAR_FUNCTION(4, "sd",      "cmd",      V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(5, "dev",     "bootcs",   V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(8, "ge",      "rxd0",     V_88F6920_PLUS)), | ||||
| 	MPP_MODE(22, | ||||
| 		 MPP_VAR_FUNCTION(0, "gpio",    NULL,       V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(1, "spi0",    "mosi",     V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(5, "dev",     "ad0",      V_88F6920_PLUS)), | ||||
| 	MPP_MODE(23, | ||||
| 		 MPP_VAR_FUNCTION(0, "gpio",    NULL,       V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(1, "spi0",    "sck",      V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(5, "dev",     "ad2",      V_88F6920_PLUS)), | ||||
| 	MPP_MODE(24, | ||||
| 		 MPP_VAR_FUNCTION(0, "gpio",    NULL,       V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(1, "spi0",    "miso",     V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(2, "ua0",     "cts",      V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(3, "ua1",     "rxd",      V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(4, "sd",      "d4",       V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(5, "dev",     "readyn",   V_88F6920_PLUS)), | ||||
| 	MPP_MODE(25, | ||||
| 		 MPP_VAR_FUNCTION(0, "gpio",    NULL,       V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(1, "spi0",    "cs0",      V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(2, "ua0",     "rts",      V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(3, "ua1",     "txd",      V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(4, "sd",      "d5",       V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(5, "dev",     "cs0",      V_88F6920_PLUS)), | ||||
| 	MPP_MODE(26, | ||||
| 		 MPP_VAR_FUNCTION(0, "gpio",    NULL,       V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(1, "spi0",    "cs2",      V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(3, "i2c1",    "sck",      V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(4, "sd",      "d6",       V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(5, "dev",     "cs1",      V_88F6920_PLUS)), | ||||
| 	MPP_MODE(27, | ||||
| 		 MPP_VAR_FUNCTION(0, "gpio",    NULL,       V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(1, "spi0",    "cs3",      V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(3, "i2c1",    "sda",      V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(4, "sd",      "d7",       V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(5, "dev",     "cs2",      V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(8, "ge",      "txclkout", V_88F6920_PLUS)), | ||||
| 	MPP_MODE(28, | ||||
| 		 MPP_VAR_FUNCTION(0, "gpio",    NULL,       V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(4, "sd",      "clk",      V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(5, "dev",     "ad5",      V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(8, "ge",      "txd0",     V_88F6920_PLUS)), | ||||
| 	MPP_MODE(29, | ||||
| 		 MPP_VAR_FUNCTION(0, "gpio",    NULL,       V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(5, "dev",     "ale0",     V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(8, "ge",      "txd1",     V_88F6920_PLUS)), | ||||
| 	MPP_MODE(30, | ||||
| 		 MPP_VAR_FUNCTION(0, "gpio",    NULL,       V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(5, "dev",     "oen",      V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(8, "ge",      "txd2",     V_88F6920_PLUS)), | ||||
| 	MPP_MODE(31, | ||||
| 		 MPP_VAR_FUNCTION(0, "gpio",    NULL,       V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(5, "dev",     "ale1",     V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(8, "ge",      "txd3",     V_88F6920_PLUS)), | ||||
| 	MPP_MODE(32, | ||||
| 		 MPP_VAR_FUNCTION(0, "gpio",    NULL,       V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(5, "dev",     "wen0",     V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(8, "ge",      "txctl",    V_88F6920_PLUS)), | ||||
| 	MPP_MODE(33, | ||||
| 		 MPP_VAR_FUNCTION(0, "gpio",    NULL,       V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(1, "m",       "decc",     V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(5, "dev",     "ad3",      V_88F6920_PLUS)), | ||||
| 	MPP_MODE(34, | ||||
| 		 MPP_VAR_FUNCTION(0, "gpio",    NULL,       V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(5, "dev",     "ad1",      V_88F6920_PLUS)), | ||||
| 	MPP_MODE(35, | ||||
| 		 MPP_VAR_FUNCTION(0, "gpio",    NULL,       V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(1, "ref",     "clk",      V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(5, "dev",     "a1",       V_88F6920_PLUS)), | ||||
| 	MPP_MODE(36, | ||||
| 		 MPP_VAR_FUNCTION(0, "gpio",    NULL,       V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(5, "dev",     "a0",       V_88F6920_PLUS)), | ||||
| 	MPP_MODE(37, | ||||
| 		 MPP_VAR_FUNCTION(0, "gpio",    NULL,       V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(4, "sd",      "d3",       V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(5, "dev",     "ad8",      V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(8, "ge",      "rxclk",    V_88F6920_PLUS)), | ||||
| 	MPP_MODE(38, | ||||
| 		 MPP_VAR_FUNCTION(0, "gpio",    NULL,       V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(3, "ref",     "clk",      V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(4, "sd",      "d0",       V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(5, "dev",     "ad4",      V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(8, "ge",      "rxd1",     V_88F6920_PLUS)), | ||||
| 	MPP_MODE(39, | ||||
| 		 MPP_VAR_FUNCTION(0, "gpio",    NULL,       V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(1, "i2c1",    "sck",      V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(3, "ua0",     "cts",      V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(4, "sd",      "d1",       V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(5, "dev",     "a2",       V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(8, "ge",      "rxd2",     V_88F6920_PLUS)), | ||||
| 	MPP_MODE(40, | ||||
| 		 MPP_VAR_FUNCTION(0, "gpio",    NULL,       V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(1, "i2c1",    "sda",      V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(3, "ua0",     "rts",      V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(4, "sd",      "d2",       V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(5, "dev",     "ad6",      V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(8, "ge",      "rxd3",     V_88F6920_PLUS)), | ||||
| 	MPP_MODE(41, | ||||
| 		 MPP_VAR_FUNCTION(0, "gpio",    NULL,       V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(1, "ua1",     "rxd",      V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(3, "ua0",     "cts",      V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(4, "spi1",    "cs3",      V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(5, "dev",     "burstn",   V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(6, "nd",      "rbn0",     V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(8, "ge",      "rxctl",    V_88F6920_PLUS)), | ||||
| 	MPP_MODE(42, | ||||
| 		 MPP_VAR_FUNCTION(0, "gpio",    NULL,       V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(1, "ua1",     "txd",      V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(3, "ua0",     "rts",      V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(5, "dev",     "ad7",      V_88F6920_PLUS)), | ||||
| 	MPP_MODE(43, | ||||
| 		 MPP_VAR_FUNCTION(0, "gpio",    NULL,       V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(1, "pcie0",   "clkreq",   V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(2, "m",       "vtt",      V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(3, "m",       "decc",     V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(4, "spi1",    "cs2",      V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(5, "dev",     "clkout",   V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(6, "nd",      "rbn1",     V_88F6920_PLUS)), | ||||
| 	MPP_MODE(44, | ||||
| 		 MPP_VAR_FUNCTION(0, "gpio",    NULL,       V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(1, "sata0",   "present",  V_88F6928), | ||||
| 		 MPP_VAR_FUNCTION(2, "sata1",   "present",  V_88F6928), | ||||
| 		 MPP_VAR_FUNCTION(7, "led",     "clk",      V_88F6920_PLUS)), | ||||
| 	MPP_MODE(45, | ||||
| 		 MPP_VAR_FUNCTION(0, "gpio",    NULL,       V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(1, "ref",     "clk",      V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(2, "pcie0",   "rstout",   V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(6, "ua1",     "rxd",      V_88F6920_PLUS)), | ||||
| 	MPP_MODE(46, | ||||
| 		 MPP_VAR_FUNCTION(0, "gpio",    NULL,       V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(1, "ref",     "clk",      V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(2, "pcie0",   "rstout",   V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(6, "ua1",     "txd",      V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(7, "led",     "stb",      V_88F6920_PLUS)), | ||||
| 	MPP_MODE(47, | ||||
| 		 MPP_VAR_FUNCTION(0, "gpio",    NULL,       V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(1, "sata0",   "present",  V_88F6928), | ||||
| 		 MPP_VAR_FUNCTION(2, "sata1",   "present",  V_88F6928), | ||||
| 		 MPP_VAR_FUNCTION(7, "led",     "data",     V_88F6920_PLUS)), | ||||
| 	MPP_MODE(48, | ||||
| 		 MPP_VAR_FUNCTION(0, "gpio",    NULL,       V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(1, "sata0",   "present",  V_88F6928), | ||||
| 		 MPP_VAR_FUNCTION(2, "m",       "vtt",      V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(3, "tdm",     "pclk",     V_88F6928), | ||||
| 		 MPP_VAR_FUNCTION(4, "audio",   "mclk",     V_88F6928), | ||||
| 		 MPP_VAR_FUNCTION(5, "sd",      "d4",       V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(6, "pcie0",   "clkreq",   V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(7, "ua1",     "txd",      V_88F6920_PLUS)), | ||||
| 	MPP_MODE(49, | ||||
| 		 MPP_VAR_FUNCTION(0, "gpio",    NULL,       V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(3, "tdm",     "fsync",    V_88F6928), | ||||
| 		 MPP_VAR_FUNCTION(4, "audio",   "lrclk",    V_88F6928), | ||||
| 		 MPP_VAR_FUNCTION(5, "sd",      "d5",       V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(7, "ua2",     "rxd",      V_88F6920_PLUS)), | ||||
| 	MPP_MODE(50, | ||||
| 		 MPP_VAR_FUNCTION(0, "gpio",    NULL,       V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(1, "pcie0",   "rstout",   V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(3, "tdm",     "drx",      V_88F6928), | ||||
| 		 MPP_VAR_FUNCTION(4, "audio",   "extclk",   V_88F6928), | ||||
| 		 MPP_VAR_FUNCTION(5, "sd",      "cmd",      V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(7, "ua2",     "rxd",      V_88F6920_PLUS)), | ||||
| 	MPP_MODE(51, | ||||
| 		 MPP_VAR_FUNCTION(0, "gpio",    NULL,       V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(3, "tdm",     "dtx",      V_88F6928), | ||||
| 		 MPP_VAR_FUNCTION(4, "audio",   "sdo",      V_88F6928), | ||||
| 		 MPP_VAR_FUNCTION(5, "m",       "decc",     V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(7, "ua2",     "txd",      V_88F6920_PLUS)), | ||||
| 	MPP_MODE(52, | ||||
| 		 MPP_VAR_FUNCTION(0, "gpio",    NULL,       V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(1, "pcie0",   "rstout",   V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(3, "tdm",     "intn",     V_88F6928), | ||||
| 		 MPP_VAR_FUNCTION(4, "audio",   "sdi",      V_88F6928), | ||||
| 		 MPP_VAR_FUNCTION(5, "sd",      "d6",       V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(7, "i2c3",    "sck",      V_88F6920_PLUS)), | ||||
| 	MPP_MODE(53, | ||||
| 		 MPP_VAR_FUNCTION(0, "gpio",    NULL,       V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(1, "sata1",   "present",  V_88F6928), | ||||
| 		 MPP_VAR_FUNCTION(2, "sata0",   "present",  V_88F6928), | ||||
| 		 MPP_VAR_FUNCTION(3, "tdm",     "rstn",     V_88F6928), | ||||
| 		 MPP_VAR_FUNCTION(4, "audio",   "bclk",     V_88F6928), | ||||
| 		 MPP_VAR_FUNCTION(5, "sd",      "d7",       V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(7, "i2c3",    "sda",      V_88F6920_PLUS)), | ||||
| 	MPP_MODE(54, | ||||
| 		 MPP_VAR_FUNCTION(0, "gpio",    NULL,       V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(1, "sata0",   "present",  V_88F6928), | ||||
| 		 MPP_VAR_FUNCTION(2, "sata1",   "present",  V_88F6928), | ||||
| 		 MPP_VAR_FUNCTION(3, "pcie0",   "rstout",   V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(5, "sd",      "d3",       V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(7, "ua3",     "txd",      V_88F6920_PLUS)), | ||||
| 	MPP_MODE(55, | ||||
| 		 MPP_VAR_FUNCTION(0, "gpio",    NULL,       V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(1, "ua1",     "cts",      V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(4, "spi1",    "cs1",      V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(5, "sd",      "d0",       V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(6, "ua1",     "rxd",      V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(7, "ua3",     "rxd",      V_88F6920_PLUS)), | ||||
| 	MPP_MODE(56, | ||||
| 		 MPP_VAR_FUNCTION(0, "gpio",    NULL,       V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(1, "ua1",     "rts",      V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(3, "m",       "decc",     V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(4, "spi1",    "mosi",     V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(6, "ua1",     "txd",      V_88F6920_PLUS)), | ||||
| 	MPP_MODE(57, | ||||
| 		 MPP_VAR_FUNCTION(0, "gpio",    NULL,       V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(4, "spi1",    "sck",      V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(5, "sd",      "clk",      V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(6, "ua1",     "txd",      V_88F6920_PLUS)), | ||||
| 	MPP_MODE(58, | ||||
| 		 MPP_VAR_FUNCTION(0, "gpio",    NULL,       V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(2, "i2c1",    "sck",      V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(3, "pcie2",   "clkreq",   V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(4, "spi1",    "miso",     V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(5, "sd",      "d1",       V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(6, "ua1",     "rxd",      V_88F6920_PLUS)), | ||||
| 	MPP_MODE(59, | ||||
| 		 MPP_VAR_FUNCTION(0, "gpio",    NULL,       V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(1, "pcie0",   "rstout",   V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(2, "i2c1",    "sda",      V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(4, "spi1",    "cs0",      V_88F6920_PLUS), | ||||
| 		 MPP_VAR_FUNCTION(5, "sd",      "d2",       V_88F6920_PLUS)), | ||||
| }; | ||||
|  | ||||
| static struct mvebu_pinctrl_soc_info armada_39x_pinctrl_info; | ||||
|  | ||||
| static const struct of_device_id armada_39x_pinctrl_of_match[] = { | ||||
| 	{ | ||||
| 		.compatible = "marvell,mv88f6920-pinctrl", | ||||
| 		.data       = (void *) V_88F6920, | ||||
| 	}, | ||||
| 	{ | ||||
| 		.compatible = "marvell,mv88f6928-pinctrl", | ||||
| 		.data       = (void *) V_88F6928, | ||||
| 	}, | ||||
| 	{ }, | ||||
| }; | ||||
|  | ||||
| static struct mvebu_mpp_ctrl armada_39x_mpp_controls[] = { | ||||
| 	MPP_FUNC_CTRL(0, 59, NULL, armada_39x_mpp_ctrl), | ||||
| }; | ||||
|  | ||||
| static struct pinctrl_gpio_range armada_39x_mpp_gpio_ranges[] = { | ||||
| 	MPP_GPIO_RANGE(0,   0,  0, 32), | ||||
| 	MPP_GPIO_RANGE(1,  32, 32, 27), | ||||
| }; | ||||
|  | ||||
| static int armada_39x_pinctrl_probe(struct platform_device *pdev) | ||||
| { | ||||
| 	struct mvebu_pinctrl_soc_info *soc = &armada_39x_pinctrl_info; | ||||
| 	const struct of_device_id *match = | ||||
| 		of_match_device(armada_39x_pinctrl_of_match, &pdev->dev); | ||||
| 	struct resource *res; | ||||
|  | ||||
| 	if (!match) | ||||
| 		return -ENODEV; | ||||
|  | ||||
| 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||||
| 	mpp_base = devm_ioremap_resource(&pdev->dev, res); | ||||
| 	if (IS_ERR(mpp_base)) | ||||
| 		return PTR_ERR(mpp_base); | ||||
|  | ||||
| 	soc->variant = (unsigned) match->data & 0xff; | ||||
| 	soc->controls = armada_39x_mpp_controls; | ||||
| 	soc->ncontrols = ARRAY_SIZE(armada_39x_mpp_controls); | ||||
| 	soc->gpioranges = armada_39x_mpp_gpio_ranges; | ||||
| 	soc->ngpioranges = ARRAY_SIZE(armada_39x_mpp_gpio_ranges); | ||||
| 	soc->modes = armada_39x_mpp_modes; | ||||
| 	soc->nmodes = armada_39x_mpp_controls[0].npins; | ||||
|  | ||||
| 	pdev->dev.platform_data = soc; | ||||
|  | ||||
| 	return mvebu_pinctrl_probe(pdev); | ||||
| } | ||||
|  | ||||
| static int armada_39x_pinctrl_remove(struct platform_device *pdev) | ||||
| { | ||||
| 	return mvebu_pinctrl_remove(pdev); | ||||
| } | ||||
|  | ||||
| static struct platform_driver armada_39x_pinctrl_driver = { | ||||
| 	.driver = { | ||||
| 		.name = "armada-39x-pinctrl", | ||||
| 		.of_match_table = of_match_ptr(armada_39x_pinctrl_of_match), | ||||
| 	}, | ||||
| 	.probe = armada_39x_pinctrl_probe, | ||||
| 	.remove = armada_39x_pinctrl_remove, | ||||
| }; | ||||
|  | ||||
| module_platform_driver(armada_39x_pinctrl_driver); | ||||
|  | ||||
| MODULE_AUTHOR("Thomas Petazzoni <thomas.petazzoni@free-electrons.com>"); | ||||
| MODULE_DESCRIPTION("Marvell Armada 39x pinctrl driver"); | ||||
| MODULE_LICENSE("GPL v2"); | ||||
| @@ -34,6 +34,7 @@ | ||||
| #include "pinctrl-mvebu.h" | ||||
|  | ||||
| static void __iomem *mpp_base; | ||||
| static u32 *mpp_saved_regs; | ||||
|  | ||||
| static int armada_xp_mpp_ctrl_get(unsigned pid, unsigned long *config) | ||||
| { | ||||
| @@ -361,7 +362,7 @@ static struct mvebu_mpp_mode armada_xp_mpp_modes[] = { | ||||
|  | ||||
| static struct mvebu_pinctrl_soc_info armada_xp_pinctrl_info; | ||||
|  | ||||
| static struct of_device_id armada_xp_pinctrl_of_match[] = { | ||||
| static const struct of_device_id armada_xp_pinctrl_of_match[] = { | ||||
| 	{ | ||||
| 		.compatible = "marvell,mv78230-pinctrl", | ||||
| 		.data       = (void *) V_MV78230, | ||||
| @@ -406,12 +407,42 @@ static struct pinctrl_gpio_range mv78460_mpp_gpio_ranges[] = { | ||||
| 	MPP_GPIO_RANGE(2,  64, 64,  3), | ||||
| }; | ||||
|  | ||||
| static int armada_xp_pinctrl_suspend(struct platform_device *pdev, | ||||
| 				     pm_message_t state) | ||||
| { | ||||
| 	struct mvebu_pinctrl_soc_info *soc = | ||||
| 		platform_get_drvdata(pdev); | ||||
| 	int i, nregs; | ||||
|  | ||||
| 	nregs = DIV_ROUND_UP(soc->nmodes, MVEBU_MPPS_PER_REG); | ||||
|  | ||||
| 	for (i = 0; i < nregs; i++) | ||||
| 		mpp_saved_regs[i] = readl(mpp_base + i * 4); | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int armada_xp_pinctrl_resume(struct platform_device *pdev) | ||||
| { | ||||
| 	struct mvebu_pinctrl_soc_info *soc = | ||||
| 		platform_get_drvdata(pdev); | ||||
| 	int i, nregs; | ||||
|  | ||||
| 	nregs = DIV_ROUND_UP(soc->nmodes, MVEBU_MPPS_PER_REG); | ||||
|  | ||||
| 	for (i = 0; i < nregs; i++) | ||||
| 		writel(mpp_saved_regs[i], mpp_base + i * 4); | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int armada_xp_pinctrl_probe(struct platform_device *pdev) | ||||
| { | ||||
| 	struct mvebu_pinctrl_soc_info *soc = &armada_xp_pinctrl_info; | ||||
| 	const struct of_device_id *match = | ||||
| 		of_match_device(armada_xp_pinctrl_of_match, &pdev->dev); | ||||
| 	struct resource *res; | ||||
| 	int nregs; | ||||
|  | ||||
| 	if (!match) | ||||
| 		return -ENODEV; | ||||
| @@ -459,6 +490,13 @@ static int armada_xp_pinctrl_probe(struct platform_device *pdev) | ||||
| 		break; | ||||
| 	} | ||||
|  | ||||
| 	nregs = DIV_ROUND_UP(soc->nmodes, MVEBU_MPPS_PER_REG); | ||||
|  | ||||
| 	mpp_saved_regs = devm_kmalloc(&pdev->dev, nregs * sizeof(u32), | ||||
| 				      GFP_KERNEL); | ||||
| 	if (!mpp_saved_regs) | ||||
| 		return -ENOMEM; | ||||
|  | ||||
| 	pdev->dev.platform_data = soc; | ||||
|  | ||||
| 	return mvebu_pinctrl_probe(pdev); | ||||
| @@ -476,6 +514,8 @@ static struct platform_driver armada_xp_pinctrl_driver = { | ||||
| 	}, | ||||
| 	.probe = armada_xp_pinctrl_probe, | ||||
| 	.remove = armada_xp_pinctrl_remove, | ||||
| 	.suspend = armada_xp_pinctrl_suspend, | ||||
| 	.resume = armada_xp_pinctrl_resume, | ||||
| }; | ||||
|  | ||||
| module_platform_driver(armada_xp_pinctrl_driver); | ||||
|   | ||||
| @@ -456,7 +456,7 @@ static struct mvebu_pinctrl_soc_info mv98dx4122_info = { | ||||
| 	.ngpioranges = ARRAY_SIZE(mv88f628x_gpio_ranges), | ||||
| }; | ||||
|  | ||||
| static struct of_device_id kirkwood_pinctrl_of_match[] = { | ||||
| static const struct of_device_id kirkwood_pinctrl_of_match[] = { | ||||
| 	{ .compatible = "marvell,88f6180-pinctrl", .data = &mv88f6180_info }, | ||||
| 	{ .compatible = "marvell,88f6190-pinctrl", .data = &mv88f6190_info }, | ||||
| 	{ .compatible = "marvell,88f6192-pinctrl", .data = &mv88f6192_info }, | ||||
|   | ||||
| @@ -211,7 +211,7 @@ static struct mvebu_pinctrl_soc_info mv88f5281_info = { | ||||
|  * There are multiple variants of the Orion SoCs, but in terms of pin | ||||
|  * muxing, they are identical. | ||||
|  */ | ||||
| static struct of_device_id orion_pinctrl_of_match[] = { | ||||
| static const struct of_device_id orion_pinctrl_of_match[] = { | ||||
| 	{ .compatible = "marvell,88f5181l-pinctrl", .data = &mv88f5181l_info }, | ||||
| 	{ .compatible = "marvell,88f5182-pinctrl", .data = &mv88f5182_info }, | ||||
| 	{ .compatible = "marvell,88f5281-pinctrl", .data = &mv88f5281_info }, | ||||
|   | ||||
| @@ -283,23 +283,40 @@ int pinconf_generic_dt_subnode_to_map(struct pinctrl_dev *pctldev, | ||||
| 	struct device *dev = pctldev->dev; | ||||
| 	unsigned long *configs = NULL; | ||||
| 	unsigned num_configs = 0; | ||||
| 	unsigned reserve; | ||||
| 	unsigned reserve, strings_count; | ||||
| 	struct property *prop; | ||||
| 	const char *group; | ||||
| 	const char *subnode_target_type = "pins"; | ||||
|  | ||||
| 	ret = of_property_count_strings(np, "pins"); | ||||
| 	if (ret < 0) { | ||||
| 		ret = of_property_count_strings(np, "groups"); | ||||
| 		if (ret < 0) | ||||
| 			/* skip this node; may contain config child nodes */ | ||||
| 			return 0; | ||||
| 		if (type == PIN_MAP_TYPE_INVALID) | ||||
| 			type = PIN_MAP_TYPE_CONFIGS_GROUP; | ||||
| 		subnode_target_type = "groups"; | ||||
| 	} else { | ||||
| 		if (type == PIN_MAP_TYPE_INVALID) | ||||
| 			type = PIN_MAP_TYPE_CONFIGS_PIN; | ||||
| 	} | ||||
| 	strings_count = ret; | ||||
|  | ||||
| 	ret = of_property_read_string(np, "function", &function); | ||||
| 	if (ret < 0) { | ||||
| 		/* EINVAL=missing, which is fine since it's optional */ | ||||
| 		if (ret != -EINVAL) | ||||
| 			dev_err(dev, "could not parse property function\n"); | ||||
| 			dev_err(dev, "%s: could not parse property function\n", | ||||
| 				of_node_full_name(np)); | ||||
| 		function = NULL; | ||||
| 	} | ||||
|  | ||||
| 	ret = pinconf_generic_parse_dt_config(np, pctldev, &configs, | ||||
| 					      &num_configs); | ||||
| 	if (ret < 0) { | ||||
| 		dev_err(dev, "could not parse node property\n"); | ||||
| 		dev_err(dev, "%s: could not parse node property\n", | ||||
| 			of_node_full_name(np)); | ||||
| 		return ret; | ||||
| 	} | ||||
|  | ||||
| @@ -309,21 +326,7 @@ int pinconf_generic_dt_subnode_to_map(struct pinctrl_dev *pctldev, | ||||
| 	if (num_configs) | ||||
| 		reserve++; | ||||
|  | ||||
| 	ret = of_property_count_strings(np, "pins"); | ||||
| 	if (ret < 0) { | ||||
| 		ret = of_property_count_strings(np, "groups"); | ||||
| 		if (ret < 0) { | ||||
| 			dev_err(dev, "could not parse property pins/groups\n"); | ||||
| 			goto exit; | ||||
| 		} | ||||
| 		if (type == PIN_MAP_TYPE_INVALID) | ||||
| 			type = PIN_MAP_TYPE_CONFIGS_GROUP; | ||||
| 		subnode_target_type = "groups"; | ||||
| 	} else { | ||||
| 		if (type == PIN_MAP_TYPE_INVALID) | ||||
| 			type = PIN_MAP_TYPE_CONFIGS_PIN; | ||||
| 	} | ||||
| 	reserve *= ret; | ||||
| 	reserve *= strings_count; | ||||
|  | ||||
| 	ret = pinctrl_utils_reserve_map(pctldev, map, reserved_maps, | ||||
| 			num_maps, reserve); | ||||
| @@ -367,15 +370,22 @@ int pinconf_generic_dt_node_to_map(struct pinctrl_dev *pctldev, | ||||
| 	*map = NULL; | ||||
| 	*num_maps = 0; | ||||
|  | ||||
| 	ret = pinconf_generic_dt_subnode_to_map(pctldev, np_config, map, | ||||
| 						&reserved_maps, num_maps, type); | ||||
| 	if (ret < 0) | ||||
| 		goto exit; | ||||
|  | ||||
| 	for_each_child_of_node(np_config, np) { | ||||
| 		ret = pinconf_generic_dt_subnode_to_map(pctldev, np, map, | ||||
| 					&reserved_maps, num_maps, type); | ||||
| 		if (ret < 0) { | ||||
| 			pinctrl_utils_dt_free_map(pctldev, *map, *num_maps); | ||||
| 			return ret; | ||||
| 		} | ||||
| 		if (ret < 0) | ||||
| 			goto exit; | ||||
| 	} | ||||
| 	return 0; | ||||
|  | ||||
| exit: | ||||
| 	pinctrl_utils_dt_free_map(pctldev, *map, *num_maps); | ||||
| 	return ret; | ||||
| } | ||||
| EXPORT_SYMBOL_GPL(pinconf_generic_dt_node_to_map); | ||||
|  | ||||
|   | ||||
							
								
								
									
										869
									
								
								drivers/pinctrl/pinctrl-amd.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										869
									
								
								drivers/pinctrl/pinctrl-amd.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,869 @@ | ||||
| /* | ||||
|  * GPIO driver for AMD | ||||
|  * | ||||
|  * Copyright (c) 2014,2015 AMD Corporation. | ||||
|  * Authors: Ken Xue <Ken.Xue@amd.com> | ||||
|  *      Wu, Jeff <Jeff.Wu@amd.com> | ||||
|  * | ||||
|  * 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. | ||||
|  */ | ||||
|  | ||||
| #include <linux/err.h> | ||||
| #include <linux/bug.h> | ||||
| #include <linux/kernel.h> | ||||
| #include <linux/module.h> | ||||
| #include <linux/spinlock.h> | ||||
| #include <linux/compiler.h> | ||||
| #include <linux/types.h> | ||||
| #include <linux/errno.h> | ||||
| #include <linux/log2.h> | ||||
| #include <linux/io.h> | ||||
| #include <linux/gpio.h> | ||||
| #include <linux/slab.h> | ||||
| #include <linux/platform_device.h> | ||||
| #include <linux/mutex.h> | ||||
| #include <linux/acpi.h> | ||||
| #include <linux/seq_file.h> | ||||
| #include <linux/interrupt.h> | ||||
| #include <linux/list.h> | ||||
| #include <linux/bitops.h> | ||||
| #include <linux/pinctrl/pinconf.h> | ||||
| #include <linux/pinctrl/pinconf-generic.h> | ||||
|  | ||||
| #include "pinctrl-utils.h" | ||||
| #include "pinctrl-amd.h" | ||||
|  | ||||
| static inline struct amd_gpio *to_amd_gpio(struct gpio_chip *gc) | ||||
| { | ||||
| 	return container_of(gc, struct amd_gpio, gc); | ||||
| } | ||||
|  | ||||
| static int amd_gpio_direction_input(struct gpio_chip *gc, unsigned offset) | ||||
| { | ||||
| 	unsigned long flags; | ||||
| 	u32 pin_reg; | ||||
| 	struct amd_gpio *gpio_dev = to_amd_gpio(gc); | ||||
|  | ||||
| 	spin_lock_irqsave(&gpio_dev->lock, flags); | ||||
| 	pin_reg = readl(gpio_dev->base + offset * 4); | ||||
| 	/* | ||||
| 	 * Suppose BIOS or Bootloader sets specific debounce for the | ||||
| 	 * GPIO. if not, set debounce to be  2.75ms and remove glitch. | ||||
| 	*/ | ||||
| 	if ((pin_reg & DB_TMR_OUT_MASK) == 0) { | ||||
| 		pin_reg |= 0xf; | ||||
| 		pin_reg |= BIT(DB_TMR_OUT_UNIT_OFF); | ||||
| 		pin_reg |= DB_TYPE_REMOVE_GLITCH << DB_CNTRL_OFF; | ||||
| 		pin_reg &= ~BIT(DB_TMR_LARGE_OFF); | ||||
| 	} | ||||
|  | ||||
| 	pin_reg &= ~BIT(OUTPUT_ENABLE_OFF); | ||||
| 	writel(pin_reg, gpio_dev->base + offset * 4); | ||||
| 	spin_unlock_irqrestore(&gpio_dev->lock, flags); | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int amd_gpio_direction_output(struct gpio_chip *gc, unsigned offset, | ||||
| 		int value) | ||||
| { | ||||
| 	u32 pin_reg; | ||||
| 	unsigned long flags; | ||||
| 	struct amd_gpio *gpio_dev = to_amd_gpio(gc); | ||||
|  | ||||
| 	spin_lock_irqsave(&gpio_dev->lock, flags); | ||||
| 	pin_reg = readl(gpio_dev->base + offset * 4); | ||||
| 	pin_reg |= BIT(OUTPUT_ENABLE_OFF); | ||||
| 	if (value) | ||||
| 		pin_reg |= BIT(OUTPUT_VALUE_OFF); | ||||
| 	else | ||||
| 		pin_reg &= ~BIT(OUTPUT_VALUE_OFF); | ||||
| 	writel(pin_reg, gpio_dev->base + offset * 4); | ||||
| 	spin_unlock_irqrestore(&gpio_dev->lock, flags); | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int amd_gpio_get_value(struct gpio_chip *gc, unsigned offset) | ||||
| { | ||||
| 	u32 pin_reg; | ||||
| 	unsigned long flags; | ||||
| 	struct amd_gpio *gpio_dev = to_amd_gpio(gc); | ||||
|  | ||||
| 	spin_lock_irqsave(&gpio_dev->lock, flags); | ||||
| 	pin_reg = readl(gpio_dev->base + offset * 4); | ||||
| 	spin_unlock_irqrestore(&gpio_dev->lock, flags); | ||||
|  | ||||
| 	return !!(pin_reg & BIT(PIN_STS_OFF)); | ||||
| } | ||||
|  | ||||
| static void amd_gpio_set_value(struct gpio_chip *gc, unsigned offset, int value) | ||||
| { | ||||
| 	u32 pin_reg; | ||||
| 	unsigned long flags; | ||||
| 	struct amd_gpio *gpio_dev = to_amd_gpio(gc); | ||||
|  | ||||
| 	spin_lock_irqsave(&gpio_dev->lock, flags); | ||||
| 	pin_reg = readl(gpio_dev->base + offset * 4); | ||||
| 	if (value) | ||||
| 		pin_reg |= BIT(OUTPUT_VALUE_OFF); | ||||
| 	else | ||||
| 		pin_reg &= ~BIT(OUTPUT_VALUE_OFF); | ||||
| 	writel(pin_reg, gpio_dev->base + offset * 4); | ||||
| 	spin_unlock_irqrestore(&gpio_dev->lock, flags); | ||||
| } | ||||
|  | ||||
| static int amd_gpio_set_debounce(struct gpio_chip *gc, unsigned offset, | ||||
| 		unsigned debounce) | ||||
| { | ||||
| 	u32 time; | ||||
| 	u32 pin_reg; | ||||
| 	int ret = 0; | ||||
| 	unsigned long flags; | ||||
| 	struct amd_gpio *gpio_dev = to_amd_gpio(gc); | ||||
|  | ||||
| 	spin_lock_irqsave(&gpio_dev->lock, flags); | ||||
| 	pin_reg = readl(gpio_dev->base + offset * 4); | ||||
|  | ||||
| 	if (debounce) { | ||||
| 		pin_reg |= DB_TYPE_REMOVE_GLITCH << DB_CNTRL_OFF; | ||||
| 		pin_reg &= ~DB_TMR_OUT_MASK; | ||||
| 		/* | ||||
| 		Debounce	Debounce	Timer	Max | ||||
| 		TmrLarge	TmrOutUnit	Unit	Debounce | ||||
| 							Time | ||||
| 		0	0	61 usec (2 RtcClk)	976 usec | ||||
| 		0	1	244 usec (8 RtcClk)	3.9 msec | ||||
| 		1	0	15.6 msec (512 RtcClk)	250 msec | ||||
| 		1	1	62.5 msec (2048 RtcClk)	1 sec | ||||
| 		*/ | ||||
|  | ||||
| 		if (debounce < 61) { | ||||
| 			pin_reg |= 1; | ||||
| 			pin_reg &= ~BIT(DB_TMR_OUT_UNIT_OFF); | ||||
| 			pin_reg &= ~BIT(DB_TMR_LARGE_OFF); | ||||
| 		} else if (debounce < 976) { | ||||
| 			time = debounce / 61; | ||||
| 			pin_reg |= time & DB_TMR_OUT_MASK; | ||||
| 			pin_reg &= ~BIT(DB_TMR_OUT_UNIT_OFF); | ||||
| 			pin_reg &= ~BIT(DB_TMR_LARGE_OFF); | ||||
| 		} else if (debounce < 3900) { | ||||
| 			time = debounce / 244; | ||||
| 			pin_reg |= time & DB_TMR_OUT_MASK; | ||||
| 			pin_reg |= BIT(DB_TMR_OUT_UNIT_OFF); | ||||
| 			pin_reg &= ~BIT(DB_TMR_LARGE_OFF); | ||||
| 		} else if (debounce < 250000) { | ||||
| 			time = debounce / 15600; | ||||
| 			pin_reg |= time & DB_TMR_OUT_MASK; | ||||
| 			pin_reg &= ~BIT(DB_TMR_OUT_UNIT_OFF); | ||||
| 			pin_reg |= BIT(DB_TMR_LARGE_OFF); | ||||
| 		} else if (debounce < 1000000) { | ||||
| 			time = debounce / 62500; | ||||
| 			pin_reg |= time & DB_TMR_OUT_MASK; | ||||
| 			pin_reg |= BIT(DB_TMR_OUT_UNIT_OFF); | ||||
| 			pin_reg |= BIT(DB_TMR_LARGE_OFF); | ||||
| 		} else { | ||||
| 			pin_reg &= ~DB_CNTRl_MASK; | ||||
| 			ret = -EINVAL; | ||||
| 		} | ||||
| 	} else { | ||||
| 		pin_reg &= ~BIT(DB_TMR_OUT_UNIT_OFF); | ||||
| 		pin_reg &= ~BIT(DB_TMR_LARGE_OFF); | ||||
| 		pin_reg &= ~DB_TMR_OUT_MASK; | ||||
| 		pin_reg &= ~DB_CNTRl_MASK; | ||||
| 	} | ||||
| 	writel(pin_reg, gpio_dev->base + offset * 4); | ||||
| 	spin_unlock_irqrestore(&gpio_dev->lock, flags); | ||||
|  | ||||
| 	return ret; | ||||
| } | ||||
|  | ||||
| #ifdef CONFIG_DEBUG_FS | ||||
| static void amd_gpio_dbg_show(struct seq_file *s, struct gpio_chip *gc) | ||||
| { | ||||
| 	u32 pin_reg; | ||||
| 	unsigned long flags; | ||||
| 	unsigned int bank, i, pin_num; | ||||
| 	struct amd_gpio *gpio_dev = to_amd_gpio(gc); | ||||
|  | ||||
| 	char *level_trig; | ||||
| 	char *active_level; | ||||
| 	char *interrupt_enable; | ||||
| 	char *interrupt_mask; | ||||
| 	char *wake_cntrl0; | ||||
| 	char *wake_cntrl1; | ||||
| 	char *wake_cntrl2; | ||||
| 	char *pin_sts; | ||||
| 	char *pull_up_sel; | ||||
| 	char *pull_up_enable; | ||||
| 	char *pull_down_enable; | ||||
| 	char *output_value; | ||||
| 	char *output_enable; | ||||
|  | ||||
| 	for (bank = 0; bank < AMD_GPIO_TOTAL_BANKS; bank++) { | ||||
| 		seq_printf(s, "GPIO bank%d\t", bank); | ||||
|  | ||||
| 		switch (bank) { | ||||
| 		case 0: | ||||
| 			i = 0; | ||||
| 			pin_num = AMD_GPIO_PINS_BANK0; | ||||
| 			break; | ||||
| 		case 1: | ||||
| 			i = 64; | ||||
| 			pin_num = AMD_GPIO_PINS_BANK1 + i; | ||||
| 			break; | ||||
| 		case 2: | ||||
| 			i = 128; | ||||
| 			pin_num = AMD_GPIO_PINS_BANK2 + i; | ||||
| 			break; | ||||
| 		} | ||||
|  | ||||
| 		for (; i < pin_num; i++) { | ||||
| 			seq_printf(s, "pin%d\t", i); | ||||
| 			spin_lock_irqsave(&gpio_dev->lock, flags); | ||||
| 			pin_reg = readl(gpio_dev->base + i * 4); | ||||
| 			spin_unlock_irqrestore(&gpio_dev->lock, flags); | ||||
|  | ||||
| 			if (pin_reg & BIT(INTERRUPT_ENABLE_OFF)) { | ||||
| 				interrupt_enable = "interrupt is enabled|"; | ||||
|  | ||||
| 				if (!(pin_reg & BIT(ACTIVE_LEVEL_OFF)) | ||||
| 				&& !(pin_reg & BIT(ACTIVE_LEVEL_OFF+1))) | ||||
| 					active_level = "Active low|"; | ||||
| 				else if (pin_reg & BIT(ACTIVE_LEVEL_OFF) | ||||
| 				&& !(pin_reg & BIT(ACTIVE_LEVEL_OFF+1))) | ||||
| 					active_level = "Active high|"; | ||||
| 				else if (!(pin_reg & BIT(ACTIVE_LEVEL_OFF)) | ||||
| 					&& pin_reg & BIT(ACTIVE_LEVEL_OFF+1)) | ||||
| 					active_level = "Active on both|"; | ||||
| 				else | ||||
| 					active_level = "Unknow Active level|"; | ||||
|  | ||||
| 				if (pin_reg & BIT(LEVEL_TRIG_OFF)) | ||||
| 					level_trig = "Level trigger|"; | ||||
| 				else | ||||
| 					level_trig = "Edge trigger|"; | ||||
|  | ||||
| 			} else { | ||||
| 				interrupt_enable = | ||||
| 					"interrupt is disabled|"; | ||||
| 				active_level = " "; | ||||
| 				level_trig = " "; | ||||
| 			} | ||||
|  | ||||
| 			if (pin_reg & BIT(INTERRUPT_MASK_OFF)) | ||||
| 				interrupt_mask = | ||||
| 					"interrupt is unmasked|"; | ||||
| 			else | ||||
| 				interrupt_mask = | ||||
| 					"interrupt is masked|"; | ||||
|  | ||||
| 			if (pin_reg & BIT(WAKE_CNTRL_OFF)) | ||||
| 				wake_cntrl0 = "enable wakeup in S0i3 state|"; | ||||
| 			else | ||||
| 				wake_cntrl0 = "disable wakeup in S0i3 state|"; | ||||
|  | ||||
| 			if (pin_reg & BIT(WAKE_CNTRL_OFF)) | ||||
| 				wake_cntrl1 = "enable wakeup in S3 state|"; | ||||
| 			else | ||||
| 				wake_cntrl1 = "disable wakeup in S3 state|"; | ||||
|  | ||||
| 			if (pin_reg & BIT(WAKE_CNTRL_OFF)) | ||||
| 				wake_cntrl2 = "enable wakeup in S4/S5 state|"; | ||||
| 			else | ||||
| 				wake_cntrl2 = "disable wakeup in S4/S5 state|"; | ||||
|  | ||||
| 			if (pin_reg & BIT(PULL_UP_ENABLE_OFF)) { | ||||
| 				pull_up_enable = "pull-up is enabled|"; | ||||
| 				if (pin_reg & BIT(PULL_UP_SEL_OFF)) | ||||
| 					pull_up_sel = "8k pull-up|"; | ||||
| 				else | ||||
| 					pull_up_sel = "4k pull-up|"; | ||||
| 			} else { | ||||
| 				pull_up_enable = "pull-up is disabled|"; | ||||
| 				pull_up_sel = " "; | ||||
| 			} | ||||
|  | ||||
| 			if (pin_reg & BIT(PULL_DOWN_ENABLE_OFF)) | ||||
| 				pull_down_enable = "pull-down is enabled|"; | ||||
| 			else | ||||
| 				pull_down_enable = "Pull-down is disabled|"; | ||||
|  | ||||
| 			if (pin_reg & BIT(OUTPUT_ENABLE_OFF)) { | ||||
| 				pin_sts = " "; | ||||
| 				output_enable = "output is enabled|"; | ||||
| 				if (pin_reg & BIT(OUTPUT_VALUE_OFF)) | ||||
| 					output_value = "output is high|"; | ||||
| 				else | ||||
| 					output_value = "output is low|"; | ||||
| 			} else { | ||||
| 				output_enable = "output is disabled|"; | ||||
| 				output_value = " "; | ||||
|  | ||||
| 				if (pin_reg & BIT(PIN_STS_OFF)) | ||||
| 					pin_sts = "input is high|"; | ||||
| 				else | ||||
| 					pin_sts = "input is low|"; | ||||
| 			} | ||||
|  | ||||
| 			seq_printf(s, "%s %s %s %s %s %s\n" | ||||
| 				" %s %s %s %s %s %s %s 0x%x\n", | ||||
| 				level_trig, active_level, interrupt_enable, | ||||
| 				interrupt_mask, wake_cntrl0, wake_cntrl1, | ||||
| 				wake_cntrl2, pin_sts, pull_up_sel, | ||||
| 				pull_up_enable, pull_down_enable, | ||||
| 				output_value, output_enable, pin_reg); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| #else | ||||
| #define amd_gpio_dbg_show NULL | ||||
| #endif | ||||
|  | ||||
| static void amd_gpio_irq_enable(struct irq_data *d) | ||||
| { | ||||
| 	u32 pin_reg; | ||||
| 	unsigned long flags; | ||||
| 	struct gpio_chip *gc = irq_data_get_irq_chip_data(d); | ||||
| 	struct amd_gpio *gpio_dev = to_amd_gpio(gc); | ||||
|  | ||||
| 	spin_lock_irqsave(&gpio_dev->lock, flags); | ||||
| 	pin_reg = readl(gpio_dev->base + (d->hwirq)*4); | ||||
| 	/* | ||||
| 		Suppose BIOS or Bootloader sets specific debounce for the | ||||
| 		GPIO. if not, set debounce to be  2.75ms. | ||||
| 	*/ | ||||
| 	if ((pin_reg & DB_TMR_OUT_MASK) == 0) { | ||||
| 		pin_reg |= 0xf; | ||||
| 		pin_reg |= BIT(DB_TMR_OUT_UNIT_OFF); | ||||
| 		pin_reg &= ~BIT(DB_TMR_LARGE_OFF); | ||||
| 	} | ||||
| 	pin_reg |= BIT(INTERRUPT_ENABLE_OFF); | ||||
| 	pin_reg |= BIT(INTERRUPT_MASK_OFF); | ||||
| 	writel(pin_reg, gpio_dev->base + (d->hwirq)*4); | ||||
| 	spin_unlock_irqrestore(&gpio_dev->lock, flags); | ||||
| } | ||||
|  | ||||
| static void amd_gpio_irq_disable(struct irq_data *d) | ||||
| { | ||||
| 	u32 pin_reg; | ||||
| 	unsigned long flags; | ||||
| 	struct gpio_chip *gc = irq_data_get_irq_chip_data(d); | ||||
| 	struct amd_gpio *gpio_dev = to_amd_gpio(gc); | ||||
|  | ||||
| 	spin_lock_irqsave(&gpio_dev->lock, flags); | ||||
| 	pin_reg = readl(gpio_dev->base + (d->hwirq)*4); | ||||
| 	pin_reg &= ~BIT(INTERRUPT_ENABLE_OFF); | ||||
| 	pin_reg &= ~BIT(INTERRUPT_MASK_OFF); | ||||
| 	writel(pin_reg, gpio_dev->base + (d->hwirq)*4); | ||||
| 	spin_unlock_irqrestore(&gpio_dev->lock, flags); | ||||
| } | ||||
|  | ||||
| static void amd_gpio_irq_mask(struct irq_data *d) | ||||
| { | ||||
| 	u32 pin_reg; | ||||
| 	unsigned long flags; | ||||
| 	struct gpio_chip *gc = irq_data_get_irq_chip_data(d); | ||||
| 	struct amd_gpio *gpio_dev = to_amd_gpio(gc); | ||||
|  | ||||
| 	spin_lock_irqsave(&gpio_dev->lock, flags); | ||||
| 	pin_reg = readl(gpio_dev->base + (d->hwirq)*4); | ||||
| 	pin_reg &= ~BIT(INTERRUPT_MASK_OFF); | ||||
| 	writel(pin_reg, gpio_dev->base + (d->hwirq)*4); | ||||
| 	spin_unlock_irqrestore(&gpio_dev->lock, flags); | ||||
| } | ||||
|  | ||||
| static void amd_gpio_irq_unmask(struct irq_data *d) | ||||
| { | ||||
| 	u32 pin_reg; | ||||
| 	unsigned long flags; | ||||
| 	struct gpio_chip *gc = irq_data_get_irq_chip_data(d); | ||||
| 	struct amd_gpio *gpio_dev = to_amd_gpio(gc); | ||||
|  | ||||
| 	spin_lock_irqsave(&gpio_dev->lock, flags); | ||||
| 	pin_reg = readl(gpio_dev->base + (d->hwirq)*4); | ||||
| 	pin_reg |= BIT(INTERRUPT_MASK_OFF); | ||||
| 	writel(pin_reg, gpio_dev->base + (d->hwirq)*4); | ||||
| 	spin_unlock_irqrestore(&gpio_dev->lock, flags); | ||||
| } | ||||
|  | ||||
| static void amd_gpio_irq_eoi(struct irq_data *d) | ||||
| { | ||||
| 	u32 reg; | ||||
| 	unsigned long flags; | ||||
| 	struct gpio_chip *gc = irq_data_get_irq_chip_data(d); | ||||
| 	struct amd_gpio *gpio_dev = to_amd_gpio(gc); | ||||
|  | ||||
| 	spin_lock_irqsave(&gpio_dev->lock, flags); | ||||
| 	reg = readl(gpio_dev->base + WAKE_INT_MASTER_REG); | ||||
| 	reg |= EOI_MASK; | ||||
| 	writel(reg, gpio_dev->base + WAKE_INT_MASTER_REG); | ||||
| 	spin_unlock_irqrestore(&gpio_dev->lock, flags); | ||||
| } | ||||
|  | ||||
| static int amd_gpio_irq_set_type(struct irq_data *d, unsigned int type) | ||||
| { | ||||
| 	int ret = 0; | ||||
| 	u32 pin_reg; | ||||
| 	unsigned long flags; | ||||
| 	struct gpio_chip *gc = irq_data_get_irq_chip_data(d); | ||||
| 	struct amd_gpio *gpio_dev = to_amd_gpio(gc); | ||||
|  | ||||
| 	spin_lock_irqsave(&gpio_dev->lock, flags); | ||||
| 	pin_reg = readl(gpio_dev->base + (d->hwirq)*4); | ||||
|  | ||||
| 	switch (type & IRQ_TYPE_SENSE_MASK) { | ||||
| 	case IRQ_TYPE_EDGE_RISING: | ||||
| 		pin_reg &= ~BIT(LEVEL_TRIG_OFF); | ||||
| 		pin_reg &= ~(ACTIVE_LEVEL_MASK << ACTIVE_LEVEL_OFF); | ||||
| 		pin_reg |= ACTIVE_HIGH << ACTIVE_LEVEL_OFF; | ||||
| 		pin_reg |= DB_TYPE_REMOVE_GLITCH << DB_CNTRL_OFF; | ||||
| 		__irq_set_handler_locked(d->irq, handle_edge_irq); | ||||
| 		break; | ||||
|  | ||||
| 	case IRQ_TYPE_EDGE_FALLING: | ||||
| 		pin_reg &= ~BIT(LEVEL_TRIG_OFF); | ||||
| 		pin_reg &= ~(ACTIVE_LEVEL_MASK << ACTIVE_LEVEL_OFF); | ||||
| 		pin_reg |= ACTIVE_LOW << ACTIVE_LEVEL_OFF; | ||||
| 		pin_reg |= DB_TYPE_REMOVE_GLITCH << DB_CNTRL_OFF; | ||||
| 		__irq_set_handler_locked(d->irq, handle_edge_irq); | ||||
| 		break; | ||||
|  | ||||
| 	case IRQ_TYPE_EDGE_BOTH: | ||||
| 		pin_reg &= ~BIT(LEVEL_TRIG_OFF); | ||||
| 		pin_reg &= ~(ACTIVE_LEVEL_MASK << ACTIVE_LEVEL_OFF); | ||||
| 		pin_reg |= BOTH_EADGE << ACTIVE_LEVEL_OFF; | ||||
| 		pin_reg |= DB_TYPE_REMOVE_GLITCH << DB_CNTRL_OFF; | ||||
| 		__irq_set_handler_locked(d->irq, handle_edge_irq); | ||||
| 		break; | ||||
|  | ||||
| 	case IRQ_TYPE_LEVEL_HIGH: | ||||
| 		pin_reg |= LEVEL_TRIGGER << LEVEL_TRIG_OFF; | ||||
| 		pin_reg &= ~(ACTIVE_LEVEL_MASK << ACTIVE_LEVEL_OFF); | ||||
| 		pin_reg |= ACTIVE_HIGH << ACTIVE_LEVEL_OFF; | ||||
| 		pin_reg &= ~(DB_CNTRl_MASK << DB_CNTRL_OFF); | ||||
| 		pin_reg |= DB_TYPE_PRESERVE_LOW_GLITCH << DB_CNTRL_OFF; | ||||
| 		__irq_set_handler_locked(d->irq, handle_level_irq); | ||||
| 		break; | ||||
|  | ||||
| 	case IRQ_TYPE_LEVEL_LOW: | ||||
| 		pin_reg |= LEVEL_TRIGGER << LEVEL_TRIG_OFF; | ||||
| 		pin_reg &= ~(ACTIVE_LEVEL_MASK << ACTIVE_LEVEL_OFF); | ||||
| 		pin_reg |= ACTIVE_LOW << ACTIVE_LEVEL_OFF; | ||||
| 		pin_reg &= ~(DB_CNTRl_MASK << DB_CNTRL_OFF); | ||||
| 		pin_reg |= DB_TYPE_PRESERVE_HIGH_GLITCH << DB_CNTRL_OFF; | ||||
| 		__irq_set_handler_locked(d->irq, handle_level_irq); | ||||
| 		break; | ||||
|  | ||||
| 	case IRQ_TYPE_NONE: | ||||
| 		break; | ||||
|  | ||||
| 	default: | ||||
| 		dev_err(&gpio_dev->pdev->dev, "Invalid type value\n"); | ||||
| 		ret = -EINVAL; | ||||
| 	} | ||||
|  | ||||
| 	pin_reg |= CLR_INTR_STAT << INTERRUPT_STS_OFF; | ||||
| 	writel(pin_reg, gpio_dev->base + (d->hwirq)*4); | ||||
| 	spin_unlock_irqrestore(&gpio_dev->lock, flags); | ||||
|  | ||||
| 	return ret; | ||||
| } | ||||
|  | ||||
| static void amd_irq_ack(struct irq_data *d) | ||||
| { | ||||
| 	/* | ||||
| 	 * based on HW design,there is no need to ack HW | ||||
| 	 * before handle current irq. But this routine is | ||||
| 	 * necessary for handle_edge_irq | ||||
| 	*/ | ||||
| } | ||||
|  | ||||
| static struct irq_chip amd_gpio_irqchip = { | ||||
| 	.name         = "amd_gpio", | ||||
| 	.irq_ack      = amd_irq_ack, | ||||
| 	.irq_enable   = amd_gpio_irq_enable, | ||||
| 	.irq_disable  = amd_gpio_irq_disable, | ||||
| 	.irq_mask     = amd_gpio_irq_mask, | ||||
| 	.irq_unmask   = amd_gpio_irq_unmask, | ||||
| 	.irq_eoi      = amd_gpio_irq_eoi, | ||||
| 	.irq_set_type = amd_gpio_irq_set_type, | ||||
| }; | ||||
|  | ||||
| static void amd_gpio_irq_handler(unsigned int irq, struct irq_desc *desc) | ||||
| { | ||||
| 	u32 i; | ||||
| 	u32 off; | ||||
| 	u32 reg; | ||||
| 	u32 pin_reg; | ||||
| 	u64 reg64; | ||||
| 	int handled = 0; | ||||
| 	unsigned long flags; | ||||
| 	struct irq_chip *chip = irq_get_chip(irq); | ||||
| 	struct gpio_chip *gc = irq_desc_get_handler_data(desc); | ||||
| 	struct amd_gpio *gpio_dev = to_amd_gpio(gc); | ||||
|  | ||||
| 	chained_irq_enter(chip, desc); | ||||
| 	/*enable GPIO interrupt again*/ | ||||
| 	spin_lock_irqsave(&gpio_dev->lock, flags); | ||||
| 	reg = readl(gpio_dev->base + WAKE_INT_STATUS_REG1); | ||||
| 	reg64 = reg; | ||||
| 	reg64 = reg64 << 32; | ||||
|  | ||||
| 	reg = readl(gpio_dev->base + WAKE_INT_STATUS_REG0); | ||||
| 	reg64 |= reg; | ||||
| 	spin_unlock_irqrestore(&gpio_dev->lock, flags); | ||||
|  | ||||
| 	/* | ||||
| 	 * first 46 bits indicates interrupt status. | ||||
| 	 * one bit represents four interrupt sources. | ||||
| 	*/ | ||||
| 	for (off = 0; off < 46 ; off++) { | ||||
| 		if (reg64 & BIT(off)) { | ||||
| 			for (i = 0; i < 4; i++) { | ||||
| 				pin_reg = readl(gpio_dev->base + | ||||
| 						(off * 4 + i) * 4); | ||||
| 				if ((pin_reg & BIT(INTERRUPT_STS_OFF)) || | ||||
| 					(pin_reg & BIT(WAKE_STS_OFF))) { | ||||
| 					irq = irq_find_mapping(gc->irqdomain, | ||||
| 								off * 4 + i); | ||||
| 					generic_handle_irq(irq); | ||||
| 					writel(pin_reg, | ||||
| 						gpio_dev->base | ||||
| 						+ (off * 4 + i) * 4); | ||||
| 					handled++; | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if (handled == 0) | ||||
| 		handle_bad_irq(irq, desc); | ||||
|  | ||||
| 	spin_lock_irqsave(&gpio_dev->lock, flags); | ||||
| 	reg = readl(gpio_dev->base + WAKE_INT_MASTER_REG); | ||||
| 	reg |= EOI_MASK; | ||||
| 	writel(reg, gpio_dev->base + WAKE_INT_MASTER_REG); | ||||
| 	spin_unlock_irqrestore(&gpio_dev->lock, flags); | ||||
|  | ||||
| 	chained_irq_exit(chip, desc); | ||||
| } | ||||
|  | ||||
| static int amd_get_groups_count(struct pinctrl_dev *pctldev) | ||||
| { | ||||
| 	struct amd_gpio *gpio_dev = pinctrl_dev_get_drvdata(pctldev); | ||||
|  | ||||
| 	return gpio_dev->ngroups; | ||||
| } | ||||
|  | ||||
| static const char *amd_get_group_name(struct pinctrl_dev *pctldev, | ||||
| 				      unsigned group) | ||||
| { | ||||
| 	struct amd_gpio *gpio_dev = pinctrl_dev_get_drvdata(pctldev); | ||||
|  | ||||
| 	return gpio_dev->groups[group].name; | ||||
| } | ||||
|  | ||||
| static int amd_get_group_pins(struct pinctrl_dev *pctldev, | ||||
| 			      unsigned group, | ||||
| 			      const unsigned **pins, | ||||
| 			      unsigned *num_pins) | ||||
| { | ||||
| 	struct amd_gpio *gpio_dev = pinctrl_dev_get_drvdata(pctldev); | ||||
|  | ||||
| 	*pins = gpio_dev->groups[group].pins; | ||||
| 	*num_pins = gpio_dev->groups[group].npins; | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static const struct pinctrl_ops amd_pinctrl_ops = { | ||||
| 	.get_groups_count	= amd_get_groups_count, | ||||
| 	.get_group_name		= amd_get_group_name, | ||||
| 	.get_group_pins		= amd_get_group_pins, | ||||
| #ifdef CONFIG_OF | ||||
| 	.dt_node_to_map		= pinconf_generic_dt_node_to_map_group, | ||||
| 	.dt_free_map		= pinctrl_utils_dt_free_map, | ||||
| #endif | ||||
| }; | ||||
|  | ||||
| static int amd_pinconf_get(struct pinctrl_dev *pctldev, | ||||
| 			  unsigned int pin, | ||||
| 			  unsigned long *config) | ||||
| { | ||||
| 	u32 pin_reg; | ||||
| 	unsigned arg; | ||||
| 	unsigned long flags; | ||||
| 	struct amd_gpio *gpio_dev = pinctrl_dev_get_drvdata(pctldev); | ||||
| 	enum pin_config_param param = pinconf_to_config_param(*config); | ||||
|  | ||||
| 	spin_lock_irqsave(&gpio_dev->lock, flags); | ||||
| 	pin_reg = readl(gpio_dev->base + pin*4); | ||||
| 	spin_unlock_irqrestore(&gpio_dev->lock, flags); | ||||
| 	switch (param) { | ||||
| 	case PIN_CONFIG_INPUT_DEBOUNCE: | ||||
| 		arg = pin_reg & DB_TMR_OUT_MASK; | ||||
| 		break; | ||||
|  | ||||
| 	case PIN_CONFIG_BIAS_PULL_DOWN: | ||||
| 		arg = (pin_reg >> PULL_DOWN_ENABLE_OFF) & BIT(0); | ||||
| 		break; | ||||
|  | ||||
| 	case PIN_CONFIG_BIAS_PULL_UP: | ||||
| 		arg = (pin_reg >> PULL_UP_SEL_OFF) & (BIT(0) | BIT(1)); | ||||
| 		break; | ||||
|  | ||||
| 	case PIN_CONFIG_DRIVE_STRENGTH: | ||||
| 		arg = (pin_reg >> DRV_STRENGTH_SEL_OFF) & DRV_STRENGTH_SEL_MASK; | ||||
| 		break; | ||||
|  | ||||
| 	default: | ||||
| 		dev_err(&gpio_dev->pdev->dev, "Invalid config param %04x\n", | ||||
| 			param); | ||||
| 		return -ENOTSUPP; | ||||
| 	} | ||||
|  | ||||
| 	*config = pinconf_to_config_packed(param, arg); | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int amd_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin, | ||||
| 				unsigned long *configs, unsigned num_configs) | ||||
| { | ||||
| 	int i; | ||||
| 	u32 arg; | ||||
| 	int ret = 0; | ||||
| 	u32 pin_reg; | ||||
| 	unsigned long flags; | ||||
| 	enum pin_config_param param; | ||||
| 	struct amd_gpio *gpio_dev = pinctrl_dev_get_drvdata(pctldev); | ||||
|  | ||||
| 	spin_lock_irqsave(&gpio_dev->lock, flags); | ||||
| 	for (i = 0; i < num_configs; i++) { | ||||
| 		param = pinconf_to_config_param(configs[i]); | ||||
| 		arg = pinconf_to_config_argument(configs[i]); | ||||
| 		pin_reg = readl(gpio_dev->base + pin*4); | ||||
|  | ||||
| 		switch (param) { | ||||
| 		case PIN_CONFIG_INPUT_DEBOUNCE: | ||||
| 			pin_reg &= ~DB_TMR_OUT_MASK; | ||||
| 			pin_reg |= arg & DB_TMR_OUT_MASK; | ||||
| 			break; | ||||
|  | ||||
| 		case PIN_CONFIG_BIAS_PULL_DOWN: | ||||
| 			pin_reg &= ~BIT(PULL_DOWN_ENABLE_OFF); | ||||
| 			pin_reg |= (arg & BIT(0)) << PULL_DOWN_ENABLE_OFF; | ||||
| 			break; | ||||
|  | ||||
| 		case PIN_CONFIG_BIAS_PULL_UP: | ||||
| 			pin_reg &= ~BIT(PULL_UP_SEL_OFF); | ||||
| 			pin_reg |= (arg & BIT(0)) << PULL_UP_SEL_OFF; | ||||
| 			pin_reg &= ~BIT(PULL_UP_ENABLE_OFF); | ||||
| 			pin_reg |= ((arg>>1) & BIT(0)) << PULL_UP_ENABLE_OFF; | ||||
| 			break; | ||||
|  | ||||
| 		case PIN_CONFIG_DRIVE_STRENGTH: | ||||
| 			pin_reg &= ~(DRV_STRENGTH_SEL_MASK | ||||
| 					<< DRV_STRENGTH_SEL_OFF); | ||||
| 			pin_reg |= (arg & DRV_STRENGTH_SEL_MASK) | ||||
| 					<< DRV_STRENGTH_SEL_OFF; | ||||
| 			break; | ||||
|  | ||||
| 		default: | ||||
| 			dev_err(&gpio_dev->pdev->dev, | ||||
| 				"Invalid config param %04x\n", param); | ||||
| 			ret = -ENOTSUPP; | ||||
| 		} | ||||
|  | ||||
| 		writel(pin_reg, gpio_dev->base + pin*4); | ||||
| 	} | ||||
| 	spin_unlock_irqrestore(&gpio_dev->lock, flags); | ||||
|  | ||||
| 	return ret; | ||||
| } | ||||
|  | ||||
| static int amd_pinconf_group_get(struct pinctrl_dev *pctldev, | ||||
| 				unsigned int group, | ||||
| 				unsigned long *config) | ||||
| { | ||||
| 	const unsigned *pins; | ||||
| 	unsigned npins; | ||||
| 	int ret; | ||||
|  | ||||
| 	ret = amd_get_group_pins(pctldev, group, &pins, &npins); | ||||
| 	if (ret) | ||||
| 		return ret; | ||||
|  | ||||
| 	if (amd_pinconf_get(pctldev, pins[0], config)) | ||||
| 			return -ENOTSUPP; | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int amd_pinconf_group_set(struct pinctrl_dev *pctldev, | ||||
| 				unsigned group, unsigned long *configs, | ||||
| 				unsigned num_configs) | ||||
| { | ||||
| 	const unsigned *pins; | ||||
| 	unsigned npins; | ||||
| 	int i, ret; | ||||
|  | ||||
| 	ret = amd_get_group_pins(pctldev, group, &pins, &npins); | ||||
| 	if (ret) | ||||
| 		return ret; | ||||
| 	for (i = 0; i < npins; i++) { | ||||
| 		if (amd_pinconf_set(pctldev, pins[i], configs, num_configs)) | ||||
| 			return -ENOTSUPP; | ||||
| 	} | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static const struct pinconf_ops amd_pinconf_ops = { | ||||
| 	.pin_config_get		= amd_pinconf_get, | ||||
| 	.pin_config_set		= amd_pinconf_set, | ||||
| 	.pin_config_group_get = amd_pinconf_group_get, | ||||
| 	.pin_config_group_set = amd_pinconf_group_set, | ||||
| }; | ||||
|  | ||||
| static struct pinctrl_desc amd_pinctrl_desc = { | ||||
| 	.pins	= kerncz_pins, | ||||
| 	.npins = ARRAY_SIZE(kerncz_pins), | ||||
| 	.pctlops = &amd_pinctrl_ops, | ||||
| 	.confops = &amd_pinconf_ops, | ||||
| 	.owner = THIS_MODULE, | ||||
| }; | ||||
|  | ||||
| static int amd_gpio_probe(struct platform_device *pdev) | ||||
| { | ||||
| 	int ret = 0; | ||||
| 	int irq_base; | ||||
| 	struct resource *res; | ||||
| 	struct amd_gpio *gpio_dev; | ||||
|  | ||||
| 	gpio_dev = devm_kzalloc(&pdev->dev, | ||||
| 				sizeof(struct amd_gpio), GFP_KERNEL); | ||||
| 	if (!gpio_dev) | ||||
| 		return -ENOMEM; | ||||
|  | ||||
| 	spin_lock_init(&gpio_dev->lock); | ||||
|  | ||||
| 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||||
| 	if (!res) { | ||||
| 		dev_err(&pdev->dev, "Failed to get gpio io resource.\n"); | ||||
| 		return -EINVAL; | ||||
| 	} | ||||
|  | ||||
| 	gpio_dev->base = devm_ioremap_nocache(&pdev->dev, res->start, | ||||
| 						resource_size(res)); | ||||
| 	if (IS_ERR(gpio_dev->base)) | ||||
| 		return PTR_ERR(gpio_dev->base); | ||||
|  | ||||
| 	irq_base = platform_get_irq(pdev, 0); | ||||
| 	if (irq_base < 0) { | ||||
| 		dev_err(&pdev->dev, "Failed to get gpio IRQ.\n"); | ||||
| 		return -EINVAL; | ||||
| 	} | ||||
|  | ||||
| 	gpio_dev->pdev = pdev; | ||||
| 	gpio_dev->gc.direction_input	= amd_gpio_direction_input; | ||||
| 	gpio_dev->gc.direction_output	= amd_gpio_direction_output; | ||||
| 	gpio_dev->gc.get			= amd_gpio_get_value; | ||||
| 	gpio_dev->gc.set			= amd_gpio_set_value; | ||||
| 	gpio_dev->gc.set_debounce	= amd_gpio_set_debounce; | ||||
| 	gpio_dev->gc.dbg_show		= amd_gpio_dbg_show; | ||||
|  | ||||
| 	gpio_dev->gc.base			= 0; | ||||
| 	gpio_dev->gc.label			= pdev->name; | ||||
| 	gpio_dev->gc.owner			= THIS_MODULE; | ||||
| 	gpio_dev->gc.dev			= &pdev->dev; | ||||
| 	gpio_dev->gc.ngpio			= TOTAL_NUMBER_OF_PINS; | ||||
| #if defined(CONFIG_OF_GPIO) | ||||
| 	gpio_dev->gc.of_node			= pdev->dev.of_node; | ||||
| #endif | ||||
|  | ||||
| 	gpio_dev->groups = kerncz_groups; | ||||
| 	gpio_dev->ngroups = ARRAY_SIZE(kerncz_groups); | ||||
|  | ||||
| 	amd_pinctrl_desc.name = dev_name(&pdev->dev); | ||||
| 	gpio_dev->pctrl = pinctrl_register(&amd_pinctrl_desc, | ||||
| 					&pdev->dev, gpio_dev); | ||||
| 	if (!gpio_dev->pctrl) { | ||||
| 		dev_err(&pdev->dev, "Couldn't register pinctrl driver\n"); | ||||
| 		return -ENODEV; | ||||
| 	} | ||||
|  | ||||
| 	ret = gpiochip_add(&gpio_dev->gc); | ||||
| 	if (ret) | ||||
| 		goto out1; | ||||
|  | ||||
| 	ret = gpiochip_add_pin_range(&gpio_dev->gc, dev_name(&pdev->dev), | ||||
| 				0, 0, TOTAL_NUMBER_OF_PINS); | ||||
| 	if (ret) { | ||||
| 		dev_err(&pdev->dev, "Failed to add pin range\n"); | ||||
| 		goto out2; | ||||
| 	} | ||||
|  | ||||
| 	ret = gpiochip_irqchip_add(&gpio_dev->gc, | ||||
| 				&amd_gpio_irqchip, | ||||
| 				0, | ||||
| 				handle_simple_irq, | ||||
| 				IRQ_TYPE_NONE); | ||||
| 	if (ret) { | ||||
| 		dev_err(&pdev->dev, "could not add irqchip\n"); | ||||
| 		ret = -ENODEV; | ||||
| 		goto out2; | ||||
| 	} | ||||
|  | ||||
| 	gpiochip_set_chained_irqchip(&gpio_dev->gc, | ||||
| 				 &amd_gpio_irqchip, | ||||
| 				 irq_base, | ||||
| 				 amd_gpio_irq_handler); | ||||
|  | ||||
| 	platform_set_drvdata(pdev, gpio_dev); | ||||
|  | ||||
| 	dev_dbg(&pdev->dev, "amd gpio driver loaded\n"); | ||||
| 	return ret; | ||||
|  | ||||
| out2: | ||||
| 	gpiochip_remove(&gpio_dev->gc); | ||||
|  | ||||
| out1: | ||||
| 	pinctrl_unregister(gpio_dev->pctrl); | ||||
| 	return ret; | ||||
| } | ||||
|  | ||||
| static int amd_gpio_remove(struct platform_device *pdev) | ||||
| { | ||||
| 	struct amd_gpio *gpio_dev; | ||||
|  | ||||
| 	gpio_dev = platform_get_drvdata(pdev); | ||||
|  | ||||
| 	gpiochip_remove(&gpio_dev->gc); | ||||
| 	pinctrl_unregister(gpio_dev->pctrl); | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static const struct acpi_device_id amd_gpio_acpi_match[] = { | ||||
| 	{ "AMD0030", 0 }, | ||||
| 	{ }, | ||||
| }; | ||||
| MODULE_DEVICE_TABLE(acpi, amd_gpio_acpi_match); | ||||
|  | ||||
| static struct platform_driver amd_gpio_driver = { | ||||
| 	.driver		= { | ||||
| 		.name	= "amd_gpio", | ||||
| 		.owner	= THIS_MODULE, | ||||
| 		.acpi_match_table = ACPI_PTR(amd_gpio_acpi_match), | ||||
| 	}, | ||||
| 	.probe		= amd_gpio_probe, | ||||
| 	.remove		= amd_gpio_remove, | ||||
| }; | ||||
|  | ||||
| module_platform_driver(amd_gpio_driver); | ||||
|  | ||||
| MODULE_LICENSE("GPL v2"); | ||||
| MODULE_AUTHOR("Ken Xue <Ken.Xue@amd.com>, Jeff Wu <Jeff.Wu@amd.com>"); | ||||
| MODULE_DESCRIPTION("AMD GPIO pinctrl driver"); | ||||
							
								
								
									
										261
									
								
								drivers/pinctrl/pinctrl-amd.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										261
									
								
								drivers/pinctrl/pinctrl-amd.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,261 @@ | ||||
| /* | ||||
|  * GPIO driver for AMD | ||||
|  * | ||||
|  * Copyright (c) 2014,2015 Ken Xue <Ken.Xue@amd.com> | ||||
|  *		Jeff Wu <Jeff.Wu@amd.com> | ||||
|  * | ||||
|  * 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. | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| #ifndef _PINCTRL_AMD_H | ||||
| #define _PINCTRL_AMD_H | ||||
|  | ||||
| #define TOTAL_NUMBER_OF_PINS	192 | ||||
| #define AMD_GPIO_PINS_PER_BANK  64 | ||||
| #define AMD_GPIO_TOTAL_BANKS    3 | ||||
|  | ||||
| #define AMD_GPIO_PINS_BANK0     63 | ||||
| #define AMD_GPIO_PINS_BANK1     64 | ||||
| #define AMD_GPIO_PINS_BANK2     56 | ||||
|  | ||||
| #define WAKE_INT_MASTER_REG 0xfc | ||||
| #define EOI_MASK (1 << 29) | ||||
|  | ||||
| #define WAKE_INT_STATUS_REG0 0x2f8 | ||||
| #define WAKE_INT_STATUS_REG1 0x2fc | ||||
|  | ||||
| #define DB_TMR_OUT_OFF			0 | ||||
| #define DB_TMR_OUT_UNIT_OFF		4 | ||||
| #define DB_CNTRL_OFF			5 | ||||
| #define DB_TMR_LARGE_OFF		7 | ||||
| #define LEVEL_TRIG_OFF			8 | ||||
| #define ACTIVE_LEVEL_OFF		9 | ||||
| #define INTERRUPT_ENABLE_OFF		11 | ||||
| #define INTERRUPT_MASK_OFF		12 | ||||
| #define WAKE_CNTRL_OFF			13 | ||||
| #define PIN_STS_OFF			16 | ||||
| #define DRV_STRENGTH_SEL_OFF		17 | ||||
| #define PULL_UP_SEL_OFF			19 | ||||
| #define PULL_UP_ENABLE_OFF		20 | ||||
| #define PULL_DOWN_ENABLE_OFF		21 | ||||
| #define OUTPUT_VALUE_OFF		22 | ||||
| #define OUTPUT_ENABLE_OFF		23 | ||||
| #define SW_CNTRL_IN_OFF			24 | ||||
| #define SW_CNTRL_EN_OFF			25 | ||||
| #define INTERRUPT_STS_OFF		28 | ||||
| #define WAKE_STS_OFF			29 | ||||
|  | ||||
| #define DB_TMR_OUT_MASK	0xFUL | ||||
| #define DB_CNTRl_MASK	0x3UL | ||||
| #define ACTIVE_LEVEL_MASK	0x3UL | ||||
| #define DRV_STRENGTH_SEL_MASK	0x3UL | ||||
|  | ||||
| #define DB_TYPE_NO_DEBOUNCE               0x0UL | ||||
| #define DB_TYPE_PRESERVE_LOW_GLITCH       0x1UL | ||||
| #define DB_TYPE_PRESERVE_HIGH_GLITCH      0x2UL | ||||
| #define DB_TYPE_REMOVE_GLITCH             0x3UL | ||||
|  | ||||
| #define EDGE_TRAGGER	0x0UL | ||||
| #define LEVEL_TRIGGER	0x1UL | ||||
|  | ||||
| #define ACTIVE_HIGH	0x0UL | ||||
| #define ACTIVE_LOW	0x1UL | ||||
| #define BOTH_EADGE	0x2UL | ||||
|  | ||||
| #define ENABLE_INTERRUPT	0x1UL | ||||
| #define DISABLE_INTERRUPT	0x0UL | ||||
|  | ||||
| #define ENABLE_INTERRUPT_MASK	0x0UL | ||||
| #define DISABLE_INTERRUPT_MASK	0x1UL | ||||
|  | ||||
| #define CLR_INTR_STAT	0x1UL | ||||
|  | ||||
| struct amd_pingroup { | ||||
| 	const char *name; | ||||
| 	const unsigned *pins; | ||||
| 	unsigned npins; | ||||
| }; | ||||
|  | ||||
| struct amd_function { | ||||
| 	const char *name; | ||||
| 	const char * const *groups; | ||||
| 	unsigned ngroups; | ||||
| }; | ||||
|  | ||||
| struct amd_gpio { | ||||
| 	spinlock_t              lock; | ||||
| 	void __iomem            *base; | ||||
|  | ||||
| 	const struct amd_pingroup *groups; | ||||
| 	u32 ngroups; | ||||
| 	struct pinctrl_dev *pctrl; | ||||
| 	struct gpio_chip        gc; | ||||
| 	struct resource         *res; | ||||
| 	struct platform_device  *pdev; | ||||
| }; | ||||
|  | ||||
| /*  KERNCZ configuration*/ | ||||
| static const struct pinctrl_pin_desc kerncz_pins[] = { | ||||
| 	PINCTRL_PIN(0, "GPIO_0"), | ||||
| 	PINCTRL_PIN(1, "GPIO_1"), | ||||
| 	PINCTRL_PIN(2, "GPIO_2"), | ||||
| 	PINCTRL_PIN(3, "GPIO_3"), | ||||
| 	PINCTRL_PIN(4, "GPIO_4"), | ||||
| 	PINCTRL_PIN(5, "GPIO_5"), | ||||
| 	PINCTRL_PIN(6, "GPIO_6"), | ||||
| 	PINCTRL_PIN(7, "GPIO_7"), | ||||
| 	PINCTRL_PIN(8, "GPIO_8"), | ||||
| 	PINCTRL_PIN(9, "GPIO_9"), | ||||
| 	PINCTRL_PIN(10, "GPIO_10"), | ||||
| 	PINCTRL_PIN(11, "GPIO_11"), | ||||
| 	PINCTRL_PIN(12, "GPIO_12"), | ||||
| 	PINCTRL_PIN(13, "GPIO_13"), | ||||
| 	PINCTRL_PIN(14, "GPIO_14"), | ||||
| 	PINCTRL_PIN(15, "GPIO_15"), | ||||
| 	PINCTRL_PIN(16, "GPIO_16"), | ||||
| 	PINCTRL_PIN(17, "GPIO_17"), | ||||
| 	PINCTRL_PIN(18, "GPIO_18"), | ||||
| 	PINCTRL_PIN(19, "GPIO_19"), | ||||
| 	PINCTRL_PIN(20, "GPIO_20"), | ||||
| 	PINCTRL_PIN(23, "GPIO_23"), | ||||
| 	PINCTRL_PIN(24, "GPIO_24"), | ||||
| 	PINCTRL_PIN(25, "GPIO_25"), | ||||
| 	PINCTRL_PIN(26, "GPIO_26"), | ||||
| 	PINCTRL_PIN(39, "GPIO_39"), | ||||
| 	PINCTRL_PIN(40, "GPIO_40"), | ||||
| 	PINCTRL_PIN(43, "GPIO_42"), | ||||
| 	PINCTRL_PIN(46, "GPIO_46"), | ||||
| 	PINCTRL_PIN(47, "GPIO_47"), | ||||
| 	PINCTRL_PIN(48, "GPIO_48"), | ||||
| 	PINCTRL_PIN(49, "GPIO_49"), | ||||
| 	PINCTRL_PIN(50, "GPIO_50"), | ||||
| 	PINCTRL_PIN(51, "GPIO_51"), | ||||
| 	PINCTRL_PIN(52, "GPIO_52"), | ||||
| 	PINCTRL_PIN(53, "GPIO_53"), | ||||
| 	PINCTRL_PIN(54, "GPIO_54"), | ||||
| 	PINCTRL_PIN(55, "GPIO_55"), | ||||
| 	PINCTRL_PIN(56, "GPIO_56"), | ||||
| 	PINCTRL_PIN(57, "GPIO_57"), | ||||
| 	PINCTRL_PIN(58, "GPIO_58"), | ||||
| 	PINCTRL_PIN(59, "GPIO_59"), | ||||
| 	PINCTRL_PIN(60, "GPIO_60"), | ||||
| 	PINCTRL_PIN(61, "GPIO_61"), | ||||
| 	PINCTRL_PIN(62, "GPIO_62"), | ||||
| 	PINCTRL_PIN(64, "GPIO_64"), | ||||
| 	PINCTRL_PIN(65, "GPIO_65"), | ||||
| 	PINCTRL_PIN(66, "GPIO_66"), | ||||
| 	PINCTRL_PIN(68, "GPIO_68"), | ||||
| 	PINCTRL_PIN(69, "GPIO_69"), | ||||
| 	PINCTRL_PIN(70, "GPIO_70"), | ||||
| 	PINCTRL_PIN(71, "GPIO_71"), | ||||
| 	PINCTRL_PIN(72, "GPIO_72"), | ||||
| 	PINCTRL_PIN(74, "GPIO_74"), | ||||
| 	PINCTRL_PIN(75, "GPIO_75"), | ||||
| 	PINCTRL_PIN(76, "GPIO_76"), | ||||
| 	PINCTRL_PIN(84, "GPIO_84"), | ||||
| 	PINCTRL_PIN(85, "GPIO_85"), | ||||
| 	PINCTRL_PIN(86, "GPIO_86"), | ||||
| 	PINCTRL_PIN(87, "GPIO_87"), | ||||
| 	PINCTRL_PIN(88, "GPIO_88"), | ||||
| 	PINCTRL_PIN(89, "GPIO_89"), | ||||
| 	PINCTRL_PIN(90, "GPIO_90"), | ||||
| 	PINCTRL_PIN(91, "GPIO_91"), | ||||
| 	PINCTRL_PIN(92, "GPIO_92"), | ||||
| 	PINCTRL_PIN(93, "GPIO_93"), | ||||
| 	PINCTRL_PIN(95, "GPIO_95"), | ||||
| 	PINCTRL_PIN(96, "GPIO_96"), | ||||
| 	PINCTRL_PIN(97, "GPIO_97"), | ||||
| 	PINCTRL_PIN(98, "GPIO_98"), | ||||
| 	PINCTRL_PIN(99, "GPIO_99"), | ||||
| 	PINCTRL_PIN(100, "GPIO_100"), | ||||
| 	PINCTRL_PIN(101, "GPIO_101"), | ||||
| 	PINCTRL_PIN(102, "GPIO_102"), | ||||
| 	PINCTRL_PIN(113, "GPIO_113"), | ||||
| 	PINCTRL_PIN(114, "GPIO_114"), | ||||
| 	PINCTRL_PIN(115, "GPIO_115"), | ||||
| 	PINCTRL_PIN(116, "GPIO_116"), | ||||
| 	PINCTRL_PIN(117, "GPIO_117"), | ||||
| 	PINCTRL_PIN(118, "GPIO_118"), | ||||
| 	PINCTRL_PIN(119, "GPIO_119"), | ||||
| 	PINCTRL_PIN(120, "GPIO_120"), | ||||
| 	PINCTRL_PIN(121, "GPIO_121"), | ||||
| 	PINCTRL_PIN(122, "GPIO_122"), | ||||
| 	PINCTRL_PIN(126, "GPIO_126"), | ||||
| 	PINCTRL_PIN(129, "GPIO_129"), | ||||
| 	PINCTRL_PIN(130, "GPIO_130"), | ||||
| 	PINCTRL_PIN(131, "GPIO_131"), | ||||
| 	PINCTRL_PIN(132, "GPIO_132"), | ||||
| 	PINCTRL_PIN(133, "GPIO_133"), | ||||
| 	PINCTRL_PIN(135, "GPIO_135"), | ||||
| 	PINCTRL_PIN(136, "GPIO_136"), | ||||
| 	PINCTRL_PIN(137, "GPIO_137"), | ||||
| 	PINCTRL_PIN(138, "GPIO_138"), | ||||
| 	PINCTRL_PIN(139, "GPIO_139"), | ||||
| 	PINCTRL_PIN(140, "GPIO_140"), | ||||
| 	PINCTRL_PIN(141, "GPIO_141"), | ||||
| 	PINCTRL_PIN(142, "GPIO_142"), | ||||
| 	PINCTRL_PIN(143, "GPIO_143"), | ||||
| 	PINCTRL_PIN(144, "GPIO_144"), | ||||
| 	PINCTRL_PIN(145, "GPIO_145"), | ||||
| 	PINCTRL_PIN(146, "GPIO_146"), | ||||
| 	PINCTRL_PIN(147, "GPIO_147"), | ||||
| 	PINCTRL_PIN(148, "GPIO_148"), | ||||
| 	PINCTRL_PIN(166, "GPIO_166"), | ||||
| 	PINCTRL_PIN(167, "GPIO_167"), | ||||
| 	PINCTRL_PIN(168, "GPIO_168"), | ||||
| 	PINCTRL_PIN(169, "GPIO_169"), | ||||
| 	PINCTRL_PIN(170, "GPIO_170"), | ||||
| 	PINCTRL_PIN(171, "GPIO_171"), | ||||
| 	PINCTRL_PIN(172, "GPIO_172"), | ||||
| 	PINCTRL_PIN(173, "GPIO_173"), | ||||
| 	PINCTRL_PIN(174, "GPIO_174"), | ||||
| 	PINCTRL_PIN(175, "GPIO_175"), | ||||
| 	PINCTRL_PIN(176, "GPIO_176"), | ||||
| 	PINCTRL_PIN(177, "GPIO_177"), | ||||
| }; | ||||
|  | ||||
| static const unsigned i2c0_pins[] = {145, 146}; | ||||
| static const unsigned i2c1_pins[] = {147, 148}; | ||||
| static const unsigned i2c2_pins[] = {113, 114}; | ||||
| static const unsigned i2c3_pins[] = {19, 20}; | ||||
|  | ||||
| static const unsigned uart0_pins[] = {135, 136, 137, 138, 139}; | ||||
| static const unsigned uart1_pins[] = {140, 141, 142, 143, 144}; | ||||
|  | ||||
| static const struct amd_pingroup kerncz_groups[] = { | ||||
| 	{ | ||||
| 		.name = "i2c0", | ||||
| 		.pins = i2c0_pins, | ||||
| 		.npins = 2, | ||||
| 	}, | ||||
| 	{ | ||||
| 		.name = "i2c1", | ||||
| 		.pins = i2c1_pins, | ||||
| 		.npins = 2, | ||||
| 	}, | ||||
| 	{ | ||||
| 		.name = "i2c2", | ||||
| 		.pins = i2c2_pins, | ||||
| 		.npins = 2, | ||||
| 	}, | ||||
| 	{ | ||||
| 		.name = "i2c3", | ||||
| 		.pins = i2c3_pins, | ||||
| 		.npins = 2, | ||||
| 	}, | ||||
| 	{ | ||||
| 		.name = "uart0", | ||||
| 		.pins = uart0_pins, | ||||
| 		.npins = 9, | ||||
| 	}, | ||||
| 	{ | ||||
| 		.name = "uart1", | ||||
| 		.pins = uart1_pins, | ||||
| 		.npins = 5, | ||||
| 	}, | ||||
| }; | ||||
|  | ||||
| #endif | ||||
| @@ -625,7 +625,7 @@ static int as3722_pinctrl_remove(struct platform_device *pdev) | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static struct of_device_id as3722_pinctrl_of_match[] = { | ||||
| static const struct of_device_id as3722_pinctrl_of_match[] = { | ||||
| 	{ .compatible = "ams,as3722-pinctrl", }, | ||||
| 	{ }, | ||||
| }; | ||||
|   | ||||
| @@ -451,18 +451,18 @@ static enum at91_mux at91_mux_get_periph(void __iomem *pio, unsigned mask) | ||||
|  | ||||
| static bool at91_mux_get_deglitch(void __iomem *pio, unsigned pin) | ||||
| { | ||||
| 	return (__raw_readl(pio + PIO_IFSR) >> pin) & 0x1; | ||||
| 	return (readl_relaxed(pio + PIO_IFSR) >> pin) & 0x1; | ||||
| } | ||||
|  | ||||
| static void at91_mux_set_deglitch(void __iomem *pio, unsigned mask, bool is_on) | ||||
| { | ||||
| 	__raw_writel(mask, pio + (is_on ? PIO_IFER : PIO_IFDR)); | ||||
| 	writel_relaxed(mask, pio + (is_on ? PIO_IFER : PIO_IFDR)); | ||||
| } | ||||
|  | ||||
| static bool at91_mux_pio3_get_deglitch(void __iomem *pio, unsigned pin) | ||||
| { | ||||
| 	if ((__raw_readl(pio + PIO_IFSR) >> pin) & 0x1) | ||||
| 		return !((__raw_readl(pio + PIO_IFSCSR) >> pin) & 0x1); | ||||
| 	if ((readl_relaxed(pio + PIO_IFSR) >> pin) & 0x1) | ||||
| 		return !((readl_relaxed(pio + PIO_IFSCSR) >> pin) & 0x1); | ||||
|  | ||||
| 	return false; | ||||
| } | ||||
| @@ -470,55 +470,55 @@ static bool at91_mux_pio3_get_deglitch(void __iomem *pio, unsigned pin) | ||||
| static void at91_mux_pio3_set_deglitch(void __iomem *pio, unsigned mask, bool is_on) | ||||
| { | ||||
| 	if (is_on) | ||||
| 		__raw_writel(mask, pio + PIO_IFSCDR); | ||||
| 		writel_relaxed(mask, pio + PIO_IFSCDR); | ||||
| 	at91_mux_set_deglitch(pio, mask, is_on); | ||||
| } | ||||
|  | ||||
| static bool at91_mux_pio3_get_debounce(void __iomem *pio, unsigned pin, u32 *div) | ||||
| { | ||||
| 	*div = __raw_readl(pio + PIO_SCDR); | ||||
| 	*div = readl_relaxed(pio + PIO_SCDR); | ||||
|  | ||||
| 	return ((__raw_readl(pio + PIO_IFSR) >> pin) & 0x1) && | ||||
| 	       ((__raw_readl(pio + PIO_IFSCSR) >> pin) & 0x1); | ||||
| 	return ((readl_relaxed(pio + PIO_IFSR) >> pin) & 0x1) && | ||||
| 	       ((readl_relaxed(pio + PIO_IFSCSR) >> pin) & 0x1); | ||||
| } | ||||
|  | ||||
| static void at91_mux_pio3_set_debounce(void __iomem *pio, unsigned mask, | ||||
| 				bool is_on, u32 div) | ||||
| { | ||||
| 	if (is_on) { | ||||
| 		__raw_writel(mask, pio + PIO_IFSCER); | ||||
| 		__raw_writel(div & PIO_SCDR_DIV, pio + PIO_SCDR); | ||||
| 		__raw_writel(mask, pio + PIO_IFER); | ||||
| 		writel_relaxed(mask, pio + PIO_IFSCER); | ||||
| 		writel_relaxed(div & PIO_SCDR_DIV, pio + PIO_SCDR); | ||||
| 		writel_relaxed(mask, pio + PIO_IFER); | ||||
| 	} else | ||||
| 		__raw_writel(mask, pio + PIO_IFSCDR); | ||||
| 		writel_relaxed(mask, pio + PIO_IFSCDR); | ||||
| } | ||||
|  | ||||
| static bool at91_mux_pio3_get_pulldown(void __iomem *pio, unsigned pin) | ||||
| { | ||||
| 	return !((__raw_readl(pio + PIO_PPDSR) >> pin) & 0x1); | ||||
| 	return !((readl_relaxed(pio + PIO_PPDSR) >> pin) & 0x1); | ||||
| } | ||||
|  | ||||
| static void at91_mux_pio3_set_pulldown(void __iomem *pio, unsigned mask, bool is_on) | ||||
| { | ||||
| 	if (is_on) | ||||
| 		__raw_writel(mask, pio + PIO_PUDR); | ||||
| 		writel_relaxed(mask, pio + PIO_PUDR); | ||||
|  | ||||
| 	__raw_writel(mask, pio + (is_on ? PIO_PPDER : PIO_PPDDR)); | ||||
| 	writel_relaxed(mask, pio + (is_on ? PIO_PPDER : PIO_PPDDR)); | ||||
| } | ||||
|  | ||||
| static void at91_mux_pio3_disable_schmitt_trig(void __iomem *pio, unsigned mask) | ||||
| { | ||||
| 	__raw_writel(__raw_readl(pio + PIO_SCHMITT) | mask, pio + PIO_SCHMITT); | ||||
| 	writel_relaxed(readl_relaxed(pio + PIO_SCHMITT) | mask, pio + PIO_SCHMITT); | ||||
| } | ||||
|  | ||||
| static bool at91_mux_pio3_get_schmitt_trig(void __iomem *pio, unsigned pin) | ||||
| { | ||||
| 	return (__raw_readl(pio + PIO_SCHMITT) >> pin) & 0x1; | ||||
| 	return (readl_relaxed(pio + PIO_SCHMITT) >> pin) & 0x1; | ||||
| } | ||||
|  | ||||
| static inline u32 read_drive_strength(void __iomem *reg, unsigned pin) | ||||
| { | ||||
| 	unsigned tmp = __raw_readl(reg); | ||||
| 	unsigned tmp = readl_relaxed(reg); | ||||
|  | ||||
| 	tmp = tmp >> two_bit_pin_value_shift_amount(pin); | ||||
|  | ||||
| @@ -554,13 +554,13 @@ static unsigned at91_mux_sam9x5_get_drivestrength(void __iomem *pio, | ||||
|  | ||||
| static void set_drive_strength(void __iomem *reg, unsigned pin, u32 strength) | ||||
| { | ||||
| 	unsigned tmp = __raw_readl(reg); | ||||
| 	unsigned tmp = readl_relaxed(reg); | ||||
| 	unsigned shift = two_bit_pin_value_shift_amount(pin); | ||||
|  | ||||
| 	tmp &= ~(DRIVE_STRENGTH_MASK  <<  shift); | ||||
| 	tmp |= strength << shift; | ||||
|  | ||||
| 	__raw_writel(tmp, reg); | ||||
| 	writel_relaxed(tmp, reg); | ||||
| } | ||||
|  | ||||
| static void at91_mux_sama5d3_set_drivestrength(void __iomem *pio, unsigned pin, | ||||
| @@ -1114,7 +1114,7 @@ static int at91_pinctrl_parse_functions(struct device_node *np, | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static struct of_device_id at91_pinctrl_of_match[] = { | ||||
| static const struct of_device_id at91_pinctrl_of_match[] = { | ||||
| 	{ .compatible = "atmel,sama5d3-pinctrl", .data = &sama5d3_ops }, | ||||
| 	{ .compatible = "atmel,at91sam9x5-pinctrl", .data = &at91sam9x5_ops }, | ||||
| 	{ .compatible = "atmel,at91rm9200-pinctrl", .data = &at91rm9200_ops }, | ||||
| @@ -1240,8 +1240,7 @@ static int at91_pinctrl_probe(struct platform_device *pdev) | ||||
|  | ||||
| 	if (!info->pctl) { | ||||
| 		dev_err(&pdev->dev, "could not register AT91 pinctrl driver\n"); | ||||
| 		ret = -EINVAL; | ||||
| 		goto err; | ||||
| 		return -EINVAL; | ||||
| 	} | ||||
|  | ||||
| 	/* We will handle a range of GPIO pins */ | ||||
| @@ -1252,9 +1251,6 @@ static int at91_pinctrl_probe(struct platform_device *pdev) | ||||
| 	dev_info(&pdev->dev, "initialized AT91 pinctrl driver\n"); | ||||
|  | ||||
| 	return 0; | ||||
|  | ||||
| err: | ||||
| 	return ret; | ||||
| } | ||||
|  | ||||
| static int at91_pinctrl_remove(struct platform_device *pdev) | ||||
| @@ -1535,9 +1531,9 @@ void at91_pinctrl_gpio_suspend(void) | ||||
|  | ||||
| 		pio = gpio_chips[i]->regbase; | ||||
|  | ||||
| 		backups[i] = __raw_readl(pio + PIO_IMR); | ||||
| 		__raw_writel(backups[i], pio + PIO_IDR); | ||||
| 		__raw_writel(wakeups[i], pio + PIO_IER); | ||||
| 		backups[i] = readl_relaxed(pio + PIO_IMR); | ||||
| 		writel_relaxed(backups[i], pio + PIO_IDR); | ||||
| 		writel_relaxed(wakeups[i], pio + PIO_IER); | ||||
|  | ||||
| 		if (!wakeups[i]) | ||||
| 			clk_disable_unprepare(gpio_chips[i]->clock); | ||||
| @@ -1562,8 +1558,8 @@ void at91_pinctrl_gpio_resume(void) | ||||
| 		if (!wakeups[i]) | ||||
| 			clk_prepare_enable(gpio_chips[i]->clock); | ||||
|  | ||||
| 		__raw_writel(wakeups[i], pio + PIO_IDR); | ||||
| 		__raw_writel(backups[i], pio + PIO_IER); | ||||
| 		writel_relaxed(wakeups[i], pio + PIO_IDR); | ||||
| 		writel_relaxed(backups[i], pio + PIO_IER); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @@ -1694,7 +1690,7 @@ static struct gpio_chip at91_gpio_template = { | ||||
| 	.ngpio			= MAX_NB_GPIO_PER_BANK, | ||||
| }; | ||||
|  | ||||
| static struct of_device_id at91_gpio_of_match[] = { | ||||
| static const struct of_device_id at91_gpio_of_match[] = { | ||||
| 	{ .compatible = "atmel,at91sam9x5-gpio", .data = &at91sam9x5_ops, }, | ||||
| 	{ .compatible = "atmel,at91rm9200-gpio", .data = &at91rm9200_ops }, | ||||
| 	{ /* sentinel */ } | ||||
|   | ||||
| @@ -193,4 +193,4 @@ enum ltq_pin { | ||||
| extern int ltq_pinctrl_register(struct platform_device *pdev, | ||||
| 				   struct ltq_pinmux_info *info); | ||||
| extern int ltq_pinctrl_unregister(struct platform_device *pdev); | ||||
| #endif	/* __PINCTRL_PXA3XX_H */ | ||||
| #endif	/* __PINCTRL_LANTIQ_H */ | ||||
|   | ||||
| @@ -987,7 +987,7 @@ static struct palmas_pinctrl_data tps80036_pinctrl_data = { | ||||
| 	.num_pin_groups = ARRAY_SIZE(tps80036_pingroups), | ||||
| }; | ||||
|  | ||||
| static struct of_device_id palmas_pinctrl_of_match[] = { | ||||
| static const struct of_device_id palmas_pinctrl_of_match[] = { | ||||
| 	{ .compatible = "ti,palmas-pinctrl", .data = &tps65913_pinctrl_data}, | ||||
| 	{ .compatible = "ti,tps65913-pinctrl", .data = &tps65913_pinctrl_data}, | ||||
| 	{ .compatible = "ti,tps80036-pinctrl", .data = &tps80036_pinctrl_data}, | ||||
|   | ||||
| @@ -1501,7 +1501,7 @@ static void pcs_free_resources(struct pcs_device *pcs) | ||||
| 		}							\ | ||||
| 	} while (0); | ||||
|  | ||||
| static struct of_device_id pcs_of_match[]; | ||||
| static const struct of_device_id pcs_of_match[]; | ||||
|  | ||||
| static int pcs_add_gpio_func(struct device_node *node, struct pcs_device *pcs) | ||||
| { | ||||
| @@ -2000,7 +2000,7 @@ static const struct pcs_soc_data pinconf_single = { | ||||
| 	.flags = PCS_FEAT_PINCONF, | ||||
| }; | ||||
|  | ||||
| static struct of_device_id pcs_of_match[] = { | ||||
| static const struct of_device_id pcs_of_match[] = { | ||||
| 	{ .compatible = "ti,omap3-padconf", .data = &pinctrl_single_omap_wkup }, | ||||
| 	{ .compatible = "ti,omap4-padconf", .data = &pinctrl_single_omap_wkup }, | ||||
| 	{ .compatible = "ti,omap5-padconf", .data = &pinctrl_single_omap_wkup }, | ||||
|   | ||||
| @@ -206,6 +206,8 @@ | ||||
| #define gpio_chip_to_bank(chip) \ | ||||
| 		container_of(chip, struct st_gpio_bank, gpio_chip) | ||||
|  | ||||
| #define pc_to_bank(pc) \ | ||||
| 		container_of(pc, struct st_gpio_bank, pc) | ||||
|  | ||||
| enum st_retime_style { | ||||
| 	st_retime_style_none, | ||||
| @@ -398,6 +400,16 @@ static const struct st_pctl_data stih407_flashdata = { | ||||
| 	.rt = 100, | ||||
| }; | ||||
|  | ||||
| static struct st_pio_control *st_get_pio_control( | ||||
| 			struct pinctrl_dev *pctldev, int pin) | ||||
| { | ||||
| 	struct pinctrl_gpio_range *range = | ||||
| 			 pinctrl_find_gpio_range_from_pin(pctldev, pin); | ||||
| 	struct st_gpio_bank *bank = gpio_range_to_bank(range); | ||||
|  | ||||
| 	return &bank->pc; | ||||
| } | ||||
|  | ||||
| /* Low level functions.. */ | ||||
| static inline int st_gpio_bank(int gpio) | ||||
| { | ||||
| @@ -460,6 +472,20 @@ static void st_pctl_set_function(struct st_pio_control *pc, | ||||
| 	regmap_field_write(alt, val); | ||||
| } | ||||
|  | ||||
| static unsigned int st_pctl_get_pin_function(struct st_pio_control *pc, int pin) | ||||
| { | ||||
| 	struct regmap_field *alt = pc->alt; | ||||
| 	unsigned int val; | ||||
| 	int offset = pin * 4; | ||||
|  | ||||
| 	if (!alt) | ||||
| 		return 0; | ||||
|  | ||||
| 	regmap_field_read(alt, &val); | ||||
|  | ||||
| 	return (val >> offset) & 0xf; | ||||
| } | ||||
|  | ||||
| static unsigned long st_pinconf_delay_to_bit(unsigned int delay, | ||||
| 	const struct st_pctl_data *data, unsigned long config) | ||||
| { | ||||
| @@ -757,6 +783,35 @@ static int st_gpio_direction_output(struct gpio_chip *chip, | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int st_gpio_get_direction(struct gpio_chip *chip, unsigned offset) | ||||
| { | ||||
| 	struct st_gpio_bank *bank = gpio_chip_to_bank(chip); | ||||
| 	struct st_pio_control pc = bank->pc; | ||||
| 	unsigned long config; | ||||
| 	unsigned int direction = 0; | ||||
| 	unsigned int function; | ||||
| 	unsigned int value; | ||||
| 	int i = 0; | ||||
|  | ||||
| 	/* Alternate function direction is handled by Pinctrl */ | ||||
| 	function = st_pctl_get_pin_function(&pc, offset); | ||||
| 	if (function) { | ||||
| 		st_pinconf_get_direction(&pc, offset, &config); | ||||
| 		return !ST_PINCONF_UNPACK_OE(config); | ||||
| 	} | ||||
|  | ||||
| 	/* | ||||
| 	 * GPIO direction is handled differently | ||||
| 	 * - See st_gpio_direction() above for an explanation | ||||
| 	 */ | ||||
| 	for (i = 0; i <= 2; i++) { | ||||
| 		value = readl(bank->base + REG_PIO_PC(i)); | ||||
| 		direction |= ((value >> offset) & 0x1) << i; | ||||
| 	} | ||||
|  | ||||
| 	return (direction == ST_GPIO_DIRECTION_IN); | ||||
| } | ||||
|  | ||||
| static int st_gpio_xlate(struct gpio_chip *gc, | ||||
| 			const struct of_phandle_args *gpiospec, u32 *flags) | ||||
| { | ||||
| @@ -904,16 +959,6 @@ static int st_pmx_get_groups(struct pinctrl_dev *pctldev, | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static struct st_pio_control *st_get_pio_control( | ||||
| 			struct pinctrl_dev *pctldev, int pin) | ||||
| { | ||||
| 	struct pinctrl_gpio_range *range = | ||||
| 			 pinctrl_find_gpio_range_from_pin(pctldev, pin); | ||||
| 	struct st_gpio_bank *bank = gpio_range_to_bank(range); | ||||
|  | ||||
| 	return &bank->pc; | ||||
| } | ||||
|  | ||||
| static int st_pmx_set_mux(struct pinctrl_dev *pctldev, unsigned fselector, | ||||
| 			unsigned group) | ||||
| { | ||||
| @@ -1011,17 +1056,30 @@ static int st_pinconf_get(struct pinctrl_dev *pctldev, | ||||
| static void st_pinconf_dbg_show(struct pinctrl_dev *pctldev, | ||||
| 				   struct seq_file *s, unsigned pin_id) | ||||
| { | ||||
| 	struct st_pio_control *pc; | ||||
| 	unsigned long config; | ||||
| 	unsigned int function; | ||||
| 	int offset = st_gpio_pin(pin_id); | ||||
| 	char f[16]; | ||||
|  | ||||
| 	mutex_unlock(&pctldev->mutex); | ||||
| 	pc = st_get_pio_control(pctldev, pin_id); | ||||
| 	st_pinconf_get(pctldev, pin_id, &config); | ||||
| 	mutex_lock(&pctldev->mutex); | ||||
| 	seq_printf(s, "[OE:%ld,PU:%ld,OD:%ld]\n" | ||||
|  | ||||
| 	function = st_pctl_get_pin_function(pc, offset); | ||||
| 	if (function) | ||||
| 		snprintf(f, 10, "Alt Fn %d", function); | ||||
| 	else | ||||
| 		snprintf(f, 5, "GPIO"); | ||||
|  | ||||
| 	seq_printf(s, "[OE:%d,PU:%ld,OD:%ld]\t%s\n" | ||||
| 		"\t\t[retime:%ld,invclk:%ld,clknotdat:%ld," | ||||
| 		"de:%ld,rt-clk:%ld,rt-delay:%ld]", | ||||
| 		ST_PINCONF_UNPACK_OE(config), | ||||
| 		!st_gpio_get_direction(&pc_to_bank(pc)->gpio_chip, offset), | ||||
| 		ST_PINCONF_UNPACK_PU(config), | ||||
| 		ST_PINCONF_UNPACK_OD(config), | ||||
| 		f, | ||||
| 		ST_PINCONF_UNPACK_RT(config), | ||||
| 		ST_PINCONF_UNPACK_RT_INVERTCLK(config), | ||||
| 		ST_PINCONF_UNPACK_RT_CLKNOTDATA(config), | ||||
| @@ -1438,6 +1496,7 @@ static struct gpio_chip st_gpio_template = { | ||||
| 	.set			= st_gpio_set, | ||||
| 	.direction_input	= st_gpio_direction_input, | ||||
| 	.direction_output	= st_gpio_direction_output, | ||||
| 	.get_direction		= st_gpio_get_direction, | ||||
| 	.ngpio			= ST_GPIO_PINS_PER_BANK, | ||||
| 	.of_gpio_n_cells	= 1, | ||||
| 	.of_xlate		= st_gpio_xlate, | ||||
| @@ -1531,7 +1590,7 @@ static int st_gpiolib_register_bank(struct st_pinctrl *info, | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static struct of_device_id st_pctl_of_match[] = { | ||||
| static const struct of_device_id st_pctl_of_match[] = { | ||||
| 	{ .compatible = "st,stih415-sbc-pinctrl", .data = &stih415_sbc_data }, | ||||
| 	{ .compatible = "st,stih415-rear-pinctrl", .data = &stih415_rear_data }, | ||||
| 	{ .compatible = "st,stih415-left-pinctrl", .data = &stih415_left_data }, | ||||
|   | ||||
| @@ -103,6 +103,7 @@ static const struct cfg_param { | ||||
| 	{"nvidia,lock",			TEGRA_PINCONF_PARAM_LOCK}, | ||||
| 	{"nvidia,io-reset",		TEGRA_PINCONF_PARAM_IORESET}, | ||||
| 	{"nvidia,rcv-sel",		TEGRA_PINCONF_PARAM_RCV_SEL}, | ||||
| 	{"nvidia,io-hv",		TEGRA_PINCONF_PARAM_RCV_SEL}, | ||||
| 	{"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}, | ||||
| @@ -348,14 +349,24 @@ static int tegra_pinconf_reg(struct tegra_pmx *pmx, | ||||
| 		*width = 1; | ||||
| 		break; | ||||
| 	case TEGRA_PINCONF_PARAM_HIGH_SPEED_MODE: | ||||
| 		*bank = g->drv_bank; | ||||
| 		*reg = g->drv_reg; | ||||
| 		if (pmx->soc->hsm_in_mux) { | ||||
| 			*bank = g->mux_bank; | ||||
| 			*reg = g->mux_reg; | ||||
| 		} else { | ||||
| 			*bank = g->drv_bank; | ||||
| 			*reg = g->drv_reg; | ||||
| 		} | ||||
| 		*bit = g->hsm_bit; | ||||
| 		*width = 1; | ||||
| 		break; | ||||
| 	case TEGRA_PINCONF_PARAM_SCHMITT: | ||||
| 		*bank = g->drv_bank; | ||||
| 		*reg = g->drv_reg; | ||||
| 		if (pmx->soc->schmitt_in_mux) { | ||||
| 			*bank = g->mux_bank; | ||||
| 			*reg = g->mux_reg; | ||||
| 		} else { | ||||
| 			*bank = g->drv_bank; | ||||
| 			*reg = g->drv_reg; | ||||
| 		} | ||||
| 		*bit = g->schmitt_bit; | ||||
| 		*width = 1; | ||||
| 		break; | ||||
| @@ -390,8 +401,13 @@ static int tegra_pinconf_reg(struct tegra_pmx *pmx, | ||||
| 		*width = g->slwr_width; | ||||
| 		break; | ||||
| 	case TEGRA_PINCONF_PARAM_DRIVE_TYPE: | ||||
| 		*bank = g->drv_bank; | ||||
| 		*reg = g->drv_reg; | ||||
| 		if (pmx->soc->drvtype_in_mux) { | ||||
| 			*bank = g->mux_bank; | ||||
| 			*reg = g->mux_reg; | ||||
| 		} else { | ||||
| 			*bank = g->drv_bank; | ||||
| 			*reg = g->drv_reg; | ||||
| 		} | ||||
| 		*bit = g->drvtype_bit; | ||||
| 		*width = 2; | ||||
| 		break; | ||||
|   | ||||
| @@ -139,26 +139,26 @@ struct tegra_pingroup { | ||||
| 	u32 pupd_bank:2; | ||||
| 	u32 tri_bank:2; | ||||
| 	u32 drv_bank:2; | ||||
| 	u32 mux_bit:6; | ||||
| 	u32 pupd_bit:6; | ||||
| 	u32 tri_bit:6; | ||||
| 	u32 einput_bit:6; | ||||
| 	u32 odrain_bit:6; | ||||
| 	u32 lock_bit:6; | ||||
| 	u32 ioreset_bit:6; | ||||
| 	u32 rcv_sel_bit:6; | ||||
| 	u32 hsm_bit:6; | ||||
| 	u32 schmitt_bit:6; | ||||
| 	u32 lpmd_bit:6; | ||||
| 	u32 drvdn_bit:6; | ||||
| 	u32 drvup_bit:6; | ||||
| 	u32 slwr_bit:6; | ||||
| 	u32 slwf_bit:6; | ||||
| 	u32 drvtype_bit:6; | ||||
| 	u32 drvdn_width:6; | ||||
| 	u32 drvup_width:6; | ||||
| 	u32 slwr_width:6; | ||||
| 	u32 slwf_width:6; | ||||
| 	s32 mux_bit:6; | ||||
| 	s32 pupd_bit:6; | ||||
| 	s32 tri_bit:6; | ||||
| 	s32 einput_bit:6; | ||||
| 	s32 odrain_bit:6; | ||||
| 	s32 lock_bit:6; | ||||
| 	s32 ioreset_bit:6; | ||||
| 	s32 rcv_sel_bit:6; | ||||
| 	s32 hsm_bit:6; | ||||
| 	s32 schmitt_bit:6; | ||||
| 	s32 lpmd_bit:6; | ||||
| 	s32 drvdn_bit:6; | ||||
| 	s32 drvup_bit:6; | ||||
| 	s32 slwr_bit:6; | ||||
| 	s32 slwf_bit:6; | ||||
| 	s32 drvtype_bit:6; | ||||
| 	s32 drvdn_width:6; | ||||
| 	s32 drvup_width:6; | ||||
| 	s32 slwr_width:6; | ||||
| 	s32 slwf_width:6; | ||||
| }; | ||||
|  | ||||
| /** | ||||
| @@ -182,6 +182,9 @@ struct tegra_pinctrl_soc_data { | ||||
| 	unsigned nfunctions; | ||||
| 	const struct tegra_pingroup *groups; | ||||
| 	unsigned ngroups; | ||||
| 	bool hsm_in_mux; | ||||
| 	bool schmitt_in_mux; | ||||
| 	bool drvtype_in_mux; | ||||
| }; | ||||
|  | ||||
| int tegra_pinctrl_probe(struct platform_device *pdev, | ||||
|   | ||||
| @@ -1547,6 +1547,7 @@ static struct tegra_function tegra114_functions[] = { | ||||
| #define DRV_PINGROUP_REG_A		0x868	/* bank 0 */ | ||||
| #define PINGROUP_REG_A			0x3000	/* bank 1 */ | ||||
|  | ||||
| #define DRV_PINGROUP_REG(r)		((r) - DRV_PINGROUP_REG_A) | ||||
| #define PINGROUP_REG(r)			((r) - PINGROUP_REG_A) | ||||
|  | ||||
| #define PINGROUP_BIT_Y(b)		(b) | ||||
| @@ -1572,20 +1573,17 @@ static struct tegra_function tegra114_functions[] = { | ||||
| 		.tri_reg = PINGROUP_REG(r),				\ | ||||
| 		.tri_bank = 1,						\ | ||||
| 		.tri_bit = 4,						\ | ||||
| 		.einput_bit = PINGROUP_BIT_Y(5),			\ | ||||
| 		.einput_bit = 5,					\ | ||||
| 		.odrain_bit = PINGROUP_BIT_##od(6),			\ | ||||
| 		.lock_bit = PINGROUP_BIT_Y(7),				\ | ||||
| 		.lock_bit = 7,						\ | ||||
| 		.ioreset_bit = PINGROUP_BIT_##ior(8),			\ | ||||
| 		.rcv_sel_bit = PINGROUP_BIT_##rcv_sel(9),		\ | ||||
| 		.drv_reg = -1,						\ | ||||
| 	} | ||||
|  | ||||
| #define DRV_PINGROUP_REG(r)		((r) - DRV_PINGROUP_REG_A) | ||||
|  | ||||
| #define DRV_PINGROUP(pg_name, r, hsm_b, schmitt_b, lpmd_b,		\ | ||||
| 		     drvdn_b, drvdn_w, drvup_b, drvup_w,		\ | ||||
| 		     slwr_b, slwr_w, slwf_b, slwf_w,			\ | ||||
| 		     drvtype)						\ | ||||
| #define DRV_PINGROUP(pg_name, r, hsm_b, schmitt_b, lpmd_b, drvdn_b,	\ | ||||
| 		     drvdn_w, drvup_b, drvup_w, slwr_b, slwr_w,		\ | ||||
| 		     slwf_b, slwf_w, drvtype)				\ | ||||
| 	{								\ | ||||
| 		.name = "drive_" #pg_name,				\ | ||||
| 		.pins = drive_##pg_name##_pins,				\ | ||||
| @@ -1843,6 +1841,9 @@ static const struct tegra_pinctrl_soc_data tegra114_pinctrl = { | ||||
| 	.nfunctions = ARRAY_SIZE(tegra114_functions), | ||||
| 	.groups = tegra114_groups, | ||||
| 	.ngroups = ARRAY_SIZE(tegra114_groups), | ||||
| 	.hsm_in_mux = false, | ||||
| 	.schmitt_in_mux = false, | ||||
| 	.drvtype_in_mux = false, | ||||
| }; | ||||
|  | ||||
| static int tegra114_pinctrl_probe(struct platform_device *pdev) | ||||
|   | ||||
| @@ -1536,6 +1536,7 @@ enum tegra_mux { | ||||
| 	TEGRA_MUX_CLK, | ||||
| 	TEGRA_MUX_CLK12, | ||||
| 	TEGRA_MUX_CPU, | ||||
| 	TEGRA_MUX_CSI, | ||||
| 	TEGRA_MUX_DAP, | ||||
| 	TEGRA_MUX_DAP1, | ||||
| 	TEGRA_MUX_DAP2, | ||||
| @@ -1544,6 +1545,7 @@ enum tegra_mux { | ||||
| 	TEGRA_MUX_DISPLAYA_ALT, | ||||
| 	TEGRA_MUX_DISPLAYB, | ||||
| 	TEGRA_MUX_DP, | ||||
| 	TEGRA_MUX_DSI_B, | ||||
| 	TEGRA_MUX_DTV, | ||||
| 	TEGRA_MUX_EXTPERIPH1, | ||||
| 	TEGRA_MUX_EXTPERIPH2, | ||||
| @@ -1613,8 +1615,6 @@ enum tegra_mux { | ||||
| 	TEGRA_MUX_VI_ALT3, | ||||
| 	TEGRA_MUX_VIMCLK2, | ||||
| 	TEGRA_MUX_VIMCLK2_ALT, | ||||
| 	TEGRA_MUX_CSI, | ||||
| 	TEGRA_MUX_DSI_B, | ||||
| }; | ||||
|  | ||||
| #define FUNCTION(fname)					\ | ||||
| @@ -1630,6 +1630,7 @@ static struct tegra_function tegra124_functions[] = { | ||||
| 	FUNCTION(clk), | ||||
| 	FUNCTION(clk12), | ||||
| 	FUNCTION(cpu), | ||||
| 	FUNCTION(csi), | ||||
| 	FUNCTION(dap), | ||||
| 	FUNCTION(dap1), | ||||
| 	FUNCTION(dap2), | ||||
| @@ -1638,6 +1639,7 @@ static struct tegra_function tegra124_functions[] = { | ||||
| 	FUNCTION(displaya_alt), | ||||
| 	FUNCTION(displayb), | ||||
| 	FUNCTION(dp), | ||||
| 	FUNCTION(dsi_b), | ||||
| 	FUNCTION(dtv), | ||||
| 	FUNCTION(extperiph1), | ||||
| 	FUNCTION(extperiph2), | ||||
| @@ -1707,15 +1709,15 @@ static struct tegra_function tegra124_functions[] = { | ||||
| 	FUNCTION(vi_alt3), | ||||
| 	FUNCTION(vimclk2), | ||||
| 	FUNCTION(vimclk2_alt), | ||||
| 	FUNCTION(csi), | ||||
| 	FUNCTION(dsi_b), | ||||
| }; | ||||
|  | ||||
| #define DRV_PINGROUP_REG_A		0x868	/* bank 0 */ | ||||
| #define PINGROUP_REG_A			0x3000	/* bank 1 */ | ||||
| #define MIPI_PAD_CTRL_PINGROUP_REG_A	0x820	/* bank 2 */ | ||||
|  | ||||
| #define DRV_PINGROUP_REG(r)		((r) - DRV_PINGROUP_REG_A) | ||||
| #define PINGROUP_REG(r)			((r) - PINGROUP_REG_A) | ||||
| #define MIPI_PAD_CTRL_PINGROUP_REG_Y(r)	((r) - MIPI_PAD_CTRL_PINGROUP_REG_A) | ||||
|  | ||||
| #define PINGROUP_BIT_Y(b)		(b) | ||||
| #define PINGROUP_BIT_N(b)		(-1) | ||||
| @@ -1740,20 +1742,17 @@ static struct tegra_function tegra124_functions[] = { | ||||
| 		.tri_reg = PINGROUP_REG(r),				\ | ||||
| 		.tri_bank = 1,						\ | ||||
| 		.tri_bit = 4,						\ | ||||
| 		.einput_bit = PINGROUP_BIT_Y(5),			\ | ||||
| 		.einput_bit = 5,					\ | ||||
| 		.odrain_bit = PINGROUP_BIT_##od(6),			\ | ||||
| 		.lock_bit = PINGROUP_BIT_Y(7),				\ | ||||
| 		.lock_bit = 7,						\ | ||||
| 		.ioreset_bit = PINGROUP_BIT_##ior(8),			\ | ||||
| 		.rcv_sel_bit = PINGROUP_BIT_##rcv_sel(9),		\ | ||||
| 		.drv_reg = -1,						\ | ||||
| 	} | ||||
|  | ||||
| #define DRV_PINGROUP_REG(r)		((r) - DRV_PINGROUP_REG_A) | ||||
|  | ||||
| #define DRV_PINGROUP(pg_name, r, hsm_b, schmitt_b, lpmd_b,		\ | ||||
| 		     drvdn_b, drvdn_w, drvup_b, drvup_w,		\ | ||||
| 		     slwr_b, slwr_w, slwf_b, slwf_w,			\ | ||||
| 		     drvtype)						\ | ||||
| #define DRV_PINGROUP(pg_name, r, hsm_b, schmitt_b, lpmd_b, drvdn_b,	\ | ||||
| 		     drvdn_w, drvup_b, drvup_w, slwr_b, slwr_w,		\ | ||||
| 		     slwf_b, slwf_w, drvtype)				\ | ||||
| 	{								\ | ||||
| 		.name = "drive_" #pg_name,				\ | ||||
| 		.pins = drive_##pg_name##_pins,				\ | ||||
| @@ -1782,8 +1781,6 @@ static struct tegra_function tegra124_functions[] = { | ||||
| 		.drvtype_bit = PINGROUP_BIT_##drvtype(6),		\ | ||||
| 	} | ||||
|  | ||||
| #define MIPI_PAD_CTRL_PINGROUP_REG_Y(r)	((r) - MIPI_PAD_CTRL_PINGROUP_REG_A) | ||||
|  | ||||
| #define MIPI_PAD_CTRL_PINGROUP(pg_name, r, b, f0, f1)			\ | ||||
| 	{								\ | ||||
| 		.name = "mipi_pad_ctrl_" #pg_name,			\ | ||||
| @@ -2044,8 +2041,8 @@ static const struct tegra_pingroup tegra124_groups[] = { | ||||
| 	DRV_PINGROUP(sdio4,       0x9c4,  2,  3,  4,  12,  5,  20,  5,  28,  2,  30,  2,  N), | ||||
| 	DRV_PINGROUP(ao4,         0x9c8,  2,  3,  4,  12,  7,  20,  7,  28,  2,  30,  2,  Y), | ||||
|  | ||||
| 	/*		       pg_name, r      b  f0,  f1 */ | ||||
| 	MIPI_PAD_CTRL_PINGROUP(dsi_b,   0x820, 1, CSI, DSI_B) | ||||
| 	/*                     pg_name, r,     b, f0,  f1 */ | ||||
| 	MIPI_PAD_CTRL_PINGROUP(dsi_b,   0x820, 1, CSI, DSI_B), | ||||
| }; | ||||
|  | ||||
| static const struct tegra_pinctrl_soc_data tegra124_pinctrl = { | ||||
| @@ -2056,6 +2053,9 @@ static const struct tegra_pinctrl_soc_data tegra124_pinctrl = { | ||||
| 	.nfunctions = ARRAY_SIZE(tegra124_functions), | ||||
| 	.groups = tegra124_groups, | ||||
| 	.ngroups = ARRAY_SIZE(tegra124_groups), | ||||
| 	.hsm_in_mux = false, | ||||
| 	.schmitt_in_mux = false, | ||||
| 	.drvtype_in_mux = false, | ||||
| }; | ||||
|  | ||||
| static int tegra124_pinctrl_probe(struct platform_device *pdev) | ||||
|   | ||||
| @@ -2221,6 +2221,9 @@ static const struct tegra_pinctrl_soc_data tegra20_pinctrl = { | ||||
| 	.nfunctions = ARRAY_SIZE(tegra20_functions), | ||||
| 	.groups = tegra20_groups, | ||||
| 	.ngroups = ARRAY_SIZE(tegra20_groups), | ||||
| 	.hsm_in_mux = false, | ||||
| 	.schmitt_in_mux = false, | ||||
| 	.drvtype_in_mux = false, | ||||
| }; | ||||
|  | ||||
| static int tegra20_pinctrl_probe(struct platform_device *pdev) | ||||
|   | ||||
							
								
								
									
										1588
									
								
								drivers/pinctrl/pinctrl-tegra210.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1588
									
								
								drivers/pinctrl/pinctrl-tegra210.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -2108,70 +2108,69 @@ static struct tegra_function tegra30_functions[] = { | ||||
| #define DRV_PINGROUP_REG_A		0x868	/* bank 0 */ | ||||
| #define PINGROUP_REG_A			0x3000	/* bank 1 */ | ||||
|  | ||||
| #define DRV_PINGROUP_REG(r)		((r) - DRV_PINGROUP_REG_A) | ||||
| #define PINGROUP_REG(r)			((r) - PINGROUP_REG_A) | ||||
|  | ||||
| #define PINGROUP_BIT_Y(b)		(b) | ||||
| #define PINGROUP_BIT_N(b)		(-1) | ||||
|  | ||||
| #define PINGROUP(pg_name, f0, f1, f2, f3, r, od, ior)		\ | ||||
| 	{							\ | ||||
| 		.name = #pg_name,				\ | ||||
| 		.pins = pg_name##_pins,				\ | ||||
| 		.npins = ARRAY_SIZE(pg_name##_pins),		\ | ||||
| 		.funcs = {					\ | ||||
| 			TEGRA_MUX_##f0,				\ | ||||
| 			TEGRA_MUX_##f1,				\ | ||||
| 			TEGRA_MUX_##f2,				\ | ||||
| 			TEGRA_MUX_##f3,				\ | ||||
| 		},						\ | ||||
| 		.mux_reg = PINGROUP_REG(r),			\ | ||||
| 		.mux_bank = 1,					\ | ||||
| 		.mux_bit = 0,					\ | ||||
| 		.pupd_reg = PINGROUP_REG(r),			\ | ||||
| 		.pupd_bank = 1,					\ | ||||
| 		.pupd_bit = 2,					\ | ||||
| 		.tri_reg = PINGROUP_REG(r),			\ | ||||
| 		.tri_bank = 1,					\ | ||||
| 		.tri_bit = 4,					\ | ||||
| 		.einput_bit = PINGROUP_BIT_Y(5),		\ | ||||
| 		.odrain_bit = PINGROUP_BIT_##od(6),		\ | ||||
| 		.lock_bit = PINGROUP_BIT_Y(7),			\ | ||||
| 		.ioreset_bit = PINGROUP_BIT_##ior(8),		\ | ||||
| 		.rcv_sel_bit = -1,				\ | ||||
| 		.drv_reg = -1,					\ | ||||
| #define PINGROUP(pg_name, f0, f1, f2, f3, r, od, ior)			\ | ||||
| 	{								\ | ||||
| 		.name = #pg_name,					\ | ||||
| 		.pins = pg_name##_pins,					\ | ||||
| 		.npins = ARRAY_SIZE(pg_name##_pins),			\ | ||||
| 		.funcs = {						\ | ||||
| 			TEGRA_MUX_##f0,					\ | ||||
| 			TEGRA_MUX_##f1,					\ | ||||
| 			TEGRA_MUX_##f2,					\ | ||||
| 			TEGRA_MUX_##f3,					\ | ||||
| 		},							\ | ||||
| 		.mux_reg = PINGROUP_REG(r),				\ | ||||
| 		.mux_bank = 1,						\ | ||||
| 		.mux_bit = 0,						\ | ||||
| 		.pupd_reg = PINGROUP_REG(r),				\ | ||||
| 		.pupd_bank = 1,						\ | ||||
| 		.pupd_bit = 2,						\ | ||||
| 		.tri_reg = PINGROUP_REG(r),				\ | ||||
| 		.tri_bank = 1,						\ | ||||
| 		.tri_bit = 4,						\ | ||||
| 		.einput_bit = 5,					\ | ||||
| 		.odrain_bit = PINGROUP_BIT_##od(6),			\ | ||||
| 		.lock_bit = 7,						\ | ||||
| 		.ioreset_bit = PINGROUP_BIT_##ior(8),			\ | ||||
| 		.rcv_sel_bit = -1,					\ | ||||
| 		.drv_reg = -1,						\ | ||||
| 	} | ||||
|  | ||||
| #define DRV_PINGROUP_REG(r)		((r) - DRV_PINGROUP_REG_A) | ||||
|  | ||||
| #define DRV_PINGROUP(pg_name, r, hsm_b, schmitt_b, lpmd_b,	\ | ||||
| 		     drvdn_b, drvdn_w, drvup_b, drvup_w,	\ | ||||
| 		     slwr_b, slwr_w, slwf_b, slwf_w)		\ | ||||
| 	{							\ | ||||
| 		.name = "drive_" #pg_name,			\ | ||||
| 		.pins = drive_##pg_name##_pins,			\ | ||||
| 		.npins = ARRAY_SIZE(drive_##pg_name##_pins),	\ | ||||
| 		.mux_reg = -1,					\ | ||||
| 		.pupd_reg = -1,					\ | ||||
| 		.tri_reg = -1,					\ | ||||
| 		.einput_bit = -1,				\ | ||||
| 		.odrain_bit = -1,				\ | ||||
| 		.lock_bit = -1,					\ | ||||
| 		.ioreset_bit = -1,				\ | ||||
| 		.rcv_sel_bit = -1,				\ | ||||
| 		.drv_reg = DRV_PINGROUP_REG(r),			\ | ||||
| 		.drv_bank = 0,					\ | ||||
| 		.hsm_bit = hsm_b,				\ | ||||
| 		.schmitt_bit = schmitt_b,			\ | ||||
| 		.lpmd_bit = lpmd_b,				\ | ||||
| 		.drvdn_bit = drvdn_b,				\ | ||||
| 		.drvdn_width = drvdn_w,				\ | ||||
| 		.drvup_bit = drvup_b,				\ | ||||
| 		.drvup_width = drvup_w,				\ | ||||
| 		.slwr_bit = slwr_b,				\ | ||||
| 		.slwr_width = slwr_w,				\ | ||||
| 		.slwf_bit = slwf_b,				\ | ||||
| 		.slwf_width = slwf_w,				\ | ||||
| 		.drvtype_bit = -1,				\ | ||||
| #define DRV_PINGROUP(pg_name, r, hsm_b, schmitt_b, lpmd_b, drvdn_b,	\ | ||||
| 		     drvdn_w, drvup_b, drvup_w, slwr_b, slwr_w,		\ | ||||
| 		     slwf_b, slwf_w)					\ | ||||
| 	{								\ | ||||
| 		.name = "drive_" #pg_name,				\ | ||||
| 		.pins = drive_##pg_name##_pins,				\ | ||||
| 		.npins = ARRAY_SIZE(drive_##pg_name##_pins),		\ | ||||
| 		.mux_reg = -1,						\ | ||||
| 		.pupd_reg = -1,						\ | ||||
| 		.tri_reg = -1,						\ | ||||
| 		.einput_bit = -1,					\ | ||||
| 		.odrain_bit = -1,					\ | ||||
| 		.lock_bit = -1,						\ | ||||
| 		.ioreset_bit = -1,					\ | ||||
| 		.rcv_sel_bit = -1,					\ | ||||
| 		.drv_reg = DRV_PINGROUP_REG(r),				\ | ||||
| 		.drv_bank = 0,						\ | ||||
| 		.hsm_bit = hsm_b,					\ | ||||
| 		.schmitt_bit = schmitt_b,				\ | ||||
| 		.lpmd_bit = lpmd_b,					\ | ||||
| 		.drvdn_bit = drvdn_b,					\ | ||||
| 		.drvdn_width = drvdn_w,					\ | ||||
| 		.drvup_bit = drvup_b,					\ | ||||
| 		.drvup_width = drvup_w,					\ | ||||
| 		.slwr_bit = slwr_b,					\ | ||||
| 		.slwr_width = slwr_w,					\ | ||||
| 		.slwf_bit = slwf_b,					\ | ||||
| 		.slwf_width = slwf_w,					\ | ||||
| 		.drvtype_bit = -1,					\ | ||||
| 	} | ||||
|  | ||||
| static const struct tegra_pingroup tegra30_groups[] = { | ||||
| @@ -2477,6 +2476,9 @@ static const struct tegra_pinctrl_soc_data tegra30_pinctrl = { | ||||
| 	.nfunctions = ARRAY_SIZE(tegra30_functions), | ||||
| 	.groups = tegra30_groups, | ||||
| 	.ngroups = ARRAY_SIZE(tegra30_groups), | ||||
| 	.hsm_in_mux = false, | ||||
| 	.schmitt_in_mux = false, | ||||
| 	.drvtype_in_mux = false, | ||||
| }; | ||||
|  | ||||
| static int tegra30_pinctrl_probe(struct platform_device *pdev) | ||||
|   | ||||
| @@ -969,7 +969,7 @@ static int tz1090_pdc_pinctrl_remove(struct platform_device *pdev) | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static struct of_device_id tz1090_pdc_pinctrl_of_match[] = { | ||||
| static const struct of_device_id tz1090_pdc_pinctrl_of_match[] = { | ||||
| 	{ .compatible = "img,tz1090-pdc-pinctrl", }, | ||||
| 	{ }, | ||||
| }; | ||||
|   | ||||
| @@ -1984,7 +1984,7 @@ static int tz1090_pinctrl_remove(struct platform_device *pdev) | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static struct of_device_id tz1090_pinctrl_of_match[] = { | ||||
| static const struct of_device_id tz1090_pinctrl_of_match[] = { | ||||
| 	{ .compatible = "img,tz1090-pinctrl", }, | ||||
| 	{ }, | ||||
| }; | ||||
|   | ||||
| @@ -193,11 +193,11 @@ static int msm_config_reg(struct msm_pinctrl *pctrl, | ||||
| 		*mask = 7; | ||||
| 		break; | ||||
| 	case PIN_CONFIG_OUTPUT: | ||||
| 	case PIN_CONFIG_INPUT_ENABLE: | ||||
| 		*bit = g->oe_bit; | ||||
| 		*mask = 1; | ||||
| 		break; | ||||
| 	default: | ||||
| 		dev_err(pctrl->dev, "Invalid config param %04x\n", param); | ||||
| 		return -ENOTSUPP; | ||||
| 	} | ||||
|  | ||||
| @@ -261,10 +261,14 @@ static int msm_config_group_get(struct pinctrl_dev *pctldev, | ||||
| 		val = readl(pctrl->regs + g->io_reg); | ||||
| 		arg = !!(val & BIT(g->in_bit)); | ||||
| 		break; | ||||
| 	case PIN_CONFIG_INPUT_ENABLE: | ||||
| 		/* Pin is output */ | ||||
| 		if (arg) | ||||
| 			return -EINVAL; | ||||
| 		arg = 1; | ||||
| 		break; | ||||
| 	default: | ||||
| 		dev_err(pctrl->dev, "Unsupported config parameter: %x\n", | ||||
| 			param); | ||||
| 		return -EINVAL; | ||||
| 		return -ENOTSUPP; | ||||
| 	} | ||||
|  | ||||
| 	*config = pinconf_to_config_packed(param, arg); | ||||
| @@ -333,6 +337,10 @@ static int msm_config_group_set(struct pinctrl_dev *pctldev, | ||||
| 			/* enable output */ | ||||
| 			arg = 1; | ||||
| 			break; | ||||
| 		case PIN_CONFIG_INPUT_ENABLE: | ||||
| 			/* disable output */ | ||||
| 			arg = 0; | ||||
| 			break; | ||||
| 		default: | ||||
| 			dev_err(pctrl->dev, "Unsupported config parameter: %x\n", | ||||
| 				param); | ||||
| @@ -357,6 +365,7 @@ static int msm_config_group_set(struct pinctrl_dev *pctldev, | ||||
| } | ||||
|  | ||||
| static const struct pinconf_ops msm_pinconf_ops = { | ||||
| 	.is_generic		= true, | ||||
| 	.pin_config_group_get	= msm_config_group_get, | ||||
| 	.pin_config_group_set	= msm_config_group_set, | ||||
| }; | ||||
|   | ||||
| @@ -810,6 +810,7 @@ static int pmic_gpio_remove(struct platform_device *pdev) | ||||
| } | ||||
|  | ||||
| static const struct of_device_id pmic_gpio_of_match[] = { | ||||
| 	{ .compatible = "qcom,pm8916-gpio" },	/* 4 GPIO's */ | ||||
| 	{ .compatible = "qcom,pm8941-gpio" },	/* 36 GPIO's */ | ||||
| 	{ .compatible = "qcom,pma8084-gpio" },	/* 22 GPIO's */ | ||||
| 	{ }, | ||||
|   | ||||
| @@ -925,6 +925,7 @@ static int pmic_mpp_remove(struct platform_device *pdev) | ||||
|  | ||||
| static const struct of_device_id pmic_mpp_of_match[] = { | ||||
| 	{ .compatible = "qcom,pm8841-mpp" },	/* 4 MPP's */ | ||||
| 	{ .compatible = "qcom,pm8916-mpp" },	/* 4 MPP's */ | ||||
| 	{ .compatible = "qcom,pm8941-mpp" },	/* 8 MPP's */ | ||||
| 	{ .compatible = "qcom,pma8084-mpp" },	/* 8 MPP's */ | ||||
| 	{ }, | ||||
|   | ||||
| @@ -1240,6 +1240,159 @@ const struct samsung_pin_ctrl exynos5420_pin_ctrl[] __initconst = { | ||||
| 	}, | ||||
| }; | ||||
|  | ||||
| /* pin banks of exynos5433 pin-controller - ALIVE */ | ||||
| static const struct samsung_pin_bank_data exynos5433_pin_banks0[] = { | ||||
| 	EXYNOS_PIN_BANK_EINTW(8, 0x000, "gpa0", 0x00), | ||||
| 	EXYNOS_PIN_BANK_EINTW(8, 0x020, "gpa1", 0x04), | ||||
| 	EXYNOS_PIN_BANK_EINTW(8, 0x040, "gpa2", 0x08), | ||||
| 	EXYNOS_PIN_BANK_EINTW(8, 0x060, "gpa3", 0x0c), | ||||
| }; | ||||
|  | ||||
| /* pin banks of exynos5433 pin-controller - AUD */ | ||||
| static const struct samsung_pin_bank_data exynos5433_pin_banks1[] = { | ||||
| 	EXYNOS_PIN_BANK_EINTG(7, 0x000, "gpz0", 0x00), | ||||
| 	EXYNOS_PIN_BANK_EINTG(4, 0x020, "gpz1", 0x04), | ||||
| }; | ||||
|  | ||||
| /* pin banks of exynos5433 pin-controller - CPIF */ | ||||
| static const struct samsung_pin_bank_data exynos5433_pin_banks2[] = { | ||||
| 	EXYNOS_PIN_BANK_EINTG(2, 0x000, "gpv6", 0x00), | ||||
| }; | ||||
|  | ||||
| /* pin banks of exynos5433 pin-controller - eSE */ | ||||
| static const struct samsung_pin_bank_data exynos5433_pin_banks3[] = { | ||||
| 	EXYNOS_PIN_BANK_EINTG(3, 0x000, "gpj2", 0x00), | ||||
| }; | ||||
|  | ||||
| /* pin banks of exynos5433 pin-controller - FINGER */ | ||||
| static const struct samsung_pin_bank_data exynos5433_pin_banks4[] = { | ||||
| 	EXYNOS_PIN_BANK_EINTG(4, 0x000, "gpd5", 0x00), | ||||
| }; | ||||
|  | ||||
| /* pin banks of exynos5433 pin-controller - FSYS */ | ||||
| static const struct samsung_pin_bank_data exynos5433_pin_banks5[] = { | ||||
| 	EXYNOS_PIN_BANK_EINTG(6, 0x000, "gph1", 0x00), | ||||
| 	EXYNOS_PIN_BANK_EINTG(7, 0x020, "gpr4", 0x04), | ||||
| 	EXYNOS_PIN_BANK_EINTG(5, 0x040, "gpr0", 0x08), | ||||
| 	EXYNOS_PIN_BANK_EINTG(8, 0x060, "gpr1", 0x0c), | ||||
| 	EXYNOS_PIN_BANK_EINTG(2, 0x080, "gpr2", 0x10), | ||||
| 	EXYNOS_PIN_BANK_EINTG(8, 0x0a0, "gpr3", 0x14), | ||||
| }; | ||||
|  | ||||
| /* pin banks of exynos5433 pin-controller - IMEM */ | ||||
| static const struct samsung_pin_bank_data exynos5433_pin_banks6[] = { | ||||
| 	EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpf0", 0x00), | ||||
| }; | ||||
|  | ||||
| /* pin banks of exynos5433 pin-controller - NFC */ | ||||
| static const struct samsung_pin_bank_data exynos5433_pin_banks7[] = { | ||||
| 	EXYNOS_PIN_BANK_EINTG(3, 0x000, "gpj0", 0x00), | ||||
| }; | ||||
|  | ||||
| /* pin banks of exynos5433 pin-controller - PERIC */ | ||||
| static const struct samsung_pin_bank_data exynos5433_pin_banks8[] = { | ||||
| 	EXYNOS_PIN_BANK_EINTG(6, 0x000, "gpv7", 0x00), | ||||
| 	EXYNOS_PIN_BANK_EINTG(5, 0x020, "gpb0", 0x04), | ||||
| 	EXYNOS_PIN_BANK_EINTG(8, 0x040, "gpc0", 0x08), | ||||
| 	EXYNOS_PIN_BANK_EINTG(2, 0x060, "gpc1", 0x0c), | ||||
| 	EXYNOS_PIN_BANK_EINTG(6, 0x080, "gpc2", 0x10), | ||||
| 	EXYNOS_PIN_BANK_EINTG(8, 0x0a0, "gpc3", 0x14), | ||||
| 	EXYNOS_PIN_BANK_EINTG(2, 0x0c0, "gpg0", 0x18), | ||||
| 	EXYNOS_PIN_BANK_EINTG(4, 0x0e0, "gpd0", 0x1c), | ||||
| 	EXYNOS_PIN_BANK_EINTG(6, 0x100, "gpd1", 0x20), | ||||
| 	EXYNOS_PIN_BANK_EINTG(8, 0x120, "gpd2", 0x24), | ||||
| 	EXYNOS_PIN_BANK_EINTG(5, 0x140, "gpd4", 0x28), | ||||
| 	EXYNOS_PIN_BANK_EINTG(2, 0x160, "gpd8", 0x2c), | ||||
| 	EXYNOS_PIN_BANK_EINTG(7, 0x180, "gpd6", 0x30), | ||||
| 	EXYNOS_PIN_BANK_EINTG(3, 0x1a0, "gpd7", 0x34), | ||||
| 	EXYNOS_PIN_BANK_EINTG(5, 0x1c0, "gpg1", 0x38), | ||||
| 	EXYNOS_PIN_BANK_EINTG(2, 0x1e0, "gpg2", 0x3c), | ||||
| 	EXYNOS_PIN_BANK_EINTG(8, 0x200, "gpg3", 0x40), | ||||
| }; | ||||
|  | ||||
| /* pin banks of exynos5433 pin-controller - TOUCH */ | ||||
| static const struct samsung_pin_bank_data exynos5433_pin_banks9[] = { | ||||
| 	EXYNOS_PIN_BANK_EINTG(3, 0x000, "gpj1", 0x00), | ||||
| }; | ||||
|  | ||||
| /* | ||||
|  * Samsung pinctrl driver data for Exynos5433 SoC. Exynos5433 SoC includes | ||||
|  * ten gpio/pin-mux/pinconfig controllers. | ||||
|  */ | ||||
| const struct samsung_pin_ctrl exynos5433_pin_ctrl[] = { | ||||
| 	{ | ||||
| 		/* pin-controller instance 0 data */ | ||||
| 		.pin_banks	= exynos5433_pin_banks0, | ||||
| 		.nr_banks	= ARRAY_SIZE(exynos5433_pin_banks0), | ||||
| 		.eint_wkup_init = exynos_eint_wkup_init, | ||||
| 		.suspend	= exynos_pinctrl_suspend, | ||||
| 		.resume		= exynos_pinctrl_resume, | ||||
| 	}, { | ||||
| 		/* pin-controller instance 1 data */ | ||||
| 		.pin_banks	= exynos5433_pin_banks1, | ||||
| 		.nr_banks	= ARRAY_SIZE(exynos5433_pin_banks1), | ||||
| 		.eint_gpio_init = exynos_eint_gpio_init, | ||||
| 		.suspend	= exynos_pinctrl_suspend, | ||||
| 		.resume		= exynos_pinctrl_resume, | ||||
| 	}, { | ||||
| 		/* pin-controller instance 2 data */ | ||||
| 		.pin_banks	= exynos5433_pin_banks2, | ||||
| 		.nr_banks	= ARRAY_SIZE(exynos5433_pin_banks2), | ||||
| 		.eint_gpio_init = exynos_eint_gpio_init, | ||||
| 		.suspend	= exynos_pinctrl_suspend, | ||||
| 		.resume		= exynos_pinctrl_resume, | ||||
| 	}, { | ||||
| 		/* pin-controller instance 3 data */ | ||||
| 		.pin_banks	= exynos5433_pin_banks3, | ||||
| 		.nr_banks	= ARRAY_SIZE(exynos5433_pin_banks3), | ||||
| 		.eint_gpio_init = exynos_eint_gpio_init, | ||||
| 		.suspend	= exynos_pinctrl_suspend, | ||||
| 		.resume		= exynos_pinctrl_resume, | ||||
| 	}, { | ||||
| 		/* pin-controller instance 4 data */ | ||||
| 		.pin_banks	= exynos5433_pin_banks4, | ||||
| 		.nr_banks	= ARRAY_SIZE(exynos5433_pin_banks4), | ||||
| 		.eint_gpio_init = exynos_eint_gpio_init, | ||||
| 		.suspend	= exynos_pinctrl_suspend, | ||||
| 		.resume		= exynos_pinctrl_resume, | ||||
| 	}, { | ||||
| 		/* pin-controller instance 5 data */ | ||||
| 		.pin_banks	= exynos5433_pin_banks5, | ||||
| 		.nr_banks	= ARRAY_SIZE(exynos5433_pin_banks5), | ||||
| 		.eint_gpio_init = exynos_eint_gpio_init, | ||||
| 		.suspend	= exynos_pinctrl_suspend, | ||||
| 		.resume		= exynos_pinctrl_resume, | ||||
| 	}, { | ||||
| 		/* pin-controller instance 6 data */ | ||||
| 		.pin_banks	= exynos5433_pin_banks6, | ||||
| 		.nr_banks	= ARRAY_SIZE(exynos5433_pin_banks6), | ||||
| 		.eint_gpio_init = exynos_eint_gpio_init, | ||||
| 		.suspend	= exynos_pinctrl_suspend, | ||||
| 		.resume		= exynos_pinctrl_resume, | ||||
| 	}, { | ||||
| 		/* pin-controller instance 7 data */ | ||||
| 		.pin_banks	= exynos5433_pin_banks7, | ||||
| 		.nr_banks	= ARRAY_SIZE(exynos5433_pin_banks7), | ||||
| 		.eint_gpio_init = exynos_eint_gpio_init, | ||||
| 		.suspend	= exynos_pinctrl_suspend, | ||||
| 		.resume		= exynos_pinctrl_resume, | ||||
| 	}, { | ||||
| 		/* pin-controller instance 8 data */ | ||||
| 		.pin_banks	= exynos5433_pin_banks8, | ||||
| 		.nr_banks	= ARRAY_SIZE(exynos5433_pin_banks8), | ||||
| 		.eint_gpio_init = exynos_eint_gpio_init, | ||||
| 		.suspend	= exynos_pinctrl_suspend, | ||||
| 		.resume		= exynos_pinctrl_resume, | ||||
| 	}, { | ||||
| 		/* pin-controller instance 9 data */ | ||||
| 		.pin_banks	= exynos5433_pin_banks9, | ||||
| 		.nr_banks	= ARRAY_SIZE(exynos5433_pin_banks9), | ||||
| 		.eint_gpio_init = exynos_eint_gpio_init, | ||||
| 		.suspend	= exynos_pinctrl_suspend, | ||||
| 		.resume		= exynos_pinctrl_resume, | ||||
| 	}, | ||||
| }; | ||||
|  | ||||
| /* pin banks of exynos7 pin-controller - ALIVE */ | ||||
| static const struct samsung_pin_bank_data exynos7_pin_banks0[] __initconst = { | ||||
| 	EXYNOS_PIN_BANK_EINTW(8, 0x000, "gpa0", 0x00), | ||||
| @@ -1324,7 +1477,6 @@ const struct samsung_pin_ctrl exynos7_pin_ctrl[] __initconst = { | ||||
| 		/* pin-controller instance 0 Alive data */ | ||||
| 		.pin_banks	= exynos7_pin_banks0, | ||||
| 		.nr_banks	= ARRAY_SIZE(exynos7_pin_banks0), | ||||
| 		.eint_gpio_init = exynos_eint_gpio_init, | ||||
| 		.eint_wkup_init = exynos_eint_wkup_init, | ||||
| 	}, { | ||||
| 		/* pin-controller instance 1 BUS0 data */ | ||||
|   | ||||
| @@ -1239,6 +1239,8 @@ static const struct of_device_id samsung_pinctrl_dt_match[] = { | ||||
| 		.data = (void *)exynos5260_pin_ctrl }, | ||||
| 	{ .compatible = "samsung,exynos5420-pinctrl", | ||||
| 		.data = (void *)exynos5420_pin_ctrl }, | ||||
| 	{ .compatible = "samsung,exynos5433-pinctrl", | ||||
| 		.data = (void *)exynos5433_pin_ctrl }, | ||||
| 	{ .compatible = "samsung,s5pv210-pinctrl", | ||||
| 		.data = (void *)s5pv210_pin_ctrl }, | ||||
| 	{ .compatible = "samsung,exynos7-pinctrl", | ||||
|   | ||||
| @@ -271,6 +271,7 @@ extern const struct samsung_pin_ctrl exynos4415_pin_ctrl[]; | ||||
| extern const struct samsung_pin_ctrl exynos5250_pin_ctrl[]; | ||||
| extern const struct samsung_pin_ctrl exynos5260_pin_ctrl[]; | ||||
| extern const struct samsung_pin_ctrl exynos5420_pin_ctrl[]; | ||||
| extern const struct samsung_pin_ctrl exynos5433_pin_ctrl[]; | ||||
| extern const struct samsung_pin_ctrl exynos7_pin_ctrl[]; | ||||
| extern const struct samsung_pin_ctrl s3c64xx_pin_ctrl[]; | ||||
| extern const struct samsung_pin_ctrl s3c2412_pin_ctrl[]; | ||||
|   | ||||
| @@ -92,10 +92,10 @@ static int sh_pfc_map_resources(struct sh_pfc *pfc, | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static void __iomem *sh_pfc_phys_to_virt(struct sh_pfc *pfc, | ||||
| 					 unsigned long address) | ||||
| static void __iomem *sh_pfc_phys_to_virt(struct sh_pfc *pfc, u32 reg) | ||||
| { | ||||
| 	struct sh_pfc_window *window; | ||||
| 	phys_addr_t address = reg; | ||||
| 	unsigned int i; | ||||
|  | ||||
| 	/* scan through physical windows and convert address */ | ||||
| @@ -144,8 +144,7 @@ static int sh_pfc_enum_in_range(u16 enum_id, const struct pinmux_range *r) | ||||
| 	return 1; | ||||
| } | ||||
|  | ||||
| unsigned long sh_pfc_read_raw_reg(void __iomem *mapped_reg, | ||||
| 				  unsigned long reg_width) | ||||
| u32 sh_pfc_read_raw_reg(void __iomem *mapped_reg, unsigned int reg_width) | ||||
| { | ||||
| 	switch (reg_width) { | ||||
| 	case 8: | ||||
| @@ -160,8 +159,8 @@ unsigned long sh_pfc_read_raw_reg(void __iomem *mapped_reg, | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| void sh_pfc_write_raw_reg(void __iomem *mapped_reg, unsigned long reg_width, | ||||
| 			  unsigned long data) | ||||
| void sh_pfc_write_raw_reg(void __iomem *mapped_reg, unsigned int reg_width, | ||||
| 			  u32 data) | ||||
| { | ||||
| 	switch (reg_width) { | ||||
| 	case 8: | ||||
| @@ -180,10 +179,9 @@ void sh_pfc_write_raw_reg(void __iomem *mapped_reg, unsigned long reg_width, | ||||
|  | ||||
| static void sh_pfc_config_reg_helper(struct sh_pfc *pfc, | ||||
| 				     const struct pinmux_cfg_reg *crp, | ||||
| 				     unsigned long in_pos, | ||||
| 				     void __iomem **mapped_regp, | ||||
| 				     unsigned long *maskp, | ||||
| 				     unsigned long *posp) | ||||
| 				     unsigned int in_pos, | ||||
| 				     void __iomem **mapped_regp, u32 *maskp, | ||||
| 				     unsigned int *posp) | ||||
| { | ||||
| 	unsigned int k; | ||||
|  | ||||
| @@ -202,15 +200,16 @@ static void sh_pfc_config_reg_helper(struct sh_pfc *pfc, | ||||
|  | ||||
| static void sh_pfc_write_config_reg(struct sh_pfc *pfc, | ||||
| 				    const struct pinmux_cfg_reg *crp, | ||||
| 				    unsigned long field, unsigned long value) | ||||
| 				    unsigned int field, u32 value) | ||||
| { | ||||
| 	void __iomem *mapped_reg; | ||||
| 	unsigned long mask, pos, data; | ||||
| 	unsigned int pos; | ||||
| 	u32 mask, data; | ||||
|  | ||||
| 	sh_pfc_config_reg_helper(pfc, crp, field, &mapped_reg, &mask, &pos); | ||||
|  | ||||
| 	dev_dbg(pfc->dev, "write_reg addr = %lx, value = %ld, field = %ld, " | ||||
| 		"r_width = %ld, f_width = %ld\n", | ||||
| 	dev_dbg(pfc->dev, "write_reg addr = %x, value = 0x%x, field = %u, " | ||||
| 		"r_width = %u, f_width = %u\n", | ||||
| 		crp->reg, value, field, crp->reg_width, crp->field_width); | ||||
|  | ||||
| 	mask = ~(mask << pos); | ||||
| @@ -229,26 +228,28 @@ static void sh_pfc_write_config_reg(struct sh_pfc *pfc, | ||||
| } | ||||
|  | ||||
| static int sh_pfc_get_config_reg(struct sh_pfc *pfc, u16 enum_id, | ||||
| 				 const struct pinmux_cfg_reg **crp, int *fieldp, | ||||
| 				 int *valuep) | ||||
| 				 const struct pinmux_cfg_reg **crp, | ||||
| 				 unsigned int *fieldp, u32 *valuep) | ||||
| { | ||||
| 	const struct pinmux_cfg_reg *config_reg; | ||||
| 	unsigned long r_width, f_width, curr_width, ncomb; | ||||
| 	unsigned int k, m, n, pos, bit_pos; | ||||
| 	unsigned int k = 0; | ||||
|  | ||||
| 	k = 0; | ||||
| 	while (1) { | ||||
| 		config_reg = pfc->info->cfg_regs + k; | ||||
|  | ||||
| 		r_width = config_reg->reg_width; | ||||
| 		f_width = config_reg->field_width; | ||||
| 		const struct pinmux_cfg_reg *config_reg = | ||||
| 			pfc->info->cfg_regs + k; | ||||
| 		unsigned int r_width = config_reg->reg_width; | ||||
| 		unsigned int f_width = config_reg->field_width; | ||||
| 		unsigned int curr_width; | ||||
| 		unsigned int bit_pos; | ||||
| 		unsigned int pos = 0; | ||||
| 		unsigned int m = 0; | ||||
|  | ||||
| 		if (!r_width) | ||||
| 			break; | ||||
|  | ||||
| 		pos = 0; | ||||
| 		m = 0; | ||||
| 		for (bit_pos = 0; bit_pos < r_width; bit_pos += curr_width) { | ||||
| 			u32 ncomb; | ||||
| 			u32 n; | ||||
|  | ||||
| 			if (f_width) | ||||
| 				curr_width = f_width; | ||||
| 			else | ||||
| @@ -297,11 +298,8 @@ static int sh_pfc_mark_to_enum(struct sh_pfc *pfc, u16 mark, int pos, | ||||
|  | ||||
| int sh_pfc_config_mux(struct sh_pfc *pfc, unsigned mark, int pinmux_type) | ||||
| { | ||||
| 	const struct pinmux_cfg_reg *cr = NULL; | ||||
| 	u16 enum_id; | ||||
| 	const struct pinmux_range *range; | ||||
| 	int in_range, pos, field, value; | ||||
| 	int ret; | ||||
| 	int pos = 0; | ||||
|  | ||||
| 	switch (pinmux_type) { | ||||
| 	case PINMUX_TYPE_GPIO: | ||||
| @@ -321,13 +319,15 @@ int sh_pfc_config_mux(struct sh_pfc *pfc, unsigned mark, int pinmux_type) | ||||
| 		return -EINVAL; | ||||
| 	} | ||||
|  | ||||
| 	pos = 0; | ||||
| 	enum_id = 0; | ||||
| 	field = 0; | ||||
| 	value = 0; | ||||
|  | ||||
| 	/* Iterate over all the configuration fields we need to update. */ | ||||
| 	while (1) { | ||||
| 		const struct pinmux_cfg_reg *cr; | ||||
| 		unsigned int field; | ||||
| 		u16 enum_id; | ||||
| 		u32 value; | ||||
| 		int in_range; | ||||
| 		int ret; | ||||
|  | ||||
| 		pos = sh_pfc_mark_to_enum(pfc, mark, pos, &enum_id); | ||||
| 		if (pos < 0) | ||||
| 			return pos; | ||||
| @@ -579,9 +579,6 @@ static int sh_pfc_remove(struct platform_device *pdev) | ||||
| } | ||||
|  | ||||
| static const struct platform_device_id sh_pfc_id_table[] = { | ||||
| #ifdef CONFIG_PINCTRL_PFC_EMEV2 | ||||
| 	{ "pfc-emev2", (kernel_ulong_t)&emev2_pinmux_info }, | ||||
| #endif | ||||
| #ifdef CONFIG_PINCTRL_PFC_R8A73A4 | ||||
| 	{ "pfc-r8a73a4", (kernel_ulong_t)&r8a73a4_pinmux_info }, | ||||
| #endif | ||||
| @@ -594,12 +591,6 @@ static const struct platform_device_id sh_pfc_id_table[] = { | ||||
| #ifdef CONFIG_PINCTRL_PFC_R8A7779 | ||||
| 	{ "pfc-r8a7779", (kernel_ulong_t)&r8a7779_pinmux_info }, | ||||
| #endif | ||||
| #ifdef CONFIG_PINCTRL_PFC_R8A7790 | ||||
| 	{ "pfc-r8a7790", (kernel_ulong_t)&r8a7790_pinmux_info }, | ||||
| #endif | ||||
| #ifdef CONFIG_PINCTRL_PFC_R8A7791 | ||||
| 	{ "pfc-r8a7791", (kernel_ulong_t)&r8a7791_pinmux_info }, | ||||
| #endif | ||||
| #ifdef CONFIG_PINCTRL_PFC_SH7203 | ||||
| 	{ "pfc-sh7203", (kernel_ulong_t)&sh7203_pinmux_info }, | ||||
| #endif | ||||
|   | ||||
| @@ -57,10 +57,9 @@ int sh_pfc_unregister_gpiochip(struct sh_pfc *pfc); | ||||
| int sh_pfc_register_pinctrl(struct sh_pfc *pfc); | ||||
| int sh_pfc_unregister_pinctrl(struct sh_pfc *pfc); | ||||
|  | ||||
| unsigned long sh_pfc_read_raw_reg(void __iomem *mapped_reg, | ||||
| 				  unsigned long reg_width); | ||||
| void sh_pfc_write_raw_reg(void __iomem *mapped_reg, unsigned long reg_width, | ||||
| 			  unsigned long data); | ||||
| u32 sh_pfc_read_raw_reg(void __iomem *mapped_reg, unsigned int reg_width); | ||||
| void sh_pfc_write_raw_reg(void __iomem *mapped_reg, unsigned int reg_width, | ||||
| 			  u32 data); | ||||
|  | ||||
| int sh_pfc_get_pin_index(struct sh_pfc *pfc, unsigned int pin); | ||||
| int sh_pfc_config_mux(struct sh_pfc *pfc, unsigned mark, int pinmux_type); | ||||
|   | ||||
| @@ -21,7 +21,7 @@ | ||||
|  | ||||
| struct sh_pfc_gpio_data_reg { | ||||
| 	const struct pinmux_data_reg *info; | ||||
| 	unsigned long shadow; | ||||
| 	u32 shadow; | ||||
| }; | ||||
|  | ||||
| struct sh_pfc_gpio_pin { | ||||
| @@ -59,19 +59,20 @@ static void gpio_get_data_reg(struct sh_pfc_chip *chip, unsigned int offset, | ||||
| 	*bit = gpio_pin->dbit; | ||||
| } | ||||
|  | ||||
| static unsigned long gpio_read_data_reg(struct sh_pfc_chip *chip, | ||||
| 					const struct pinmux_data_reg *dreg) | ||||
| static u32 gpio_read_data_reg(struct sh_pfc_chip *chip, | ||||
| 			      const struct pinmux_data_reg *dreg) | ||||
| { | ||||
| 	void __iomem *mem = dreg->reg - chip->mem->phys + chip->mem->virt; | ||||
| 	phys_addr_t address = dreg->reg; | ||||
| 	void __iomem *mem = address - chip->mem->phys + chip->mem->virt; | ||||
|  | ||||
| 	return sh_pfc_read_raw_reg(mem, dreg->reg_width); | ||||
| } | ||||
|  | ||||
| static void gpio_write_data_reg(struct sh_pfc_chip *chip, | ||||
| 				const struct pinmux_data_reg *dreg, | ||||
| 				unsigned long value) | ||||
| 				const struct pinmux_data_reg *dreg, u32 value) | ||||
| { | ||||
| 	void __iomem *mem = dreg->reg - chip->mem->phys + chip->mem->virt; | ||||
| 	phys_addr_t address = dreg->reg; | ||||
| 	void __iomem *mem = address - chip->mem->phys + chip->mem->virt; | ||||
|  | ||||
| 	sh_pfc_write_raw_reg(mem, dreg->reg_width, value); | ||||
| } | ||||
| @@ -85,7 +86,7 @@ static void gpio_setup_data_reg(struct sh_pfc_chip *chip, unsigned idx) | ||||
| 	unsigned int bit; | ||||
| 	unsigned int i; | ||||
|  | ||||
| 	for (i = 0, dreg = pfc->info->data_regs; dreg->reg; ++i, ++dreg) { | ||||
| 	for (i = 0, dreg = pfc->info->data_regs; dreg->reg_width; ++i, ++dreg) { | ||||
| 		for (bit = 0; bit < dreg->reg_width; bit++) { | ||||
| 			if (dreg->enum_ids[bit] == pin->enum_id) { | ||||
| 				gpio_pin->dreg = i; | ||||
| @@ -154,17 +155,17 @@ static void gpio_pin_set_value(struct sh_pfc_chip *chip, unsigned offset, | ||||
| 			       int value) | ||||
| { | ||||
| 	struct sh_pfc_gpio_data_reg *reg; | ||||
| 	unsigned long pos; | ||||
| 	unsigned int bit; | ||||
| 	unsigned int pos; | ||||
|  | ||||
| 	gpio_get_data_reg(chip, offset, ®, &bit); | ||||
|  | ||||
| 	pos = reg->info->reg_width - (bit + 1); | ||||
|  | ||||
| 	if (value) | ||||
| 		set_bit(pos, ®->shadow); | ||||
| 		reg->shadow |= BIT(pos); | ||||
| 	else | ||||
| 		clear_bit(pos, ®->shadow); | ||||
| 		reg->shadow &= ~BIT(pos); | ||||
|  | ||||
| 	gpio_write_data_reg(chip, reg->info, reg->shadow); | ||||
| } | ||||
| @@ -186,8 +187,8 @@ static int gpio_pin_get(struct gpio_chip *gc, unsigned offset) | ||||
| { | ||||
| 	struct sh_pfc_chip *chip = gpio_to_pfc_chip(gc); | ||||
| 	struct sh_pfc_gpio_data_reg *reg; | ||||
| 	unsigned long pos; | ||||
| 	unsigned int bit; | ||||
| 	unsigned int pos; | ||||
|  | ||||
| 	gpio_get_data_reg(chip, offset, ®, &bit); | ||||
|  | ||||
| @@ -341,6 +342,7 @@ sh_pfc_add_gpiochip(struct sh_pfc *pfc, int(*setup)(struct sh_pfc_chip *), | ||||
| int sh_pfc_register_gpiochip(struct sh_pfc *pfc) | ||||
| { | ||||
| 	struct sh_pfc_chip *chip; | ||||
| 	phys_addr_t address; | ||||
| 	unsigned int i; | ||||
| 	int ret; | ||||
|  | ||||
| @@ -352,11 +354,12 @@ int sh_pfc_register_gpiochip(struct sh_pfc *pfc) | ||||
| 	 * that covers the data registers. In that case don't try to handle | ||||
| 	 * GPIOs. | ||||
| 	 */ | ||||
| 	address = pfc->info->data_regs[0].reg; | ||||
| 	for (i = 0; i < pfc->num_windows; ++i) { | ||||
| 		struct sh_pfc_window *window = &pfc->windows[i]; | ||||
|  | ||||
| 		if (pfc->info->data_regs[0].reg >= window->phys && | ||||
| 		    pfc->info->data_regs[0].reg < window->phys + window->size) | ||||
| 		if (address >= window->phys && | ||||
| 		    address < window->phys + window->size) | ||||
| 			break; | ||||
| 	} | ||||
|  | ||||
|   | ||||
| @@ -1799,6 +1799,81 @@ static const unsigned int audio_clkout_d_pins[] = { | ||||
| static const unsigned int audio_clkout_d_mux[] = { | ||||
| 	AUDIO_CLKOUT_D_MARK, | ||||
| }; | ||||
| /* - AVB -------------------------------------------------------------------- */ | ||||
| static const unsigned int avb_link_pins[] = { | ||||
| 	RCAR_GP_PIN(3, 11), | ||||
| }; | ||||
| static const unsigned int avb_link_mux[] = { | ||||
| 	AVB_LINK_MARK, | ||||
| }; | ||||
| static const unsigned int avb_magic_pins[] = { | ||||
| 	RCAR_GP_PIN(2, 14), | ||||
| }; | ||||
| static const unsigned int avb_magic_mux[] = { | ||||
| 	AVB_MAGIC_MARK, | ||||
| }; | ||||
| static const unsigned int avb_phy_int_pins[] = { | ||||
| 	RCAR_GP_PIN(2, 15), | ||||
| }; | ||||
| static const unsigned int avb_phy_int_mux[] = { | ||||
| 	AVB_PHY_INT_MARK, | ||||
| }; | ||||
| static const unsigned int avb_mdio_pins[] = { | ||||
| 	RCAR_GP_PIN(2, 11), RCAR_GP_PIN(2, 12), | ||||
| }; | ||||
| static const unsigned int avb_mdio_mux[] = { | ||||
| 	AVB_MDC_MARK, AVB_MDIO_MARK, | ||||
| }; | ||||
| static const unsigned int avb_mii_pins[] = { | ||||
| 	RCAR_GP_PIN(0, 8), RCAR_GP_PIN(0, 9), RCAR_GP_PIN(0, 10), | ||||
| 	RCAR_GP_PIN(0, 11), | ||||
|  | ||||
| 	RCAR_GP_PIN(3, 13), RCAR_GP_PIN(2, 0), RCAR_GP_PIN(2, 1), | ||||
| 	RCAR_GP_PIN(2, 2), | ||||
|  | ||||
| 	RCAR_GP_PIN(2, 7), RCAR_GP_PIN(2, 8), RCAR_GP_PIN(2, 9), | ||||
| 	RCAR_GP_PIN(2, 10), RCAR_GP_PIN(3, 8), RCAR_GP_PIN(3, 10), | ||||
| 	RCAR_GP_PIN(3, 12), | ||||
| }; | ||||
| static const unsigned int avb_mii_mux[] = { | ||||
| 	AVB_TXD0_MARK, AVB_TXD1_MARK, AVB_TXD2_MARK, | ||||
| 	AVB_TXD3_MARK, | ||||
|  | ||||
| 	AVB_RXD0_MARK, AVB_RXD1_MARK, AVB_RXD2_MARK, | ||||
| 	AVB_RXD3_MARK, | ||||
|  | ||||
| 	AVB_RX_ER_MARK, AVB_RX_CLK_MARK, AVB_RX_DV_MARK, | ||||
| 	AVB_CRS_MARK, AVB_TX_EN_MARK, AVB_TX_CLK_MARK, | ||||
| 	AVB_COL_MARK, | ||||
| }; | ||||
| static const unsigned int avb_gmii_pins[] = { | ||||
| 	RCAR_GP_PIN(0, 8), RCAR_GP_PIN(0, 9), RCAR_GP_PIN(0, 10), | ||||
| 	RCAR_GP_PIN(0, 11), RCAR_GP_PIN(0, 12), RCAR_GP_PIN(0, 13), | ||||
| 	RCAR_GP_PIN(0, 14), RCAR_GP_PIN(0, 15), | ||||
|  | ||||
| 	RCAR_GP_PIN(3, 13), RCAR_GP_PIN(2, 0), RCAR_GP_PIN(2, 1), | ||||
| 	RCAR_GP_PIN(2, 2), RCAR_GP_PIN(2, 3), RCAR_GP_PIN(2, 4), | ||||
| 	RCAR_GP_PIN(2, 5), RCAR_GP_PIN(2, 6), | ||||
|  | ||||
| 	RCAR_GP_PIN(2, 7), RCAR_GP_PIN(2, 8), RCAR_GP_PIN(2, 9), | ||||
| 	RCAR_GP_PIN(2, 10), RCAR_GP_PIN(2, 13), RCAR_GP_PIN(2, 16), | ||||
| 	RCAR_GP_PIN(3, 8), RCAR_GP_PIN(3, 9), RCAR_GP_PIN(3, 10), | ||||
| 	RCAR_GP_PIN(3, 12), | ||||
| }; | ||||
| static const unsigned int avb_gmii_mux[] = { | ||||
| 	AVB_TXD0_MARK, AVB_TXD1_MARK, AVB_TXD2_MARK, | ||||
| 	AVB_TXD3_MARK, AVB_TXD4_MARK, AVB_TXD5_MARK, | ||||
| 	AVB_TXD6_MARK, AVB_TXD7_MARK, | ||||
|  | ||||
| 	AVB_RXD0_MARK, AVB_RXD1_MARK, AVB_RXD2_MARK, | ||||
| 	AVB_RXD3_MARK, AVB_RXD4_MARK, AVB_RXD5_MARK, | ||||
| 	AVB_RXD6_MARK, AVB_RXD7_MARK, | ||||
|  | ||||
| 	AVB_RX_ER_MARK, AVB_RX_CLK_MARK, AVB_RX_DV_MARK, | ||||
| 	AVB_CRS_MARK, AVB_GTX_CLK_MARK, AVB_GTXREFCLK_MARK, | ||||
| 	AVB_TX_EN_MARK, AVB_TX_ER_MARK, AVB_TX_CLK_MARK, | ||||
| 	AVB_COL_MARK, | ||||
| }; | ||||
| /* - DU RGB ----------------------------------------------------------------- */ | ||||
| static const unsigned int du_rgb666_pins[] = { | ||||
| 	/* R[7:2], G[7:2], B[7:2] */ | ||||
| @@ -3823,6 +3898,12 @@ static const struct sh_pfc_pin_group pinmux_groups[] = { | ||||
| 	SH_PFC_PIN_GROUP(audio_clkout_b), | ||||
| 	SH_PFC_PIN_GROUP(audio_clkout_c), | ||||
| 	SH_PFC_PIN_GROUP(audio_clkout_d), | ||||
| 	SH_PFC_PIN_GROUP(avb_link), | ||||
| 	SH_PFC_PIN_GROUP(avb_magic), | ||||
| 	SH_PFC_PIN_GROUP(avb_phy_int), | ||||
| 	SH_PFC_PIN_GROUP(avb_mdio), | ||||
| 	SH_PFC_PIN_GROUP(avb_mii), | ||||
| 	SH_PFC_PIN_GROUP(avb_gmii), | ||||
| 	SH_PFC_PIN_GROUP(du_rgb666), | ||||
| 	SH_PFC_PIN_GROUP(du_rgb888), | ||||
| 	SH_PFC_PIN_GROUP(du_clk_out_0), | ||||
| @@ -4101,6 +4182,15 @@ static const char * const audio_clk_groups[] = { | ||||
| 	"audio_clkout_d", | ||||
| }; | ||||
|  | ||||
| static const char * const avb_groups[] = { | ||||
| 	"avb_link", | ||||
| 	"avb_magic", | ||||
| 	"avb_phy_int", | ||||
| 	"avb_mdio", | ||||
| 	"avb_mii", | ||||
| 	"avb_gmii", | ||||
| }; | ||||
|  | ||||
| static const char * const du_groups[] = { | ||||
| 	"du_rgb666", | ||||
| 	"du_rgb888", | ||||
| @@ -4507,6 +4597,7 @@ static const char * const vin3_groups[] = { | ||||
|  | ||||
| static const struct sh_pfc_function pinmux_functions[] = { | ||||
| 	SH_PFC_FUNCTION(audio_clk), | ||||
| 	SH_PFC_FUNCTION(avb), | ||||
| 	SH_PFC_FUNCTION(du), | ||||
| 	SH_PFC_FUNCTION(du0), | ||||
| 	SH_PFC_FUNCTION(du1), | ||||
|   | ||||
| @@ -69,9 +69,10 @@ struct pinmux_func { | ||||
| }; | ||||
|  | ||||
| struct pinmux_cfg_reg { | ||||
| 	unsigned long reg, reg_width, field_width; | ||||
| 	u32 reg; | ||||
| 	u8 reg_width, field_width; | ||||
| 	const u16 *enum_ids; | ||||
| 	const unsigned long *var_field_width; | ||||
| 	const u8 *var_field_width; | ||||
| }; | ||||
|  | ||||
| #define PINMUX_CFG_REG(name, r, r_width, f_width) \ | ||||
| @@ -80,12 +81,13 @@ struct pinmux_cfg_reg { | ||||
|  | ||||
| #define PINMUX_CFG_REG_VAR(name, r, r_width, var_fw0, var_fwn...) \ | ||||
| 	.reg = r, .reg_width = r_width,	\ | ||||
| 	.var_field_width = (const unsigned long [r_width]) \ | ||||
| 	.var_field_width = (const u8 [r_width]) \ | ||||
| 		{ var_fw0, var_fwn, 0 }, \ | ||||
| 	.enum_ids = (const u16 []) | ||||
|  | ||||
| struct pinmux_data_reg { | ||||
| 	unsigned long reg, reg_width; | ||||
| 	u32 reg; | ||||
| 	u8 reg_width; | ||||
| 	const u16 *enum_ids; | ||||
| }; | ||||
|  | ||||
| @@ -148,7 +150,7 @@ struct sh_pfc_soc_info { | ||||
| 	const struct pinmux_irq *gpio_irq; | ||||
| 	unsigned int gpio_irq_size; | ||||
|  | ||||
| 	unsigned long unlock_reg; | ||||
| 	u32 unlock_reg; | ||||
| }; | ||||
|  | ||||
| /* ----------------------------------------------------------------------------- | ||||
| @@ -302,20 +304,21 @@ struct sh_pfc_soc_info { | ||||
| /* | ||||
|  * PORTnCR macro | ||||
|  */ | ||||
| #define _PCRH(in, in_pd, in_pu, out)	\ | ||||
| 	0, (out), (in), 0,		\ | ||||
| 	0, 0, 0, 0,			\ | ||||
| 	0, 0, (in_pd), 0,		\ | ||||
| 	0, 0, (in_pu), 0 | ||||
|  | ||||
| #define PORTCR(nr, reg)							\ | ||||
| 	{								\ | ||||
| 		PINMUX_CFG_REG("PORT" nr "CR", reg, 8, 4) {		\ | ||||
| 			_PCRH(PORT##nr##_IN, 0, 0, PORT##nr##_OUT),	\ | ||||
| 				PORT##nr##_FN0, PORT##nr##_FN1,		\ | ||||
| 				PORT##nr##_FN2, PORT##nr##_FN3,		\ | ||||
| 				PORT##nr##_FN4, PORT##nr##_FN5,		\ | ||||
| 				PORT##nr##_FN6, PORT##nr##_FN7 }	\ | ||||
| 		PINMUX_CFG_REG_VAR("PORT" nr "CR", reg, 8, 2, 2, 1, 3) {\ | ||||
| 			/* PULMD[1:0], handled by .set_bias() */	\ | ||||
| 			0, 0, 0, 0,					\ | ||||
| 			/* IE and OE */					\ | ||||
| 			0, PORT##nr##_OUT, PORT##nr##_IN, 0,		\ | ||||
| 			/* SEC, not supported */			\ | ||||
| 			0, 0,						\ | ||||
| 			/* PTMD[2:0] */					\ | ||||
| 			PORT##nr##_FN0, PORT##nr##_FN1,			\ | ||||
| 			PORT##nr##_FN2, PORT##nr##_FN3,			\ | ||||
| 			PORT##nr##_FN4, PORT##nr##_FN5,			\ | ||||
| 			PORT##nr##_FN6, PORT##nr##_FN7			\ | ||||
| 		}							\ | ||||
| 	} | ||||
|  | ||||
| #endif /* __SH_PFC_H */ | ||||
|   | ||||
| @@ -39,10 +39,9 @@ struct sirfsoc_gpio_bank { | ||||
| struct sirfsoc_gpio_chip { | ||||
| 	struct of_mm_gpio_chip chip; | ||||
| 	struct sirfsoc_gpio_bank sgpio_bank[SIRFSOC_GPIO_NO_OF_BANKS]; | ||||
| 	spinlock_t lock; | ||||
| }; | ||||
|  | ||||
| static DEFINE_SPINLOCK(sgpio_lock); | ||||
|  | ||||
| static struct sirfsoc_pin_group *sirfsoc_pin_groups; | ||||
| static int sirfsoc_pingrp_cnt; | ||||
|  | ||||
| @@ -427,13 +426,13 @@ static void sirfsoc_gpio_irq_ack(struct irq_data *d) | ||||
|  | ||||
| 	offset = SIRFSOC_GPIO_CTRL(bank->id, idx); | ||||
|  | ||||
| 	spin_lock_irqsave(&sgpio_lock, flags); | ||||
| 	spin_lock_irqsave(&sgpio->lock, flags); | ||||
|  | ||||
| 	val = readl(sgpio->chip.regs + offset); | ||||
|  | ||||
| 	writel(val, sgpio->chip.regs + offset); | ||||
|  | ||||
| 	spin_unlock_irqrestore(&sgpio_lock, flags); | ||||
| 	spin_unlock_irqrestore(&sgpio->lock, flags); | ||||
| } | ||||
|  | ||||
| static void __sirfsoc_gpio_irq_mask(struct sirfsoc_gpio_chip *sgpio, | ||||
| @@ -445,14 +444,14 @@ static void __sirfsoc_gpio_irq_mask(struct sirfsoc_gpio_chip *sgpio, | ||||
|  | ||||
| 	offset = SIRFSOC_GPIO_CTRL(bank->id, idx); | ||||
|  | ||||
| 	spin_lock_irqsave(&sgpio_lock, flags); | ||||
| 	spin_lock_irqsave(&sgpio->lock, flags); | ||||
|  | ||||
| 	val = readl(sgpio->chip.regs + offset); | ||||
| 	val &= ~SIRFSOC_GPIO_CTL_INTR_EN_MASK; | ||||
| 	val &= ~SIRFSOC_GPIO_CTL_INTR_STS_MASK; | ||||
| 	writel(val, sgpio->chip.regs + offset); | ||||
|  | ||||
| 	spin_unlock_irqrestore(&sgpio_lock, flags); | ||||
| 	spin_unlock_irqrestore(&sgpio->lock, flags); | ||||
| } | ||||
|  | ||||
| static void sirfsoc_gpio_irq_mask(struct irq_data *d) | ||||
| @@ -475,14 +474,14 @@ static void sirfsoc_gpio_irq_unmask(struct irq_data *d) | ||||
|  | ||||
| 	offset = SIRFSOC_GPIO_CTRL(bank->id, idx); | ||||
|  | ||||
| 	spin_lock_irqsave(&sgpio_lock, flags); | ||||
| 	spin_lock_irqsave(&sgpio->lock, flags); | ||||
|  | ||||
| 	val = readl(sgpio->chip.regs + offset); | ||||
| 	val &= ~SIRFSOC_GPIO_CTL_INTR_STS_MASK; | ||||
| 	val |= SIRFSOC_GPIO_CTL_INTR_EN_MASK; | ||||
| 	writel(val, sgpio->chip.regs + offset); | ||||
|  | ||||
| 	spin_unlock_irqrestore(&sgpio_lock, flags); | ||||
| 	spin_unlock_irqrestore(&sgpio->lock, flags); | ||||
| } | ||||
|  | ||||
| static int sirfsoc_gpio_irq_type(struct irq_data *d, unsigned type) | ||||
| @@ -496,7 +495,7 @@ static int sirfsoc_gpio_irq_type(struct irq_data *d, unsigned type) | ||||
|  | ||||
| 	offset = SIRFSOC_GPIO_CTRL(bank->id, idx); | ||||
|  | ||||
| 	spin_lock_irqsave(&sgpio_lock, flags); | ||||
| 	spin_lock_irqsave(&sgpio->lock, flags); | ||||
|  | ||||
| 	val = readl(sgpio->chip.regs + offset); | ||||
| 	val &= ~(SIRFSOC_GPIO_CTL_INTR_STS_MASK | SIRFSOC_GPIO_CTL_OUT_EN_MASK); | ||||
| @@ -533,7 +532,7 @@ static int sirfsoc_gpio_irq_type(struct irq_data *d, unsigned type) | ||||
|  | ||||
| 	writel(val, sgpio->chip.regs + offset); | ||||
|  | ||||
| 	spin_unlock_irqrestore(&sgpio_lock, flags); | ||||
| 	spin_unlock_irqrestore(&sgpio->lock, flags); | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
| @@ -568,7 +567,7 @@ static void sirfsoc_gpio_handle_irq(unsigned int irq, struct irq_desc *desc) | ||||
| 	status = readl(sgpio->chip.regs + SIRFSOC_GPIO_INT_STATUS(bank->id)); | ||||
| 	if (!status) { | ||||
| 		printk(KERN_WARNING | ||||
| 			"%s: gpio id %d status %#x no interrupt is flaged\n", | ||||
| 			"%s: gpio id %d status %#x no interrupt is flagged\n", | ||||
| 			__func__, bank->id, status); | ||||
| 		handle_bad_irq(irq, desc); | ||||
| 		return; | ||||
| @@ -697,11 +696,11 @@ static int sirfsoc_gpio_direction_output(struct gpio_chip *chip, | ||||
|  | ||||
| 	offset = SIRFSOC_GPIO_CTRL(bank->id, idx); | ||||
|  | ||||
| 	spin_lock_irqsave(&sgpio_lock, flags); | ||||
| 	spin_lock_irqsave(&sgpio->lock, flags); | ||||
|  | ||||
| 	sirfsoc_gpio_set_output(sgpio, bank, offset, value); | ||||
|  | ||||
| 	spin_unlock_irqrestore(&sgpio_lock, flags); | ||||
| 	spin_unlock_irqrestore(&sgpio->lock, flags); | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
| @@ -793,6 +792,7 @@ static int sirfsoc_gpio_probe(struct device_node *np) | ||||
| 	sgpio = devm_kzalloc(&pdev->dev, sizeof(*sgpio), GFP_KERNEL); | ||||
| 	if (!sgpio) | ||||
| 		return -ENOMEM; | ||||
| 	spin_lock_init(&sgpio->lock); | ||||
|  | ||||
| 	regs = of_iomap(np, 0); | ||||
| 	if (!regs) | ||||
|   | ||||
| @@ -1020,7 +1020,7 @@ static int sun4i_a10_pinctrl_probe(struct platform_device *pdev) | ||||
| 				  &sun4i_a10_pinctrl_data); | ||||
| } | ||||
|  | ||||
| static struct of_device_id sun4i_a10_pinctrl_match[] = { | ||||
| static const struct of_device_id sun4i_a10_pinctrl_match[] = { | ||||
| 	{ .compatible = "allwinner,sun4i-a10-pinctrl", }, | ||||
| 	{} | ||||
| }; | ||||
|   | ||||
| @@ -670,7 +670,7 @@ static int sun5i_a10s_pinctrl_probe(struct platform_device *pdev) | ||||
| 				  &sun5i_a10s_pinctrl_data); | ||||
| } | ||||
|  | ||||
| static struct of_device_id sun5i_a10s_pinctrl_match[] = { | ||||
| static const struct of_device_id sun5i_a10s_pinctrl_match[] = { | ||||
| 	{ .compatible = "allwinner,sun5i-a10s-pinctrl", }, | ||||
| 	{} | ||||
| }; | ||||
|   | ||||
| @@ -388,7 +388,7 @@ static int sun5i_a13_pinctrl_probe(struct platform_device *pdev) | ||||
| 				  &sun5i_a13_pinctrl_data); | ||||
| } | ||||
|  | ||||
| static struct of_device_id sun5i_a13_pinctrl_match[] = { | ||||
| static const struct of_device_id sun5i_a13_pinctrl_match[] = { | ||||
| 	{ .compatible = "allwinner,sun5i-a13-pinctrl", }, | ||||
| 	{} | ||||
| }; | ||||
|   | ||||
| @@ -120,7 +120,7 @@ static int sun6i_a31_r_pinctrl_probe(struct platform_device *pdev) | ||||
| 	return ret; | ||||
| } | ||||
|  | ||||
| static struct of_device_id sun6i_a31_r_pinctrl_match[] = { | ||||
| static const struct of_device_id sun6i_a31_r_pinctrl_match[] = { | ||||
| 	{ .compatible = "allwinner,sun6i-a31-r-pinctrl", }, | ||||
| 	{} | ||||
| }; | ||||
|   | ||||
| @@ -922,7 +922,7 @@ static int sun6i_a31_pinctrl_probe(struct platform_device *pdev) | ||||
| 				  &sun6i_a31_pinctrl_data); | ||||
| } | ||||
|  | ||||
| static struct of_device_id sun6i_a31_pinctrl_match[] = { | ||||
| static const struct of_device_id sun6i_a31_pinctrl_match[] = { | ||||
| 	{ .compatible = "allwinner,sun6i-a31-pinctrl", }, | ||||
| 	{} | ||||
| }; | ||||
|   | ||||
| @@ -794,7 +794,7 @@ static int sun6i_a31s_pinctrl_probe(struct platform_device *pdev) | ||||
| 				  &sun6i_a31s_pinctrl_data); | ||||
| } | ||||
|  | ||||
| static struct of_device_id sun6i_a31s_pinctrl_match[] = { | ||||
| static const struct of_device_id sun6i_a31s_pinctrl_match[] = { | ||||
| 	{ .compatible = "allwinner,sun6i-a31s-pinctrl", }, | ||||
| 	{} | ||||
| }; | ||||
|   | ||||
| @@ -1045,7 +1045,7 @@ static int sun7i_a20_pinctrl_probe(struct platform_device *pdev) | ||||
| 				  &sun7i_a20_pinctrl_data); | ||||
| } | ||||
|  | ||||
| static struct of_device_id sun7i_a20_pinctrl_match[] = { | ||||
| static const struct of_device_id sun7i_a20_pinctrl_match[] = { | ||||
| 	{ .compatible = "allwinner,sun7i-a20-pinctrl", }, | ||||
| 	{} | ||||
| }; | ||||
|   | ||||
| @@ -119,7 +119,7 @@ static int sun8i_a23_r_pinctrl_probe(struct platform_device *pdev) | ||||
| 	return ret; | ||||
| } | ||||
|  | ||||
| static struct of_device_id sun8i_a23_r_pinctrl_match[] = { | ||||
| static const struct of_device_id sun8i_a23_r_pinctrl_match[] = { | ||||
| 	{ .compatible = "allwinner,sun8i-a23-r-pinctrl", }, | ||||
| 	{} | ||||
| }; | ||||
|   | ||||
| @@ -571,7 +571,7 @@ static int sun8i_a23_pinctrl_probe(struct platform_device *pdev) | ||||
| 				  &sun8i_a23_pinctrl_data); | ||||
| } | ||||
|  | ||||
| static struct of_device_id sun8i_a23_pinctrl_match[] = { | ||||
| static const struct of_device_id sun8i_a23_pinctrl_match[] = { | ||||
| 	{ .compatible = "allwinner,sun8i-a23-pinctrl", }, | ||||
| 	{} | ||||
| }; | ||||
|   | ||||
| @@ -729,7 +729,7 @@ static int sun9i_a80_pinctrl_probe(struct platform_device *pdev) | ||||
| 				  &sun9i_a80_pinctrl_data); | ||||
| } | ||||
|  | ||||
| static struct of_device_id sun9i_a80_pinctrl_match[] = { | ||||
| static const struct of_device_id sun9i_a80_pinctrl_match[] = { | ||||
| 	{ .compatible = "allwinner,sun9i-a80-pinctrl", }, | ||||
| 	{} | ||||
| }; | ||||
|   | ||||
| @@ -478,7 +478,7 @@ static int vt8500_pinctrl_remove(struct platform_device *pdev) | ||||
| 	return wmt_pinctrl_remove(pdev); | ||||
| } | ||||
|  | ||||
| static struct of_device_id wmt_pinctrl_of_match[] = { | ||||
| static const struct of_device_id wmt_pinctrl_of_match[] = { | ||||
| 	{ .compatible = "via,vt8500-pinctrl" }, | ||||
| 	{ /* sentinel */ }, | ||||
| }; | ||||
|   | ||||
| @@ -509,7 +509,7 @@ static int wm8505_pinctrl_remove(struct platform_device *pdev) | ||||
| 	return wmt_pinctrl_remove(pdev); | ||||
| } | ||||
|  | ||||
| static struct of_device_id wmt_pinctrl_of_match[] = { | ||||
| static const struct of_device_id wmt_pinctrl_of_match[] = { | ||||
| 	{ .compatible = "wm,wm8505-pinctrl" }, | ||||
| 	{ /* sentinel */ }, | ||||
| }; | ||||
|   | ||||
| @@ -347,7 +347,7 @@ static int wm8650_pinctrl_remove(struct platform_device *pdev) | ||||
| 	return wmt_pinctrl_remove(pdev); | ||||
| } | ||||
|  | ||||
| static struct of_device_id wmt_pinctrl_of_match[] = { | ||||
| static const struct of_device_id wmt_pinctrl_of_match[] = { | ||||
| 	{ .compatible = "wm,wm8650-pinctrl" }, | ||||
| 	{ /* sentinel */ }, | ||||
| }; | ||||
|   | ||||
| @@ -386,7 +386,7 @@ static int wm8750_pinctrl_remove(struct platform_device *pdev) | ||||
| 	return wmt_pinctrl_remove(pdev); | ||||
| } | ||||
|  | ||||
| static struct of_device_id wmt_pinctrl_of_match[] = { | ||||
| static const struct of_device_id wmt_pinctrl_of_match[] = { | ||||
| 	{ .compatible = "wm,wm8750-pinctrl" }, | ||||
| 	{ /* sentinel */ }, | ||||
| }; | ||||
|   | ||||
| @@ -365,7 +365,7 @@ static int wm8850_pinctrl_remove(struct platform_device *pdev) | ||||
| 	return wmt_pinctrl_remove(pdev); | ||||
| } | ||||
|  | ||||
| static struct of_device_id wmt_pinctrl_of_match[] = { | ||||
| static const struct of_device_id wmt_pinctrl_of_match[] = { | ||||
| 	{ .compatible = "wm,wm8850-pinctrl" }, | ||||
| 	{ /* sentinel */ }, | ||||
| }; | ||||
|   | ||||
							
								
								
									
										32
									
								
								include/dt-bindings/gpio/meson8b-gpio.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								include/dt-bindings/gpio/meson8b-gpio.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,32 @@ | ||||
| /* | ||||
|  * GPIO definitions for Amlogic Meson8b SoCs | ||||
|  * | ||||
|  * Copyright (C) 2015 Endless Mobile, Inc. | ||||
|  * Author: Carlo Caione <carlo@endlessm.com> | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License | ||||
|  * version 2 as published by the Free Software Foundation. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| #ifndef _DT_BINDINGS_MESON8B_GPIO_H | ||||
| #define _DT_BINDINGS_MESON8B_GPIO_H | ||||
|  | ||||
| #include <dt-bindings/gpio/meson8-gpio.h> | ||||
|  | ||||
| /* GPIO Bank DIF */ | ||||
| #define DIF_0_P		120 | ||||
| #define DIF_0_N		121 | ||||
| #define DIF_1_P		122 | ||||
| #define DIF_1_N		123 | ||||
| #define DIF_2_P		124 | ||||
| #define DIF_2_N		125 | ||||
| #define DIF_3_P		126 | ||||
| #define DIF_3_N		127 | ||||
| #define DIF_4_P		128 | ||||
| #define DIF_4_N		129 | ||||
|  | ||||
| #endif /* _DT_BINDINGS_MESON8B_GPIO_H */ | ||||
							
								
								
									
										40
									
								
								include/dt-bindings/pinctrl/mt65xx.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								include/dt-bindings/pinctrl/mt65xx.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,40 @@ | ||||
| /* | ||||
|  * Copyright (c) 2014 MediaTek Inc. | ||||
|  * Author: Hongzhou.Yang <hongzhou.yang@mediatek.com> | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License version 2 as | ||||
|  * published by the Free Software Foundation. | ||||
|  * | ||||
|  * This program is distributed in the hope that 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. | ||||
|  */ | ||||
|  | ||||
| #ifndef _DT_BINDINGS_PINCTRL_MT65XX_H | ||||
| #define _DT_BINDINGS_PINCTRL_MT65XX_H | ||||
|  | ||||
| #define MTK_PIN_NO(x) ((x) << 8) | ||||
| #define MTK_GET_PIN_NO(x) ((x) >> 8) | ||||
| #define MTK_GET_PIN_FUNC(x) ((x) & 0xf) | ||||
|  | ||||
| #define MTK_PUPD_SET_R1R0_00 100 | ||||
| #define MTK_PUPD_SET_R1R0_01 101 | ||||
| #define MTK_PUPD_SET_R1R0_10 102 | ||||
| #define MTK_PUPD_SET_R1R0_11 103 | ||||
|  | ||||
| #define MTK_DRIVE_2mA  2 | ||||
| #define MTK_DRIVE_4mA  4 | ||||
| #define MTK_DRIVE_6mA  6 | ||||
| #define MTK_DRIVE_8mA  8 | ||||
| #define MTK_DRIVE_10mA 10 | ||||
| #define MTK_DRIVE_12mA 12 | ||||
| #define MTK_DRIVE_14mA 14 | ||||
| #define MTK_DRIVE_16mA 16 | ||||
| #define MTK_DRIVE_20mA 20 | ||||
| #define MTK_DRIVE_24mA 24 | ||||
| #define MTK_DRIVE_28mA 28 | ||||
| #define MTK_DRIVE_32mA 32 | ||||
|  | ||||
| #endif /* _DT_BINDINGS_PINCTRL_MT65XX_H */ | ||||
| @@ -48,6 +48,14 @@ | ||||
| #define PM8058_GPIO_L5			6 | ||||
| #define PM8058_GPIO_L2			7 | ||||
|  | ||||
| /* | ||||
|  * Note: PM8916 GPIO1 and GPIO2 are supporting | ||||
|  * only L2(1.15V) and L5(1.8V) options | ||||
|  */ | ||||
| #define PM8916_GPIO_VPH			0 | ||||
| #define PM8916_GPIO_L2			2 | ||||
| #define PM8916_GPIO_L5			3 | ||||
|  | ||||
| #define PM8917_GPIO_VPH			0 | ||||
| #define PM8917_GPIO_S4			2 | ||||
| #define PM8917_GPIO_L15			3 | ||||
| @@ -115,6 +123,13 @@ | ||||
| #define PM8058_GPIO39_MP3_CLK		PMIC_GPIO_FUNC_FUNC1 | ||||
| #define PM8058_GPIO40_EXT_BB_EN		PMIC_GPIO_FUNC_FUNC1 | ||||
|  | ||||
| #define PM8916_GPIO1_BAT_ALRM_OUT	PMIC_GPIO_FUNC_FUNC1 | ||||
| #define PM8916_GPIO1_KEYP_DRV		PMIC_GPIO_FUNC_FUNC2 | ||||
| #define PM8916_GPIO2_DIV_CLK		PMIC_GPIO_FUNC_FUNC1 | ||||
| #define PM8916_GPIO2_SLEEP_CLK		PMIC_GPIO_FUNC_FUNC2 | ||||
| #define PM8916_GPIO3_KEYP_DRV		PMIC_GPIO_FUNC_FUNC1 | ||||
| #define PM8916_GPIO4_KEYP_DRV		PMIC_GPIO_FUNC_FUNC2 | ||||
|  | ||||
| #define PM8917_GPIO9_18_KEYP_DRV	PMIC_GPIO_FUNC_FUNC1 | ||||
| #define PM8917_GPIO20_BAT_ALRM_OUT	PMIC_GPIO_FUNC_FUNC1 | ||||
| #define PM8917_GPIO21_23_UART_TX	PMIC_GPIO_FUNC_FUNC2 | ||||
|   | ||||
| @@ -10,6 +10,10 @@ | ||||
| #define PM8841_MPP_VPH			0 | ||||
| #define PM8841_MPP_S3			2 | ||||
|  | ||||
| #define PM8916_MPP_VPH			0 | ||||
| #define PM8916_MPP_L2			2 | ||||
| #define PM8916_MPP_L5			3 | ||||
|  | ||||
| #define PM8941_MPP_VPH			0 | ||||
| #define PM8941_MPP_L1			1 | ||||
| #define PM8941_MPP_S3			2 | ||||
|   | ||||
		Reference in New Issue
	
	Block a user