diff --git a/arch/arm64/boot/dts/sunxi/overlay/bpi-m4berry/Makefile b/arch/arm64/boot/dts/sunxi/overlay/bpi-m4berry/Makefile index e4296a97e..c63dcd222 100755 --- a/arch/arm64/boot/dts/sunxi/overlay/bpi-m4berry/Makefile +++ b/arch/arm64/boot/dts/sunxi/overlay/bpi-m4berry/Makefile @@ -8,11 +8,17 @@ dtbo-$(CONFIG_BOARD_BANANAPI_M4BERRY) += \ bpi-m4berry-ph-uart2.dtbo \ bpi-m4berry-uart5.dtbo \ bpi-m4berry-pwm1.dtbo \ + bpi-m4berry-pwm1-beeper.dtbo \ + bpi-m4berry-pwm1-fan.dtbo \ bpi-m4berry-spi1.dtbo \ + bpi-m4berry-spi1-flash.dtbo \ + bpi-m4berry-waveshare-tft24.dtbo \ + bpi-m4berry-waveshare-tft35c.dtbo \ bpi-m4berry-spdifout.dtbo \ bpi-m4berry-i2smic-mems.dtbo \ bpi-m4berry-nxez-pcm512x-hifi.dtbo \ - bpi-m4berry-waveshare-wm8960-hifi.dtbo + bpi-m4berry-waveshare-wm8960-hifi.dtbo \ + bpi-m4berry-ds3231.dtbo targets += $(dtbo-y) diff --git a/arch/arm64/boot/dts/sunxi/overlay/bpi-m4berry/bpi-m4berry-ds3231.dts b/arch/arm64/boot/dts/sunxi/overlay/bpi-m4berry/bpi-m4berry-ds3231.dts new file mode 100755 index 000000000..fb5df39cf --- /dev/null +++ b/arch/arm64/boot/dts/sunxi/overlay/bpi-m4berry/bpi-m4berry-ds3231.dts @@ -0,0 +1,27 @@ +/dts-v1/; +/plugin/; + +/ { + fragment@0 { + target = <&twi4>; + + __overlay__ { + status = "okay"; + + /* rtc-ds1307.ko */ + ds3231: rtc@68 { + status = "okay"; + compatible = "ds3231"; + reg = <0x68>; + }; + }; + }; + + fragment@1 { + target = <&rtc>; + + __overlay__ { + status = "disabled"; + }; + }; +}; diff --git a/arch/arm64/boot/dts/sunxi/overlay/bpi-m4berry/bpi-m4berry-i2c-eeprom.dts b/arch/arm64/boot/dts/sunxi/overlay/bpi-m4berry/bpi-m4berry-i2c-eeprom.dts new file mode 100755 index 000000000..1922153d3 --- /dev/null +++ b/arch/arm64/boot/dts/sunxi/overlay/bpi-m4berry/bpi-m4berry-i2c-eeprom.dts @@ -0,0 +1,19 @@ +/dts-v1/; +/plugin/; + +/ { + fragment@0 { + target = <&twi4>; + + __overlay__ { + status = "okay"; + + at24@50 { + compatible = "at24,24c02"; + reg = <0x50>; + pagesize = <8>; + //read-only; + }; + }; + }; +}; diff --git a/arch/arm64/boot/dts/sunxi/overlay/bpi-m4berry/bpi-m4berry-pwm1-beeper.dts b/arch/arm64/boot/dts/sunxi/overlay/bpi-m4berry/bpi-m4berry-pwm1-beeper.dts new file mode 100755 index 000000000..197e76713 --- /dev/null +++ b/arch/arm64/boot/dts/sunxi/overlay/bpi-m4berry/bpi-m4berry-pwm1-beeper.dts @@ -0,0 +1,32 @@ +/dts-v1/; +/plugin/; + +/ { + fragment@0 { + target = <&pwm>; + + __overlay__ { + status = "okay"; + }; + }; + + fragment@1 { + target = <&pwm1>; + + __overlay__ { + status = "okay"; + }; + }; + + fragment@2 { + target-path = "/"; + + __overlay__ { + beeper: beeper { + compatible = "pwm-beeper"; + pwms = <&pwm 1 1000000 0>; + status = "okay"; + }; + }; + }; +}; diff --git a/arch/arm64/boot/dts/sunxi/overlay/bpi-m4berry/bpi-m4berry-pwm1-fan.dts b/arch/arm64/boot/dts/sunxi/overlay/bpi-m4berry/bpi-m4berry-pwm1-fan.dts new file mode 100755 index 000000000..26881ff0c --- /dev/null +++ b/arch/arm64/boot/dts/sunxi/overlay/bpi-m4berry/bpi-m4berry-pwm1-fan.dts @@ -0,0 +1,77 @@ +/dts-v1/; +/plugin/; + +/ { + fragment@0 { + target = <&pwm>; + + __overlay__ { + status = "okay"; + }; + }; + + fragment@1 { + target = <&pwm1>; + + __overlay__ { + status = "okay"; + }; + }; + + fragment@2 { + target = <&pwm1_pin_b>; + + __overlay__ { + /* pull down for input mode when pwm disable */ + bias-pull-down; + }; + }; + + fragment@3 { + target-path = "/"; + + __overlay__ { + pwmfan: pwm-fan { + compatible = "pwm-fan"; + pwms = <&pwm 1 10000 0>; + cooling-min-state = <0>; + cooling-max-state = <2>; + #cooling-cells = <2>; + cooling-levels = <0 150 230>; + status = "okay"; + }; + }; + }; + + fragment@4 { + target = <&cpu_thermal>; + + __overlay__ { + trips { + fan0: fan@0 { + temperature = <65000>; + hysteresis = <5000>; + type = "active"; + }; + + fan1: fan@1 { + temperature = <80000>; + hysteresis = <5000>; + type = "active"; + }; + }; + + cooling-maps { + fan_cooling_map0 { + trip = <&fan0>; + cooling-device = <&pwmfan 0 1>; + }; + + fan_cooling_map1 { + trip = <&fan1>; + cooling-device = <&pwmfan 1 2>; + }; + }; + }; + }; +}; diff --git a/arch/arm64/boot/dts/sunxi/overlay/bpi-m4berry/bpi-m4berry-spi1-flash.dts b/arch/arm64/boot/dts/sunxi/overlay/bpi-m4berry/bpi-m4berry-spi1-flash.dts new file mode 100755 index 000000000..1bc329f19 --- /dev/null +++ b/arch/arm64/boot/dts/sunxi/overlay/bpi-m4berry/bpi-m4berry-spi1-flash.dts @@ -0,0 +1,22 @@ +/dts-v1/; +/plugin/; + +/ { + fragment@0 { + target = <&spi1>; + __overlay__ { + status = "okay"; + + spi1_cs_number = <1>; + spi1_cs_bitmap = <1>; + + spiflash: w25q128@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "w25q128", "jedec,spi-nor", "winbond,w25q128"; + spi-max-frequency = <100000000>; + reg = <0>; + }; + }; + }; +}; diff --git a/arch/arm64/boot/dts/sunxi/overlay/bpi-m4berry/bpi-m4berry-waveshare-tft24.dts b/arch/arm64/boot/dts/sunxi/overlay/bpi-m4berry/bpi-m4berry-waveshare-tft24.dts new file mode 100755 index 000000000..8b324dbf1 --- /dev/null +++ b/arch/arm64/boot/dts/sunxi/overlay/bpi-m4berry/bpi-m4berry-waveshare-tft24.dts @@ -0,0 +1,28 @@ +/dts-v1/; +/plugin/; + +/ { + fragment@0 { + target = <&spi1>; + __overlay__ { + status = "okay"; + + spi1_cs_number = <1>; + spi1_cs_bitmap = <1>; + + tft24: tft24@0 { + compatible = "ilitek,ili9341"; + reg = <0>; + spi-max-frequency = <50000000>; + rotate = <90>; + bgr = <0>; + fps = <30>; + buswidth = <8>; + reset-gpios = <0x23 0x07 0x3 0x00>; //phy.13 + dc-gpios = <0x23 0x06 0x1 0x00>; //phy.22 + led-gpios = <0x23 0x06 0xb 0x00>; //phy.12 + debug = <0>; + }; + }; + }; +}; diff --git a/arch/arm64/boot/dts/sunxi/overlay/bpi-m4berry/bpi-m4berry-waveshare-tft35c.dts b/arch/arm64/boot/dts/sunxi/overlay/bpi-m4berry/bpi-m4berry-waveshare-tft35c.dts new file mode 100755 index 000000000..c76e06847 --- /dev/null +++ b/arch/arm64/boot/dts/sunxi/overlay/bpi-m4berry/bpi-m4berry-waveshare-tft35c.dts @@ -0,0 +1,60 @@ +/dts-v1/; +/plugin/; + +/ { + fragment@0 { + target = <&spi1>; + __overlay__ { + status = "okay"; + + spi1_cs_number = <2>; + spi1_cs_bitmap = <3>; + + tft35c: tft35c@0 { + compatible = "ilitek,ili9486"; + reg = <0>; + spi-max-frequency = <80000000>; + txbuflen = <32768>; + rotate = <90>; + bgr = <0>; + fps = <30>; + buswidth = <8>; + regwidth = <16>; + reset-gpios = <0x23 0x06 0x1 0x00>; //phy.22 + dc-gpios = <0x23 0x06 0x9 0x00>; //phy.18 + debug = <0>; + + init = <0x10000f1 0x36 0x4 0x0 0x3c 0xf 0x8f + 0x10000f2 0x18 0xa3 0x12 0x2 0xb2 0x12 0xff 0x10 0x0 + 0x10000f8 0x21 0x4 + 0x10000f9 0x0 0x8 + 0x1000036 0x8 + 0x10000b4 0x0 + 0x10000c1 0x41 + 0x10000c5 0x0 0x91 0x80 0x0 + 0x10000e0 0xf 0x1f 0x1c 0xc 0xf 0x8 0x48 0x98 0x37 0xa 0x13 0x4 0x11 0xd 0x0 + 0x10000e1 0xf 0x32 0x2e 0xb 0xd 0x5 0x47 0x75 0x37 0x6 0x10 0x3 0x24 0x20 0x0 + 0x100003a 0x55 + 0x1000011 + 0x1000036 0x28 + 0x20000ff + 0x1000029>; + }; + + ads7846: ads7846@1 { + status = "okay"; + compatible = "ti,ads7846"; + + spi-max-frequency = <2000000>; + reg = <1>; + + pendown-gpio = <0x23 0x07 0x2 0x00>; //phy.11 + + ti,x-plate-ohms = /bits/ 16 <60>; + ti,pressure-max = /bits/ 16 <255>; + + //linux,wakeup; + }; + }; + }; +}; diff --git a/arch/arm64/boot/dts/sunxi/overlay/bpi-m4zero/Makefile b/arch/arm64/boot/dts/sunxi/overlay/bpi-m4zero/Makefile index 98a1764c4..bda21c77e 100755 --- a/arch/arm64/boot/dts/sunxi/overlay/bpi-m4zero/Makefile +++ b/arch/arm64/boot/dts/sunxi/overlay/bpi-m4zero/Makefile @@ -6,11 +6,15 @@ dtbo-$(CONFIG_BOARD_BANANAPI_M4ZERO) += \ bpi-m4zero-uart4.dtbo \ bpi-m4zero-uart5.dtbo \ bpi-m4zero-pwm2.dtbo \ + bpi-m4zero-pwm2-beeper.dtbo \ + bpi-m4zero-pwm2-fan.dtbo \ bpi-m4zero-spi1.dtbo \ + bpi-m4zero-spi1-flash.dtbo \ bpi-m4zero-spdifout.dtbo \ bpi-m4zero-i2smic-mems.dtbo \ bpi-m4zero-nxez-pcm512x-hifi.dtbo \ - bpi-m4zero-waveshare-wm8960-hifi.dtbo + bpi-m4zero-waveshare-wm8960-hifi.dtbo \ + bpi-m4zero-ds3231.dtbo targets += $(dtbo-y) always := $(dtbo-y) diff --git a/arch/arm64/boot/dts/sunxi/overlay/bpi-m4zero/bpi-m4zero-ds3231.dts b/arch/arm64/boot/dts/sunxi/overlay/bpi-m4zero/bpi-m4zero-ds3231.dts new file mode 100755 index 000000000..2b77c3825 --- /dev/null +++ b/arch/arm64/boot/dts/sunxi/overlay/bpi-m4zero/bpi-m4zero-ds3231.dts @@ -0,0 +1,27 @@ +/dts-v1/; +/plugin/; + +/ { + fragment@0 { + target = <&twi0>; + + __overlay__ { + status = "okay"; + + /* rtc-ds1307.ko */ + ds3231: rtc@68 { + status = "okay"; + compatible = "ds3231"; + reg = <0x68>; + }; + }; + }; + + fragment@1 { + target = <&rtc>; + + __overlay__ { + status = "disabled"; + }; + }; +}; diff --git a/arch/arm64/boot/dts/sunxi/overlay/bpi-m4zero/bpi-m4zero-pwm2-beeper.dts b/arch/arm64/boot/dts/sunxi/overlay/bpi-m4zero/bpi-m4zero-pwm2-beeper.dts new file mode 100755 index 000000000..d730db21d --- /dev/null +++ b/arch/arm64/boot/dts/sunxi/overlay/bpi-m4zero/bpi-m4zero-pwm2-beeper.dts @@ -0,0 +1,32 @@ +/dts-v1/; +/plugin/; + +/ { + fragment@0 { + target = <&pwm>; + + __overlay__ { + status = "okay"; + }; + }; + + fragment@1 { + target = <&pwm2>; + + __overlay__ { + status = "okay"; + }; + }; + + fragment@2 { + target-path = "/"; + + __overlay__ { + beeper: beeper { + compatible = "pwm-beeper"; + pwms = <&pwm 2 1000000 0>; + status = "okay"; + }; + }; + }; +}; diff --git a/arch/arm64/boot/dts/sunxi/overlay/bpi-m4zero/bpi-m4zero-pwm2-fan.dts b/arch/arm64/boot/dts/sunxi/overlay/bpi-m4zero/bpi-m4zero-pwm2-fan.dts new file mode 100755 index 000000000..ea985cd48 --- /dev/null +++ b/arch/arm64/boot/dts/sunxi/overlay/bpi-m4zero/bpi-m4zero-pwm2-fan.dts @@ -0,0 +1,77 @@ +/dts-v1/; +/plugin/; + +/ { + fragment@0 { + target = <&pwm>; + + __overlay__ { + status = "okay"; + }; + }; + + fragment@1 { + target = <&pwm2>; + + __overlay__ { + status = "okay"; + }; + }; + + fragment@2 { + target = <&pwm2_pin_b>; + + __overlay__ { + /* pull down for input mode when pwm disable */ + bias-pull-down; + }; + }; + + fragment@3 { + target-path = "/"; + + __overlay__ { + pwmfan: pwm-fan { + compatible = "pwm-fan"; + pwms = <&pwm 2 10000 0>; + cooling-min-state = <0>; + cooling-max-state = <2>; + #cooling-cells = <2>; + cooling-levels = <0 150 230>; + status = "okay"; + }; + }; + }; + + fragment@4 { + target = <&cpu_thermal>; + + __overlay__ { + trips { + fan0: fan@0 { + temperature = <65000>; + hysteresis = <5000>; + type = "active"; + }; + + fan1: fan@1 { + temperature = <80000>; + hysteresis = <5000>; + type = "active"; + }; + }; + + cooling-maps { + fan_cooling_map0 { + trip = <&fan0>; + cooling-device = <&pwmfan 0 1>; + }; + + fan_cooling_map1 { + trip = <&fan1>; + cooling-device = <&pwmfan 1 2>; + }; + }; + }; + }; +}; diff --git a/arch/arm64/boot/dts/sunxi/overlay/bpi-m4zero/bpi-m4zero-pwm2.dts b/arch/arm64/boot/dts/sunxi/overlay/bpi-m4zero/bpi-m4zero-pwm2.dts index e69392a54..a86d9e050 100755 --- a/arch/arm64/boot/dts/sunxi/overlay/bpi-m4zero/bpi-m4zero-pwm2.dts +++ b/arch/arm64/boot/dts/sunxi/overlay/bpi-m4zero/bpi-m4zero-pwm2.dts @@ -11,7 +11,7 @@ }; fragment@1 { - target = <&pwm1>; + target = <&pwm2>; __overlay__ { status = "okay"; diff --git a/arch/arm64/boot/dts/sunxi/overlay/bpi-m4zero/bpi-m4zero-spi1-flash.dts b/arch/arm64/boot/dts/sunxi/overlay/bpi-m4zero/bpi-m4zero-spi1-flash.dts new file mode 100755 index 000000000..1bc329f19 --- /dev/null +++ b/arch/arm64/boot/dts/sunxi/overlay/bpi-m4zero/bpi-m4zero-spi1-flash.dts @@ -0,0 +1,22 @@ +/dts-v1/; +/plugin/; + +/ { + fragment@0 { + target = <&spi1>; + __overlay__ { + status = "okay"; + + spi1_cs_number = <1>; + spi1_cs_bitmap = <1>; + + spiflash: w25q128@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "w25q128", "jedec,spi-nor", "winbond,w25q128"; + spi-max-frequency = <100000000>; + reg = <0>; + }; + }; + }; +}; diff --git a/arch/arm64/boot/dts/sunxi/sun50i-h616-bananapi-m4berry.dts b/arch/arm64/boot/dts/sunxi/sun50i-h616-bananapi-m4berry.dts index fd9e664e0..2a7d0e08f 100644 --- a/arch/arm64/boot/dts/sunxi/sun50i-h616-bananapi-m4berry.dts +++ b/arch/arm64/boot/dts/sunxi/sun50i-h616-bananapi-m4berry.dts @@ -367,6 +367,12 @@ phandle = <0x7a>; }; + gpiomem { + compatible = "allwinner, gpiomem"; + reg = <0x0 0x0300b000 0x0 0x400>; /* GPIO banks */ + status = "okay"; + }; + soc@3000000 { compatible = "simple-bus"; #address-cells = <0x2>; @@ -694,6 +700,7 @@ pwm-base = <0>; sunxi-pwms = <&pwm0>, <&pwm1>, <&pwm2>, <&pwm3>, <&pwm4>, <&pwm5>; + #pwm-cells = <3>; status = "okay"; }; @@ -1086,7 +1093,7 @@ }; spi1@1 { - pins = "PH9"; + pins = "PH5", "PH9"; function = "spi1"; drive-strength = <0x14>; bias-pull-up; @@ -1094,7 +1101,7 @@ }; spi1@2 { - pins = "PH6", "PH7", "PH8", "PH9"; + pins = "PH5", "PH6", "PH7", "PH8", "PH9"; function = "gpio_in"; drive-strength = <0x14>; phandle = <0x47>; @@ -1596,12 +1603,6 @@ pinctrl-names = "default", "sleep"; twi_drv_used = <0x1>; phandle = <0xa0>; - - eeprom@50 { - compatible = "atmel,24c16"; - reg = <0x50>; - status = "disabled"; - }; }; twi@5002400 { @@ -1837,15 +1838,6 @@ /*spi_dbi_enable = <0x0>;*/ phandle = <0xaa>; - spi_board1@0 { - device_type = "spi_board1"; - compatible = "linux,spidev"; - spi-max-frequency = <0x5f5e100>; - reg = <0x0>; - spi-rx-bus-width = <0x1>; - spi-tx-bus-width = <0x1>; - status = "disabled"; - }; }; ts0@5060000 { @@ -2794,7 +2786,7 @@ thermal-zones { - cpu_thermal_zone { + cpu_thermal: cpu_thermal_zone { polling-delay-passive = <0x1f4>; polling-delay = <0x3e8>; thermal-sensors = <0x72 0x2>; @@ -2825,7 +2817,7 @@ }; }; - cooling-maps { + cpu_cooling_maps: cooling-maps { map0 { trip = <0x73>; @@ -2911,6 +2903,7 @@ reg_pio1_8 = "/pio-18"; reg_pio3_3 = "/pio-33"; dram = "/dram"; + gpiomem = "/gpiomem"; soc = "/soc@3000000"; disp = "/soc@3000000/disp@1000000"; ve = "/soc@3000000/ve@1c0e000"; diff --git a/arch/arm64/boot/dts/sunxi/sun50i-h616-bananapi-m4zero.dts b/arch/arm64/boot/dts/sunxi/sun50i-h616-bananapi-m4zero.dts index a43e15a89..88dde5a48 100644 --- a/arch/arm64/boot/dts/sunxi/sun50i-h616-bananapi-m4zero.dts +++ b/arch/arm64/boot/dts/sunxi/sun50i-h616-bananapi-m4zero.dts @@ -367,6 +367,12 @@ phandle = <0x7a>; }; + gpiomem { + compatible = "allwinner, gpiomem"; + reg = <0x0 0x0300b000 0x0 0x400>; /* GPIO banks */ + status = "okay"; + }; + soc@3000000 { compatible = "simple-bus"; #address-cells = <0x2>; @@ -694,6 +700,7 @@ pwm-base = <0>; sunxi-pwms = <&pwm0>, <&pwm1>, <&pwm2>, <&pwm3>, <&pwm4>, <&pwm5>; + #pwm-cells = <3>; status = "okay"; }; @@ -744,6 +751,7 @@ status = "disabled"; }; + /* ephy ac200 */ pwm5: pwm5@300a015 { compatible = "allwinner,sunxi-pwm5"; reg = <0x0 0x0300a015 0x0 0x4>; @@ -1079,7 +1087,7 @@ }; spi1@1 { - pins = "PH9"; + pins = "PH5", "PH9"; function = "spi1"; drive-strength = <0x14>; bias-pull-up; @@ -1849,15 +1857,6 @@ /*spi_dbi_enable = <0x0>;*/ phandle = <0xaa>; - spi_board1@0 { - device_type = "spi_board1"; - compatible = "linux,spidev"; - spi-max-frequency = <0x5f5e100>; - reg = <0x0>; - spi-rx-bus-width = <0x1>; - spi-tx-bus-width = <0x1>; - status = "disabled"; - }; }; ts0@5060000 { @@ -2821,7 +2820,7 @@ thermal-zones { - cpu_thermal_zone { + cpu_thermal: cpu_thermal_zone { polling-delay-passive = <0x1f4>; polling-delay = <0x3e8>; thermal-sensors = <0x72 0x2>; @@ -2852,7 +2851,7 @@ }; }; - cooling-maps { + cpu_cooling_maps: cooling-maps { map0 { trip = <0x73>; @@ -2938,6 +2937,7 @@ reg_pio1_8 = "/pio-18"; reg_pio3_3 = "/pio-33"; dram = "/dram"; + gpiomem = "/gpiomem"; soc = "/soc@3000000"; disp = "/soc@3000000/disp@1000000"; ve = "/soc@3000000/ve@1c0e000"; diff --git a/arch/arm64/configs/bananapi_m4berry_defconfig b/arch/arm64/configs/bananapi_m4berry_defconfig index d44e40446..78995fd3c 100644 --- a/arch/arm64/configs/bananapi_m4berry_defconfig +++ b/arch/arm64/configs/bananapi_m4berry_defconfig @@ -2382,7 +2382,7 @@ CONFIG_USB_NET_CDCETHER=y CONFIG_USB_NET_CDC_NCM=y # CONFIG_USB_NET_HUAWEI_CDC_NCM is not set # CONFIG_USB_NET_CDC_MBIM is not set -# CONFIG_USB_NET_DM9601 is not set +CONFIG_USB_NET_DM9601=m # CONFIG_USB_NET_SR9700 is not set # CONFIG_USB_NET_SR9800 is not set # CONFIG_USB_NET_SMSC75XX is not set @@ -2766,7 +2766,7 @@ CONFIG_INPUT_MISC=y CONFIG_INPUT_AXP2101_PEK=y CONFIG_INPUT_UINPUT=y # CONFIG_INPUT_PCF8574 is not set -# CONFIG_INPUT_PWM_BEEPER is not set +CONFIG_INPUT_PWM_BEEPER=m # CONFIG_INPUT_PWM_VIBRA is not set # CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set # CONFIG_INPUT_ADXL34X is not set @@ -2822,6 +2822,7 @@ CONFIG_TRACE_ROUTER=m CONFIG_TRACE_SINK=m CONFIG_NULL_TTY=m CONFIG_LDISC_AUTOLOAD=y +CONFIG_DEVGPIOMEM=y CONFIG_DEVMEM=y # @@ -3331,7 +3332,7 @@ CONFIG_HWMON=y # CONFIG_SENSORS_OCC_P8_I2C is not set # CONFIG_SENSORS_PCF8591 is not set # CONFIG_PMBUS is not set -# CONFIG_SENSORS_PWM_FAN is not set +CONFIG_SENSORS_PWM_FAN=m # CONFIG_SENSORS_SHT15 is not set # CONFIG_SENSORS_SHT21 is not set # CONFIG_SENSORS_SHT3x is not set diff --git a/arch/arm64/configs/bananapi_m4zero_defconfig b/arch/arm64/configs/bananapi_m4zero_defconfig index 155408d6f..d19b6775e 100644 --- a/arch/arm64/configs/bananapi_m4zero_defconfig +++ b/arch/arm64/configs/bananapi_m4zero_defconfig @@ -2766,7 +2766,7 @@ CONFIG_INPUT_MISC=y CONFIG_INPUT_AXP2101_PEK=y CONFIG_INPUT_UINPUT=y # CONFIG_INPUT_PCF8574 is not set -# CONFIG_INPUT_PWM_BEEPER is not set +CONFIG_INPUT_PWM_BEEPER=m # CONFIG_INPUT_PWM_VIBRA is not set # CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set # CONFIG_INPUT_ADXL34X is not set @@ -2822,6 +2822,7 @@ CONFIG_TRACE_ROUTER=m CONFIG_TRACE_SINK=m CONFIG_NULL_TTY=m CONFIG_LDISC_AUTOLOAD=y +CONFIG_DEVGPIOMEM=y CONFIG_DEVMEM=y # @@ -3331,7 +3332,7 @@ CONFIG_HWMON=y # CONFIG_SENSORS_OCC_P8_I2C is not set # CONFIG_SENSORS_PCF8591 is not set # CONFIG_PMBUS is not set -# CONFIG_SENSORS_PWM_FAN is not set +CONFIG_SENSORS_PWM_FAN=m # CONFIG_SENSORS_SHT15 is not set # CONFIG_SENSORS_SHT21 is not set # CONFIG_SENSORS_SHT3x is not set diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index b6b131302..ec2800856 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig @@ -7,6 +7,15 @@ menu "Character devices" source "drivers/tty/Kconfig" +config DEVGPIOMEM + tristate "/dev/gpiomem rootless GPIO access via mmap()" + default y + help + Provides users with root-free access to the GPIO registers. + Calling mmap(/dev/gpiomem) will map the GPIO register page + to the user's pointer. This drvier can allow to access + gpio memory area in user account. + config DEVMEM bool "/dev/mem virtual device support" default y diff --git a/drivers/char/Makefile b/drivers/char/Makefile index 1a483a2ea..ba26d714d 100644 --- a/drivers/char/Makefile +++ b/drivers/char/Makefile @@ -3,6 +3,7 @@ # Makefile for the kernel character device drivers. # +obj-$(CONFIG_DEVGPIOMEM) += gpiomem.o obj-y += mem.o random.o obj-$(CONFIG_TTY_PRINTK) += ttyprintk.o obj-y += misc.o diff --git a/drivers/char/gpiomem.c b/drivers/char/gpiomem.c new file mode 100644 index 000000000..1d9930455 --- /dev/null +++ b/drivers/char/gpiomem.c @@ -0,0 +1,248 @@ +/* + * linux/drivers/char/gpiomem.c + * + * GPIO memory device driver + * + * Creates a chardev /dev/gpiomem which will provide user access to + * the GPIO registers when it is mmap()'d. + * No longer need root for user GPIO access, but without relaxing permissions + * on /dev/mem. + * + * This driver is based on bcm2835-gpiomem.c in Raspberrypi's linux kernel 4.4: + * Written by Luke Wren + * Copyright (c) 2015, Raspberry Pi (Trading) Ltd. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DEVICE_NAME "sunxi-gpiomem" +#define DRIVER_NAME "sunxi-gpiomem" +#define DEVICE_MINOR 0 + +struct regs_phys { + unsigned long start; + unsigned long end; +}; + +struct sunxi_gpiomem_instance { + struct regs_phys gpio_regs_phys[32]; + int gpio_area_count; + struct device *dev; +}; + +static struct cdev sunxi_gpiomem_cdev; +static dev_t sunxi_gpiomem_devid; +static struct class *sunxi_gpiomem_class; +static struct device *sunxi_gpiomem_dev; +static struct sunxi_gpiomem_instance *inst; + +static int sunxi_gpiomem_open(struct inode *inode, struct file *file) +{ + int dev = iminor(inode); + int ret = 0; + + dev_info(inst->dev, "gpiomem device opened."); + + if (dev != DEVICE_MINOR) { + dev_err(inst->dev, "Unknown minor device: %d", dev); + ret = -ENXIO; + } + return ret; +} + +static int sunxi_gpiomem_release(struct inode *inode, struct file *file) +{ + int dev = iminor(inode); + int ret = 0; + + if (dev != DEVICE_MINOR) { + dev_err(inst->dev, "Unknown minor device %d", dev); + ret = -ENXIO; + } + return ret; +} + +static const struct vm_operations_struct sunxi_gpiomem_vm_ops = { +#ifdef CONFIG_HAVE_IOREMAP_PROT + .access = generic_access_phys +#endif +}; + +static int sunxi_gpiomem_mmap(struct file *file, struct vm_area_struct *vma) +{ + int gpio_area = 0; + unsigned long start = vma->vm_pgoff << PAGE_SHIFT; + unsigned long end = start + vma->vm_end - vma->vm_start; + + while (gpio_area < inst->gpio_area_count) { + if ((inst->gpio_regs_phys[gpio_area].start >= start) && + (inst->gpio_regs_phys[gpio_area].end <= end)) + goto found; + gpio_area++; + } + + return -EACCES; + +found: + vma->vm_page_prot = phys_mem_access_prot(file, vma->vm_pgoff, + vma->vm_end - vma->vm_start, + vma->vm_page_prot); + + vma->vm_ops = &sunxi_gpiomem_vm_ops; + + if (remap_pfn_range(vma, vma->vm_start, + vma->vm_pgoff, + vma->vm_end - vma->vm_start, + vma->vm_page_prot)) { + return -EAGAIN; + } + + return 0; +} + +static const struct file_operations +sunxi_gpiomem_fops = { + .owner = THIS_MODULE, + .open = sunxi_gpiomem_open, + .release = sunxi_gpiomem_release, + .mmap = sunxi_gpiomem_mmap, +}; + +static int sunxi_gpiomem_probe(struct platform_device *pdev) +{ + int err = 0; + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + struct resource *res = NULL; + int i = 0; + + /* Allocate buffers and instance data */ + inst = kzalloc(sizeof(struct sunxi_gpiomem_instance), GFP_KERNEL); + + if (!inst) { + err = -ENOMEM; + goto failed_inst_alloc; + } + + inst->dev = dev; + inst->gpio_area_count = of_property_count_elems_of_size(np, "reg", + sizeof(u32)) / 4; + + if (inst->gpio_area_count > 32 || inst->gpio_area_count <= 0) { + dev_err(inst->dev, "failed to get gpio register area."); + err = -EINVAL; + goto failed_inst_alloc; + } + + dev_info(inst->dev, "Initialised: GPIO register area is %d", + inst->gpio_area_count); + + for (i = 0; i < inst->gpio_area_count; ++i) { + res = platform_get_resource(pdev, IORESOURCE_MEM, i); + if (res) { + inst->gpio_regs_phys[i].start = res->start; + inst->gpio_regs_phys[i].end = res->end; + } else { + dev_err(inst->dev, "failed to get IO resource area %d", i); + err = -ENOENT; + goto failed_get_resource; + } + } + + /* Create character device entries */ + err = alloc_chrdev_region(&sunxi_gpiomem_devid, + DEVICE_MINOR, 1, DEVICE_NAME); + if (err != 0) { + dev_err(inst->dev, "unable to allocate device number"); + goto failed_alloc_chrdev; + } + cdev_init(&sunxi_gpiomem_cdev, &sunxi_gpiomem_fops); + sunxi_gpiomem_cdev.owner = THIS_MODULE; + err = cdev_add(&sunxi_gpiomem_cdev, sunxi_gpiomem_devid, 1); + if (err != 0) { + dev_err(inst->dev, "unable to register device"); + goto failed_cdev_add; + } + + /* Create sysfs entries */ + sunxi_gpiomem_class = class_create(THIS_MODULE, DEVICE_NAME); + err = IS_ERR(sunxi_gpiomem_class); + if (err) + goto failed_class_create; + + sunxi_gpiomem_dev = device_create(sunxi_gpiomem_class, NULL, + sunxi_gpiomem_devid, NULL, + "gpiomem"); + err = IS_ERR(sunxi_gpiomem_dev); + if (err) + goto failed_device_create; + + for (i = 0; i < inst->gpio_area_count; ++i) { + dev_info(inst->dev, + "Initialised: Registers at start:0x%08lx end:0x%08lx size:0x%08lx", + inst->gpio_regs_phys[i].start, + inst->gpio_regs_phys[i].end, + inst->gpio_regs_phys[i].end - inst->gpio_regs_phys[i].start); + } + + return 0; + +failed_device_create: + class_destroy(sunxi_gpiomem_class); +failed_class_create: + cdev_del(&sunxi_gpiomem_cdev); +failed_cdev_add: + unregister_chrdev_region(sunxi_gpiomem_devid, 1); +failed_alloc_chrdev: +failed_get_resource: + kfree(inst); +failed_inst_alloc: + dev_err(inst->dev, "could not load sunxi_gpiomem"); + return err; +} + +static int sunxi_gpiomem_remove(struct platform_device *pdev) +{ + struct device *dev = inst->dev; + + kfree(inst); + device_destroy(sunxi_gpiomem_class, sunxi_gpiomem_devid); + class_destroy(sunxi_gpiomem_class); + cdev_del(&sunxi_gpiomem_cdev); + unregister_chrdev_region(sunxi_gpiomem_devid, 1); + + dev_info(dev, "GPIO mem driver removed - OK"); + return 0; +} + +static const struct of_device_id sunxi_gpiomem_of_match[] = { + {.compatible = "allwinner, gpiomem",}, + { }, +}; +MODULE_DEVICE_TABLE(of, sunxi_gpiomem_of_match); + +static struct platform_driver sunxi_gpiomem_driver = { + .driver = { + .name = DRIVER_NAME, + .owner = THIS_MODULE, + .of_match_table = sunxi_gpiomem_of_match, + }, + .probe = sunxi_gpiomem_probe, + .remove = sunxi_gpiomem_remove, +}; + +module_platform_driver(sunxi_gpiomem_driver); + +MODULE_ALIAS("platform:gpiomem"); +MODULE_DESCRIPTION("Allwinner gpiomem driver for accessing GPIO from userspace"); +MODULE_LICENSE("GPL"); diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c index d247d0ae8..2230eff78 100644 --- a/drivers/input/touchscreen/ads7846.c +++ b/drivers/input/touchscreen/ads7846.c @@ -1275,10 +1275,12 @@ static int ads7846_probe(struct spi_device *spi) unsigned long irq_flags; int err; +#if !defined(CONFIG_BOARD_BANANAPI_M4BERRY) && !defined(CONFIG_BOARD_BANANAPI_M4ZERO) if (!spi->irq) { - dev_dbg(&spi->dev, "no IRQ?\n"); + dev_err(&spi->dev, "no IRQ?\n"); return -EINVAL; } +#endif /* don't exceed max specified sample rate */ if (spi->max_speed_hz > (125000 * SAMPLE_BITS)) { @@ -1402,15 +1404,23 @@ static int ads7846_probe(struct spi_device *spi) if (IS_ERR(ts->reg)) { err = PTR_ERR(ts->reg); dev_err(&spi->dev, "unable to get regulator: %d\n", err); +#if !defined(CONFIG_BOARD_BANANAPI_M4BERRY) && !defined(CONFIG_BOARD_BANANAPI_M4ZERO) goto err_free_gpio; +#endif } err = regulator_enable(ts->reg); if (err) { dev_err(&spi->dev, "unable to enable regulator: %d\n", err); +#if !defined(CONFIG_BOARD_BANANAPI_M4BERRY) && !defined(CONFIG_BOARD_BANANAPI_M4ZERO) goto err_put_regulator; +#endif } +#if defined(CONFIG_BOARD_BANANAPI_M4BERRY) || defined(CONFIG_BOARD_BANANAPI_M4ZERO) + spi->irq = gpio_to_irq(ts->gpio_pendown); +#endif + irq_flags = pdata->irq_flags ? : IRQF_TRIGGER_FALLING; irq_flags |= IRQF_ONESHOT; @@ -1472,11 +1482,13 @@ static int ads7846_probe(struct spi_device *spi) free_irq(spi->irq, ts); err_disable_regulator: regulator_disable(ts->reg); +#if !defined(CONFIG_BOARD_BANANAPI_M4BERRY) && !defined(CONFIG_BOARD_BANANAPI_M4ZERO) err_put_regulator: regulator_put(ts->reg); err_free_gpio: if (!ts->get_pendown_state) gpio_free(ts->gpio_pendown); +#endif err_cleanup_filter: if (ts->filter_cleanup) ts->filter_cleanup(ts->filter_data); diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c index d5a08b7ae..2ebc79aad 100644 --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c @@ -2482,6 +2482,7 @@ static const struct flash_info spi_nor_ids[] = { { "w25q80", INFO(0xef5014, 0, 64 * 1024, 16, SECT_4K) }, { "w25q80bl", INFO(0xef4014, 0, 64 * 1024, 16, SECT_4K) }, { "w25q128", INFO(0xef4018, 0, 64 * 1024, 256, SECT_4K) }, + { "w25q128fv", INFO(0xffa00e, 0, 64 * 1024, 256, SECT_4K) }, { "w25q256", INFO(0xef4019, 0, 64 * 1024, 512, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, { "w25q256jvm", INFO(0xef7019, 0, 64 * 1024, 512, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },