Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
bdb18d93
Commit
bdb18d93
authored
May 22, 2017
by
Linus Walleij
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'ingenic' into devel
parents
7f0ff06c
e25f2af6
Changes
21
Hide whitespace changes
Inline
Side-by-side
Showing
21 changed files
with
1639 additions
and
1095 deletions
+1639
-1095
Documentation/devicetree/bindings/gpio/ingenic,gpio.txt
Documentation/devicetree/bindings/gpio/ingenic,gpio.txt
+46
-0
Documentation/devicetree/bindings/pinctrl/ingenic,pinctrl.txt
...mentation/devicetree/bindings/pinctrl/ingenic,pinctrl.txt
+41
-0
arch/mips/Kconfig
arch/mips/Kconfig
+1
-0
arch/mips/boot/dts/ingenic/ci20.dts
arch/mips/boot/dts/ingenic/ci20.dts
+60
-0
arch/mips/boot/dts/ingenic/jz4740.dtsi
arch/mips/boot/dts/ingenic/jz4740.dtsi
+68
-0
arch/mips/boot/dts/ingenic/jz4780.dtsi
arch/mips/boot/dts/ingenic/jz4780.dtsi
+98
-0
arch/mips/boot/dts/ingenic/qi_lb60.dts
arch/mips/boot/dts/ingenic/qi_lb60.dts
+13
-0
arch/mips/include/asm/mach-jz4740/gpio.h
arch/mips/include/asm/mach-jz4740/gpio.h
+0
-371
arch/mips/jz4740/Makefile
arch/mips/jz4740/Makefile
+0
-2
arch/mips/jz4740/board-qi_lb60.c
arch/mips/jz4740/board-qi_lb60.c
+36
-12
arch/mips/jz4740/gpio.c
arch/mips/jz4740/gpio.c
+0
-519
drivers/gpio/Kconfig
drivers/gpio/Kconfig
+10
-0
drivers/gpio/Makefile
drivers/gpio/Makefile
+1
-0
drivers/gpio/gpio-ingenic.c
drivers/gpio/gpio-ingenic.c
+394
-0
drivers/mmc/host/jz4740_mmc.c
drivers/mmc/host/jz4740_mmc.c
+5
-39
drivers/mtd/nand/jz4740_nand.c
drivers/mtd/nand/jz4740_nand.c
+1
-22
drivers/pinctrl/Kconfig
drivers/pinctrl/Kconfig
+9
-0
drivers/pinctrl/Makefile
drivers/pinctrl/Makefile
+1
-0
drivers/pinctrl/pinctrl-ingenic.c
drivers/pinctrl/pinctrl-ingenic.c
+852
-0
drivers/pwm/pwm-jz4740.c
drivers/pwm/pwm-jz4740.c
+0
-29
drivers/video/fbdev/jz4740_fb.c
drivers/video/fbdev/jz4740_fb.c
+3
-101
No files found.
Documentation/devicetree/bindings/gpio/ingenic,gpio.txt
0 → 100644
View file @
bdb18d93
Ingenic jz47xx GPIO controller
That the Ingenic GPIO driver node must be a sub-node of the Ingenic pinctrl
driver node.
Required properties:
--------------------
- compatible: Must contain one of:
- "ingenic,jz4740-gpio"
- "ingenic,jz4770-gpio"
- "ingenic,jz4780-gpio"
- reg: The GPIO bank number.
- interrupt-controller: Marks the device node as an interrupt controller.
- interrupts: Interrupt specifier for the controllers interrupt.
- #interrupt-cells: Should be 2. Refer to
../interrupt-controller/interrupts.txt for more details.
- gpio-controller: Marks the device node as a GPIO controller.
- #gpio-cells: Should be 2. The first cell is the GPIO number and the second
cell specifies GPIO flags, as defined in <dt-bindings/gpio/gpio.h>. Only the
GPIO_ACTIVE_HIGH and GPIO_ACTIVE_LOW flags are supported.
- gpio-ranges: Range of pins managed by the GPIO controller. Refer to
'gpio.txt' in this directory for more details.
Example:
--------
&pinctrl {
#address-cells = <1>;
#size-cells = <0>;
gpa: gpio@0 {
compatible = "ingenic,jz4740-gpio";
reg = <0>;
gpio-controller;
gpio-ranges = <&pinctrl 0 0 32>;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
interrupt-parent = <&intc>;
interrupts = <28>;
};
};
Documentation/devicetree/bindings/pinctrl/ingenic,pinctrl.txt
0 → 100644
View file @
bdb18d93
Ingenic jz47xx pin controller
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".
For the jz47xx SoCs, pin control is tightly bound with GPIO ports. All pins may
be used as GPIOs, multiplexed device functions are configured within the
GPIO port configuration registers and it is typical to refer to pins using the
naming scheme "PxN" where x is a character identifying the GPIO port with
which the pin is associated and N is an integer from 0 to 31 identifying the
pin within that GPIO port. For example PA0 is the first pin in GPIO port A, and
PB31 is the last pin in GPIO port B. The jz4740 contains 4 GPIO ports, PA to
PD, for a total of 128 pins. The jz4780 contains 6 GPIO ports, PA to PF, for a
total of 192 pins.
Required properties:
--------------------
- compatible: One of:
- "ingenic,jz4740-pinctrl"
- "ingenic,jz4770-pinctrl"
- "ingenic,jz4780-pinctrl"
- reg: Address range of the pinctrl registers.
GPIO sub-nodes
--------------
The pinctrl node can have optional sub-nodes for the Ingenic GPIO driver;
please refer to ../gpio/ingenic,gpio.txt.
Example:
--------
pinctrl: pin-controller@10010000 {
compatible = "ingenic,jz4740-pinctrl";
reg = <0x10010000 0x400>;
};
arch/mips/Kconfig
View file @
bdb18d93
...
...
@@ -364,6 +364,7 @@ config MACH_INGENIC
select SYS_SUPPORTS_ZBOOT_UART16550
select DMA_NONCOHERENT
select IRQ_MIPS_CPU
select PINCTRL
select GPIOLIB
select COMMON_CLK
select GENERIC_IRQ_CHIP
...
...
arch/mips/boot/dts/ingenic/ci20.dts
View file @
bdb18d93
...
...
@@ -29,18 +29,30 @@ &ext {
&uart0 {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&pins_uart0>;
};
&uart1 {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&pins_uart1>;
};
&uart3 {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&pins_uart2>;
};
&uart4 {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&pins_uart4>;
};
&nemc {
...
...
@@ -61,6 +73,13 @@ nandc: nand-controller@1 {
ingenic,nemc-tAW = <15>;
ingenic,nemc-tSTRV = <100>;
/*
* Only CLE/ALE are needed for the devices that are connected, rather
* than the full address line set.
*/
pinctrl-names = "default";
pinctrl-0 = <&pins_nemc>;
nand@1 {
reg = <1>;
...
...
@@ -69,6 +88,9 @@ nand@1 {
nand-ecc-mode = "hw";
nand-on-flash-bbt;
pinctrl-names = "default";
pinctrl-0 = <&pins_nemc_cs1>;
partitions {
compatible = "fixed-partitions";
#address-cells = <2>;
...
...
@@ -106,3 +128,41 @@ partition@0x8c00000 {
&bch {
status = "okay";
};
&pinctrl {
pins_uart0: uart0 {
function = "uart0";
groups = "uart0-data";
bias-disable;
};
pins_uart1: uart1 {
function = "uart1";
groups = "uart1-data";
bias-disable;
};
pins_uart2: uart2 {
function = "uart2";
groups = "uart2-data", "uart2-hwflow";
bias-disable;
};
pins_uart4: uart4 {
function = "uart4";
groups = "uart4-data";
bias-disable;
};
pins_nemc: nemc {
function = "nemc";
groups = "nemc-data", "nemc-cle-ale", "nemc-rd-we", "nemc-frd-fwe";
bias-disable;
};
pins_nemc_cs1: nemc-cs1 {
function = "nemc-cs1";
groups = "nemc-cs1";
bias-disable;
};
};
arch/mips/boot/dts/ingenic/jz4740.dtsi
View file @
bdb18d93
...
...
@@ -55,6 +55,74 @@ rtc_dev: rtc@10003000 {
clock-names = "rtc";
};
pinctrl: pin-controller@10010000 {
compatible = "ingenic,jz4740-pinctrl";
reg = <0x10010000 0x400>;
#address-cells = <1>;
#size-cells = <0>;
gpa: gpio@0 {
compatible = "ingenic,jz4740-gpio";
reg = <0>;
gpio-controller;
gpio-ranges = <&pinctrl 0 0 32>;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
interrupt-parent = <&intc>;
interrupts = <28>;
};
gpb: gpio@1 {
compatible = "ingenic,jz4740-gpio";
reg = <1>;
gpio-controller;
gpio-ranges = <&pinctrl 0 32 32>;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
interrupt-parent = <&intc>;
interrupts = <27>;
};
gpc: gpio@2 {
compatible = "ingenic,jz4740-gpio";
reg = <2>;
gpio-controller;
gpio-ranges = <&pinctrl 0 64 32>;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
interrupt-parent = <&intc>;
interrupts = <26>;
};
gpd: gpio@3 {
compatible = "ingenic,jz4740-gpio";
reg = <3>;
gpio-controller;
gpio-ranges = <&pinctrl 0 96 32>;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
interrupt-parent = <&intc>;
interrupts = <25>;
};
};
uart0: serial@10030000 {
compatible = "ingenic,jz4740-uart";
reg = <0x10030000 0x100>;
...
...
arch/mips/boot/dts/ingenic/jz4780.dtsi
View file @
bdb18d93
...
...
@@ -44,6 +44,104 @@ cgu: jz4780-cgu@10000000 {
#clock-cells = <1>;
};
pinctrl: pin-controller@10010000 {
compatible = "ingenic,jz4780-pinctrl";
reg = <0x10010000 0x600>;
#address-cells = <1>;
#size-cells = <0>;
gpa: gpio@0 {
compatible = "ingenic,jz4780-gpio";
reg = <0>;
gpio-controller;
gpio-ranges = <&pinctrl 0 0 32>;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
interrupt-parent = <&intc>;
interrupts = <17>;
};
gpb: gpio@1 {
compatible = "ingenic,jz4780-gpio";
reg = <1>;
gpio-controller;
gpio-ranges = <&pinctrl 0 32 32>;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
interrupt-parent = <&intc>;
interrupts = <16>;
};
gpc: gpio@2 {
compatible = "ingenic,jz4780-gpio";
reg = <2>;
gpio-controller;
gpio-ranges = <&pinctrl 0 64 32>;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
interrupt-parent = <&intc>;
interrupts = <15>;
};
gpd: gpio@3 {
compatible = "ingenic,jz4780-gpio";
reg = <3>;
gpio-controller;
gpio-ranges = <&pinctrl 0 96 32>;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
interrupt-parent = <&intc>;
interrupts = <14>;
};
gpe: gpio@4 {
compatible = "ingenic,jz4780-gpio";
reg = <4>;
gpio-controller;
gpio-ranges = <&pinctrl 0 128 32>;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
interrupt-parent = <&intc>;
interrupts = <13>;
};
gpf: gpio@5 {
compatible = "ingenic,jz4780-gpio";
reg = <5>;
gpio-controller;
gpio-ranges = <&pinctrl 0 160 32>;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
interrupt-parent = <&intc>;
interrupts = <12>;
};
};
uart0: serial@10030000 {
compatible = "ingenic,jz4780-uart";
reg = <0x10030000 0x100>;
...
...
arch/mips/boot/dts/ingenic/qi_lb60.dts
View file @
bdb18d93
...
...
@@ -17,3 +17,16 @@ &ext {
&rtc_dev {
system-power-controller;
};
&uart0 {
pinctrl-names = "default";
pinctrl-0 = <&pins_uart0>;
};
&pinctrl {
pins_uart0: uart0 {
function = "uart0";
groups = "uart0-data";
bias-disable;
};
};
arch/mips/include/asm/mach-jz4740/gpio.h
View file @
bdb18d93
...
...
@@ -16,380 +16,9 @@
#ifndef _JZ_GPIO_H
#define _JZ_GPIO_H
#include <linux/types.h>
enum
jz_gpio_function
{
JZ_GPIO_FUNC_NONE
,
JZ_GPIO_FUNC1
,
JZ_GPIO_FUNC2
,
JZ_GPIO_FUNC3
,
};
/*
Usually a driver for a SoC component has to request several gpio pins and
configure them as function pins.
jz_gpio_bulk_request can be used to ease this process.
Usually one would do something like:
static const struct jz_gpio_bulk_request i2c_pins[] = {
JZ_GPIO_BULK_PIN(I2C_SDA),
JZ_GPIO_BULK_PIN(I2C_SCK),
};
inside the probe function:
ret = jz_gpio_bulk_request(i2c_pins, ARRAY_SIZE(i2c_pins));
if (ret) {
...
inside the remove function:
jz_gpio_bulk_free(i2c_pins, ARRAY_SIZE(i2c_pins));
*/
struct
jz_gpio_bulk_request
{
int
gpio
;
const
char
*
name
;
enum
jz_gpio_function
function
;
};
#define JZ_GPIO_BULK_PIN(pin) { \
.gpio = JZ_GPIO_ ## pin, \
.name = #pin, \
.function = JZ_GPIO_FUNC_ ## pin \
}
int
jz_gpio_bulk_request
(
const
struct
jz_gpio_bulk_request
*
request
,
size_t
num
);
void
jz_gpio_bulk_free
(
const
struct
jz_gpio_bulk_request
*
request
,
size_t
num
);
void
jz_gpio_bulk_suspend
(
const
struct
jz_gpio_bulk_request
*
request
,
size_t
num
);
void
jz_gpio_bulk_resume
(
const
struct
jz_gpio_bulk_request
*
request
,
size_t
num
);
void
jz_gpio_enable_pullup
(
unsigned
gpio
);
void
jz_gpio_disable_pullup
(
unsigned
gpio
);
int
jz_gpio_set_function
(
int
gpio
,
enum
jz_gpio_function
function
);
int
jz_gpio_port_direction_input
(
int
port
,
uint32_t
mask
);
int
jz_gpio_port_direction_output
(
int
port
,
uint32_t
mask
);
void
jz_gpio_port_set_value
(
int
port
,
uint32_t
value
,
uint32_t
mask
);
uint32_t
jz_gpio_port_get_value
(
int
port
,
uint32_t
mask
);
#define JZ_GPIO_PORTA(x) ((x) + 32 * 0)
#define JZ_GPIO_PORTB(x) ((x) + 32 * 1)
#define JZ_GPIO_PORTC(x) ((x) + 32 * 2)
#define JZ_GPIO_PORTD(x) ((x) + 32 * 3)
/* Port A function pins */
#define JZ_GPIO_MEM_DATA0 JZ_GPIO_PORTA(0)
#define JZ_GPIO_MEM_DATA1 JZ_GPIO_PORTA(1)
#define JZ_GPIO_MEM_DATA2 JZ_GPIO_PORTA(2)
#define JZ_GPIO_MEM_DATA3 JZ_GPIO_PORTA(3)
#define JZ_GPIO_MEM_DATA4 JZ_GPIO_PORTA(4)
#define JZ_GPIO_MEM_DATA5 JZ_GPIO_PORTA(5)
#define JZ_GPIO_MEM_DATA6 JZ_GPIO_PORTA(6)
#define JZ_GPIO_MEM_DATA7 JZ_GPIO_PORTA(7)
#define JZ_GPIO_MEM_DATA8 JZ_GPIO_PORTA(8)
#define JZ_GPIO_MEM_DATA9 JZ_GPIO_PORTA(9)
#define JZ_GPIO_MEM_DATA10 JZ_GPIO_PORTA(10)
#define JZ_GPIO_MEM_DATA11 JZ_GPIO_PORTA(11)
#define JZ_GPIO_MEM_DATA12 JZ_GPIO_PORTA(12)
#define JZ_GPIO_MEM_DATA13 JZ_GPIO_PORTA(13)
#define JZ_GPIO_MEM_DATA14 JZ_GPIO_PORTA(14)
#define JZ_GPIO_MEM_DATA15 JZ_GPIO_PORTA(15)
#define JZ_GPIO_MEM_DATA16 JZ_GPIO_PORTA(16)
#define JZ_GPIO_MEM_DATA17 JZ_GPIO_PORTA(17)
#define JZ_GPIO_MEM_DATA18 JZ_GPIO_PORTA(18)
#define JZ_GPIO_MEM_DATA19 JZ_GPIO_PORTA(19)
#define JZ_GPIO_MEM_DATA20 JZ_GPIO_PORTA(20)
#define JZ_GPIO_MEM_DATA21 JZ_GPIO_PORTA(21)
#define JZ_GPIO_MEM_DATA22 JZ_GPIO_PORTA(22)
#define JZ_GPIO_MEM_DATA23 JZ_GPIO_PORTA(23)
#define JZ_GPIO_MEM_DATA24 JZ_GPIO_PORTA(24)
#define JZ_GPIO_MEM_DATA25 JZ_GPIO_PORTA(25)
#define JZ_GPIO_MEM_DATA26 JZ_GPIO_PORTA(26)
#define JZ_GPIO_MEM_DATA27 JZ_GPIO_PORTA(27)
#define JZ_GPIO_MEM_DATA28 JZ_GPIO_PORTA(28)
#define JZ_GPIO_MEM_DATA29 JZ_GPIO_PORTA(29)
#define JZ_GPIO_MEM_DATA30 JZ_GPIO_PORTA(30)
#define JZ_GPIO_MEM_DATA31 JZ_GPIO_PORTA(31)
#define JZ_GPIO_FUNC_MEM_DATA0 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_DATA1 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_DATA2 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_DATA3 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_DATA4 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_DATA5 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_DATA6 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_DATA7 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_DATA8 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_DATA9 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_DATA10 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_DATA11 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_DATA12 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_DATA13 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_DATA14 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_DATA15 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_DATA16 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_DATA17 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_DATA18 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_DATA19 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_DATA20 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_DATA21 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_DATA22 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_DATA23 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_DATA24 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_DATA25 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_DATA26 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_DATA27 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_DATA28 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_DATA29 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_DATA30 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_DATA31 JZ_GPIO_FUNC1
/* Port B function pins */
#define JZ_GPIO_MEM_ADDR0 JZ_GPIO_PORTB(0)
#define JZ_GPIO_MEM_ADDR1 JZ_GPIO_PORTB(1)
#define JZ_GPIO_MEM_ADDR2 JZ_GPIO_PORTB(2)
#define JZ_GPIO_MEM_ADDR3 JZ_GPIO_PORTB(3)
#define JZ_GPIO_MEM_ADDR4 JZ_GPIO_PORTB(4)
#define JZ_GPIO_MEM_ADDR5 JZ_GPIO_PORTB(5)
#define JZ_GPIO_MEM_ADDR6 JZ_GPIO_PORTB(6)
#define JZ_GPIO_MEM_ADDR7 JZ_GPIO_PORTB(7)
#define JZ_GPIO_MEM_ADDR8 JZ_GPIO_PORTB(8)
#define JZ_GPIO_MEM_ADDR9 JZ_GPIO_PORTB(9)
#define JZ_GPIO_MEM_ADDR10 JZ_GPIO_PORTB(10)
#define JZ_GPIO_MEM_ADDR11 JZ_GPIO_PORTB(11)
#define JZ_GPIO_MEM_ADDR12 JZ_GPIO_PORTB(12)
#define JZ_GPIO_MEM_ADDR13 JZ_GPIO_PORTB(13)
#define JZ_GPIO_MEM_ADDR14 JZ_GPIO_PORTB(14)
#define JZ_GPIO_MEM_ADDR15 JZ_GPIO_PORTB(15)
#define JZ_GPIO_MEM_ADDR16 JZ_GPIO_PORTB(16)
#define JZ_GPIO_LCD_CLS JZ_GPIO_PORTB(17)
#define JZ_GPIO_LCD_SPL JZ_GPIO_PORTB(18)
#define JZ_GPIO_MEM_DCS JZ_GPIO_PORTB(19)
#define JZ_GPIO_MEM_RAS JZ_GPIO_PORTB(20)
#define JZ_GPIO_MEM_CAS JZ_GPIO_PORTB(21)
#define JZ_GPIO_MEM_SDWE JZ_GPIO_PORTB(22)
#define JZ_GPIO_MEM_CKE JZ_GPIO_PORTB(23)
#define JZ_GPIO_MEM_CKO JZ_GPIO_PORTB(24)
#define JZ_GPIO_MEM_CS0 JZ_GPIO_PORTB(25)
#define JZ_GPIO_MEM_CS1 JZ_GPIO_PORTB(26)
#define JZ_GPIO_MEM_CS2 JZ_GPIO_PORTB(27)
#define JZ_GPIO_MEM_CS3 JZ_GPIO_PORTB(28)
#define JZ_GPIO_MEM_RD JZ_GPIO_PORTB(29)
#define JZ_GPIO_MEM_WR JZ_GPIO_PORTB(30)
#define JZ_GPIO_MEM_WE0 JZ_GPIO_PORTB(31)
#define JZ_GPIO_FUNC_MEM_ADDR0 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_ADDR1 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_ADDR2 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_ADDR3 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_ADDR4 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_ADDR5 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_ADDR6 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_ADDR7 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_ADDR8 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_ADDR9 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_ADDR10 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_ADDR11 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_ADDR12 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_ADDR13 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_ADDR14 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_ADDR15 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_ADDR16 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_LCD_CLS JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_LCD_SPL JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_DCS JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_RAS JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_CAS JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_SDWE JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_CKE JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_CKO JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_CS0 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_CS1 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_CS2 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_CS3 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_RD JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_WR JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_WE0 JZ_GPIO_FUNC1
#define JZ_GPIO_MEM_ADDR21 JZ_GPIO_PORTB(17)
#define JZ_GPIO_MEM_ADDR22 JZ_GPIO_PORTB(18)
#define JZ_GPIO_FUNC_MEM_ADDR21 JZ_GPIO_FUNC2
#define JZ_GPIO_FUNC_MEM_ADDR22 JZ_GPIO_FUNC2
/* Port C function pins */
#define JZ_GPIO_LCD_DATA0 JZ_GPIO_PORTC(0)
#define JZ_GPIO_LCD_DATA1 JZ_GPIO_PORTC(1)
#define JZ_GPIO_LCD_DATA2 JZ_GPIO_PORTC(2)
#define JZ_GPIO_LCD_DATA3 JZ_GPIO_PORTC(3)
#define JZ_GPIO_LCD_DATA4 JZ_GPIO_PORTC(4)
#define JZ_GPIO_LCD_DATA5 JZ_GPIO_PORTC(5)
#define JZ_GPIO_LCD_DATA6 JZ_GPIO_PORTC(6)
#define JZ_GPIO_LCD_DATA7 JZ_GPIO_PORTC(7)
#define JZ_GPIO_LCD_DATA8 JZ_GPIO_PORTC(8)
#define JZ_GPIO_LCD_DATA9 JZ_GPIO_PORTC(9)
#define JZ_GPIO_LCD_DATA10 JZ_GPIO_PORTC(10)
#define JZ_GPIO_LCD_DATA11 JZ_GPIO_PORTC(11)
#define JZ_GPIO_LCD_DATA12 JZ_GPIO_PORTC(12)
#define JZ_GPIO_LCD_DATA13 JZ_GPIO_PORTC(13)
#define JZ_GPIO_LCD_DATA14 JZ_GPIO_PORTC(14)
#define JZ_GPIO_LCD_DATA15 JZ_GPIO_PORTC(15)
#define JZ_GPIO_LCD_DATA16 JZ_GPIO_PORTC(16)
#define JZ_GPIO_LCD_DATA17 JZ_GPIO_PORTC(17)
#define JZ_GPIO_LCD_PCLK JZ_GPIO_PORTC(18)
#define JZ_GPIO_LCD_HSYNC JZ_GPIO_PORTC(19)
#define JZ_GPIO_LCD_VSYNC JZ_GPIO_PORTC(20)
#define JZ_GPIO_LCD_DE JZ_GPIO_PORTC(21)
#define JZ_GPIO_LCD_PS JZ_GPIO_PORTC(22)
#define JZ_GPIO_LCD_REV JZ_GPIO_PORTC(23)
#define JZ_GPIO_MEM_WE1 JZ_GPIO_PORTC(24)
#define JZ_GPIO_MEM_WE2 JZ_GPIO_PORTC(25)
#define JZ_GPIO_MEM_WE3 JZ_GPIO_PORTC(26)
#define JZ_GPIO_MEM_WAIT JZ_GPIO_PORTC(27)
#define JZ_GPIO_MEM_FRE JZ_GPIO_PORTC(28)
#define JZ_GPIO_MEM_FWE JZ_GPIO_PORTC(29)
#define JZ_GPIO_FUNC_LCD_DATA0 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_LCD_DATA1 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_LCD_DATA2 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_LCD_DATA3 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_LCD_DATA4 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_LCD_DATA5 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_LCD_DATA6 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_LCD_DATA7 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_LCD_DATA8 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_LCD_DATA9 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_LCD_DATA10 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_LCD_DATA11 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_LCD_DATA12 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_LCD_DATA13 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_LCD_DATA14 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_LCD_DATA15 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_LCD_DATA16 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_LCD_DATA17 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_LCD_PCLK JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_LCD_VSYNC JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_LCD_HSYNC JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_LCD_DE JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_LCD_PS JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_LCD_REV JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_WE1 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_WE2 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_WE3 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_WAIT JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_FRE JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MEM_FWE JZ_GPIO_FUNC1
#define JZ_GPIO_MEM_ADDR19 JZ_GPIO_PORTB(22)
#define JZ_GPIO_MEM_ADDR20 JZ_GPIO_PORTB(23)
#define JZ_GPIO_FUNC_MEM_ADDR19 JZ_GPIO_FUNC2
#define JZ_GPIO_FUNC_MEM_ADDR20 JZ_GPIO_FUNC2
/* Port D function pins */
#define JZ_GPIO_CIM_DATA0 JZ_GPIO_PORTD(0)
#define JZ_GPIO_CIM_DATA1 JZ_GPIO_PORTD(1)
#define JZ_GPIO_CIM_DATA2 JZ_GPIO_PORTD(2)
#define JZ_GPIO_CIM_DATA3 JZ_GPIO_PORTD(3)
#define JZ_GPIO_CIM_DATA4 JZ_GPIO_PORTD(4)
#define JZ_GPIO_CIM_DATA5 JZ_GPIO_PORTD(5)
#define JZ_GPIO_CIM_DATA6 JZ_GPIO_PORTD(6)
#define JZ_GPIO_CIM_DATA7 JZ_GPIO_PORTD(7)
#define JZ_GPIO_MSC_CMD JZ_GPIO_PORTD(8)
#define JZ_GPIO_MSC_CLK JZ_GPIO_PORTD(9)
#define JZ_GPIO_MSC_DATA0 JZ_GPIO_PORTD(10)
#define JZ_GPIO_MSC_DATA1 JZ_GPIO_PORTD(11)
#define JZ_GPIO_MSC_DATA2 JZ_GPIO_PORTD(12)
#define JZ_GPIO_MSC_DATA3 JZ_GPIO_PORTD(13)
#define JZ_GPIO_CIM_MCLK JZ_GPIO_PORTD(14)
#define JZ_GPIO_CIM_PCLK JZ_GPIO_PORTD(15)
#define JZ_GPIO_CIM_VSYNC JZ_GPIO_PORTD(16)
#define JZ_GPIO_CIM_HSYNC JZ_GPIO_PORTD(17)
#define JZ_GPIO_SPI_CLK JZ_GPIO_PORTD(18)
#define JZ_GPIO_SPI_CE0 JZ_GPIO_PORTD(19)
#define JZ_GPIO_SPI_DT JZ_GPIO_PORTD(20)
#define JZ_GPIO_SPI_DR JZ_GPIO_PORTD(21)
#define JZ_GPIO_SPI_CE1 JZ_GPIO_PORTD(22)
#define JZ_GPIO_PWM0 JZ_GPIO_PORTD(23)
#define JZ_GPIO_PWM1 JZ_GPIO_PORTD(24)
#define JZ_GPIO_PWM2 JZ_GPIO_PORTD(25)
#define JZ_GPIO_PWM3 JZ_GPIO_PORTD(26)
#define JZ_GPIO_PWM4 JZ_GPIO_PORTD(27)
#define JZ_GPIO_PWM5 JZ_GPIO_PORTD(28)
#define JZ_GPIO_PWM6 JZ_GPIO_PORTD(30)
#define JZ_GPIO_PWM7 JZ_GPIO_PORTD(31)
#define JZ_GPIO_FUNC_CIM_DATA JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_CIM_DATA0 JZ_GPIO_FUNC_CIM_DATA
#define JZ_GPIO_FUNC_CIM_DATA1 JZ_GPIO_FUNC_CIM_DATA
#define JZ_GPIO_FUNC_CIM_DATA2 JZ_GPIO_FUNC_CIM_DATA
#define JZ_GPIO_FUNC_CIM_DATA3 JZ_GPIO_FUNC_CIM_DATA
#define JZ_GPIO_FUNC_CIM_DATA4 JZ_GPIO_FUNC_CIM_DATA
#define JZ_GPIO_FUNC_CIM_DATA5 JZ_GPIO_FUNC_CIM_DATA
#define JZ_GPIO_FUNC_CIM_DATA6 JZ_GPIO_FUNC_CIM_DATA
#define JZ_GPIO_FUNC_CIM_DATA7 JZ_GPIO_FUNC_CIM_DATA
#define JZ_GPIO_FUNC_MSC_CMD JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MSC_CLK JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MSC_DATA JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_MSC_DATA0 JZ_GPIO_FUNC_MSC_DATA
#define JZ_GPIO_FUNC_MSC_DATA1 JZ_GPIO_FUNC_MSC_DATA
#define JZ_GPIO_FUNC_MSC_DATA2 JZ_GPIO_FUNC_MSC_DATA
#define JZ_GPIO_FUNC_MSC_DATA3 JZ_GPIO_FUNC_MSC_DATA
#define JZ_GPIO_FUNC_CIM_MCLK JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_CIM_PCLK JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_CIM_VSYNC JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_CIM_HSYNC JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_SPI_CLK JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_SPI_CE0 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_SPI_DT JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_SPI_DR JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_SPI_CE1 JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_PWM JZ_GPIO_FUNC1
#define JZ_GPIO_FUNC_PWM0 JZ_GPIO_FUNC_PWM
#define JZ_GPIO_FUNC_PWM1 JZ_GPIO_FUNC_PWM
#define JZ_GPIO_FUNC_PWM2 JZ_GPIO_FUNC_PWM
#define JZ_GPIO_FUNC_PWM3 JZ_GPIO_FUNC_PWM
#define JZ_GPIO_FUNC_PWM4 JZ_GPIO_FUNC_PWM
#define JZ_GPIO_FUNC_PWM5 JZ_GPIO_FUNC_PWM
#define JZ_GPIO_FUNC_PWM6 JZ_GPIO_FUNC_PWM
#define JZ_GPIO_FUNC_PWM7 JZ_GPIO_FUNC_PWM
#define JZ_GPIO_MEM_SCLK_RSTN JZ_GPIO_PORTD(18)
#define JZ_GPIO_MEM_BCLK JZ_GPIO_PORTD(19)
#define JZ_GPIO_MEM_SDATO JZ_GPIO_PORTD(20)
#define JZ_GPIO_MEM_SDATI JZ_GPIO_PORTD(21)
#define JZ_GPIO_MEM_SYNC JZ_GPIO_PORTD(22)
#define JZ_GPIO_I2C_SDA JZ_GPIO_PORTD(23)
#define JZ_GPIO_I2C_SCK JZ_GPIO_PORTD(24)
#define JZ_GPIO_UART0_TXD JZ_GPIO_PORTD(25)
#define JZ_GPIO_UART0_RXD JZ_GPIO_PORTD(26)
#define JZ_GPIO_MEM_ADDR17 JZ_GPIO_PORTD(27)
#define JZ_GPIO_MEM_ADDR18 JZ_GPIO_PORTD(28)
#define JZ_GPIO_UART0_CTS JZ_GPIO_PORTD(30)
#define JZ_GPIO_UART0_RTS JZ_GPIO_PORTD(31)
#define JZ_GPIO_FUNC_MEM_SCLK_RSTN JZ_GPIO_FUNC2
#define JZ_GPIO_FUNC_MEM_BCLK JZ_GPIO_FUNC2
#define JZ_GPIO_FUNC_MEM_SDATO JZ_GPIO_FUNC2
#define JZ_GPIO_FUNC_MEM_SDATI JZ_GPIO_FUNC2
#define JZ_GPIO_FUNC_MEM_SYNC JZ_GPIO_FUNC2
#define JZ_GPIO_FUNC_I2C_SDA JZ_GPIO_FUNC2
#define JZ_GPIO_FUNC_I2C_SCK JZ_GPIO_FUNC2
#define JZ_GPIO_FUNC_UART0_TXD JZ_GPIO_FUNC2
#define JZ_GPIO_FUNC_UART0_RXD JZ_GPIO_FUNC2
#define JZ_GPIO_FUNC_MEM_ADDR17 JZ_GPIO_FUNC2
#define JZ_GPIO_FUNC_MEM_ADDR18 JZ_GPIO_FUNC2
#define JZ_GPIO_FUNC_UART0_CTS JZ_GPIO_FUNC2
#define JZ_GPIO_FUNC_UART0_RTS JZ_GPIO_FUNC2
#define JZ_GPIO_UART1_RXD JZ_GPIO_PORTD(30)
#define JZ_GPIO_UART1_TXD JZ_GPIO_PORTD(31)
#define JZ_GPIO_FUNC_UART1_RXD JZ_GPIO_FUNC3
#define JZ_GPIO_FUNC_UART1_TXD JZ_GPIO_FUNC3
#endif
arch/mips/jz4740/Makefile
View file @
bdb18d93
...
...
@@ -7,8 +7,6 @@
obj-y
+=
prom.o time.o reset.o setup.o
\
platform.o timer.o
obj-$(CONFIG_MACH_JZ4740)
+=
gpio.o
CFLAGS_setup.o
=
-I
$(src)
/../../../scripts/dtc/libfdt
# board specific support
...
...
arch/mips/jz4740/board-qi_lb60.c
View file @
bdb18d93
...
...
@@ -22,6 +22,8 @@
#include <linux/input/matrix_keypad.h>
#include <linux/spi/spi.h>
#include <linux/spi/spi_gpio.h>
#include <linux/pinctrl/machine.h>
#include <linux/pinctrl/pinconf-generic.h>
#include <linux/power_supply.h>
#include <linux/power/jz4740-battery.h>
#include <linux/power/gpio-charger.h>
...
...
@@ -159,7 +161,7 @@ static struct jz_nand_platform_data qi_lb60_nand_pdata = {
static
struct
gpiod_lookup_table
qi_lb60_nand_gpio_table
=
{
.
dev_id
=
"jz4740-nand.0"
,
.
table
=
{
GPIO_LOOKUP
(
"
Bank
C"
,
30
,
"busy"
,
0
),
GPIO_LOOKUP
(
"
GPIO
C"
,
30
,
"busy"
,
0
),
{
},
},
};
...
...
@@ -421,8 +423,8 @@ static struct platform_device qi_lb60_audio_device = {
static
struct
gpiod_lookup_table
qi_lb60_audio_gpio_table
=
{
.
dev_id
=
"qi-lb60-audio"
,
.
table
=
{
GPIO_LOOKUP
(
"
Bank
B"
,
29
,
"snd"
,
0
),
GPIO_LOOKUP
(
"
Bank
D"
,
4
,
"amp"
,
0
),
GPIO_LOOKUP
(
"
GPIO
B"
,
29
,
"snd"
,
0
),
GPIO_LOOKUP
(
"
GPIO
D"
,
4
,
"amp"
,
0
),
{
},
},
};
...
...
@@ -447,13 +449,36 @@ static struct platform_device *jz_platform_devices[] __initdata = {
&
qi_lb60_audio_device
,
};
static
void
__init
board_gpio_setup
(
void
)
{
/* We only need to enable/disable pullup here for pins used in generic
* drivers. Everything else is done by the drivers themselves. */
jz_gpio_disable_pullup
(
QI_LB60_GPIO_SD_VCC_EN_N
);
jz_gpio_disable_pullup
(
QI_LB60_GPIO_SD_CD
);
}
static
unsigned
long
pin_cfg_bias_disable
[]
=
{
PIN_CONFIG_BIAS_DISABLE
,
};
static
struct
pinctrl_map
pin_map
[]
__initdata
=
{
/* NAND pin configuration */
PIN_MAP_MUX_GROUP_DEFAULT
(
"jz4740-nand"
,
"10010000.jz4740-pinctrl"
,
"nand"
,
"nand-cs1"
),
/* fbdev pin configuration */
PIN_MAP_MUX_GROUP
(
"jz4740-fb"
,
PINCTRL_STATE_DEFAULT
,
"10010000.jz4740-pinctrl"
,
"lcd"
,
"lcd-8bit"
),
PIN_MAP_MUX_GROUP
(
"jz4740-fb"
,
PINCTRL_STATE_SLEEP
,
"10010000.jz4740-pinctrl"
,
"lcd"
,
"lcd-no-pins"
),
/* MMC pin configuration */
PIN_MAP_MUX_GROUP_DEFAULT
(
"jz4740-mmc.0"
,
"10010000.jz4740-pinctrl"
,
"mmc"
,
"mmc-1bit"
),
PIN_MAP_MUX_GROUP_DEFAULT
(
"jz4740-mmc.0"
,
"10010000.jz4740-pinctrl"
,
"mmc"
,
"mmc-4bit"
),
PIN_MAP_CONFIGS_PIN_DEFAULT
(
"jz4740-mmc.0"
,
"10010000.jz4740-pinctrl"
,
"PD0"
,
pin_cfg_bias_disable
),
PIN_MAP_CONFIGS_PIN_DEFAULT
(
"jz4740-mmc.0"
,
"10010000.jz4740-pinctrl"
,
"PD2"
,
pin_cfg_bias_disable
),
/* PWM pin configuration */
PIN_MAP_MUX_GROUP_DEFAULT
(
"jz4740-pwm"
,
"10010000.jz4740-pinctrl"
,
"pwm4"
,
"pwm4"
),
};
static
int
__init
qi_lb60_init_platform_devices
(
void
)
{
...
...
@@ -469,6 +494,7 @@ static int __init qi_lb60_init_platform_devices(void)
ARRAY_SIZE
(
qi_lb60_spi_board_info
));
pwm_add_table
(
qi_lb60_pwm_lookup
,
ARRAY_SIZE
(
qi_lb60_pwm_lookup
));
pinctrl_register_mappings
(
pin_map
,
ARRAY_SIZE
(
pin_map
));
return
platform_add_devices
(
jz_platform_devices
,
ARRAY_SIZE
(
jz_platform_devices
));
...
...
@@ -479,8 +505,6 @@ static int __init qi_lb60_board_setup(void)
{
printk
(
KERN_INFO
"Qi Hardware JZ4740 QI LB60 setup
\n
"
);
board_gpio_setup
();
if
(
qi_lb60_init_platform_devices
())
panic
(
"Failed to initialize platform devices"
);
...
...
arch/mips/jz4740/gpio.c
deleted
100644 → 0
View file @
7f0ff06c
/*
* Copyright (C) 2009-2010, Lars-Peter Clausen <lars@metafoo.de>
* JZ4740 platform GPIO support
*
* 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.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#include <linux/kernel.h>
#include <linux/export.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/gpio/driver.h>
/* FIXME: needed for gpio_request(), try to remove consumer API from driver */
#include <linux/gpio.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/irqchip/ingenic.h>
#include <linux/bitops.h>
#include <linux/debugfs.h>
#include <linux/seq_file.h>
#include <asm/mach-jz4740/base.h>
#include <asm/mach-jz4740/gpio.h>
#define JZ4740_GPIO_BASE_A (32*0)
#define JZ4740_GPIO_BASE_B (32*1)
#define JZ4740_GPIO_BASE_C (32*2)
#define JZ4740_GPIO_BASE_D (32*3)
#define JZ4740_GPIO_NUM_A 32
#define JZ4740_GPIO_NUM_B 32
#define JZ4740_GPIO_NUM_C 31
#define JZ4740_GPIO_NUM_D 32
#define JZ4740_IRQ_GPIO_BASE_A (JZ4740_IRQ_GPIO(0) + JZ4740_GPIO_BASE_A)
#define JZ4740_IRQ_GPIO_BASE_B (JZ4740_IRQ_GPIO(0) + JZ4740_GPIO_BASE_B)
#define JZ4740_IRQ_GPIO_BASE_C (JZ4740_IRQ_GPIO(0) + JZ4740_GPIO_BASE_C)
#define JZ4740_IRQ_GPIO_BASE_D (JZ4740_IRQ_GPIO(0) + JZ4740_GPIO_BASE_D)
#define JZ_REG_GPIO_PIN 0x00
#define JZ_REG_GPIO_DATA 0x10
#define JZ_REG_GPIO_DATA_SET 0x14
#define JZ_REG_GPIO_DATA_CLEAR 0x18
#define JZ_REG_GPIO_MASK 0x20
#define JZ_REG_GPIO_MASK_SET 0x24
#define JZ_REG_GPIO_MASK_CLEAR 0x28
#define JZ_REG_GPIO_PULL 0x30
#define JZ_REG_GPIO_PULL_SET 0x34
#define JZ_REG_GPIO_PULL_CLEAR 0x38
#define JZ_REG_GPIO_FUNC 0x40
#define JZ_REG_GPIO_FUNC_SET 0x44
#define JZ_REG_GPIO_FUNC_CLEAR 0x48
#define JZ_REG_GPIO_SELECT 0x50
#define JZ_REG_GPIO_SELECT_SET 0x54
#define JZ_REG_GPIO_SELECT_CLEAR 0x58
#define JZ_REG_GPIO_DIRECTION 0x60
#define JZ_REG_GPIO_DIRECTION_SET 0x64
#define JZ_REG_GPIO_DIRECTION_CLEAR 0x68
#define JZ_REG_GPIO_TRIGGER 0x70
#define JZ_REG_GPIO_TRIGGER_SET 0x74
#define JZ_REG_GPIO_TRIGGER_CLEAR 0x78
#define JZ_REG_GPIO_FLAG 0x80
#define JZ_REG_GPIO_FLAG_CLEAR 0x14
#define GPIO_TO_BIT(gpio) BIT(gpio & 0x1f)
#define GPIO_TO_REG(gpio, reg) (gpio_to_jz_gpio_chip(gpio)->base + (reg))
#define CHIP_TO_REG(chip, reg) (gpio_chip_to_jz_gpio_chip(chip)->base + (reg))
struct
jz_gpio_chip
{
unsigned
int
irq
;
unsigned
int
irq_base
;
uint32_t
edge_trigger_both
;
void
__iomem
*
base
;
struct
gpio_chip
gpio_chip
;
};
static
struct
jz_gpio_chip
jz4740_gpio_chips
[];
static
inline
struct
jz_gpio_chip
*
gpio_to_jz_gpio_chip
(
unsigned
int
gpio
)
{
return
&
jz4740_gpio_chips
[
gpio
>>
5
];
}
static
inline
struct
jz_gpio_chip
*
gpio_chip_to_jz_gpio_chip
(
struct
gpio_chip
*
gc
)
{
return
gpiochip_get_data
(
gc
);
}
static
inline
struct
jz_gpio_chip
*
irq_to_jz_gpio_chip
(
struct
irq_data
*
data
)
{
struct
irq_chip_generic
*
gc
=
irq_data_get_irq_chip_data
(
data
);
return
gc
->
private
;
}
static
inline
void
jz_gpio_write_bit
(
unsigned
int
gpio
,
unsigned
int
reg
)
{
writel
(
GPIO_TO_BIT
(
gpio
),
GPIO_TO_REG
(
gpio
,
reg
));
}
int
jz_gpio_set_function
(
int
gpio
,
enum
jz_gpio_function
function
)
{
if
(
function
==
JZ_GPIO_FUNC_NONE
)
{
jz_gpio_write_bit
(
gpio
,
JZ_REG_GPIO_FUNC_CLEAR
);
jz_gpio_write_bit
(
gpio
,
JZ_REG_GPIO_SELECT_CLEAR
);
jz_gpio_write_bit
(
gpio
,
JZ_REG_GPIO_TRIGGER_CLEAR
);
}
else
{
jz_gpio_write_bit
(
gpio
,
JZ_REG_GPIO_FUNC_SET
);
jz_gpio_write_bit
(
gpio
,
JZ_REG_GPIO_TRIGGER_CLEAR
);
switch
(
function
)
{
case
JZ_GPIO_FUNC1
:
jz_gpio_write_bit
(
gpio
,
JZ_REG_GPIO_SELECT_CLEAR
);
break
;
case
JZ_GPIO_FUNC3
:
jz_gpio_write_bit
(
gpio
,
JZ_REG_GPIO_TRIGGER_SET
);
case
JZ_GPIO_FUNC2
:
/* Falltrough */
jz_gpio_write_bit
(
gpio
,
JZ_REG_GPIO_SELECT_SET
);
break
;
default:
BUG
();
break
;
}
}
return
0
;
}
EXPORT_SYMBOL_GPL
(
jz_gpio_set_function
);
int
jz_gpio_bulk_request
(
const
struct
jz_gpio_bulk_request
*
request
,
size_t
num
)
{
size_t
i
;
int
ret
;
for
(
i
=
0
;
i
<
num
;
++
i
,
++
request
)
{
ret
=
gpio_request
(
request
->
gpio
,
request
->
name
);
if
(
ret
)
goto
err
;
jz_gpio_set_function
(
request
->
gpio
,
request
->
function
);
}
return
0
;
err:
for
(
--
request
;
i
>
0
;
--
i
,
--
request
)
{
gpio_free
(
request
->
gpio
);
jz_gpio_set_function
(
request
->
gpio
,
JZ_GPIO_FUNC_NONE
);
}
return
ret
;
}
EXPORT_SYMBOL_GPL
(
jz_gpio_bulk_request
);
void
jz_gpio_bulk_free
(
const
struct
jz_gpio_bulk_request
*
request
,
size_t
num
)
{
size_t
i
;
for
(
i
=
0
;
i
<
num
;
++
i
,
++
request
)
{
gpio_free
(
request
->
gpio
);
jz_gpio_set_function
(
request
->
gpio
,
JZ_GPIO_FUNC_NONE
);
}
}
EXPORT_SYMBOL_GPL
(
jz_gpio_bulk_free
);
void
jz_gpio_bulk_suspend
(
const
struct
jz_gpio_bulk_request
*
request
,
size_t
num
)
{
size_t
i
;
for
(
i
=
0
;
i
<
num
;
++
i
,
++
request
)
{
jz_gpio_set_function
(
request
->
gpio
,
JZ_GPIO_FUNC_NONE
);
jz_gpio_write_bit
(
request
->
gpio
,
JZ_REG_GPIO_DIRECTION_CLEAR
);
jz_gpio_write_bit
(
request
->
gpio
,
JZ_REG_GPIO_PULL_SET
);
}
}
EXPORT_SYMBOL_GPL
(
jz_gpio_bulk_suspend
);
void
jz_gpio_bulk_resume
(
const
struct
jz_gpio_bulk_request
*
request
,
size_t
num
)
{
size_t
i
;
for
(
i
=
0
;
i
<
num
;
++
i
,
++
request
)
jz_gpio_set_function
(
request
->
gpio
,
request
->
function
);
}
EXPORT_SYMBOL_GPL
(
jz_gpio_bulk_resume
);
void
jz_gpio_enable_pullup
(
unsigned
gpio
)
{
jz_gpio_write_bit
(
gpio
,
JZ_REG_GPIO_PULL_CLEAR
);
}
EXPORT_SYMBOL_GPL
(
jz_gpio_enable_pullup
);
void
jz_gpio_disable_pullup
(
unsigned
gpio
)
{
jz_gpio_write_bit
(
gpio
,
JZ_REG_GPIO_PULL_SET
);
}
EXPORT_SYMBOL_GPL
(
jz_gpio_disable_pullup
);
static
int
jz_gpio_get_value
(
struct
gpio_chip
*
chip
,
unsigned
gpio
)
{
return
!!
(
readl
(
CHIP_TO_REG
(
chip
,
JZ_REG_GPIO_PIN
))
&
BIT
(
gpio
));
}
static
void
jz_gpio_set_value
(
struct
gpio_chip
*
chip
,
unsigned
gpio
,
int
value
)
{
uint32_t
__iomem
*
reg
=
CHIP_TO_REG
(
chip
,
JZ_REG_GPIO_DATA_SET
);
reg
+=
!
value
;
writel
(
BIT
(
gpio
),
reg
);
}
static
int
jz_gpio_direction_output
(
struct
gpio_chip
*
chip
,
unsigned
gpio
,
int
value
)
{
writel
(
BIT
(
gpio
),
CHIP_TO_REG
(
chip
,
JZ_REG_GPIO_DIRECTION_SET
));
jz_gpio_set_value
(
chip
,
gpio
,
value
);
return
0
;
}
static
int
jz_gpio_direction_input
(
struct
gpio_chip
*
chip
,
unsigned
gpio
)
{
writel
(
BIT
(
gpio
),
CHIP_TO_REG
(
chip
,
JZ_REG_GPIO_DIRECTION_CLEAR
));
return
0
;
}
static
int
jz_gpio_to_irq
(
struct
gpio_chip
*
chip
,
unsigned
gpio
)
{
struct
jz_gpio_chip
*
jz_gpio
=
gpiochip_get_data
(
chip
);
return
jz_gpio
->
irq_base
+
gpio
;
}
int
jz_gpio_port_direction_input
(
int
port
,
uint32_t
mask
)
{
writel
(
mask
,
GPIO_TO_REG
(
port
,
JZ_REG_GPIO_DIRECTION_CLEAR
));
return
0
;
}
EXPORT_SYMBOL
(
jz_gpio_port_direction_input
);
int
jz_gpio_port_direction_output
(
int
port
,
uint32_t
mask
)
{
writel
(
mask
,
GPIO_TO_REG
(
port
,
JZ_REG_GPIO_DIRECTION_SET
));
return
0
;
}
EXPORT_SYMBOL
(
jz_gpio_port_direction_output
);
void
jz_gpio_port_set_value
(
int
port
,
uint32_t
value
,
uint32_t
mask
)
{
writel
(
~
value
&
mask
,
GPIO_TO_REG
(
port
,
JZ_REG_GPIO_DATA_CLEAR
));
writel
(
value
&
mask
,
GPIO_TO_REG
(
port
,
JZ_REG_GPIO_DATA_SET
));
}
EXPORT_SYMBOL
(
jz_gpio_port_set_value
);
uint32_t
jz_gpio_port_get_value
(
int
port
,
uint32_t
mask
)
{
uint32_t
value
=
readl
(
GPIO_TO_REG
(
port
,
JZ_REG_GPIO_PIN
));
return
value
&
mask
;
}
EXPORT_SYMBOL
(
jz_gpio_port_get_value
);
#define IRQ_TO_BIT(irq) BIT((irq - JZ4740_IRQ_GPIO(0)) & 0x1f)
static
void
jz_gpio_check_trigger_both
(
struct
jz_gpio_chip
*
chip
,
unsigned
int
irq
)
{
uint32_t
value
;
void
__iomem
*
reg
;
uint32_t
mask
=
IRQ_TO_BIT
(
irq
);
if
(
!
(
chip
->
edge_trigger_both
&
mask
))
return
;
reg
=
chip
->
base
;
value
=
readl
(
chip
->
base
+
JZ_REG_GPIO_PIN
);
if
(
value
&
mask
)
reg
+=
JZ_REG_GPIO_DIRECTION_CLEAR
;
else
reg
+=
JZ_REG_GPIO_DIRECTION_SET
;
writel
(
mask
,
reg
);
}
static
void
jz_gpio_irq_demux_handler
(
struct
irq_desc
*
desc
)
{
uint32_t
flag
;
unsigned
int
gpio_irq
;
struct
jz_gpio_chip
*
chip
=
irq_desc_get_handler_data
(
desc
);
flag
=
readl
(
chip
->
base
+
JZ_REG_GPIO_FLAG
);
if
(
!
flag
)
return
;
gpio_irq
=
chip
->
irq_base
+
__fls
(
flag
);
jz_gpio_check_trigger_both
(
chip
,
gpio_irq
);
generic_handle_irq
(
gpio_irq
);
};
static
inline
void
jz_gpio_set_irq_bit
(
struct
irq_data
*
data
,
unsigned
int
reg
)
{
struct
jz_gpio_chip
*
chip
=
irq_to_jz_gpio_chip
(
data
);
writel
(
IRQ_TO_BIT
(
data
->
irq
),
chip
->
base
+
reg
);
}
static
void
jz_gpio_irq_unmask
(
struct
irq_data
*
data
)
{
struct
jz_gpio_chip
*
chip
=
irq_to_jz_gpio_chip
(
data
);
jz_gpio_check_trigger_both
(
chip
,
data
->
irq
);
irq_gc_unmask_enable_reg
(
data
);
};
/* TODO: Check if function is gpio */
static
unsigned
int
jz_gpio_irq_startup
(
struct
irq_data
*
data
)
{
jz_gpio_set_irq_bit
(
data
,
JZ_REG_GPIO_SELECT_SET
);
jz_gpio_irq_unmask
(
data
);
return
0
;
}
static
void
jz_gpio_irq_shutdown
(
struct
irq_data
*
data
)
{
irq_gc_mask_disable_reg
(
data
);
/* Set direction to input */
jz_gpio_set_irq_bit
(
data
,
JZ_REG_GPIO_DIRECTION_CLEAR
);
jz_gpio_set_irq_bit
(
data
,
JZ_REG_GPIO_SELECT_CLEAR
);
}
static
int
jz_gpio_irq_set_type
(
struct
irq_data
*
data
,
unsigned
int
flow_type
)
{
struct
jz_gpio_chip
*
chip
=
irq_to_jz_gpio_chip
(
data
);
unsigned
int
irq
=
data
->
irq
;
if
(
flow_type
==
IRQ_TYPE_EDGE_BOTH
)
{
uint32_t
value
=
readl
(
chip
->
base
+
JZ_REG_GPIO_PIN
);
if
(
value
&
IRQ_TO_BIT
(
irq
))
flow_type
=
IRQ_TYPE_EDGE_FALLING
;
else
flow_type
=
IRQ_TYPE_EDGE_RISING
;
chip
->
edge_trigger_both
|=
IRQ_TO_BIT
(
irq
);
}
else
{
chip
->
edge_trigger_both
&=
~
IRQ_TO_BIT
(
irq
);
}
switch
(
flow_type
)
{
case
IRQ_TYPE_EDGE_RISING
:
jz_gpio_set_irq_bit
(
data
,
JZ_REG_GPIO_DIRECTION_SET
);
jz_gpio_set_irq_bit
(
data
,
JZ_REG_GPIO_TRIGGER_SET
);
break
;
case
IRQ_TYPE_EDGE_FALLING
:
jz_gpio_set_irq_bit
(
data
,
JZ_REG_GPIO_DIRECTION_CLEAR
);
jz_gpio_set_irq_bit
(
data
,
JZ_REG_GPIO_TRIGGER_SET
);
break
;
case
IRQ_TYPE_LEVEL_HIGH
:
jz_gpio_set_irq_bit
(
data
,
JZ_REG_GPIO_DIRECTION_SET
);
jz_gpio_set_irq_bit
(
data
,
JZ_REG_GPIO_TRIGGER_CLEAR
);
break
;
case
IRQ_TYPE_LEVEL_LOW
:
jz_gpio_set_irq_bit
(
data
,
JZ_REG_GPIO_DIRECTION_CLEAR
);
jz_gpio_set_irq_bit
(
data
,
JZ_REG_GPIO_TRIGGER_CLEAR
);
break
;
default:
return
-
EINVAL
;
}
return
0
;
}
static
int
jz_gpio_irq_set_wake
(
struct
irq_data
*
data
,
unsigned
int
on
)
{
struct
jz_gpio_chip
*
chip
=
irq_to_jz_gpio_chip
(
data
);
irq_gc_set_wake
(
data
,
on
);
irq_set_irq_wake
(
chip
->
irq
,
on
);
return
0
;
}
#define JZ4740_GPIO_CHIP(_bank) { \
.irq_base = JZ4740_IRQ_GPIO_BASE_ ## _bank, \
.gpio_chip = { \
.label = "Bank " # _bank, \
.owner = THIS_MODULE, \
.set = jz_gpio_set_value, \
.get = jz_gpio_get_value, \
.direction_output = jz_gpio_direction_output, \
.direction_input = jz_gpio_direction_input, \
.to_irq = jz_gpio_to_irq, \
.base = JZ4740_GPIO_BASE_ ## _bank, \
.ngpio = JZ4740_GPIO_NUM_ ## _bank, \
}, \
}
static
struct
jz_gpio_chip
jz4740_gpio_chips
[]
=
{
JZ4740_GPIO_CHIP
(
A
),
JZ4740_GPIO_CHIP
(
B
),
JZ4740_GPIO_CHIP
(
C
),
JZ4740_GPIO_CHIP
(
D
),
};
static
void
jz4740_gpio_chip_init
(
struct
jz_gpio_chip
*
chip
,
unsigned
int
id
)
{
struct
irq_chip_generic
*
gc
;
struct
irq_chip_type
*
ct
;
chip
->
base
=
ioremap
(
JZ4740_GPIO_BASE_ADDR
+
(
id
*
0x100
),
0x100
);
chip
->
irq
=
JZ4740_IRQ_INTC_GPIO
(
id
);
irq_set_chained_handler_and_data
(
chip
->
irq
,
jz_gpio_irq_demux_handler
,
chip
);
gc
=
irq_alloc_generic_chip
(
chip
->
gpio_chip
.
label
,
1
,
chip
->
irq_base
,
chip
->
base
,
handle_level_irq
);
gc
->
wake_enabled
=
IRQ_MSK
(
chip
->
gpio_chip
.
ngpio
);
gc
->
private
=
chip
;
ct
=
gc
->
chip_types
;
ct
->
regs
.
enable
=
JZ_REG_GPIO_MASK_CLEAR
;
ct
->
regs
.
disable
=
JZ_REG_GPIO_MASK_SET
;
ct
->
regs
.
ack
=
JZ_REG_GPIO_FLAG_CLEAR
;
ct
->
chip
.
name
=
"GPIO"
;
ct
->
chip
.
irq_mask
=
irq_gc_mask_disable_reg
;
ct
->
chip
.
irq_unmask
=
jz_gpio_irq_unmask
;
ct
->
chip
.
irq_ack
=
irq_gc_ack_set_bit
;
ct
->
chip
.
irq_suspend
=
ingenic_intc_irq_suspend
;
ct
->
chip
.
irq_resume
=
ingenic_intc_irq_resume
;
ct
->
chip
.
irq_startup
=
jz_gpio_irq_startup
;
ct
->
chip
.
irq_shutdown
=
jz_gpio_irq_shutdown
;
ct
->
chip
.
irq_set_type
=
jz_gpio_irq_set_type
;
ct
->
chip
.
irq_set_wake
=
jz_gpio_irq_set_wake
;
ct
->
chip
.
flags
=
IRQCHIP_SET_TYPE_MASKED
;
irq_setup_generic_chip
(
gc
,
IRQ_MSK
(
chip
->
gpio_chip
.
ngpio
),
IRQ_GC_INIT_NESTED_LOCK
,
0
,
IRQ_NOPROBE
|
IRQ_LEVEL
);
gpiochip_add_data
(
&
chip
->
gpio_chip
,
chip
);
}
static
int
__init
jz4740_gpio_init
(
void
)
{
unsigned
int
i
;
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
jz4740_gpio_chips
);
++
i
)
jz4740_gpio_chip_init
(
&
jz4740_gpio_chips
[
i
],
i
);
printk
(
KERN_INFO
"JZ4740 GPIO initialized
\n
"
);
return
0
;
}
arch_initcall
(
jz4740_gpio_init
);
#ifdef CONFIG_DEBUG_FS
static
inline
void
gpio_seq_reg
(
struct
seq_file
*
s
,
struct
jz_gpio_chip
*
chip
,
const
char
*
name
,
unsigned
int
reg
)
{
seq_printf
(
s
,
"
\t
%s: %08x
\n
"
,
name
,
readl
(
chip
->
base
+
reg
));
}
static
int
gpio_regs_show
(
struct
seq_file
*
s
,
void
*
unused
)
{
struct
jz_gpio_chip
*
chip
=
jz4740_gpio_chips
;
int
i
;
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
jz4740_gpio_chips
);
++
i
,
++
chip
)
{
seq_printf
(
s
,
"==GPIO %d==
\n
"
,
i
);
gpio_seq_reg
(
s
,
chip
,
"Pin"
,
JZ_REG_GPIO_PIN
);
gpio_seq_reg
(
s
,
chip
,
"Data"
,
JZ_REG_GPIO_DATA
);
gpio_seq_reg
(
s
,
chip
,
"Mask"
,
JZ_REG_GPIO_MASK
);
gpio_seq_reg
(
s
,
chip
,
"Pull"
,
JZ_REG_GPIO_PULL
);
gpio_seq_reg
(
s
,
chip
,
"Func"
,
JZ_REG_GPIO_FUNC
);
gpio_seq_reg
(
s
,
chip
,
"Select"
,
JZ_REG_GPIO_SELECT
);
gpio_seq_reg
(
s
,
chip
,
"Direction"
,
JZ_REG_GPIO_DIRECTION
);
gpio_seq_reg
(
s
,
chip
,
"Trigger"
,
JZ_REG_GPIO_TRIGGER
);
gpio_seq_reg
(
s
,
chip
,
"Flag"
,
JZ_REG_GPIO_FLAG
);
}
return
0
;
}
static
int
gpio_regs_open
(
struct
inode
*
inode
,
struct
file
*
file
)
{
return
single_open
(
file
,
gpio_regs_show
,
NULL
);
}
static
const
struct
file_operations
gpio_regs_operations
=
{
.
open
=
gpio_regs_open
,
.
read
=
seq_read
,
.
llseek
=
seq_lseek
,
.
release
=
single_release
,
};
static
int
__init
gpio_debugfs_init
(
void
)
{
(
void
)
debugfs_create_file
(
"jz_regs_gpio"
,
S_IFREG
|
S_IRUGO
,
NULL
,
NULL
,
&
gpio_regs_operations
);
return
0
;
}
subsys_initcall
(
gpio_debugfs_init
);
#endif
drivers/gpio/Kconfig
View file @
bdb18d93
...
...
@@ -242,6 +242,16 @@ config GPIO_ICH
If unsure, say N.
config GPIO_INGENIC
tristate "Ingenic JZ47xx SoCs GPIO support"
depends on MACH_INGENIC || COMPILE_TEST
select GPIOLIB_IRQCHIP
help
Say yes here to support the GPIO functionality present on the
JZ4740 and JZ4780 SoCs from Ingenic.
If unsure, say N.
config GPIO_IOP
tristate "Intel IOP GPIO"
depends on ARCH_IOP32X || ARCH_IOP33X || COMPILE_TEST
...
...
drivers/gpio/Makefile
View file @
bdb18d93
...
...
@@ -55,6 +55,7 @@ obj-$(CONFIG_GPIO_GPIO_MM) += gpio-gpio-mm.o
obj-$(CONFIG_GPIO_GRGPIO)
+=
gpio-grgpio.o
obj-$(CONFIG_HTC_EGPIO)
+=
gpio-htc-egpio.o
obj-$(CONFIG_GPIO_ICH)
+=
gpio-ich.o
obj-$(CONFIG_GPIO_INGENIC)
+=
gpio-ingenic.o
obj-$(CONFIG_GPIO_IOP)
+=
gpio-iop.o
obj-$(CONFIG_GPIO_IT87)
+=
gpio-it87.o
obj-$(CONFIG_GPIO_JANZ_TTL)
+=
gpio-janz-ttl.o
...
...
drivers/gpio/gpio-ingenic.c
0 → 100644
View file @
bdb18d93
/*
* Ingenic JZ47xx GPIO driver
*
* Copyright (c) 2017 Paul Cercueil <paul@crapouillou.net>
*
* License terms: GNU General Public License (GPL) version 2
*/
#include <linux/gpio/driver.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of_address.h>
#include <linux/of_device.h>
#include <linux/of_irq.h>
#include <linux/pinctrl/consumer.h>
#include <linux/regmap.h>
#define GPIO_PIN 0x00
#define GPIO_MSK 0x20
#define JZ4740_GPIO_DATA 0x10
#define JZ4740_GPIO_SELECT 0x50
#define JZ4740_GPIO_DIR 0x60
#define JZ4740_GPIO_TRIG 0x70
#define JZ4740_GPIO_FLAG 0x80
#define JZ4770_GPIO_INT 0x10
#define JZ4770_GPIO_PAT1 0x30
#define JZ4770_GPIO_PAT0 0x40
#define JZ4770_GPIO_FLAG 0x50
#define REG_SET(x) ((x) + 0x4)
#define REG_CLEAR(x) ((x) + 0x8)
enum
jz_version
{
ID_JZ4740
,
ID_JZ4770
,
ID_JZ4780
,
};
struct
ingenic_gpio_chip
{
struct
regmap
*
map
;
struct
gpio_chip
gc
;
struct
irq_chip
irq_chip
;
unsigned
int
irq
,
reg_base
;
enum
jz_version
version
;
};
static
u32
gpio_ingenic_read_reg
(
struct
ingenic_gpio_chip
*
jzgc
,
u8
reg
)
{
unsigned
int
val
;
regmap_read
(
jzgc
->
map
,
jzgc
->
reg_base
+
reg
,
&
val
);
return
(
u32
)
val
;
}
static
void
gpio_ingenic_set_bit
(
struct
ingenic_gpio_chip
*
jzgc
,
u8
reg
,
u8
offset
,
bool
set
)
{
if
(
set
)
reg
=
REG_SET
(
reg
);
else
reg
=
REG_CLEAR
(
reg
);
regmap_write
(
jzgc
->
map
,
jzgc
->
reg_base
+
reg
,
BIT
(
offset
));
}
static
inline
bool
gpio_get_value
(
struct
ingenic_gpio_chip
*
jzgc
,
u8
offset
)
{
unsigned
int
val
=
gpio_ingenic_read_reg
(
jzgc
,
GPIO_PIN
);
return
!!
(
val
&
BIT
(
offset
));
}
static
void
gpio_set_value
(
struct
ingenic_gpio_chip
*
jzgc
,
u8
offset
,
int
value
)
{
if
(
jzgc
->
version
>=
ID_JZ4770
)
gpio_ingenic_set_bit
(
jzgc
,
JZ4770_GPIO_PAT0
,
offset
,
!!
value
);
else
gpio_ingenic_set_bit
(
jzgc
,
JZ4740_GPIO_DATA
,
offset
,
!!
value
);
}
static
void
irq_set_type
(
struct
ingenic_gpio_chip
*
jzgc
,
u8
offset
,
unsigned
int
type
)
{
u8
reg1
,
reg2
;
if
(
jzgc
->
version
>=
ID_JZ4770
)
{
reg1
=
JZ4770_GPIO_PAT1
;
reg2
=
JZ4770_GPIO_PAT0
;
}
else
{
reg1
=
JZ4740_GPIO_TRIG
;
reg2
=
JZ4740_GPIO_DIR
;
}
switch
(
type
)
{
case
IRQ_TYPE_EDGE_RISING
:
gpio_ingenic_set_bit
(
jzgc
,
reg2
,
offset
,
true
);
gpio_ingenic_set_bit
(
jzgc
,
reg1
,
offset
,
true
);
break
;
case
IRQ_TYPE_EDGE_FALLING
:
gpio_ingenic_set_bit
(
jzgc
,
reg2
,
offset
,
false
);
gpio_ingenic_set_bit
(
jzgc
,
reg1
,
offset
,
true
);
break
;
case
IRQ_TYPE_LEVEL_HIGH
:
gpio_ingenic_set_bit
(
jzgc
,
reg2
,
offset
,
true
);
gpio_ingenic_set_bit
(
jzgc
,
reg1
,
offset
,
false
);
break
;
case
IRQ_TYPE_LEVEL_LOW
:
default:
gpio_ingenic_set_bit
(
jzgc
,
reg2
,
offset
,
false
);
gpio_ingenic_set_bit
(
jzgc
,
reg1
,
offset
,
false
);
break
;
}
}
static
void
ingenic_gpio_irq_mask
(
struct
irq_data
*
irqd
)
{
struct
gpio_chip
*
gc
=
irq_data_get_irq_chip_data
(
irqd
);
struct
ingenic_gpio_chip
*
jzgc
=
gpiochip_get_data
(
gc
);
gpio_ingenic_set_bit
(
jzgc
,
GPIO_MSK
,
irqd
->
hwirq
,
true
);
}
static
void
ingenic_gpio_irq_unmask
(
struct
irq_data
*
irqd
)
{
struct
gpio_chip
*
gc
=
irq_data_get_irq_chip_data
(
irqd
);
struct
ingenic_gpio_chip
*
jzgc
=
gpiochip_get_data
(
gc
);
gpio_ingenic_set_bit
(
jzgc
,
GPIO_MSK
,
irqd
->
hwirq
,
false
);
}
static
void
ingenic_gpio_irq_enable
(
struct
irq_data
*
irqd
)
{
struct
gpio_chip
*
gc
=
irq_data_get_irq_chip_data
(
irqd
);
struct
ingenic_gpio_chip
*
jzgc
=
gpiochip_get_data
(
gc
);
int
irq
=
irqd
->
hwirq
;
if
(
jzgc
->
version
>=
ID_JZ4770
)
gpio_ingenic_set_bit
(
jzgc
,
JZ4770_GPIO_INT
,
irq
,
true
);
else
gpio_ingenic_set_bit
(
jzgc
,
JZ4740_GPIO_SELECT
,
irq
,
true
);
ingenic_gpio_irq_unmask
(
irqd
);
}
static
void
ingenic_gpio_irq_disable
(
struct
irq_data
*
irqd
)
{
struct
gpio_chip
*
gc
=
irq_data_get_irq_chip_data
(
irqd
);
struct
ingenic_gpio_chip
*
jzgc
=
gpiochip_get_data
(
gc
);
int
irq
=
irqd
->
hwirq
;
ingenic_gpio_irq_mask
(
irqd
);
if
(
jzgc
->
version
>=
ID_JZ4770
)
gpio_ingenic_set_bit
(
jzgc
,
JZ4770_GPIO_INT
,
irq
,
false
);
else
gpio_ingenic_set_bit
(
jzgc
,
JZ4740_GPIO_SELECT
,
irq
,
false
);
}
static
void
ingenic_gpio_irq_ack
(
struct
irq_data
*
irqd
)
{
struct
gpio_chip
*
gc
=
irq_data_get_irq_chip_data
(
irqd
);
struct
ingenic_gpio_chip
*
jzgc
=
gpiochip_get_data
(
gc
);
int
irq
=
irqd
->
hwirq
;
bool
high
;
if
(
irqd_get_trigger_type
(
irqd
)
==
IRQ_TYPE_EDGE_BOTH
)
{
/*
* Switch to an interrupt for the opposite edge to the one that
* triggered the interrupt being ACKed.
*/
high
=
gpio_get_value
(
jzgc
,
irq
);
if
(
high
)
irq_set_type
(
jzgc
,
irq
,
IRQ_TYPE_EDGE_FALLING
);
else
irq_set_type
(
jzgc
,
irq
,
IRQ_TYPE_EDGE_RISING
);
}
if
(
jzgc
->
version
>=
ID_JZ4770
)
gpio_ingenic_set_bit
(
jzgc
,
JZ4770_GPIO_FLAG
,
irq
,
false
);
else
gpio_ingenic_set_bit
(
jzgc
,
JZ4740_GPIO_DATA
,
irq
,
true
);
}
static
int
ingenic_gpio_irq_set_type
(
struct
irq_data
*
irqd
,
unsigned
int
type
)
{
struct
gpio_chip
*
gc
=
irq_data_get_irq_chip_data
(
irqd
);
struct
ingenic_gpio_chip
*
jzgc
=
gpiochip_get_data
(
gc
);
switch
(
type
)
{
case
IRQ_TYPE_EDGE_BOTH
:
case
IRQ_TYPE_EDGE_RISING
:
case
IRQ_TYPE_EDGE_FALLING
:
irq_set_handler_locked
(
irqd
,
handle_edge_irq
);
break
;
case
IRQ_TYPE_LEVEL_HIGH
:
case
IRQ_TYPE_LEVEL_LOW
:
irq_set_handler_locked
(
irqd
,
handle_level_irq
);
break
;
default:
irq_set_handler_locked
(
irqd
,
handle_bad_irq
);
}
if
(
type
==
IRQ_TYPE_EDGE_BOTH
)
{
/*
* The hardware does not support interrupts on both edges. The
* best we can do is to set up a single-edge interrupt and then
* switch to the opposing edge when ACKing the interrupt.
*/
bool
high
=
gpio_get_value
(
jzgc
,
irqd
->
hwirq
);
type
=
high
?
IRQ_TYPE_EDGE_FALLING
:
IRQ_TYPE_EDGE_RISING
;
}
irq_set_type
(
jzgc
,
irqd
->
hwirq
,
type
);
return
0
;
}
static
int
ingenic_gpio_irq_set_wake
(
struct
irq_data
*
irqd
,
unsigned
int
on
)
{
struct
gpio_chip
*
gc
=
irq_data_get_irq_chip_data
(
irqd
);
struct
ingenic_gpio_chip
*
jzgc
=
gpiochip_get_data
(
gc
);
return
irq_set_irq_wake
(
jzgc
->
irq
,
on
);
}
static
void
ingenic_gpio_irq_handler
(
struct
irq_desc
*
desc
)
{
struct
gpio_chip
*
gc
=
irq_desc_get_handler_data
(
desc
);
struct
ingenic_gpio_chip
*
jzgc
=
gpiochip_get_data
(
gc
);
struct
irq_chip
*
irq_chip
=
irq_data_get_irq_chip
(
&
desc
->
irq_data
);
unsigned
long
flag
,
i
;
chained_irq_enter
(
irq_chip
,
desc
);
if
(
jzgc
->
version
>=
ID_JZ4770
)
flag
=
gpio_ingenic_read_reg
(
jzgc
,
JZ4770_GPIO_FLAG
);
else
flag
=
gpio_ingenic_read_reg
(
jzgc
,
JZ4740_GPIO_FLAG
);
for_each_set_bit
(
i
,
&
flag
,
32
)
generic_handle_irq
(
irq_linear_revmap
(
gc
->
irqdomain
,
i
));
chained_irq_exit
(
irq_chip
,
desc
);
}
static
void
ingenic_gpio_set
(
struct
gpio_chip
*
gc
,
unsigned
int
offset
,
int
value
)
{
struct
ingenic_gpio_chip
*
jzgc
=
gpiochip_get_data
(
gc
);
gpio_set_value
(
jzgc
,
offset
,
value
);
}
static
int
ingenic_gpio_get
(
struct
gpio_chip
*
gc
,
unsigned
int
offset
)
{
struct
ingenic_gpio_chip
*
jzgc
=
gpiochip_get_data
(
gc
);
return
(
int
)
gpio_get_value
(
jzgc
,
offset
);
}
static
int
ingenic_gpio_direction_input
(
struct
gpio_chip
*
gc
,
unsigned
int
offset
)
{
return
pinctrl_gpio_direction_input
(
gc
->
base
+
offset
);
}
static
int
ingenic_gpio_direction_output
(
struct
gpio_chip
*
gc
,
unsigned
int
offset
,
int
value
)
{
ingenic_gpio_set
(
gc
,
offset
,
value
);
return
pinctrl_gpio_direction_output
(
gc
->
base
+
offset
);
}
static
const
struct
of_device_id
ingenic_gpio_of_match
[]
=
{
{
.
compatible
=
"ingenic,jz4740-gpio"
,
.
data
=
(
void
*
)
ID_JZ4740
},
{
.
compatible
=
"ingenic,jz4770-gpio"
,
.
data
=
(
void
*
)
ID_JZ4770
},
{
.
compatible
=
"ingenic,jz4780-gpio"
,
.
data
=
(
void
*
)
ID_JZ4780
},
{},
};
MODULE_DEVICE_TABLE
(
of
,
ingenic_gpio_of_match
);
static
int
ingenic_gpio_probe
(
struct
platform_device
*
pdev
)
{
struct
device
*
dev
=
&
pdev
->
dev
;
const
struct
of_device_id
*
of_id
=
of_match_device
(
ingenic_gpio_of_match
,
dev
);
struct
ingenic_gpio_chip
*
jzgc
;
u32
bank
;
int
err
;
jzgc
=
devm_kzalloc
(
dev
,
sizeof
(
*
jzgc
),
GFP_KERNEL
);
if
(
!
jzgc
)
return
-
ENOMEM
;
jzgc
->
map
=
dev_get_drvdata
(
dev
->
parent
);
if
(
!
jzgc
->
map
)
{
dev_err
(
dev
,
"Cannot get parent regmap
\n
"
);
return
-
ENXIO
;
}
err
=
of_property_read_u32
(
dev
->
of_node
,
"reg"
,
&
bank
);
if
(
err
)
{
dev_err
(
dev
,
"Cannot read
\"
reg
\"
property: %i
\n
"
,
err
);
return
err
;
}
jzgc
->
reg_base
=
bank
*
0x100
;
jzgc
->
gc
.
label
=
devm_kasprintf
(
dev
,
GFP_KERNEL
,
"GPIO%c"
,
'A'
+
bank
);
if
(
!
jzgc
->
gc
.
label
)
return
-
ENOMEM
;
/* DO NOT EXPAND THIS: FOR BACKWARD GPIO NUMBERSPACE COMPATIBIBILITY
* ONLY: WORK TO TRANSITION CONSUMERS TO USE THE GPIO DESCRIPTOR API IN
* <linux/gpio/consumer.h> INSTEAD.
*/
jzgc
->
gc
.
base
=
bank
*
32
;
jzgc
->
gc
.
ngpio
=
32
;
jzgc
->
gc
.
parent
=
dev
;
jzgc
->
gc
.
of_node
=
dev
->
of_node
;
jzgc
->
gc
.
owner
=
THIS_MODULE
;
jzgc
->
version
=
(
enum
jz_version
)
of_id
->
data
;
jzgc
->
gc
.
set
=
ingenic_gpio_set
;
jzgc
->
gc
.
get
=
ingenic_gpio_get
;
jzgc
->
gc
.
direction_input
=
ingenic_gpio_direction_input
;
jzgc
->
gc
.
direction_output
=
ingenic_gpio_direction_output
;
if
(
of_property_read_bool
(
dev
->
of_node
,
"gpio-ranges"
))
{
jzgc
->
gc
.
request
=
gpiochip_generic_request
;
jzgc
->
gc
.
free
=
gpiochip_generic_free
;
}
err
=
devm_gpiochip_add_data
(
dev
,
&
jzgc
->
gc
,
jzgc
);
if
(
err
)
return
err
;
jzgc
->
irq
=
irq_of_parse_and_map
(
dev
->
of_node
,
0
);
if
(
!
jzgc
->
irq
)
return
-
EINVAL
;
jzgc
->
irq_chip
.
name
=
jzgc
->
gc
.
label
;
jzgc
->
irq_chip
.
irq_enable
=
ingenic_gpio_irq_enable
;
jzgc
->
irq_chip
.
irq_disable
=
ingenic_gpio_irq_disable
;
jzgc
->
irq_chip
.
irq_unmask
=
ingenic_gpio_irq_unmask
;
jzgc
->
irq_chip
.
irq_mask
=
ingenic_gpio_irq_mask
;
jzgc
->
irq_chip
.
irq_ack
=
ingenic_gpio_irq_ack
;
jzgc
->
irq_chip
.
irq_set_type
=
ingenic_gpio_irq_set_type
;
jzgc
->
irq_chip
.
irq_set_wake
=
ingenic_gpio_irq_set_wake
;
jzgc
->
irq_chip
.
flags
=
IRQCHIP_MASK_ON_SUSPEND
;
err
=
gpiochip_irqchip_add
(
&
jzgc
->
gc
,
&
jzgc
->
irq_chip
,
0
,
handle_level_irq
,
IRQ_TYPE_NONE
);
if
(
err
)
return
err
;
gpiochip_set_chained_irqchip
(
&
jzgc
->
gc
,
&
jzgc
->
irq_chip
,
jzgc
->
irq
,
ingenic_gpio_irq_handler
);
return
0
;
}
static
int
ingenic_gpio_remove
(
struct
platform_device
*
pdev
)
{
return
0
;
}
static
struct
platform_driver
ingenic_gpio_driver
=
{
.
driver
=
{
.
name
=
"gpio-ingenic"
,
.
of_match_table
=
of_match_ptr
(
ingenic_gpio_of_match
),
},
.
probe
=
ingenic_gpio_probe
,
.
remove
=
ingenic_gpio_remove
,
};
static
int
__init
ingenic_gpio_drv_register
(
void
)
{
return
platform_driver_register
(
&
ingenic_gpio_driver
);
}
subsys_initcall
(
ingenic_gpio_drv_register
);
static
void
__exit
ingenic_gpio_drv_unregister
(
void
)
{
platform_driver_unregister
(
&
ingenic_gpio_driver
);
}
module_exit
(
ingenic_gpio_drv_unregister
);
MODULE_AUTHOR
(
"Paul Cercueil <paul@crapouillou.net>"
);
MODULE_DESCRIPTION
(
"Ingenic JZ47xx GPIO driver"
);
MODULE_LICENSE
(
"GPL"
);
drivers/mmc/host/jz4740_mmc.c
View file @
bdb18d93
...
...
@@ -20,6 +20,7 @@
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/pinctrl/consumer.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
#include <linux/scatterlist.h>
...
...
@@ -27,7 +28,6 @@
#include <linux/bitops.h>
#include <linux/gpio.h>
#include <asm/mach-jz4740/gpio.h>
#include <asm/cacheflush.h>
#include <linux/dma-mapping.h>
#include <linux/dmaengine.h>
...
...
@@ -901,15 +901,6 @@ static const struct mmc_host_ops jz4740_mmc_ops = {
.
enable_sdio_irq
=
jz4740_mmc_enable_sdio_irq
,
};
static
const
struct
jz_gpio_bulk_request
jz4740_mmc_pins
[]
=
{
JZ_GPIO_BULK_PIN
(
MSC_CMD
),
JZ_GPIO_BULK_PIN
(
MSC_CLK
),
JZ_GPIO_BULK_PIN
(
MSC_DATA0
),
JZ_GPIO_BULK_PIN
(
MSC_DATA1
),
JZ_GPIO_BULK_PIN
(
MSC_DATA2
),
JZ_GPIO_BULK_PIN
(
MSC_DATA3
),
};
static
int
jz4740_mmc_request_gpio
(
struct
device
*
dev
,
int
gpio
,
const
char
*
name
,
bool
output
,
int
value
)
{
...
...
@@ -973,15 +964,6 @@ static void jz4740_mmc_free_gpios(struct platform_device *pdev)
gpio_free
(
pdata
->
gpio_power
);
}
static
inline
size_t
jz4740_mmc_num_pins
(
struct
jz4740_mmc_host
*
host
)
{
size_t
num_pins
=
ARRAY_SIZE
(
jz4740_mmc_pins
);
if
(
host
->
pdata
&&
host
->
pdata
->
data_1bit
)
num_pins
-=
3
;
return
num_pins
;
}
static
int
jz4740_mmc_probe
(
struct
platform_device
*
pdev
)
{
int
ret
;
...
...
@@ -1022,15 +1004,9 @@ static int jz4740_mmc_probe(struct platform_device* pdev)
goto
err_free_host
;
}
ret
=
jz_gpio_bulk_request
(
jz4740_mmc_pins
,
jz4740_mmc_num_pins
(
host
));
if
(
ret
)
{
dev_err
(
&
pdev
->
dev
,
"Failed to request mmc pins: %d
\n
"
,
ret
);
goto
err_free_host
;
}
ret
=
jz4740_mmc_request_gpios
(
mmc
,
pdev
);
if
(
ret
)
goto
err_
gpio_bulk_free
;
goto
err_
release_dma
;
mmc
->
ops
=
&
jz4740_mmc_ops
;
mmc
->
f_min
=
JZ_MMC_CLK_RATE
/
128
;
...
...
@@ -1086,10 +1062,9 @@ static int jz4740_mmc_probe(struct platform_device* pdev)
free_irq
(
host
->
irq
,
host
);
err_free_gpios:
jz4740_mmc_free_gpios
(
pdev
);
err_
gpio_bulk_free
:
err_
release_dma
:
if
(
host
->
use_dma
)
jz4740_mmc_release_dma_channels
(
host
);
jz_gpio_bulk_free
(
jz4740_mmc_pins
,
jz4740_mmc_num_pins
(
host
));
err_free_host:
mmc_free_host
(
mmc
);
...
...
@@ -1109,7 +1084,6 @@ static int jz4740_mmc_remove(struct platform_device *pdev)
free_irq
(
host
->
irq
,
host
);
jz4740_mmc_free_gpios
(
pdev
);
jz_gpio_bulk_free
(
jz4740_mmc_pins
,
jz4740_mmc_num_pins
(
host
));
if
(
host
->
use_dma
)
jz4740_mmc_release_dma_channels
(
host
);
...
...
@@ -1123,20 +1097,12 @@ static int jz4740_mmc_remove(struct platform_device *pdev)
static
int
jz4740_mmc_suspend
(
struct
device
*
dev
)
{
struct
jz4740_mmc_host
*
host
=
dev_get_drvdata
(
dev
);
jz_gpio_bulk_suspend
(
jz4740_mmc_pins
,
jz4740_mmc_num_pins
(
host
));
return
0
;
return
pinctrl_pm_select_sleep_state
(
dev
);
}
static
int
jz4740_mmc_resume
(
struct
device
*
dev
)
{
struct
jz4740_mmc_host
*
host
=
dev_get_drvdata
(
dev
);
jz_gpio_bulk_resume
(
jz4740_mmc_pins
,
jz4740_mmc_num_pins
(
host
));
return
0
;
return
pinctrl_pm_select_default_state
(
dev
);
}
static
SIMPLE_DEV_PM_OPS
(
jz4740_mmc_pm_ops
,
jz4740_mmc_suspend
,
...
...
drivers/mtd/nand/jz4740_nand.c
View file @
bdb18d93
...
...
@@ -25,7 +25,6 @@
#include <linux/gpio.h>
#include <asm/mach-jz4740/gpio.h>
#include <asm/mach-jz4740/jz4740_nand.h>
#define JZ_REG_NAND_CTRL 0x50
...
...
@@ -310,34 +309,20 @@ static int jz_nand_detect_bank(struct platform_device *pdev,
uint8_t
*
nand_dev_id
)
{
int
ret
;
int
gpio
;
char
gpio_name
[
9
];
char
res_name
[
6
];
uint32_t
ctrl
;
struct
nand_chip
*
chip
=
&
nand
->
chip
;
struct
mtd_info
*
mtd
=
nand_to_mtd
(
chip
);
/* Request GPIO port. */
gpio
=
JZ_GPIO_MEM_CS0
+
bank
-
1
;
sprintf
(
gpio_name
,
"NAND CS%d"
,
bank
);
ret
=
gpio_request
(
gpio
,
gpio_name
);
if
(
ret
)
{
dev_warn
(
&
pdev
->
dev
,
"Failed to request %s gpio %d: %d
\n
"
,
gpio_name
,
gpio
,
ret
);
goto
notfound_gpio
;
}
/* Request I/O resource. */
sprintf
(
res_name
,
"bank%d"
,
bank
);
ret
=
jz_nand_ioremap_resource
(
pdev
,
res_name
,
&
nand
->
bank_mem
[
bank
-
1
],
&
nand
->
bank_base
[
bank
-
1
]);
if
(
ret
)
goto
notfound_resource
;
return
ret
;
/* Enable chip in bank. */
jz_gpio_set_function
(
gpio
,
JZ_GPIO_FUNC_MEM_CS0
);
ctrl
=
readl
(
nand
->
base
+
JZ_REG_NAND_CTRL
);
ctrl
|=
JZ_NAND_CTRL_ENABLE_CHIP
(
bank
-
1
);
writel
(
ctrl
,
nand
->
base
+
JZ_REG_NAND_CTRL
);
...
...
@@ -377,12 +362,8 @@ static int jz_nand_detect_bank(struct platform_device *pdev,
dev_info
(
&
pdev
->
dev
,
"No chip found on bank %i
\n
"
,
bank
);
ctrl
&=
~
(
JZ_NAND_CTRL_ENABLE_CHIP
(
bank
-
1
));
writel
(
ctrl
,
nand
->
base
+
JZ_REG_NAND_CTRL
);
jz_gpio_set_function
(
gpio
,
JZ_GPIO_FUNC_NONE
);
jz_nand_iounmap_resource
(
nand
->
bank_mem
[
bank
-
1
],
nand
->
bank_base
[
bank
-
1
]);
notfound_resource:
gpio_free
(
gpio
);
notfound_gpio:
return
ret
;
}
...
...
@@ -503,7 +484,6 @@ static int jz_nand_probe(struct platform_device *pdev)
err_unclaim_banks:
while
(
chipnr
--
)
{
unsigned
char
bank
=
nand
->
banks
[
chipnr
];
gpio_free
(
JZ_GPIO_MEM_CS0
+
bank
-
1
);
jz_nand_iounmap_resource
(
nand
->
bank_mem
[
bank
-
1
],
nand
->
bank_base
[
bank
-
1
]);
}
...
...
@@ -530,7 +510,6 @@ static int jz_nand_remove(struct platform_device *pdev)
if
(
bank
!=
0
)
{
jz_nand_iounmap_resource
(
nand
->
bank_mem
[
bank
-
1
],
nand
->
bank_base
[
bank
-
1
]);
gpio_free
(
JZ_GPIO_MEM_CS0
+
bank
-
1
);
}
}
...
...
drivers/pinctrl/Kconfig
View file @
bdb18d93
...
...
@@ -296,6 +296,15 @@ config PINCTRL_ZYNQ
help
This selects the pinctrl driver for Xilinx Zynq.
config PINCTRL_INGENIC
bool "Pinctrl driver for the Ingenic JZ47xx SoCs"
default y
depends on MACH_INGENIC || COMPILE_TEST
select GENERIC_PINCONF
select GENERIC_PINCTRL_GROUPS
select GENERIC_PINMUX_FUNCTIONS
select REGMAP_MMIO
source "drivers/pinctrl/aspeed/Kconfig"
source "drivers/pinctrl/bcm/Kconfig"
source "drivers/pinctrl/berlin/Kconfig"
...
...
drivers/pinctrl/Makefile
View file @
bdb18d93
...
...
@@ -39,6 +39,7 @@ obj-$(CONFIG_PINCTRL_LPC18XX) += pinctrl-lpc18xx.o
obj-$(CONFIG_PINCTRL_TB10X)
+=
pinctrl-tb10x.o
obj-$(CONFIG_PINCTRL_ST)
+=
pinctrl-st.o
obj-$(CONFIG_PINCTRL_ZYNQ)
+=
pinctrl-zynq.o
obj-$(CONFIG_PINCTRL_INGENIC)
+=
pinctrl-ingenic.o
obj-$(CONFIG_ARCH_ASPEED)
+=
aspeed/
obj-y
+=
bcm/
...
...
drivers/pinctrl/pinctrl-ingenic.c
0 → 100644
View file @
bdb18d93
/*
* Ingenic SoCs pinctrl driver
*
* Copyright (c) 2017 Paul Cercueil <paul@crapouillou.net>
*
* License terms: GNU General Public License (GPL) version 2
*/
#include <linux/compiler.h>
#include <linux/gpio.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/of_device.h>
#include <linux/of_platform.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinmux.h>
#include <linux/pinctrl/pinconf.h>
#include <linux/pinctrl/pinconf-generic.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/slab.h>
#include "core.h"
#include "pinconf.h"
#include "pinmux.h"
#define JZ4740_GPIO_DATA 0x10
#define JZ4740_GPIO_PULL_DIS 0x30
#define JZ4740_GPIO_FUNC 0x40
#define JZ4740_GPIO_SELECT 0x50
#define JZ4740_GPIO_DIR 0x60
#define JZ4740_GPIO_TRIG 0x70
#define JZ4740_GPIO_FLAG 0x80
#define JZ4770_GPIO_INT 0x10
#define JZ4770_GPIO_MSK 0x20
#define JZ4770_GPIO_PAT1 0x30
#define JZ4770_GPIO_PAT0 0x40
#define JZ4770_GPIO_FLAG 0x50
#define JZ4770_GPIO_PEN 0x70
#define REG_SET(x) ((x) + 0x4)
#define REG_CLEAR(x) ((x) + 0x8)
#define PINS_PER_GPIO_CHIP 32
enum
jz_version
{
ID_JZ4740
,
ID_JZ4770
,
ID_JZ4780
,
};
struct
ingenic_chip_info
{
unsigned
int
num_chips
;
const
struct
group_desc
*
groups
;
unsigned
int
num_groups
;
const
struct
function_desc
*
functions
;
unsigned
int
num_functions
;
const
u32
*
pull_ups
,
*
pull_downs
;
};
struct
ingenic_pinctrl
{
struct
device
*
dev
;
struct
regmap
*
map
;
struct
pinctrl_dev
*
pctl
;
struct
pinctrl_pin_desc
*
pdesc
;
enum
jz_version
version
;
const
struct
ingenic_chip_info
*
info
;
};
static
const
u32
jz4740_pull_ups
[
4
]
=
{
0xffffffff
,
0xffffffff
,
0xffffffff
,
0xffffffff
,
};
static
const
u32
jz4740_pull_downs
[
4
]
=
{
0x00000000
,
0x00000000
,
0x00000000
,
0x00000000
,
};
static
int
jz4740_mmc_1bit_pins
[]
=
{
0x69
,
0x68
,
0x6a
,
};
static
int
jz4740_mmc_4bit_pins
[]
=
{
0x6b
,
0x6c
,
0x6d
,
};
static
int
jz4740_uart0_data_pins
[]
=
{
0x7a
,
0x79
,
};
static
int
jz4740_uart0_hwflow_pins
[]
=
{
0x7e
,
0x7f
,
};
static
int
jz4740_uart1_data_pins
[]
=
{
0x7e
,
0x7f
,
};
static
int
jz4740_lcd_8bit_pins
[]
=
{
0x40
,
0x41
,
0x42
,
0x43
,
0x44
,
0x45
,
0x46
,
0x47
,
0x52
,
0x53
,
0x54
,
};
static
int
jz4740_lcd_16bit_pins
[]
=
{
0x48
,
0x49
,
0x4a
,
0x4b
,
0x4c
,
0x4d
,
0x4e
,
0x4f
,
0x55
,
};
static
int
jz4740_lcd_18bit_pins
[]
=
{
0x50
,
0x51
,
};
static
int
jz4740_lcd_18bit_tft_pins
[]
=
{
0x56
,
0x57
,
0x31
,
0x32
,
};
static
int
jz4740_nand_cs1_pins
[]
=
{
0x39
,
};
static
int
jz4740_nand_cs2_pins
[]
=
{
0x3a
,
};
static
int
jz4740_nand_cs3_pins
[]
=
{
0x3b
,
};
static
int
jz4740_nand_cs4_pins
[]
=
{
0x3c
,
};
static
int
jz4740_pwm_pwm0_pins
[]
=
{
0x77
,
};
static
int
jz4740_pwm_pwm1_pins
[]
=
{
0x78
,
};
static
int
jz4740_pwm_pwm2_pins
[]
=
{
0x79
,
};
static
int
jz4740_pwm_pwm3_pins
[]
=
{
0x7a
,
};
static
int
jz4740_pwm_pwm4_pins
[]
=
{
0x7b
,
};
static
int
jz4740_pwm_pwm5_pins
[]
=
{
0x7c
,
};
static
int
jz4740_pwm_pwm6_pins
[]
=
{
0x7e
,
};
static
int
jz4740_pwm_pwm7_pins
[]
=
{
0x7f
,
};
static
int
jz4740_mmc_1bit_funcs
[]
=
{
0
,
0
,
0
,
};
static
int
jz4740_mmc_4bit_funcs
[]
=
{
0
,
0
,
0
,
};
static
int
jz4740_uart0_data_funcs
[]
=
{
1
,
1
,
};
static
int
jz4740_uart0_hwflow_funcs
[]
=
{
1
,
1
,
};
static
int
jz4740_uart1_data_funcs
[]
=
{
2
,
2
,
};
static
int
jz4740_lcd_8bit_funcs
[]
=
{
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
};
static
int
jz4740_lcd_16bit_funcs
[]
=
{
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
};
static
int
jz4740_lcd_18bit_funcs
[]
=
{
0
,
0
,
};
static
int
jz4740_lcd_18bit_tft_funcs
[]
=
{
0
,
0
,
0
,
0
,
};
static
int
jz4740_nand_cs1_funcs
[]
=
{
0
,
};
static
int
jz4740_nand_cs2_funcs
[]
=
{
0
,
};
static
int
jz4740_nand_cs3_funcs
[]
=
{
0
,
};
static
int
jz4740_nand_cs4_funcs
[]
=
{
0
,
};
static
int
jz4740_pwm_pwm0_funcs
[]
=
{
0
,
};
static
int
jz4740_pwm_pwm1_funcs
[]
=
{
0
,
};
static
int
jz4740_pwm_pwm2_funcs
[]
=
{
0
,
};
static
int
jz4740_pwm_pwm3_funcs
[]
=
{
0
,
};
static
int
jz4740_pwm_pwm4_funcs
[]
=
{
0
,
};
static
int
jz4740_pwm_pwm5_funcs
[]
=
{
0
,
};
static
int
jz4740_pwm_pwm6_funcs
[]
=
{
0
,
};
static
int
jz4740_pwm_pwm7_funcs
[]
=
{
0
,
};
#define INGENIC_PIN_GROUP(name, id) \
{ \
name, \
id##_pins, \
ARRAY_SIZE(id##_pins), \
id##_funcs, \
}
static
const
struct
group_desc
jz4740_groups
[]
=
{
INGENIC_PIN_GROUP
(
"mmc-1bit"
,
jz4740_mmc_1bit
),
INGENIC_PIN_GROUP
(
"mmc-4bit"
,
jz4740_mmc_4bit
),
INGENIC_PIN_GROUP
(
"uart0-data"
,
jz4740_uart0_data
),
INGENIC_PIN_GROUP
(
"uart0-hwflow"
,
jz4740_uart0_hwflow
),
INGENIC_PIN_GROUP
(
"uart1-data"
,
jz4740_uart1_data
),
INGENIC_PIN_GROUP
(
"lcd-8bit"
,
jz4740_lcd_8bit
),
INGENIC_PIN_GROUP
(
"lcd-16bit"
,
jz4740_lcd_16bit
),
INGENIC_PIN_GROUP
(
"lcd-18bit"
,
jz4740_lcd_18bit
),
INGENIC_PIN_GROUP
(
"lcd-18bit-tft"
,
jz4740_lcd_18bit_tft
),
{
"lcd-no-pins"
,
},
INGENIC_PIN_GROUP
(
"nand-cs1"
,
jz4740_nand_cs1
),
INGENIC_PIN_GROUP
(
"nand-cs2"
,
jz4740_nand_cs2
),
INGENIC_PIN_GROUP
(
"nand-cs3"
,
jz4740_nand_cs3
),
INGENIC_PIN_GROUP
(
"nand-cs4"
,
jz4740_nand_cs4
),
INGENIC_PIN_GROUP
(
"pwm0"
,
jz4740_pwm_pwm0
),
INGENIC_PIN_GROUP
(
"pwm1"
,
jz4740_pwm_pwm1
),
INGENIC_PIN_GROUP
(
"pwm2"
,
jz4740_pwm_pwm2
),
INGENIC_PIN_GROUP
(
"pwm3"
,
jz4740_pwm_pwm3
),
INGENIC_PIN_GROUP
(
"pwm4"
,
jz4740_pwm_pwm4
),
INGENIC_PIN_GROUP
(
"pwm5"
,
jz4740_pwm_pwm5
),
INGENIC_PIN_GROUP
(
"pwm6"
,
jz4740_pwm_pwm6
),
INGENIC_PIN_GROUP
(
"pwm7"
,
jz4740_pwm_pwm7
),
};
static
const
char
*
jz4740_mmc_groups
[]
=
{
"mmc-1bit"
,
"mmc-4bit"
,
};
static
const
char
*
jz4740_uart0_groups
[]
=
{
"uart0-data"
,
"uart0-hwflow"
,
};
static
const
char
*
jz4740_uart1_groups
[]
=
{
"uart1-data"
,
};
static
const
char
*
jz4740_lcd_groups
[]
=
{
"lcd-8bit"
,
"lcd-16bit"
,
"lcd-18bit"
,
"lcd-18bit-tft"
,
"lcd-no-pins"
,
};
static
const
char
*
jz4740_nand_groups
[]
=
{
"nand-cs1"
,
"nand-cs2"
,
"nand-cs3"
,
"nand-cs4"
,
};
static
const
char
*
jz4740_pwm0_groups
[]
=
{
"pwm0"
,
};
static
const
char
*
jz4740_pwm1_groups
[]
=
{
"pwm1"
,
};
static
const
char
*
jz4740_pwm2_groups
[]
=
{
"pwm2"
,
};
static
const
char
*
jz4740_pwm3_groups
[]
=
{
"pwm3"
,
};
static
const
char
*
jz4740_pwm4_groups
[]
=
{
"pwm4"
,
};
static
const
char
*
jz4740_pwm5_groups
[]
=
{
"pwm5"
,
};
static
const
char
*
jz4740_pwm6_groups
[]
=
{
"pwm6"
,
};
static
const
char
*
jz4740_pwm7_groups
[]
=
{
"pwm7"
,
};
static
const
struct
function_desc
jz4740_functions
[]
=
{
{
"mmc"
,
jz4740_mmc_groups
,
ARRAY_SIZE
(
jz4740_mmc_groups
),
},
{
"uart0"
,
jz4740_uart0_groups
,
ARRAY_SIZE
(
jz4740_uart0_groups
),
},
{
"uart1"
,
jz4740_uart1_groups
,
ARRAY_SIZE
(
jz4740_uart1_groups
),
},
{
"lcd"
,
jz4740_lcd_groups
,
ARRAY_SIZE
(
jz4740_lcd_groups
),
},
{
"nand"
,
jz4740_nand_groups
,
ARRAY_SIZE
(
jz4740_nand_groups
),
},
{
"pwm0"
,
jz4740_pwm0_groups
,
ARRAY_SIZE
(
jz4740_pwm0_groups
),
},
{
"pwm1"
,
jz4740_pwm1_groups
,
ARRAY_SIZE
(
jz4740_pwm1_groups
),
},
{
"pwm2"
,
jz4740_pwm2_groups
,
ARRAY_SIZE
(
jz4740_pwm2_groups
),
},
{
"pwm3"
,
jz4740_pwm3_groups
,
ARRAY_SIZE
(
jz4740_pwm3_groups
),
},
{
"pwm4"
,
jz4740_pwm4_groups
,
ARRAY_SIZE
(
jz4740_pwm4_groups
),
},
{
"pwm5"
,
jz4740_pwm5_groups
,
ARRAY_SIZE
(
jz4740_pwm5_groups
),
},
{
"pwm6"
,
jz4740_pwm6_groups
,
ARRAY_SIZE
(
jz4740_pwm6_groups
),
},
{
"pwm7"
,
jz4740_pwm7_groups
,
ARRAY_SIZE
(
jz4740_pwm7_groups
),
},
};
static
const
struct
ingenic_chip_info
jz4740_chip_info
=
{
.
num_chips
=
4
,
.
groups
=
jz4740_groups
,
.
num_groups
=
ARRAY_SIZE
(
jz4740_groups
),
.
functions
=
jz4740_functions
,
.
num_functions
=
ARRAY_SIZE
(
jz4740_functions
),
.
pull_ups
=
jz4740_pull_ups
,
.
pull_downs
=
jz4740_pull_downs
,
};
static
const
u32
jz4770_pull_ups
[
6
]
=
{
0x3fffffff
,
0xfff0030c
,
0xffffffff
,
0xffff4fff
,
0xfffffb7c
,
0xffa7f00f
,
};
static
const
u32
jz4770_pull_downs
[
6
]
=
{
0x00000000
,
0x000f0c03
,
0x00000000
,
0x0000b000
,
0x00000483
,
0x00580ff0
,
};
static
int
jz4770_uart0_data_pins
[]
=
{
0xa0
,
0xa3
,
};
static
int
jz4770_uart0_hwflow_pins
[]
=
{
0xa1
,
0xa2
,
};
static
int
jz4770_uart1_data_pins
[]
=
{
0x7a
,
0x7c
,
};
static
int
jz4770_uart1_hwflow_pins
[]
=
{
0x7b
,
0x7d
,
};
static
int
jz4770_uart2_data_pins
[]
=
{
0x66
,
0x67
,
};
static
int
jz4770_uart2_hwflow_pins
[]
=
{
0x65
,
0x64
,
};
static
int
jz4770_uart3_data_pins
[]
=
{
0x6c
,
0x85
,
};
static
int
jz4770_uart3_hwflow_pins
[]
=
{
0x88
,
0x89
,
};
static
int
jz4770_uart4_data_pins
[]
=
{
0x54
,
0x4a
,
};
static
int
jz4770_mmc0_8bit_a_pins
[]
=
{
0x04
,
0x05
,
0x06
,
0x07
,
0x18
,
};
static
int
jz4770_mmc0_4bit_a_pins
[]
=
{
0x15
,
0x16
,
0x17
,
};
static
int
jz4770_mmc0_1bit_a_pins
[]
=
{
0x12
,
0x13
,
0x14
,
};
static
int
jz4770_mmc0_4bit_e_pins
[]
=
{
0x95
,
0x96
,
0x97
,
};
static
int
jz4770_mmc0_1bit_e_pins
[]
=
{
0x9c
,
0x9d
,
0x94
,
};
static
int
jz4770_mmc1_4bit_d_pins
[]
=
{
0x75
,
0x76
,
0x77
,
};
static
int
jz4770_mmc1_1bit_d_pins
[]
=
{
0x78
,
0x79
,
0x74
,
};
static
int
jz4770_mmc1_4bit_e_pins
[]
=
{
0x95
,
0x96
,
0x97
,
};
static
int
jz4770_mmc1_1bit_e_pins
[]
=
{
0x9c
,
0x9d
,
0x94
,
};
static
int
jz4770_nemc_data_pins
[]
=
{
0x00
,
0x01
,
0x02
,
0x03
,
0x04
,
0x05
,
0x06
,
0x07
,
};
static
int
jz4770_nemc_cle_ale_pins
[]
=
{
0x20
,
0x21
,
};
static
int
jz4770_nemc_addr_pins
[]
=
{
0x22
,
0x23
,
0x24
,
0x25
,
};
static
int
jz4770_nemc_rd_we_pins
[]
=
{
0x10
,
0x11
,
};
static
int
jz4770_nemc_frd_fwe_pins
[]
=
{
0x12
,
0x13
,
};
static
int
jz4770_nemc_cs1_pins
[]
=
{
0x15
,
};
static
int
jz4770_nemc_cs2_pins
[]
=
{
0x16
,
};
static
int
jz4770_nemc_cs3_pins
[]
=
{
0x17
,
};
static
int
jz4770_nemc_cs4_pins
[]
=
{
0x18
,
};
static
int
jz4770_nemc_cs5_pins
[]
=
{
0x19
,
};
static
int
jz4770_nemc_cs6_pins
[]
=
{
0x1a
,
};
static
int
jz4770_i2c0_pins
[]
=
{
0x6e
,
0x6f
,
};
static
int
jz4770_i2c1_pins
[]
=
{
0x8e
,
0x8f
,
};
static
int
jz4770_i2c2_pins
[]
=
{
0xb0
,
0xb1
,
};
static
int
jz4770_i2c3_pins
[]
=
{
0x6a
,
0x6b
,
};
static
int
jz4770_i2c4_e_pins
[]
=
{
0x8c
,
0x8d
,
};
static
int
jz4770_i2c4_f_pins
[]
=
{
0xb9
,
0xb8
,
};
static
int
jz4770_cim_pins
[]
=
{
0x26
,
0x27
,
0x28
,
0x29
,
0x2a
,
0x2b
,
0x2c
,
0x2d
,
0x2e
,
0x2f
,
0x30
,
0x31
,
};
static
int
jz4770_lcd_32bit_pins
[]
=
{
0x40
,
0x41
,
0x42
,
0x43
,
0x44
,
0x45
,
0x46
,
0x47
,
0x48
,
0x49
,
0x4a
,
0x4b
,
0x4c
,
0x4d
,
0x4e
,
0x4f
,
0x50
,
0x51
,
0x52
,
0x53
,
0x54
,
0x55
,
0x56
,
0x57
,
0x58
,
0x59
,
0x51
,
};
static
int
jz4770_pwm_pwm0_pins
[]
=
{
0x80
,
};
static
int
jz4770_pwm_pwm1_pins
[]
=
{
0x81
,
};
static
int
jz4770_pwm_pwm2_pins
[]
=
{
0x82
,
};
static
int
jz4770_pwm_pwm3_pins
[]
=
{
0x83
,
};
static
int
jz4770_pwm_pwm4_pins
[]
=
{
0x84
,
};
static
int
jz4770_pwm_pwm5_pins
[]
=
{
0x85
,
};
static
int
jz4770_pwm_pwm6_pins
[]
=
{
0x6a
,
};
static
int
jz4770_pwm_pwm7_pins
[]
=
{
0x6b
,
};
static
int
jz4770_uart0_data_funcs
[]
=
{
0
,
0
,
};
static
int
jz4770_uart0_hwflow_funcs
[]
=
{
0
,
0
,
};
static
int
jz4770_uart1_data_funcs
[]
=
{
0
,
0
,
};
static
int
jz4770_uart1_hwflow_funcs
[]
=
{
0
,
0
,
};
static
int
jz4770_uart2_data_funcs
[]
=
{
1
,
1
,
};
static
int
jz4770_uart2_hwflow_funcs
[]
=
{
1
,
1
,
};
static
int
jz4770_uart3_data_funcs
[]
=
{
0
,
1
,
};
static
int
jz4770_uart3_hwflow_funcs
[]
=
{
0
,
0
,
};
static
int
jz4770_uart4_data_funcs
[]
=
{
2
,
2
,
};
static
int
jz4770_mmc0_8bit_a_funcs
[]
=
{
1
,
1
,
1
,
1
,
1
,
};
static
int
jz4770_mmc0_4bit_a_funcs
[]
=
{
1
,
1
,
1
,
};
static
int
jz4770_mmc0_1bit_a_funcs
[]
=
{
1
,
1
,
0
,
};
static
int
jz4770_mmc0_4bit_e_funcs
[]
=
{
0
,
0
,
0
,
};
static
int
jz4770_mmc0_1bit_e_funcs
[]
=
{
0
,
0
,
0
,
};
static
int
jz4770_mmc1_4bit_d_funcs
[]
=
{
0
,
0
,
0
,
};
static
int
jz4770_mmc1_1bit_d_funcs
[]
=
{
0
,
0
,
0
,
};
static
int
jz4770_mmc1_4bit_e_funcs
[]
=
{
1
,
1
,
1
,
};
static
int
jz4770_mmc1_1bit_e_funcs
[]
=
{
1
,
1
,
1
,
};
static
int
jz4770_nemc_data_funcs
[]
=
{
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
};
static
int
jz4770_nemc_cle_ale_funcs
[]
=
{
0
,
0
,
};
static
int
jz4770_nemc_addr_funcs
[]
=
{
0
,
0
,
0
,
0
,
};
static
int
jz4770_nemc_rd_we_funcs
[]
=
{
0
,
0
,
};
static
int
jz4770_nemc_frd_fwe_funcs
[]
=
{
0
,
0
,
};
static
int
jz4770_nemc_cs1_funcs
[]
=
{
0
,
};
static
int
jz4770_nemc_cs2_funcs
[]
=
{
0
,
};
static
int
jz4770_nemc_cs3_funcs
[]
=
{
0
,
};
static
int
jz4770_nemc_cs4_funcs
[]
=
{
0
,
};
static
int
jz4770_nemc_cs5_funcs
[]
=
{
0
,
};
static
int
jz4770_nemc_cs6_funcs
[]
=
{
0
,
};
static
int
jz4770_i2c0_funcs
[]
=
{
0
,
0
,
};
static
int
jz4770_i2c1_funcs
[]
=
{
0
,
0
,
};
static
int
jz4770_i2c2_funcs
[]
=
{
2
,
2
,
};
static
int
jz4770_i2c3_funcs
[]
=
{
1
,
1
,
};
static
int
jz4770_i2c4_e_funcs
[]
=
{
1
,
1
,
};
static
int
jz4770_i2c4_f_funcs
[]
=
{
1
,
1
,
};
static
int
jz4770_cim_funcs
[]
=
{
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
};
static
int
jz4770_lcd_32bit_funcs
[]
=
{
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
};
static
int
jz4770_pwm_pwm0_funcs
[]
=
{
0
,
};
static
int
jz4770_pwm_pwm1_funcs
[]
=
{
0
,
};
static
int
jz4770_pwm_pwm2_funcs
[]
=
{
0
,
};
static
int
jz4770_pwm_pwm3_funcs
[]
=
{
0
,
};
static
int
jz4770_pwm_pwm4_funcs
[]
=
{
0
,
};
static
int
jz4770_pwm_pwm5_funcs
[]
=
{
0
,
};
static
int
jz4770_pwm_pwm6_funcs
[]
=
{
0
,
};
static
int
jz4770_pwm_pwm7_funcs
[]
=
{
0
,
};
static
const
struct
group_desc
jz4770_groups
[]
=
{
INGENIC_PIN_GROUP
(
"uart0-data"
,
jz4770_uart0_data
),
INGENIC_PIN_GROUP
(
"uart0-hwflow"
,
jz4770_uart0_hwflow
),
INGENIC_PIN_GROUP
(
"uart1-data"
,
jz4770_uart1_data
),
INGENIC_PIN_GROUP
(
"uart1-hwflow"
,
jz4770_uart1_hwflow
),
INGENIC_PIN_GROUP
(
"uart2-data"
,
jz4770_uart2_data
),
INGENIC_PIN_GROUP
(
"uart2-hwflow"
,
jz4770_uart2_hwflow
),
INGENIC_PIN_GROUP
(
"uart3-data"
,
jz4770_uart3_data
),
INGENIC_PIN_GROUP
(
"uart3-hwflow"
,
jz4770_uart3_hwflow
),
INGENIC_PIN_GROUP
(
"uart4-data"
,
jz4770_uart4_data
),
INGENIC_PIN_GROUP
(
"mmc0-8bit-a"
,
jz4770_mmc0_8bit_a
),
INGENIC_PIN_GROUP
(
"mmc0-4bit-a"
,
jz4770_mmc0_4bit_a
),
INGENIC_PIN_GROUP
(
"mmc0-1bit-a"
,
jz4770_mmc0_1bit_a
),
INGENIC_PIN_GROUP
(
"mmc0-4bit-e"
,
jz4770_mmc0_4bit_e
),
INGENIC_PIN_GROUP
(
"mmc0-1bit-e"
,
jz4770_mmc0_1bit_e
),
INGENIC_PIN_GROUP
(
"mmc1-4bit-d"
,
jz4770_mmc1_4bit_d
),
INGENIC_PIN_GROUP
(
"mmc1-1bit-d"
,
jz4770_mmc1_1bit_d
),
INGENIC_PIN_GROUP
(
"mmc1-4bit-e"
,
jz4770_mmc1_4bit_e
),
INGENIC_PIN_GROUP
(
"mmc1-1bit-e"
,
jz4770_mmc1_1bit_e
),
INGENIC_PIN_GROUP
(
"nemc-data"
,
jz4770_nemc_data
),
INGENIC_PIN_GROUP
(
"nemc-cle-ale"
,
jz4770_nemc_cle_ale
),
INGENIC_PIN_GROUP
(
"nemc-addr"
,
jz4770_nemc_addr
),
INGENIC_PIN_GROUP
(
"nemc-rd-we"
,
jz4770_nemc_rd_we
),
INGENIC_PIN_GROUP
(
"nemc-frd-fwe"
,
jz4770_nemc_frd_fwe
),
INGENIC_PIN_GROUP
(
"nemc-cs1"
,
jz4770_nemc_cs1
),
INGENIC_PIN_GROUP
(
"nemc-cs2"
,
jz4770_nemc_cs2
),
INGENIC_PIN_GROUP
(
"nemc-cs3"
,
jz4770_nemc_cs3
),
INGENIC_PIN_GROUP
(
"nemc-cs4"
,
jz4770_nemc_cs4
),
INGENIC_PIN_GROUP
(
"nemc-cs5"
,
jz4770_nemc_cs5
),
INGENIC_PIN_GROUP
(
"nemc-cs6"
,
jz4770_nemc_cs6
),
INGENIC_PIN_GROUP
(
"i2c0-data"
,
jz4770_i2c0
),
INGENIC_PIN_GROUP
(
"i2c1-data"
,
jz4770_i2c1
),
INGENIC_PIN_GROUP
(
"i2c2-data"
,
jz4770_i2c2
),
INGENIC_PIN_GROUP
(
"i2c3-data"
,
jz4770_i2c3
),
INGENIC_PIN_GROUP
(
"i2c4-data-e"
,
jz4770_i2c4_e
),
INGENIC_PIN_GROUP
(
"i2c4-data-f"
,
jz4770_i2c4_f
),
INGENIC_PIN_GROUP
(
"cim-data"
,
jz4770_cim
),
INGENIC_PIN_GROUP
(
"lcd-32bit"
,
jz4770_lcd_32bit
),
{
"lcd-no-pins"
,
},
INGENIC_PIN_GROUP
(
"pwm0"
,
jz4770_pwm_pwm0
),
INGENIC_PIN_GROUP
(
"pwm1"
,
jz4770_pwm_pwm1
),
INGENIC_PIN_GROUP
(
"pwm2"
,
jz4770_pwm_pwm2
),
INGENIC_PIN_GROUP
(
"pwm3"
,
jz4770_pwm_pwm3
),
INGENIC_PIN_GROUP
(
"pwm4"
,
jz4770_pwm_pwm4
),
INGENIC_PIN_GROUP
(
"pwm5"
,
jz4770_pwm_pwm5
),
INGENIC_PIN_GROUP
(
"pwm6"
,
jz4770_pwm_pwm6
),
INGENIC_PIN_GROUP
(
"pwm7"
,
jz4770_pwm_pwm7
),
};
static
const
char
*
jz4770_uart0_groups
[]
=
{
"uart0-data"
,
"uart0-hwflow"
,
};
static
const
char
*
jz4770_uart1_groups
[]
=
{
"uart1-data"
,
"uart1-hwflow"
,
};
static
const
char
*
jz4770_uart2_groups
[]
=
{
"uart2-data"
,
"uart2-hwflow"
,
};
static
const
char
*
jz4770_uart3_groups
[]
=
{
"uart3-data"
,
"uart3-hwflow"
,
};
static
const
char
*
jz4770_uart4_groups
[]
=
{
"uart4-data"
,
};
static
const
char
*
jz4770_mmc0_groups
[]
=
{
"mmc0-8bit-a"
,
"mmc0-4bit-a"
,
"mmc0-1bit-a"
,
"mmc0-1bit-e"
,
"mmc0-4bit-e"
,
};
static
const
char
*
jz4770_mmc1_groups
[]
=
{
"mmc1-1bit-d"
,
"mmc1-4bit-d"
,
"mmc1-1bit-e"
,
"mmc1-4bit-e"
,
};
static
const
char
*
jz4770_nemc_groups
[]
=
{
"nemc-data"
,
"nemc-cle-ale"
,
"nemc-addr"
,
"nemc-rd-we"
,
"nemc-frd-fwe"
,
};
static
const
char
*
jz4770_cs1_groups
[]
=
{
"nemc-cs1"
,
};
static
const
char
*
jz4770_cs6_groups
[]
=
{
"nemc-cs6"
,
};
static
const
char
*
jz4770_i2c0_groups
[]
=
{
"i2c0-data"
,
};
static
const
char
*
jz4770_i2c1_groups
[]
=
{
"i2c1-data"
,
};
static
const
char
*
jz4770_i2c2_groups
[]
=
{
"i2c2-data"
,
};
static
const
char
*
jz4770_i2c3_groups
[]
=
{
"i2c3-data"
,
};
static
const
char
*
jz4770_i2c4_groups
[]
=
{
"i2c4-data-e"
,
"i2c4-data-f"
,
};
static
const
char
*
jz4770_cim_groups
[]
=
{
"cim-data"
,
};
static
const
char
*
jz4770_lcd_groups
[]
=
{
"lcd-32bit"
,
"lcd-no-pins"
,
};
static
const
char
*
jz4770_pwm0_groups
[]
=
{
"pwm0"
,
};
static
const
char
*
jz4770_pwm1_groups
[]
=
{
"pwm1"
,
};
static
const
char
*
jz4770_pwm2_groups
[]
=
{
"pwm2"
,
};
static
const
char
*
jz4770_pwm3_groups
[]
=
{
"pwm3"
,
};
static
const
char
*
jz4770_pwm4_groups
[]
=
{
"pwm4"
,
};
static
const
char
*
jz4770_pwm5_groups
[]
=
{
"pwm5"
,
};
static
const
char
*
jz4770_pwm6_groups
[]
=
{
"pwm6"
,
};
static
const
char
*
jz4770_pwm7_groups
[]
=
{
"pwm7"
,
};
static
const
struct
function_desc
jz4770_functions
[]
=
{
{
"uart0"
,
jz4770_uart0_groups
,
ARRAY_SIZE
(
jz4770_uart0_groups
),
},
{
"uart1"
,
jz4770_uart1_groups
,
ARRAY_SIZE
(
jz4770_uart1_groups
),
},
{
"uart2"
,
jz4770_uart2_groups
,
ARRAY_SIZE
(
jz4770_uart2_groups
),
},
{
"uart3"
,
jz4770_uart3_groups
,
ARRAY_SIZE
(
jz4770_uart3_groups
),
},
{
"uart4"
,
jz4770_uart4_groups
,
ARRAY_SIZE
(
jz4770_uart4_groups
),
},
{
"mmc0"
,
jz4770_mmc0_groups
,
ARRAY_SIZE
(
jz4770_mmc0_groups
),
},
{
"mmc1"
,
jz4770_mmc1_groups
,
ARRAY_SIZE
(
jz4770_mmc1_groups
),
},
{
"nemc"
,
jz4770_nemc_groups
,
ARRAY_SIZE
(
jz4770_nemc_groups
),
},
{
"nemc-cs1"
,
jz4770_cs1_groups
,
ARRAY_SIZE
(
jz4770_cs1_groups
),
},
{
"nemc-cs6"
,
jz4770_cs6_groups
,
ARRAY_SIZE
(
jz4770_cs6_groups
),
},
{
"i2c0"
,
jz4770_i2c0_groups
,
ARRAY_SIZE
(
jz4770_i2c0_groups
),
},
{
"i2c1"
,
jz4770_i2c1_groups
,
ARRAY_SIZE
(
jz4770_i2c1_groups
),
},
{
"i2c2"
,
jz4770_i2c2_groups
,
ARRAY_SIZE
(
jz4770_i2c2_groups
),
},
{
"i2c3"
,
jz4770_i2c3_groups
,
ARRAY_SIZE
(
jz4770_i2c3_groups
),
},
{
"i2c4"
,
jz4770_i2c4_groups
,
ARRAY_SIZE
(
jz4770_i2c4_groups
),
},
{
"cim"
,
jz4770_cim_groups
,
ARRAY_SIZE
(
jz4770_cim_groups
),
},
{
"lcd"
,
jz4770_lcd_groups
,
ARRAY_SIZE
(
jz4770_lcd_groups
),
},
{
"pwm0"
,
jz4770_pwm0_groups
,
ARRAY_SIZE
(
jz4770_pwm0_groups
),
},
{
"pwm1"
,
jz4770_pwm1_groups
,
ARRAY_SIZE
(
jz4770_pwm1_groups
),
},
{
"pwm2"
,
jz4770_pwm2_groups
,
ARRAY_SIZE
(
jz4770_pwm2_groups
),
},
{
"pwm3"
,
jz4770_pwm3_groups
,
ARRAY_SIZE
(
jz4770_pwm3_groups
),
},
{
"pwm4"
,
jz4770_pwm4_groups
,
ARRAY_SIZE
(
jz4770_pwm4_groups
),
},
{
"pwm5"
,
jz4770_pwm5_groups
,
ARRAY_SIZE
(
jz4770_pwm5_groups
),
},
{
"pwm6"
,
jz4770_pwm6_groups
,
ARRAY_SIZE
(
jz4770_pwm6_groups
),
},
{
"pwm7"
,
jz4770_pwm7_groups
,
ARRAY_SIZE
(
jz4770_pwm7_groups
),
},
};
static
const
struct
ingenic_chip_info
jz4770_chip_info
=
{
.
num_chips
=
6
,
.
groups
=
jz4770_groups
,
.
num_groups
=
ARRAY_SIZE
(
jz4770_groups
),
.
functions
=
jz4770_functions
,
.
num_functions
=
ARRAY_SIZE
(
jz4770_functions
),
.
pull_ups
=
jz4770_pull_ups
,
.
pull_downs
=
jz4770_pull_downs
,
};
static
inline
void
ingenic_config_pin
(
struct
ingenic_pinctrl
*
jzpc
,
unsigned
int
pin
,
u8
reg
,
bool
set
)
{
unsigned
int
idx
=
pin
%
PINS_PER_GPIO_CHIP
;
unsigned
int
offt
=
pin
/
PINS_PER_GPIO_CHIP
;
regmap_write
(
jzpc
->
map
,
offt
*
0x100
+
(
set
?
REG_SET
(
reg
)
:
REG_CLEAR
(
reg
)),
BIT
(
idx
));
}
static
inline
bool
ingenic_get_pin_config
(
struct
ingenic_pinctrl
*
jzpc
,
unsigned
int
pin
,
u8
reg
)
{
unsigned
int
idx
=
pin
%
PINS_PER_GPIO_CHIP
;
unsigned
int
offt
=
pin
/
PINS_PER_GPIO_CHIP
;
unsigned
int
val
;
regmap_read
(
jzpc
->
map
,
offt
*
0x100
+
reg
,
&
val
);
return
val
&
BIT
(
idx
);
}
static
struct
pinctrl_ops
ingenic_pctlops
=
{
.
get_groups_count
=
pinctrl_generic_get_group_count
,
.
get_group_name
=
pinctrl_generic_get_group_name
,
.
get_group_pins
=
pinctrl_generic_get_group_pins
,
.
dt_node_to_map
=
pinconf_generic_dt_node_to_map_all
,
.
dt_free_map
=
pinconf_generic_dt_free_map
,
};
static
int
ingenic_pinmux_set_pin_fn
(
struct
ingenic_pinctrl
*
jzpc
,
int
pin
,
int
func
)
{
unsigned
int
idx
=
pin
%
PINS_PER_GPIO_CHIP
;
unsigned
int
offt
=
pin
/
PINS_PER_GPIO_CHIP
;
dev_dbg
(
jzpc
->
dev
,
"set pin P%c%u to function %u
\n
"
,
'A'
+
offt
,
idx
,
func
);
if
(
jzpc
->
version
>=
ID_JZ4770
)
{
ingenic_config_pin
(
jzpc
,
pin
,
JZ4770_GPIO_INT
,
false
);
ingenic_config_pin
(
jzpc
,
pin
,
JZ4770_GPIO_MSK
,
false
);
ingenic_config_pin
(
jzpc
,
pin
,
JZ4770_GPIO_PAT1
,
func
&
0x2
);
ingenic_config_pin
(
jzpc
,
pin
,
JZ4770_GPIO_PAT0
,
func
&
0x1
);
}
else
{
ingenic_config_pin
(
jzpc
,
pin
,
JZ4740_GPIO_FUNC
,
true
);
ingenic_config_pin
(
jzpc
,
pin
,
JZ4740_GPIO_TRIG
,
func
&
0x2
);
ingenic_config_pin
(
jzpc
,
pin
,
JZ4740_GPIO_SELECT
,
func
>
0
);
}
return
0
;
}
static
int
ingenic_pinmux_set_mux
(
struct
pinctrl_dev
*
pctldev
,
unsigned
int
selector
,
unsigned
int
group
)
{
struct
ingenic_pinctrl
*
jzpc
=
pinctrl_dev_get_drvdata
(
pctldev
);
struct
function_desc
*
func
;
struct
group_desc
*
grp
;
unsigned
int
i
;
func
=
pinmux_generic_get_function
(
pctldev
,
selector
);
if
(
!
func
)
return
-
EINVAL
;
grp
=
pinctrl_generic_get_group
(
pctldev
,
group
);
if
(
!
grp
)
return
-
EINVAL
;
dev_dbg
(
pctldev
->
dev
,
"enable function %s group %s
\n
"
,
func
->
name
,
grp
->
name
);
for
(
i
=
0
;
i
<
grp
->
num_pins
;
i
++
)
{
int
*
pin_modes
=
grp
->
data
;
ingenic_pinmux_set_pin_fn
(
jzpc
,
grp
->
pins
[
i
],
pin_modes
[
i
]);
}
return
0
;
}
static
int
ingenic_pinmux_gpio_set_direction
(
struct
pinctrl_dev
*
pctldev
,
struct
pinctrl_gpio_range
*
range
,
unsigned
int
pin
,
bool
input
)
{
struct
ingenic_pinctrl
*
jzpc
=
pinctrl_dev_get_drvdata
(
pctldev
);
unsigned
int
idx
=
pin
%
PINS_PER_GPIO_CHIP
;
unsigned
int
offt
=
pin
/
PINS_PER_GPIO_CHIP
;
dev_dbg
(
pctldev
->
dev
,
"set pin P%c%u to %sput
\n
"
,
'A'
+
offt
,
idx
,
input
?
"in"
:
"out"
);
if
(
jzpc
->
version
>=
ID_JZ4770
)
{
ingenic_config_pin
(
jzpc
,
pin
,
JZ4770_GPIO_INT
,
false
);
ingenic_config_pin
(
jzpc
,
pin
,
JZ4770_GPIO_MSK
,
true
);
ingenic_config_pin
(
jzpc
,
pin
,
JZ4770_GPIO_PAT1
,
input
);
}
else
{
ingenic_config_pin
(
jzpc
,
pin
,
JZ4740_GPIO_SELECT
,
false
);
ingenic_config_pin
(
jzpc
,
pin
,
JZ4740_GPIO_DIR
,
input
);
ingenic_config_pin
(
jzpc
,
pin
,
JZ4740_GPIO_FUNC
,
false
);
}
return
0
;
}
static
struct
pinmux_ops
ingenic_pmxops
=
{
.
get_functions_count
=
pinmux_generic_get_function_count
,
.
get_function_name
=
pinmux_generic_get_function_name
,
.
get_function_groups
=
pinmux_generic_get_function_groups
,
.
set_mux
=
ingenic_pinmux_set_mux
,
.
gpio_set_direction
=
ingenic_pinmux_gpio_set_direction
,
};
static
int
ingenic_pinconf_get
(
struct
pinctrl_dev
*
pctldev
,
unsigned
int
pin
,
unsigned
long
*
config
)
{
struct
ingenic_pinctrl
*
jzpc
=
pinctrl_dev_get_drvdata
(
pctldev
);
enum
pin_config_param
param
=
pinconf_to_config_param
(
*
config
);
unsigned
int
idx
=
pin
%
PINS_PER_GPIO_CHIP
;
unsigned
int
offt
=
pin
/
PINS_PER_GPIO_CHIP
;
bool
pull
;
if
(
jzpc
->
version
>=
ID_JZ4770
)
pull
=
!
ingenic_get_pin_config
(
jzpc
,
pin
,
JZ4770_GPIO_PEN
);
else
pull
=
!
ingenic_get_pin_config
(
jzpc
,
pin
,
JZ4740_GPIO_PULL_DIS
);
switch
(
param
)
{
case
PIN_CONFIG_BIAS_DISABLE
:
if
(
pull
)
return
-
EINVAL
;
break
;
case
PIN_CONFIG_BIAS_PULL_UP
:
if
(
!
pull
||
!
(
jzpc
->
info
->
pull_ups
[
offt
]
&
BIT
(
idx
)))
return
-
EINVAL
;
break
;
case
PIN_CONFIG_BIAS_PULL_DOWN
:
if
(
!
pull
||
!
(
jzpc
->
info
->
pull_downs
[
offt
]
&
BIT
(
idx
)))
return
-
EINVAL
;
break
;
default:
return
-
ENOTSUPP
;
}
*
config
=
pinconf_to_config_packed
(
param
,
1
);
return
0
;
}
static
void
ingenic_set_bias
(
struct
ingenic_pinctrl
*
jzpc
,
unsigned
int
pin
,
bool
enabled
)
{
if
(
jzpc
->
version
>=
ID_JZ4770
)
ingenic_config_pin
(
jzpc
,
pin
,
JZ4770_GPIO_PEN
,
!
enabled
);
else
ingenic_config_pin
(
jzpc
,
pin
,
JZ4740_GPIO_PULL_DIS
,
!
enabled
);
}
static
int
ingenic_pinconf_set
(
struct
pinctrl_dev
*
pctldev
,
unsigned
int
pin
,
unsigned
long
*
configs
,
unsigned
int
num_configs
)
{
struct
ingenic_pinctrl
*
jzpc
=
pinctrl_dev_get_drvdata
(
pctldev
);
unsigned
int
idx
=
pin
%
PINS_PER_GPIO_CHIP
;
unsigned
int
offt
=
pin
/
PINS_PER_GPIO_CHIP
;
unsigned
int
cfg
;
for
(
cfg
=
0
;
cfg
<
num_configs
;
cfg
++
)
{
switch
(
pinconf_to_config_param
(
configs
[
cfg
]))
{
case
PIN_CONFIG_BIAS_DISABLE
:
case
PIN_CONFIG_BIAS_PULL_UP
:
case
PIN_CONFIG_BIAS_PULL_DOWN
:
continue
;
default:
return
-
ENOTSUPP
;
}
}
for
(
cfg
=
0
;
cfg
<
num_configs
;
cfg
++
)
{
switch
(
pinconf_to_config_param
(
configs
[
cfg
]))
{
case
PIN_CONFIG_BIAS_DISABLE
:
dev_dbg
(
jzpc
->
dev
,
"disable pull-over for pin P%c%u
\n
"
,
'A'
+
offt
,
idx
);
ingenic_set_bias
(
jzpc
,
pin
,
false
);
break
;
case
PIN_CONFIG_BIAS_PULL_UP
:
if
(
!
(
jzpc
->
info
->
pull_ups
[
offt
]
&
BIT
(
idx
)))
return
-
EINVAL
;
dev_dbg
(
jzpc
->
dev
,
"set pull-up for pin P%c%u
\n
"
,
'A'
+
offt
,
idx
);
ingenic_set_bias
(
jzpc
,
pin
,
true
);
break
;
case
PIN_CONFIG_BIAS_PULL_DOWN
:
if
(
!
(
jzpc
->
info
->
pull_downs
[
offt
]
&
BIT
(
idx
)))
return
-
EINVAL
;
dev_dbg
(
jzpc
->
dev
,
"set pull-down for pin P%c%u
\n
"
,
'A'
+
offt
,
idx
);
ingenic_set_bias
(
jzpc
,
pin
,
true
);
break
;
default:
unreachable
();
}
}
return
0
;
}
static
int
ingenic_pinconf_group_get
(
struct
pinctrl_dev
*
pctldev
,
unsigned
int
group
,
unsigned
long
*
config
)
{
const
unsigned
int
*
pins
;
unsigned
int
i
,
npins
,
old
=
0
;
int
ret
;
ret
=
pinctrl_generic_get_group_pins
(
pctldev
,
group
,
&
pins
,
&
npins
);
if
(
ret
)
return
ret
;
for
(
i
=
0
;
i
<
npins
;
i
++
)
{
if
(
ingenic_pinconf_get
(
pctldev
,
pins
[
i
],
config
))
return
-
ENOTSUPP
;
/* configs do not match between two pins */
if
(
i
&&
(
old
!=
*
config
))
return
-
ENOTSUPP
;
old
=
*
config
;
}
return
0
;
}
static
int
ingenic_pinconf_group_set
(
struct
pinctrl_dev
*
pctldev
,
unsigned
int
group
,
unsigned
long
*
configs
,
unsigned
int
num_configs
)
{
const
unsigned
int
*
pins
;
unsigned
int
i
,
npins
;
int
ret
;
ret
=
pinctrl_generic_get_group_pins
(
pctldev
,
group
,
&
pins
,
&
npins
);
if
(
ret
)
return
ret
;
for
(
i
=
0
;
i
<
npins
;
i
++
)
{
ret
=
ingenic_pinconf_set
(
pctldev
,
pins
[
i
],
configs
,
num_configs
);
if
(
ret
)
return
ret
;
}
return
0
;
}
static
struct
pinconf_ops
ingenic_confops
=
{
.
is_generic
=
true
,
.
pin_config_get
=
ingenic_pinconf_get
,
.
pin_config_set
=
ingenic_pinconf_set
,
.
pin_config_group_get
=
ingenic_pinconf_group_get
,
.
pin_config_group_set
=
ingenic_pinconf_group_set
,
};
static
const
struct
regmap_config
ingenic_pinctrl_regmap_config
=
{
.
reg_bits
=
32
,
.
val_bits
=
32
,
.
reg_stride
=
4
,
};
static
const
struct
of_device_id
ingenic_pinctrl_of_match
[]
=
{
{
.
compatible
=
"ingenic,jz4740-pinctrl"
,
.
data
=
(
void
*
)
ID_JZ4740
},
{
.
compatible
=
"ingenic,jz4770-pinctrl"
,
.
data
=
(
void
*
)
ID_JZ4770
},
{
.
compatible
=
"ingenic,jz4780-pinctrl"
,
.
data
=
(
void
*
)
ID_JZ4780
},
{},
};
int
ingenic_pinctrl_probe
(
struct
platform_device
*
pdev
)
{
struct
device
*
dev
=
&
pdev
->
dev
;
struct
ingenic_pinctrl
*
jzpc
;
struct
pinctrl_desc
*
pctl_desc
;
void
__iomem
*
base
;
const
struct
platform_device_id
*
id
=
platform_get_device_id
(
pdev
);
const
struct
of_device_id
*
of_id
=
of_match_device
(
ingenic_pinctrl_of_match
,
dev
);
const
struct
ingenic_chip_info
*
chip_info
;
unsigned
int
i
;
int
err
;
jzpc
=
devm_kzalloc
(
dev
,
sizeof
(
*
jzpc
),
GFP_KERNEL
);
if
(
!
jzpc
)
return
-
ENOMEM
;
base
=
devm_ioremap_resource
(
dev
,
platform_get_resource
(
pdev
,
IORESOURCE_MEM
,
0
));
if
(
IS_ERR
(
base
))
{
dev_err
(
dev
,
"Failed to ioremap registers
\n
"
);
return
PTR_ERR
(
base
);
}
jzpc
->
map
=
devm_regmap_init_mmio
(
dev
,
base
,
&
ingenic_pinctrl_regmap_config
);
if
(
IS_ERR
(
jzpc
->
map
))
{
dev_err
(
dev
,
"Failed to create regmap
\n
"
);
return
PTR_ERR
(
jzpc
->
map
);
}
jzpc
->
dev
=
dev
;
if
(
of_id
)
jzpc
->
version
=
(
enum
jz_version
)
of_id
->
data
;
else
jzpc
->
version
=
(
enum
jz_version
)
id
->
driver_data
;
if
(
jzpc
->
version
>=
ID_JZ4770
)
chip_info
=
&
jz4770_chip_info
;
else
chip_info
=
&
jz4740_chip_info
;
jzpc
->
info
=
chip_info
;
pctl_desc
=
devm_kzalloc
(
&
pdev
->
dev
,
sizeof
(
*
pctl_desc
),
GFP_KERNEL
);
if
(
!
pctl_desc
)
return
-
ENOMEM
;
/* fill in pinctrl_desc structure */
pctl_desc
->
name
=
dev_name
(
dev
);
pctl_desc
->
owner
=
THIS_MODULE
;
pctl_desc
->
pctlops
=
&
ingenic_pctlops
;
pctl_desc
->
pmxops
=
&
ingenic_pmxops
;
pctl_desc
->
confops
=
&
ingenic_confops
;
pctl_desc
->
npins
=
chip_info
->
num_chips
*
PINS_PER_GPIO_CHIP
;
pctl_desc
->
pins
=
jzpc
->
pdesc
=
devm_kzalloc
(
&
pdev
->
dev
,
sizeof
(
*
jzpc
->
pdesc
)
*
pctl_desc
->
npins
,
GFP_KERNEL
);
if
(
!
jzpc
->
pdesc
)
return
-
ENOMEM
;
for
(
i
=
0
;
i
<
pctl_desc
->
npins
;
i
++
)
{
jzpc
->
pdesc
[
i
].
number
=
i
;
jzpc
->
pdesc
[
i
].
name
=
kasprintf
(
GFP_KERNEL
,
"P%c%d"
,
'A'
+
(
i
/
PINS_PER_GPIO_CHIP
),
i
%
PINS_PER_GPIO_CHIP
);
}
jzpc
->
pctl
=
devm_pinctrl_register
(
dev
,
pctl_desc
,
jzpc
);
if
(
!
jzpc
->
pctl
)
{
dev_err
(
dev
,
"Failed to register pinctrl
\n
"
);
return
-
EINVAL
;
}
for
(
i
=
0
;
i
<
chip_info
->
num_groups
;
i
++
)
{
const
struct
group_desc
*
group
=
&
chip_info
->
groups
[
i
];
err
=
pinctrl_generic_add_group
(
jzpc
->
pctl
,
group
->
name
,
group
->
pins
,
group
->
num_pins
,
group
->
data
);
if
(
err
)
{
dev_err
(
dev
,
"Failed to register group %s
\n
"
,
group
->
name
);
return
err
;
}
}
for
(
i
=
0
;
i
<
chip_info
->
num_functions
;
i
++
)
{
const
struct
function_desc
*
func
=
&
chip_info
->
functions
[
i
];
err
=
pinmux_generic_add_function
(
jzpc
->
pctl
,
func
->
name
,
func
->
group_names
,
func
->
num_group_names
,
func
->
data
);
if
(
err
)
{
dev_err
(
dev
,
"Failed to register function %s
\n
"
,
func
->
name
);
return
err
;
}
}
dev_set_drvdata
(
dev
,
jzpc
->
map
);
if
(
dev
->
of_node
)
{
err
=
of_platform_populate
(
dev
->
of_node
,
NULL
,
NULL
,
dev
);
if
(
err
)
{
dev_err
(
dev
,
"Failed to probe GPIO devices
\n
"
);
return
err
;
}
}
return
0
;
}
static
const
struct
platform_device_id
ingenic_pinctrl_ids
[]
=
{
{
"jz4740-pinctrl"
,
ID_JZ4740
},
{
"jz4770-pinctrl"
,
ID_JZ4770
},
{
"jz4780-pinctrl"
,
ID_JZ4780
},
{},
};
static
struct
platform_driver
ingenic_pinctrl_driver
=
{
.
driver
=
{
.
name
=
"pinctrl-ingenic"
,
.
of_match_table
=
of_match_ptr
(
ingenic_pinctrl_of_match
),
.
suppress_bind_attrs
=
true
,
},
.
probe
=
ingenic_pinctrl_probe
,
.
id_table
=
ingenic_pinctrl_ids
,
};
static
int
__init
ingenic_pinctrl_drv_register
(
void
)
{
return
platform_driver_register
(
&
ingenic_pinctrl_driver
);
}
postcore_initcall
(
ingenic_pinctrl_drv_register
);
drivers/pwm/pwm-jz4740.c
View file @
bdb18d93
...
...
@@ -21,22 +21,10 @@
#include <linux/platform_device.h>
#include <linux/pwm.h>
#include <asm/mach-jz4740/gpio.h>
#include <asm/mach-jz4740/timer.h>
#define NUM_PWM 8
static
const
unsigned
int
jz4740_pwm_gpio_list
[
NUM_PWM
]
=
{
JZ_GPIO_PWM0
,
JZ_GPIO_PWM1
,
JZ_GPIO_PWM2
,
JZ_GPIO_PWM3
,
JZ_GPIO_PWM4
,
JZ_GPIO_PWM5
,
JZ_GPIO_PWM6
,
JZ_GPIO_PWM7
,
};
struct
jz4740_pwm_chip
{
struct
pwm_chip
chip
;
struct
clk
*
clk
;
...
...
@@ -49,9 +37,6 @@ static inline struct jz4740_pwm_chip *to_jz4740(struct pwm_chip *chip)
static
int
jz4740_pwm_request
(
struct
pwm_chip
*
chip
,
struct
pwm_device
*
pwm
)
{
unsigned
int
gpio
=
jz4740_pwm_gpio_list
[
pwm
->
hwpwm
];
int
ret
;
/*
* Timers 0 and 1 are used for system tasks, so they are unavailable
* for use as PWMs.
...
...
@@ -59,15 +44,6 @@ static int jz4740_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
if
(
pwm
->
hwpwm
<
2
)
return
-
EBUSY
;
ret
=
gpio_request
(
gpio
,
pwm
->
label
);
if
(
ret
)
{
dev_err
(
chip
->
dev
,
"Failed to request GPIO#%u for PWM: %d
\n
"
,
gpio
,
ret
);
return
ret
;
}
jz_gpio_set_function
(
gpio
,
JZ_GPIO_FUNC_PWM
);
jz4740_timer_start
(
pwm
->
hwpwm
);
return
0
;
...
...
@@ -75,13 +51,8 @@ static int jz4740_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
static
void
jz4740_pwm_free
(
struct
pwm_chip
*
chip
,
struct
pwm_device
*
pwm
)
{
unsigned
int
gpio
=
jz4740_pwm_gpio_list
[
pwm
->
hwpwm
];
jz4740_timer_set_ctrl
(
pwm
->
hwpwm
,
0
);
jz_gpio_set_function
(
gpio
,
JZ_GPIO_FUNC_NONE
);
gpio_free
(
gpio
);
jz4740_timer_stop
(
pwm
->
hwpwm
);
}
...
...
drivers/video/fbdev/jz4740_fb.c
View file @
bdb18d93
...
...
@@ -17,6 +17,7 @@
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/platform_device.h>
#include <linux/pinctrl/consumer.h>
#include <linux/clk.h>
#include <linux/delay.h>
...
...
@@ -27,7 +28,6 @@
#include <linux/dma-mapping.h>
#include <asm/mach-jz4740/jz4740_fb.h>
#include <asm/mach-jz4740/gpio.h>
#define JZ_REG_LCD_CFG 0x00
#define JZ_REG_LCD_VSYNC 0x04
...
...
@@ -146,93 +146,6 @@ static const struct fb_fix_screeninfo jzfb_fix = {
.
accel
=
FB_ACCEL_NONE
,
};
static
const
struct
jz_gpio_bulk_request
jz_lcd_ctrl_pins
[]
=
{
JZ_GPIO_BULK_PIN
(
LCD_PCLK
),
JZ_GPIO_BULK_PIN
(
LCD_HSYNC
),
JZ_GPIO_BULK_PIN
(
LCD_VSYNC
),
JZ_GPIO_BULK_PIN
(
LCD_DE
),
JZ_GPIO_BULK_PIN
(
LCD_PS
),
JZ_GPIO_BULK_PIN
(
LCD_REV
),
JZ_GPIO_BULK_PIN
(
LCD_CLS
),
JZ_GPIO_BULK_PIN
(
LCD_SPL
),
};
static
const
struct
jz_gpio_bulk_request
jz_lcd_data_pins
[]
=
{
JZ_GPIO_BULK_PIN
(
LCD_DATA0
),
JZ_GPIO_BULK_PIN
(
LCD_DATA1
),
JZ_GPIO_BULK_PIN
(
LCD_DATA2
),
JZ_GPIO_BULK_PIN
(
LCD_DATA3
),
JZ_GPIO_BULK_PIN
(
LCD_DATA4
),
JZ_GPIO_BULK_PIN
(
LCD_DATA5
),
JZ_GPIO_BULK_PIN
(
LCD_DATA6
),
JZ_GPIO_BULK_PIN
(
LCD_DATA7
),
JZ_GPIO_BULK_PIN
(
LCD_DATA8
),
JZ_GPIO_BULK_PIN
(
LCD_DATA9
),
JZ_GPIO_BULK_PIN
(
LCD_DATA10
),
JZ_GPIO_BULK_PIN
(
LCD_DATA11
),
JZ_GPIO_BULK_PIN
(
LCD_DATA12
),
JZ_GPIO_BULK_PIN
(
LCD_DATA13
),
JZ_GPIO_BULK_PIN
(
LCD_DATA14
),
JZ_GPIO_BULK_PIN
(
LCD_DATA15
),
JZ_GPIO_BULK_PIN
(
LCD_DATA16
),
JZ_GPIO_BULK_PIN
(
LCD_DATA17
),
};
static
unsigned
int
jzfb_num_ctrl_pins
(
struct
jzfb
*
jzfb
)
{
unsigned
int
num
;
switch
(
jzfb
->
pdata
->
lcd_type
)
{
case
JZ_LCD_TYPE_GENERIC_16_BIT
:
num
=
4
;
break
;
case
JZ_LCD_TYPE_GENERIC_18_BIT
:
num
=
4
;
break
;
case
JZ_LCD_TYPE_8BIT_SERIAL
:
num
=
3
;
break
;
case
JZ_LCD_TYPE_SPECIAL_TFT_1
:
case
JZ_LCD_TYPE_SPECIAL_TFT_2
:
case
JZ_LCD_TYPE_SPECIAL_TFT_3
:
num
=
8
;
break
;
default:
num
=
0
;
break
;
}
return
num
;
}
static
unsigned
int
jzfb_num_data_pins
(
struct
jzfb
*
jzfb
)
{
unsigned
int
num
;
switch
(
jzfb
->
pdata
->
lcd_type
)
{
case
JZ_LCD_TYPE_GENERIC_16_BIT
:
num
=
16
;
break
;
case
JZ_LCD_TYPE_GENERIC_18_BIT
:
num
=
18
;
break
;
case
JZ_LCD_TYPE_8BIT_SERIAL
:
num
=
8
;
break
;
case
JZ_LCD_TYPE_SPECIAL_TFT_1
:
case
JZ_LCD_TYPE_SPECIAL_TFT_2
:
case
JZ_LCD_TYPE_SPECIAL_TFT_3
:
if
(
jzfb
->
pdata
->
bpp
==
18
)
num
=
18
;
else
num
=
16
;
break
;
default:
num
=
0
;
break
;
}
return
num
;
}
/* Based on CNVT_TOHW macro from skeletonfb.c */
static
inline
uint32_t
jzfb_convert_color_to_hw
(
unsigned
val
,
struct
fb_bitfield
*
bf
)
...
...
@@ -487,8 +400,7 @@ static void jzfb_enable(struct jzfb *jzfb)
clk_prepare_enable
(
jzfb
->
ldclk
);
jz_gpio_bulk_resume
(
jz_lcd_ctrl_pins
,
jzfb_num_ctrl_pins
(
jzfb
));
jz_gpio_bulk_resume
(
jz_lcd_data_pins
,
jzfb_num_data_pins
(
jzfb
));
pinctrl_pm_select_default_state
(
&
jzfb
->
pdev
->
dev
);
writel
(
0
,
jzfb
->
base
+
JZ_REG_LCD_STATE
);
...
...
@@ -511,8 +423,7 @@ static void jzfb_disable(struct jzfb *jzfb)
ctrl
=
readl
(
jzfb
->
base
+
JZ_REG_LCD_STATE
);
}
while
(
!
(
ctrl
&
JZ_LCD_STATE_DISABLED
));
jz_gpio_bulk_suspend
(
jz_lcd_ctrl_pins
,
jzfb_num_ctrl_pins
(
jzfb
));
jz_gpio_bulk_suspend
(
jz_lcd_data_pins
,
jzfb_num_data_pins
(
jzfb
));
pinctrl_pm_select_sleep_state
(
&
jzfb
->
pdev
->
dev
);
clk_disable_unprepare
(
jzfb
->
ldclk
);
}
...
...
@@ -701,9 +612,6 @@ static int jzfb_probe(struct platform_device *pdev)
fb
->
mode
=
NULL
;
jzfb_set_par
(
fb
);
jz_gpio_bulk_request
(
jz_lcd_ctrl_pins
,
jzfb_num_ctrl_pins
(
jzfb
));
jz_gpio_bulk_request
(
jz_lcd_data_pins
,
jzfb_num_data_pins
(
jzfb
));
ret
=
register_framebuffer
(
fb
);
if
(
ret
)
{
dev_err
(
&
pdev
->
dev
,
"Failed to register framebuffer: %d
\n
"
,
ret
);
...
...
@@ -715,9 +623,6 @@ static int jzfb_probe(struct platform_device *pdev)
return
0
;
err_free_devmem:
jz_gpio_bulk_free
(
jz_lcd_ctrl_pins
,
jzfb_num_ctrl_pins
(
jzfb
));
jz_gpio_bulk_free
(
jz_lcd_data_pins
,
jzfb_num_data_pins
(
jzfb
));
fb_dealloc_cmap
(
&
fb
->
cmap
);
jzfb_free_devmem
(
jzfb
);
err_framebuffer_release:
...
...
@@ -731,9 +636,6 @@ static int jzfb_remove(struct platform_device *pdev)
jzfb_blank
(
FB_BLANK_POWERDOWN
,
jzfb
->
fb
);
jz_gpio_bulk_free
(
jz_lcd_ctrl_pins
,
jzfb_num_ctrl_pins
(
jzfb
));
jz_gpio_bulk_free
(
jz_lcd_data_pins
,
jzfb_num_data_pins
(
jzfb
));
fb_dealloc_cmap
(
&
jzfb
->
fb
->
cmap
);
jzfb_free_devmem
(
jzfb
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment