mirror of
https://github.com/FunKey-Project/FunKey-OS.git
synced 2025-12-12 15:48:51 +01:00
bumped linux to latest Funkey_S with integrated patches
Signed-off-by: Michel-FK <michel.stempin@funkey-project.com>
This commit is contained in:
parent
a8e82b4b55
commit
2f7ee632e0
@ -1,74 +0,0 @@
|
||||
fb_st7789v.c | 34 ++++++++++++++++++++++++++++++++--
|
||||
1 file changed, 32 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/drivers/staging/fbtft/fb_st7789v.c b/drivers/staging/fbtft/fb_st7789v.c
|
||||
index a5d7c87..69f52af 100644
|
||||
--- a/drivers/staging/fbtft/fb_st7789v.c
|
||||
+++ b/drivers/staging/fbtft/fb_st7789v.c
|
||||
@@ -86,6 +86,28 @@ enum st7789v_command {
|
||||
static int init_display(struct fbtft_par *par)
|
||||
{
|
||||
/* turn off sleep mode */
|
||||
+ /*write_reg(par, 0x11);
|
||||
+ mdelay(120);
|
||||
+
|
||||
+ write_reg(par, 0x36, 0x00);
|
||||
+ write_reg(par, 0x3A, 0x05);
|
||||
+
|
||||
+ write_reg(par, 0xB2,0x0C,0x0C,0x00,0x33,0x33);
|
||||
+ write_reg(par, 0xB7,0x35);
|
||||
+ write_reg(par, 0xBB,0x1A);
|
||||
+ write_reg(par, 0xC0,0x2C);
|
||||
+ write_reg(par, 0xC2,0x01);
|
||||
+ write_reg(par, 0xC3,0x0B);
|
||||
+ write_reg(par, 0xC4,0x20);
|
||||
+ write_reg(par, 0xC6,0x0F);
|
||||
+ write_reg(par, 0xD0,0xA4,0xA1);
|
||||
+ write_reg(par, 0x21);
|
||||
+ write_reg(par, 0xE0,0x00,0x19,0x1E,0x0A,0x09,0x15,0x3D,0x44,0x51,0x12,0x03,0x00,0x3F,0x3F);
|
||||
+ write_reg(par, 0xE1,0x00,0x18,0x1E,0x0A,0x09,0x25,0x3F,0x43,0x52,0x33,0x03,0x00,0x3F,0x3F);
|
||||
+ write_reg(par, 0x29);*/
|
||||
+
|
||||
+
|
||||
+ /* turn off sleep mode */
|
||||
write_reg(par, MIPI_DCS_EXIT_SLEEP_MODE);
|
||||
mdelay(120);
|
||||
|
||||
@@ -128,7 +150,14 @@ static int init_display(struct fbtft_par *par)
|
||||
*/
|
||||
write_reg(par, PWCTRL1, 0xA4, 0xA1);
|
||||
|
||||
+ /* Ystart at 80 , Yend at 240 */
|
||||
+ write_reg(par, 0x2B, 0x00, 0x50, 0x00, 0xF0);
|
||||
+
|
||||
+ /* Display Inversion of colors */
|
||||
+ write_reg(par, 0x21);
|
||||
+
|
||||
write_reg(par, MIPI_DCS_SET_DISPLAY_ON);
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -189,7 +218,7 @@ static int set_gamma(struct fbtft_par *par, u32 *curves)
|
||||
* The masks are the same for both positive and negative voltage
|
||||
* gamma curves.
|
||||
*/
|
||||
- static const u8 gamma_par_mask[] = {
|
||||
+ const u8 gamma_par_mask[] = {
|
||||
0xFF, /* V63[3:0], V0[3:0]*/
|
||||
0x3F, /* V1[5:0] */
|
||||
0x3F, /* V2[5:0] */
|
||||
@@ -241,7 +270,7 @@ static int blank(struct fbtft_par *par, bool on)
|
||||
static struct fbtft_display display = {
|
||||
.regwidth = 8,
|
||||
.width = 240,
|
||||
- .height = 320,
|
||||
+ .height = 240,
|
||||
.gamma_num = 2,
|
||||
.gamma_len = 14,
|
||||
.gamma = DEFAULT_GAMMA,
|
||||
@@ -263,3 +292,4 @@ MODULE_ALIAS("platform:st7789v");
|
||||
MODULE_DESCRIPTION("FB driver for the ST7789V LCD Controller");
|
||||
MODULE_AUTHOR("Dennis Menschel");
|
||||
MODULE_LICENSE("GPL");
|
||||
+
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,195 +0,0 @@
|
||||
--- /dev/null 2019-05-04 09:53:55.553276856 +0200
|
||||
+++ a/arch/arm/boot/dts/sun8i-v3s-funkey.dts 2019-05-04 20:06:53.118696800 +0200
|
||||
@@ -0,0 +1,192 @@
|
||||
+/*
|
||||
+ * Copyright (C) 2019 Michel Stempin <michel.stempin@wanadoo.fr>
|
||||
+ *
|
||||
+ * This file is dual-licensed: you can use it either under the terms
|
||||
+ * of the GPL or the X11 license, at your option. Note that this dual
|
||||
+ * licensing only applies to this file, and not this project as a
|
||||
+ * whole.
|
||||
+ *
|
||||
+ * a) This file 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.
|
||||
+ *
|
||||
+ * This file is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ * GNU General Public License for more details.
|
||||
+ *
|
||||
+ * Or, alternatively,
|
||||
+ *
|
||||
+ * b) Permission is hereby granted, free of charge, to any person
|
||||
+ * obtaining a copy of this software and associated documentation
|
||||
+ * files (the "Software"), to deal in the Software without
|
||||
+ * restriction, including without limitation the rights to use,
|
||||
+ * copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
+ * sell copies of the Software, and to permit persons to whom the
|
||||
+ * Software is furnished to do so, subject to the following
|
||||
+ * conditions:
|
||||
+ *
|
||||
+ * The above copyright notice and this permission notice shall be
|
||||
+ * included in all copies or substantial portions of the Software.
|
||||
+ *
|
||||
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
+ * OTHER DEALINGS IN THE SOFTWARE.
|
||||
+ */
|
||||
+
|
||||
+/dts-v1/;
|
||||
+#include "sun8i-v3s.dtsi"
|
||||
+#include "sunxi-common-regulators.dtsi"
|
||||
+
|
||||
+/ {
|
||||
+ model = "FunKey";
|
||||
+ compatible = "funkey", "allwinner,sun8i-v3s";
|
||||
+
|
||||
+ aliases {
|
||||
+ serial0 = &uart0;
|
||||
+ };
|
||||
+
|
||||
+ chosen {
|
||||
+ stdout-path = "serial0:115200n8";
|
||||
+ };
|
||||
+
|
||||
+ backlight: backlight {
|
||||
+ compatible = "pwm-backlight";
|
||||
+ pwms = <&pwm 0 100000 1>;
|
||||
+ brightness-levels = <0 1 2 3 8 14 21 32 46 60 80 100>; //2.2 div factor
|
||||
+ default-brightness-level = <11>;
|
||||
+ power-supply = <®_vcc5v0>;
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&codec {
|
||||
+ allwinner,audio-routing =
|
||||
+ "Headphone", "HP",
|
||||
+ "Headphone", "HPCOM",
|
||||
+ "MIC1", "Mic",
|
||||
+ "Mic", "HBIAS";
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&ehci0 {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&i2c0 {
|
||||
+ status = "okay";
|
||||
+
|
||||
+ /* axp209: pmic@34 {
|
||||
+ compatible = "x-powers,axp209";
|
||||
+ reg = <0x34>;
|
||||
+ interrupts = <0>;
|
||||
+ interrupt-controller;
|
||||
+ #interrupt-cells = <1>;
|
||||
+ }; */
|
||||
+};
|
||||
+
|
||||
+&mmc0 {
|
||||
+ pinctrl-0 = <&mmc0_pins_a>;
|
||||
+ pinctrl-names = "default";
|
||||
+ broken-cd;
|
||||
+ bus-width = <4>;
|
||||
+ vmmc-supply = <®_vcc3v3>;
|
||||
+ vqmmc-supply = <®_vcc3v3>;
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&ohci0 {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+/*
|
||||
+#include "axp209.dtsi"
|
||||
+
|
||||
+®_dcdc2 {
|
||||
+ regulator-always-on;
|
||||
+ regulator-min-microvolt = <1000000>;
|
||||
+ regulator-max-microvolt = <1400000>;
|
||||
+ regulator-name = "vdd-cpu-sys-ephy";
|
||||
+};
|
||||
+
|
||||
+®_dcdc3 {
|
||||
+ regulator-always-on;
|
||||
+ regulator-min-microvolt = <3000000>;
|
||||
+ regulator-max-microvolt = <3450000>;
|
||||
+ regulator-name = "vcc-io-ephy-mcsi-usb";
|
||||
+};
|
||||
+
|
||||
+®_ldo1 {
|
||||
+ regulator-min-microvolt = <3000000>;
|
||||
+ regulator-max-microvolt = <3600000>;
|
||||
+ regulator-name = "vcc-rtc";
|
||||
+};
|
||||
+
|
||||
+®_ldo2 {
|
||||
+ regulator-always-on;
|
||||
+ regulator-min-microvolt = <2800000>;
|
||||
+ regulator-max-microvolt = <3300000>;
|
||||
+ regulator-name = "avcc-pll";
|
||||
+};
|
||||
+*/
|
||||
+
|
||||
+®_vcc3v0 {
|
||||
+ regulator-always-on;
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+®_vcc3v3 {
|
||||
+ regulator-always-on;
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+®_vcc5v0 {
|
||||
+ regulator-always-on;
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&spi0 {
|
||||
+ status = "okay";
|
||||
+
|
||||
+ st7789v@0 {
|
||||
+ compatible = "sitronix,st7789v";
|
||||
+ reg = <0>;
|
||||
+ spi-max-frequency = <50000000>;
|
||||
+ txbuflen = <115200>;
|
||||
+ rotate = <0>;
|
||||
+ fps = <50>;
|
||||
+ buswidth = <8>;
|
||||
+ reset-gpios = <&pio 1 2 GPIO_ACTIVE_HIGH>; //PB2
|
||||
+ dc-gpios = <&pio 2 0 GPIO_ACTIVE_LOW>; //PC0 (MISO)
|
||||
+ debug = <0>;
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&uart0 {
|
||||
+ pinctrl-0 = <&uart0_pins_a>;
|
||||
+ pinctrl-names = "default";
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&pwm {
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&pwm0_pins>;
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&usb_otg {
|
||||
+ dr_mode = "peripheral";
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&usbphy {
|
||||
+ usb0_vbus-supply = <®_vcc5v0>;
|
||||
+ phy-supply = <®_vcc5v0>;
|
||||
+ vcc = <®_vcc5v0>;
|
||||
+ status = "okay";
|
||||
+};
|
||||
@ -1,12 +0,0 @@
|
||||
diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
|
||||
index 1f97ae8..e798bf1 100644
|
||||
--- a/arch/arm/boot/dts/Makefile
|
||||
+++ b/arch/arm/boot/dts/Makefile
|
||||
@@ -932,6 +932,7 @@ dtb-$(CONFIG_MACH_SUN8I) += \
|
||||
sun8i-h3-orangepi-plus2e.dtb \
|
||||
sun8i-r16-bananapi-m2m.dtb \
|
||||
sun8i-r16-parrot.dtb \
|
||||
+ sun8i-v3s-funkey.dtb \
|
||||
sun8i-v3s-licheepi-zero.dtb \
|
||||
sun8i-v3s-licheepi-zero-dock.dtb \
|
||||
sun8i-v3s-licheepi-zero-with-480x272-lcd.dtb \
|
||||
@ -1,69 +0,0 @@
|
||||
diff --git a/arch/arm/boot/dts/sun8i-v3s-funkey.dts b/arch/arm/boot/dts/sun8i-v3s-funkey.dts
|
||||
index 0a8ce5c0..31fddd2e 100644
|
||||
--- a/arch/arm/boot/dts/sun8i-v3s-funkey.dts
|
||||
+++ b/arch/arm/boot/dts/sun8i-v3s-funkey.dts
|
||||
@@ -81,13 +81,14 @@
|
||||
&i2c0 {
|
||||
status = "okay";
|
||||
|
||||
- /* axp209: pmic@34 {
|
||||
+ axp209: pmic@34 {
|
||||
compatible = "x-powers,axp209";
|
||||
reg = <0x34>;
|
||||
- interrupts = <0>;
|
||||
+ interrupt-parent = <&pio>;
|
||||
+ interrupts = <1 5 IRQ_TYPE_EDGE_FALLING>;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <1>;
|
||||
- }; */
|
||||
+ };
|
||||
};
|
||||
|
||||
&mmc0 {
|
||||
@@ -104,9 +105,24 @@
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
-/*
|
||||
#include "axp209.dtsi"
|
||||
|
||||
+&ac_power_supply {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&axp_gpio {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&battery_power_supply {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&usb_power_supply {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
®_dcdc2 {
|
||||
regulator-always-on;
|
||||
regulator-min-microvolt = <1000000>;
|
||||
@@ -133,7 +149,6 @@
|
||||
regulator-max-microvolt = <3300000>;
|
||||
regulator-name = "avcc-pll";
|
||||
};
|
||||
-*/
|
||||
|
||||
®_vcc3v0 {
|
||||
regulator-always-on;
|
||||
diff --git a/drivers/regulator/axp20x-regulator.c b/drivers/regulator/axp20x-regulator.c
|
||||
index 376a99b7..0718d191 100644
|
||||
--- a/drivers/regulator/axp20x-regulator.c
|
||||
+++ b/drivers/regulator/axp20x-regulator.c
|
||||
@@ -169,7 +169,7 @@ static const struct regulator_desc axp20x_regulators[] = {
|
||||
AXP20X_DCDC2_V_OUT, 0x3f, AXP20X_PWR_OUT_CTRL, 0x10),
|
||||
AXP_DESC(AXP20X, DCDC3, "dcdc3", "vin3", 700, 3500, 25,
|
||||
AXP20X_DCDC3_V_OUT, 0x7f, AXP20X_PWR_OUT_CTRL, 0x02),
|
||||
- AXP_DESC_FIXED(AXP20X, LDO1, "ldo1", "acin", 1300),
|
||||
+ AXP_DESC_FIXED(AXP20X, LDO1, "ldo1", "acin", 3300),
|
||||
AXP_DESC(AXP20X, LDO2, "ldo2", "ldo24in", 1800, 3300, 100,
|
||||
AXP20X_LDO24_V_OUT, 0xf0, AXP20X_PWR_OUT_CTRL, 0x04),
|
||||
AXP_DESC(AXP20X, LDO3, "ldo3", "ldo3in", 700, 3500, 25,
|
||||
@ -1,77 +0,0 @@
|
||||
From 8096f82b8211e2d75f57048a30961e1d8616364e Mon Sep 17 00:00:00 2001
|
||||
From: vincent <vbusoenseirb@gmail.com>
|
||||
Date: Sat, 26 Oct 2019 10:44:34 +0200
|
||||
Subject: [PATCH] fbtft set to 39Hz refresh rate
|
||||
|
||||
---
|
||||
drivers/staging/fbtft/fb_st7789v.c | 16 +++++++++++++---
|
||||
drivers/staging/fbtft/fbtft-core.c | 8 +++++++-
|
||||
2 files changed, 20 insertions(+), 4 deletions(-)
|
||||
mode change 100644 => 100755 drivers/staging/fbtft/fb_st7789v.c
|
||||
mode change 100644 => 100755 drivers/staging/fbtft/fbtft-core.c
|
||||
|
||||
diff --git a/drivers/staging/fbtft/fb_st7789v.c b/drivers/staging/fbtft/fb_st7789v.c
|
||||
old mode 100644
|
||||
new mode 100755
|
||||
index 69f52af..00756de
|
||||
--- a/drivers/staging/fbtft/fb_st7789v.c
|
||||
+++ b/drivers/staging/fbtft/fb_st7789v.c
|
||||
@@ -150,12 +150,12 @@ static int init_display(struct fbtft_par *par)
|
||||
*/
|
||||
write_reg(par, PWCTRL1, 0xA4, 0xA1);
|
||||
|
||||
- /* Ystart at 80 , Yend at 240 */
|
||||
- write_reg(par, 0x2B, 0x00, 0x50, 0x00, 0xF0);
|
||||
-
|
||||
/* Display Inversion of colors */
|
||||
write_reg(par, 0x21);
|
||||
|
||||
+ /* 39Hz refresh rate */
|
||||
+ write_reg(par, 0xC6,0x1F);
|
||||
+
|
||||
write_reg(par, MIPI_DCS_SET_DISPLAY_ON);
|
||||
|
||||
return 0;
|
||||
@@ -190,6 +190,16 @@ static int set_var(struct fbtft_par *par)
|
||||
return -EINVAL;
|
||||
}
|
||||
write_reg(par, MIPI_DCS_SET_ADDRESS_MODE, madctl_par);
|
||||
+
|
||||
+ // All offset operations are done after in fbtft_set_addr_win, not here
|
||||
+ /* Ystart at 0 , Yend at 239 */
|
||||
+ //write_reg(par, 0x2B, 0x00, 0x50, 0x00, 0xEF);
|
||||
+ write_reg(par, 0x2B, 0x00, 0x00, 0x00, 0xEF);
|
||||
+ //write_reg(par, 0x2B, 0x00, 0x50, 0x01, 0x3F);
|
||||
+ /* Xstart at 80 , Xend at 319 */
|
||||
+ write_reg(par, 0x2A, 0x00, 0x50, 0x01, 0x3F);
|
||||
+ //write_reg(par, 0x2A, 0x00, 0x50, 0x00, 0xEF);
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
diff --git a/drivers/staging/fbtft/fbtft-core.c b/drivers/staging/fbtft/fbtft-core.c
|
||||
old mode 100644
|
||||
new mode 100755
|
||||
index 6d0363d..7fbf92e
|
||||
--- a/drivers/staging/fbtft/fbtft-core.c
|
||||
+++ b/drivers/staging/fbtft/fbtft-core.c
|
||||
@@ -391,9 +391,15 @@ static void fbtft_update_display(struct fbtft_par *par, unsigned int start_line,
|
||||
fbtft_par_dbg(DEBUG_UPDATE_DISPLAY, par, "%s(start_line=%u, end_line=%u)\n",
|
||||
__func__, start_line, end_line);
|
||||
|
||||
- if (par->fbtftops.set_addr_win)
|
||||
+ // Carefull removing this. this will work only if the full screen is updated all at once
|
||||
+ if (par->fbtftops.set_addr_win){
|
||||
par->fbtftops.set_addr_win(par, 0, start_line,
|
||||
par->info->var.xres - 1, end_line);
|
||||
+ }
|
||||
+ /*if (par->fbtftops.set_addr_win){
|
||||
+ par->fbtftops.set_addr_win(par, 80, start_line,
|
||||
+ 320 - 1, end_line);
|
||||
+ }*/
|
||||
|
||||
offset = start_line * par->info->fix.line_length;
|
||||
len = (end_line - start_line + 1) * par->info->fix.line_length;
|
||||
--
|
||||
1.9.1
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,22 +0,0 @@
|
||||
diff --git a/arch/arm/boot/dts/sun8i-v3s.dtsi b/arch/arm/boot/dts/sun8i-v3s.dtsi
|
||||
index 5379f2d7..f9765995 100644
|
||||
--- a/arch/arm/boot/dts/sun8i-v3s.dtsi
|
||||
+++ b/arch/arm/boot/dts/sun8i-v3s.dtsi
|
||||
@@ -73,6 +73,17 @@
|
||||
device_type = "cpu";
|
||||
reg = <0>;
|
||||
clocks = <&ccu CLK_CPU>;
|
||||
+ clock-latency = <244144>; /* 8 32k periods */
|
||||
+ clock-frequency = <1296000>;
|
||||
+ operating-points = <
|
||||
+ /* kHz uV */
|
||||
+ 1296000 1200000
|
||||
+ 1008000 1200000
|
||||
+ 864000 1200000
|
||||
+ 720000 1100000
|
||||
+ 480000 1000000
|
||||
+ >;
|
||||
+
|
||||
};
|
||||
};
|
||||
|
||||
@ -1,39 +0,0 @@
|
||||
diff --git a/arch/arm/boot/dts/sun8i-v3s-funkey.dts b/arch/arm/boot/dts/sun8i-v3s-funkey.dts
|
||||
index ad694808..3be3c7f1 100644
|
||||
--- a/arch/arm/boot/dts/sun8i-v3s-funkey.dts
|
||||
+++ b/arch/arm/boot/dts/sun8i-v3s-funkey.dts
|
||||
@@ -74,6 +74,10 @@
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
+&codec_analog {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
&ehci0 {
|
||||
status = "okay";
|
||||
};
|
||||
diff --git a/arch/arm/boot/dts/sun8i-v3s.dtsi b/arch/arm/boot/dts/sun8i-v3s.dtsi
|
||||
index 5379f2d7..02f6c844 100644
|
||||
--- a/arch/arm/boot/dts/sun8i-v3s.dtsi
|
||||
+++ b/arch/arm/boot/dts/sun8i-v3s.dtsi
|
||||
@@ -433,6 +444,7 @@
|
||||
codec_analog: codec-analog@01c23000 {
|
||||
compatible = "allwinner,sun8i-v3s-codec-analog";
|
||||
reg = <0x01c23000 0x4>;
|
||||
+ status = "disabled";
|
||||
};
|
||||
|
||||
uart0: serial@01c28000 {
|
||||
diff --git a/sound/soc/sunxi/Makefile b/sound/soc/sunxi/Makefile
|
||||
index 4a9ef673..655780ab 100644
|
||||
--- a/sound/soc/sunxi/Makefile
|
||||
+++ b/sound/soc/sunxi/Makefile
|
||||
@@ -1,6 +1,6 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
+obj-$(CONFIG_SND_SUN8I_CODEC_ANALOG) += sun8i-codec-analog.o
|
||||
obj-$(CONFIG_SND_SUN4I_CODEC) += sun4i-codec.o
|
||||
obj-$(CONFIG_SND_SUN4I_I2S) += sun4i-i2s.o
|
||||
obj-$(CONFIG_SND_SUN4I_SPDIF) += sun4i-spdif.o
|
||||
-obj-$(CONFIG_SND_SUN8I_CODEC_ANALOG) += sun8i-codec-analog.o
|
||||
obj-$(CONFIG_SND_SUN8I_CODEC) += sun8i-codec.o
|
||||
@ -1,45 +0,0 @@
|
||||
From fcef516f0bb110628d43c23320ef36389f689439 Mon Sep 17 00:00:00 2001
|
||||
From: vincent <vbusoenseirb@gmail.com>
|
||||
Date: Sun, 27 Oct 2019 16:39:04 +0100
|
||||
Subject: [PATCH] axp209 PEK linked to KEY_Q, not KEY_POWER
|
||||
|
||||
---
|
||||
drivers/input/misc/axp20x-pek.c | 15 ++++++++++-----
|
||||
1 file changed, 10 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/drivers/input/misc/axp20x-pek.c b/drivers/input/misc/axp20x-pek.c
|
||||
index debeeae..5dac8e9 100644
|
||||
--- a/drivers/input/misc/axp20x-pek.c
|
||||
+++ b/drivers/input/misc/axp20x-pek.c
|
||||
@@ -214,10 +214,14 @@ static irqreturn_t axp20x_pek_irq(int irq, void *pwr)
|
||||
* The power-button is connected to ground so a falling edge (dbf)
|
||||
* means it is pressed.
|
||||
*/
|
||||
- if (irq == axp20x_pek->irq_dbf)
|
||||
- input_report_key(idev, KEY_POWER, true);
|
||||
- else if (irq == axp20x_pek->irq_dbr)
|
||||
- input_report_key(idev, KEY_POWER, false);
|
||||
+ if (irq == axp20x_pek->irq_dbf){
|
||||
+ //input_report_key(idev, KEY_POWER, true);
|
||||
+ input_report_key(idev, KEY_Q, true);
|
||||
+ }
|
||||
+ else if (irq == axp20x_pek->irq_dbr){
|
||||
+ //input_report_key(idev, KEY_POWER, false);
|
||||
+ input_report_key(idev, KEY_Q, false);
|
||||
+ }
|
||||
|
||||
input_sync(idev);
|
||||
|
||||
@@ -259,7 +263,8 @@ static int axp20x_pek_probe_input_device(struct axp20x_pek *axp20x_pek,
|
||||
idev->phys = "m1kbd/input2";
|
||||
idev->dev.parent = &pdev->dev;
|
||||
|
||||
- input_set_capability(idev, EV_KEY, KEY_POWER);
|
||||
+ //input_set_capability(idev, EV_KEY, KEY_POWER);
|
||||
+ input_set_capability(idev, EV_KEY, KEY_Q);
|
||||
|
||||
input_set_drvdata(idev, axp20x_pek);
|
||||
|
||||
--
|
||||
1.9.1
|
||||
|
||||
@ -1,43 +0,0 @@
|
||||
diff --git a/drivers/usb/gadget/udc/core.c b/drivers/usb/gadget/udc/core.c
|
||||
index 284bd1a7..97db9fa4 100644
|
||||
--- a/drivers/usb/gadget/udc/core.c
|
||||
+++ b/drivers/usb/gadget/udc/core.c
|
||||
@@ -973,15 +973,19 @@ static void usb_gadget_state_work(struct work_struct *work)
|
||||
struct usb_gadget *gadget = work_to_gadget(work);
|
||||
struct usb_udc *udc = gadget->udc;
|
||||
|
||||
- if (udc)
|
||||
+ if (udc) {
|
||||
sysfs_notify(&udc->dev.kobj, NULL, "state");
|
||||
+ kobject_uevent(&udc->dev.kobj, KOBJ_CHANGE);
|
||||
+ }
|
||||
}
|
||||
|
||||
void usb_gadget_set_state(struct usb_gadget *gadget,
|
||||
enum usb_device_state state)
|
||||
{
|
||||
- gadget->state = state;
|
||||
- schedule_work(&gadget->work);
|
||||
+ if (state != gadget->state) {
|
||||
+ gadget->state = state;
|
||||
+ schedule_work(&gadget->work);
|
||||
+ }
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(usb_gadget_set_state);
|
||||
|
||||
@@ -1565,6 +1569,15 @@ static int usb_udc_uevent(struct device *dev, struct kobj_uevent_env *env)
|
||||
}
|
||||
}
|
||||
|
||||
+ if (udc->gadget) {
|
||||
+ ret = add_uevent_var(env, "USB_UDC_STATE=%s",
|
||||
+ usb_state_string(udc->gadget->state));
|
||||
+ if (ret) {
|
||||
+ dev_err(dev, "failed to add uevent USB_UDC_STATE\n");
|
||||
+ return ret;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1,173 +0,0 @@
|
||||
diff --git a/drivers/spi/spi-sun6i.c b/drivers/spi/spi-sun6i.c
|
||||
index 8533f4e..88ad45e 100644
|
||||
--- a/drivers/spi/spi-sun6i.c
|
||||
+++ b/drivers/spi/spi-sun6i.c
|
||||
@@ -88,8 +88,12 @@
|
||||
#define SUN6I_TXDATA_REG 0x200
|
||||
#define SUN6I_RXDATA_REG 0x300
|
||||
|
||||
+#define SUN6I_SPI_MODE_BITS (SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LSB_FIRST)
|
||||
+
|
||||
+#define SUN6I_SPI_MAX_SPEED_HZ 100000000
|
||||
+#define SUN6I_SPI_MIN_SPEED_HZ 3000
|
||||
+
|
||||
struct sun6i_spi {
|
||||
- struct spi_master *master;
|
||||
void __iomem *base_addr;
|
||||
struct clk *hclk;
|
||||
struct clk *mclk;
|
||||
@@ -189,6 +193,9 @@ static void sun6i_spi_set_cs(struct spi_device *spi, bool enable)
|
||||
else
|
||||
reg &= ~SUN6I_TFR_CTL_CS_LEVEL;
|
||||
|
||||
+ /* We want to control the chip select manually */
|
||||
+ reg |= SUN6I_TFR_CTL_CS_MANUAL;
|
||||
+
|
||||
sun6i_spi_write(sspi, SUN6I_TFR_CTL_REG, reg);
|
||||
}
|
||||
|
||||
@@ -197,6 +204,39 @@ static size_t sun6i_spi_max_transfer_size(struct spi_device *spi)
|
||||
return SUN6I_MAX_XFER_SIZE - 1;
|
||||
}
|
||||
|
||||
+static int sun6i_spi_prepare_message(struct spi_master *master,
|
||||
+ struct spi_message *msg)
|
||||
+{
|
||||
+ struct spi_device *spi = msg->spi;
|
||||
+ struct sun6i_spi *sspi = spi_master_get_devdata(master);
|
||||
+ u32 reg;
|
||||
+
|
||||
+ /*
|
||||
+ * Setup the transfer control register: Chip Select,
|
||||
+ * polarities, etc.
|
||||
+ */
|
||||
+ reg = sun6i_spi_read(sspi, SUN6I_TFR_CTL_REG);
|
||||
+
|
||||
+ if (spi->mode & SPI_CPOL)
|
||||
+ reg |= SUN6I_TFR_CTL_CPOL;
|
||||
+ else
|
||||
+ reg &= ~SUN6I_TFR_CTL_CPOL;
|
||||
+
|
||||
+ if (spi->mode & SPI_CPHA)
|
||||
+ reg |= SUN6I_TFR_CTL_CPHA;
|
||||
+ else
|
||||
+ reg &= ~SUN6I_TFR_CTL_CPHA;
|
||||
+
|
||||
+ if (spi->mode & SPI_LSB_FIRST)
|
||||
+ reg |= SUN6I_TFR_CTL_FBS;
|
||||
+ else
|
||||
+ reg &= ~SUN6I_TFR_CTL_FBS;
|
||||
+
|
||||
+ sun6i_spi_write(sspi, SUN6I_TFR_CTL_REG, reg);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static int sun6i_spi_transfer_one(struct spi_master *master,
|
||||
struct spi_device *spi,
|
||||
struct spi_transfer *tfr)
|
||||
@@ -235,27 +275,8 @@ static int sun6i_spi_transfer_one(struct spi_master *master,
|
||||
(trig_level << SUN6I_FIFO_CTL_RF_RDY_TRIG_LEVEL_BITS) |
|
||||
(trig_level << SUN6I_FIFO_CTL_TF_ERQ_TRIG_LEVEL_BITS));
|
||||
|
||||
- /*
|
||||
- * Setup the transfer control register: Chip Select,
|
||||
- * polarities, etc.
|
||||
- */
|
||||
- reg = sun6i_spi_read(sspi, SUN6I_TFR_CTL_REG);
|
||||
-
|
||||
- if (spi->mode & SPI_CPOL)
|
||||
- reg |= SUN6I_TFR_CTL_CPOL;
|
||||
- else
|
||||
- reg &= ~SUN6I_TFR_CTL_CPOL;
|
||||
-
|
||||
- if (spi->mode & SPI_CPHA)
|
||||
- reg |= SUN6I_TFR_CTL_CPHA;
|
||||
- else
|
||||
- reg &= ~SUN6I_TFR_CTL_CPHA;
|
||||
-
|
||||
- if (spi->mode & SPI_LSB_FIRST)
|
||||
- reg |= SUN6I_TFR_CTL_FBS;
|
||||
- else
|
||||
- reg &= ~SUN6I_TFR_CTL_FBS;
|
||||
|
||||
+ reg = sun6i_spi_read(sspi, SUN6I_TFR_CTL_REG);
|
||||
/*
|
||||
* If it's a TX only transfer, we don't want to fill the RX
|
||||
* FIFO with bogus data
|
||||
@@ -265,11 +286,9 @@ static int sun6i_spi_transfer_one(struct spi_master *master,
|
||||
else
|
||||
reg |= SUN6I_TFR_CTL_DHB;
|
||||
|
||||
- /* We want to control the chip select manually */
|
||||
- reg |= SUN6I_TFR_CTL_CS_MANUAL;
|
||||
-
|
||||
sun6i_spi_write(sspi, SUN6I_TFR_CTL_REG, reg);
|
||||
|
||||
+
|
||||
/* Ensure that we have a parent clock fast enough */
|
||||
mclk_rate = clk_get_rate(sspi->mclk);
|
||||
if (mclk_rate < (2 * tfr->speed_hz)) {
|
||||
@@ -442,12 +461,24 @@ static int sun6i_spi_probe(struct platform_device *pdev)
|
||||
struct resource *res;
|
||||
int ret = 0, irq;
|
||||
|
||||
- master = spi_alloc_master(&pdev->dev, sizeof(struct sun6i_spi));
|
||||
+ master = spi_alloc_master(&pdev->dev, sizeof(*sspi));
|
||||
if (!master) {
|
||||
dev_err(&pdev->dev, "Unable to allocate SPI Master\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
+ master->max_speed_hz = SUN6I_SPI_MAX_SPEED_HZ;
|
||||
+ master->min_speed_hz = SUN6I_SPI_MIN_SPEED_HZ;
|
||||
+ master->num_chipselect = 4;
|
||||
+ master->mode_bits = SUN6I_SPI_MODE_BITS;
|
||||
+ master->bits_per_word_mask = SPI_BPW_MASK(8);
|
||||
+ master->set_cs = sun6i_spi_set_cs;
|
||||
+ master->prepare_message = sun6i_spi_prepare_message;
|
||||
+ master->transfer_one = sun6i_spi_transfer_one;
|
||||
+ master->max_transfer_size = sun6i_spi_max_transfer_size;
|
||||
+ master->dev.of_node = pdev->dev.of_node;
|
||||
+ master->auto_runtime_pm = true;
|
||||
+
|
||||
platform_set_drvdata(pdev, master);
|
||||
sspi = spi_master_get_devdata(master);
|
||||
|
||||
@@ -466,26 +497,14 @@ static int sun6i_spi_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
ret = devm_request_irq(&pdev->dev, irq, sun6i_spi_handler,
|
||||
- 0, "sun6i-spi", sspi);
|
||||
+ 0, dev_name(&pdev->dev), sspi);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "Cannot request IRQ\n");
|
||||
goto err_free_master;
|
||||
}
|
||||
|
||||
- sspi->master = master;
|
||||
sspi->fifo_depth = (unsigned long)of_device_get_match_data(&pdev->dev);
|
||||
|
||||
- master->max_speed_hz = 100 * 1000 * 1000;
|
||||
- master->min_speed_hz = 3 * 1000;
|
||||
- master->set_cs = sun6i_spi_set_cs;
|
||||
- master->transfer_one = sun6i_spi_transfer_one;
|
||||
- master->num_chipselect = 4;
|
||||
- master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LSB_FIRST;
|
||||
- master->bits_per_word_mask = SPI_BPW_MASK(8);
|
||||
- master->dev.of_node = pdev->dev.of_node;
|
||||
- master->auto_runtime_pm = true;
|
||||
- master->max_transfer_size = sun6i_spi_max_transfer_size;
|
||||
-
|
||||
sspi->hclk = devm_clk_get(&pdev->dev, "ahb");
|
||||
if (IS_ERR(sspi->hclk)) {
|
||||
dev_err(&pdev->dev, "Unable to acquire AHB clock\n");
|
||||
@@ -525,7 +544,7 @@ static int sun6i_spi_probe(struct platform_device *pdev)
|
||||
|
||||
ret = devm_spi_register_master(&pdev->dev, master);
|
||||
if (ret) {
|
||||
- dev_err(&pdev->dev, "cannot register SPI master\n");
|
||||
+ dev_err(&pdev->dev, "Couldn't register SPI master\n");
|
||||
goto err_pm_disable;
|
||||
}
|
||||
|
||||
@ -1,17 +0,0 @@
|
||||
diff --git a/drivers/spi/spi-sun6i.c b/drivers/spi/spi-sun6i.c
|
||||
index 88ad45e..78acc1f 100644
|
||||
--- a/drivers/spi/spi-sun6i.c
|
||||
+++ b/drivers/spi/spi-sun6i.c
|
||||
@@ -193,6 +193,12 @@ static void sun6i_spi_set_cs(struct spi_device *spi, bool enable)
|
||||
else
|
||||
reg &= ~SUN6I_TFR_CTL_CS_LEVEL;
|
||||
|
||||
+ /* Handle chip select "reverse" polarity */
|
||||
+ if (spi->mode & SPI_CS_HIGH)
|
||||
+ reg &= ~SUN6I_TFR_CTL_SPOL;
|
||||
+ else
|
||||
+ reg |= SUN6I_TFR_CTL_SPOL;
|
||||
+
|
||||
/* We want to control the chip select manually */
|
||||
reg |= SUN6I_TFR_CTL_CS_MANUAL;
|
||||
|
||||
@ -1,111 +0,0 @@
|
||||
diff --git a/drivers/spi/spi-sun6i.c b/drivers/spi/spi-sun6i.c
|
||||
index 78acc1f..4db1f20 100644
|
||||
--- a/drivers/spi/spi-sun6i.c
|
||||
+++ b/drivers/spi/spi-sun6i.c
|
||||
@@ -207,7 +207,10 @@ static void sun6i_spi_set_cs(struct spi_device *spi, bool enable)
|
||||
|
||||
static size_t sun6i_spi_max_transfer_size(struct spi_device *spi)
|
||||
{
|
||||
- return SUN6I_MAX_XFER_SIZE - 1;
|
||||
+ struct spi_master *master = spi->master;
|
||||
+ struct sun6i_spi *sspi = spi_master_get_devdata(master);
|
||||
+
|
||||
+ return sspi->fifo_depth;
|
||||
}
|
||||
|
||||
static int sun6i_spi_prepare_message(struct spi_master *master,
|
||||
@@ -250,13 +253,18 @@ static int sun6i_spi_transfer_one(struct spi_master *master,
|
||||
struct sun6i_spi *sspi = spi_master_get_devdata(master);
|
||||
unsigned int mclk_rate, div, timeout;
|
||||
unsigned int start, end, tx_time;
|
||||
- unsigned int trig_level;
|
||||
unsigned int tx_len = 0;
|
||||
int ret = 0;
|
||||
u32 reg;
|
||||
|
||||
- if (tfr->len > SUN6I_MAX_XFER_SIZE)
|
||||
- return -EINVAL;
|
||||
+ /* A zero length transfer never finishes if programmed
|
||||
+ in the hardware */
|
||||
+ if (!tfr->len)
|
||||
+ return 0;
|
||||
+
|
||||
+ /* Don't support transfer larger than the FIFO */
|
||||
+ if (tfr->len > sspi->fifo_depth)
|
||||
+ return -EMSGSIZE;
|
||||
|
||||
reinit_completion(&sspi->done);
|
||||
sspi->tx_buf = tfr->tx_buf;
|
||||
@@ -270,17 +278,6 @@ static int sun6i_spi_transfer_one(struct spi_master *master,
|
||||
sun6i_spi_write(sspi, SUN6I_FIFO_CTL_REG,
|
||||
SUN6I_FIFO_CTL_RF_RST | SUN6I_FIFO_CTL_TF_RST);
|
||||
|
||||
- /*
|
||||
- * Setup FIFO interrupt trigger level
|
||||
- * Here we choose 3/4 of the full fifo depth, as it's the hardcoded
|
||||
- * value used in old generation of Allwinner SPI controller.
|
||||
- * (See spi-sun4i.c)
|
||||
- */
|
||||
- trig_level = sspi->fifo_depth / 4 * 3;
|
||||
- sun6i_spi_write(sspi, SUN6I_FIFO_CTL_REG,
|
||||
- (trig_level << SUN6I_FIFO_CTL_RF_RDY_TRIG_LEVEL_BITS) |
|
||||
- (trig_level << SUN6I_FIFO_CTL_TF_ERQ_TRIG_LEVEL_BITS));
|
||||
-
|
||||
|
||||
reg = sun6i_spi_read(sspi, SUN6I_TFR_CTL_REG);
|
||||
/*
|
||||
@@ -342,12 +339,8 @@ static int sun6i_spi_transfer_one(struct spi_master *master,
|
||||
/* Fill the TX FIFO */
|
||||
sun6i_spi_fill_fifo(sspi, sspi->fifo_depth);
|
||||
|
||||
- /* Enable the interrupts */
|
||||
- sun6i_spi_write(sspi, SUN6I_INT_CTL_REG, SUN6I_INT_CTL_TC);
|
||||
- sun6i_spi_enable_interrupt(sspi, SUN6I_INT_CTL_TC |
|
||||
- SUN6I_INT_CTL_RF_RDY);
|
||||
- if (tx_len > sspi->fifo_depth)
|
||||
- sun6i_spi_enable_interrupt(sspi, SUN6I_INT_CTL_TF_ERQ);
|
||||
+ /* Enable transfer complete interrupt */
|
||||
+ sun6i_spi_enable_interrupt(sspi, SUN6I_INT_CTL_TC);
|
||||
|
||||
/* Start the transfer */
|
||||
reg = sun6i_spi_read(sspi, SUN6I_TFR_CTL_REG);
|
||||
@@ -376,7 +369,9 @@ out:
|
||||
static irqreturn_t sun6i_spi_handler(int irq, void *dev_id)
|
||||
{
|
||||
struct sun6i_spi *sspi = dev_id;
|
||||
- u32 status = sun6i_spi_read(sspi, SUN6I_INT_STA_REG);
|
||||
+ u32 status;
|
||||
+
|
||||
+ status = sun6i_spi_read(sspi, SUN6I_INT_STA_REG);
|
||||
|
||||
/* Transfer complete */
|
||||
if (status & SUN6I_INT_CTL_TC) {
|
||||
@@ -386,28 +381,6 @@ static irqreturn_t sun6i_spi_handler(int irq, void *dev_id)
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
- /* Receive FIFO 3/4 full */
|
||||
- if (status & SUN6I_INT_CTL_RF_RDY) {
|
||||
- sun6i_spi_drain_fifo(sspi, SUN6I_FIFO_DEPTH);
|
||||
- /* Only clear the interrupt _after_ draining the FIFO */
|
||||
- sun6i_spi_write(sspi, SUN6I_INT_STA_REG, SUN6I_INT_CTL_RF_RDY);
|
||||
- return IRQ_HANDLED;
|
||||
- }
|
||||
-
|
||||
- /* Transmit FIFO 3/4 empty */
|
||||
- if (status & SUN6I_INT_CTL_TF_ERQ) {
|
||||
- sun6i_spi_fill_fifo(sspi, SUN6I_FIFO_DEPTH);
|
||||
-
|
||||
- if (!sspi->len)
|
||||
- /* nothing left to transmit */
|
||||
- sun6i_spi_disable_interrupt(sspi, SUN6I_INT_CTL_TF_ERQ);
|
||||
-
|
||||
- /* Only clear the interrupt _after_ re-seeding the FIFO */
|
||||
- sun6i_spi_write(sspi, SUN6I_INT_STA_REG, SUN6I_INT_CTL_TF_ERQ);
|
||||
-
|
||||
- return IRQ_HANDLED;
|
||||
- }
|
||||
-
|
||||
return IRQ_NONE;
|
||||
}
|
||||
|
||||
@ -1,113 +0,0 @@
|
||||
diff --git a/drivers/spi/spi-sun6i.c b/drivers/spi/spi-sun6i.c
|
||||
index 4db1f20..210cef9 100644
|
||||
--- a/drivers/spi/spi-sun6i.c
|
||||
+++ b/drivers/spi/spi-sun6i.c
|
||||
@@ -99,8 +99,6 @@ struct sun6i_spi {
|
||||
struct clk *mclk;
|
||||
struct reset_control *rstc;
|
||||
|
||||
- struct completion done;
|
||||
-
|
||||
const u8 *tx_buf;
|
||||
u8 *rx_buf;
|
||||
int len;
|
||||
@@ -246,6 +244,30 @@ static int sun6i_spi_prepare_message(struct spi_master *master,
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int sun6i_spi_wait_for_transfer(struct spi_device *spi,
|
||||
+ struct spi_transfer *tfr)
|
||||
+{
|
||||
+ struct spi_master *master = spi->master;
|
||||
+ unsigned int start, end, tx_time;
|
||||
+ unsigned int timeout;
|
||||
+
|
||||
+ /* smart wait for completion */
|
||||
+ tx_time = max(tfr->len * 8 * 2 / (tfr->speed_hz / 1000), 100U);
|
||||
+ start = jiffies;
|
||||
+ timeout = wait_for_completion_timeout(&master->xfer_completion,
|
||||
+ msecs_to_jiffies(tx_time));
|
||||
+ end = jiffies;
|
||||
+ if (!timeout) {
|
||||
+ dev_warn(&master->dev,
|
||||
+ "%s: timeout transferring %u bytes@%iHz for %i(%i)ms",
|
||||
+ dev_name(&spi->dev), tfr->len, tfr->speed_hz,
|
||||
+ jiffies_to_msecs(end - start), tx_time);
|
||||
+ return -ETIMEDOUT;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static int sun6i_spi_transfer_one(struct spi_master *master,
|
||||
struct spi_device *spi,
|
||||
struct spi_transfer *tfr)
|
||||
@@ -266,7 +288,6 @@ static int sun6i_spi_transfer_one(struct spi_master *master,
|
||||
if (tfr->len > sspi->fifo_depth)
|
||||
return -EMSGSIZE;
|
||||
|
||||
- reinit_completion(&sspi->done);
|
||||
sspi->tx_buf = tfr->tx_buf;
|
||||
sspi->rx_buf = tfr->rx_buf;
|
||||
sspi->len = tfr->len;
|
||||
@@ -346,21 +367,9 @@ static int sun6i_spi_transfer_one(struct spi_master *master,
|
||||
reg = sun6i_spi_read(sspi, SUN6I_TFR_CTL_REG);
|
||||
sun6i_spi_write(sspi, SUN6I_TFR_CTL_REG, reg | SUN6I_TFR_CTL_XCH);
|
||||
|
||||
- tx_time = max(tfr->len * 8 * 2 / (tfr->speed_hz / 1000), 100U);
|
||||
- start = jiffies;
|
||||
- timeout = wait_for_completion_timeout(&sspi->done,
|
||||
- msecs_to_jiffies(tx_time));
|
||||
- end = jiffies;
|
||||
- if (!timeout) {
|
||||
- dev_warn(&master->dev,
|
||||
- "%s: timeout transferring %u bytes@%iHz for %i(%i)ms",
|
||||
- dev_name(&spi->dev), tfr->len, tfr->speed_hz,
|
||||
- jiffies_to_msecs(end - start), tx_time);
|
||||
- ret = -ETIMEDOUT;
|
||||
- goto out;
|
||||
- }
|
||||
+ /* Wait for completion */
|
||||
+ ret = sun6i_spi_wait_for_transfer(spi, tfr);
|
||||
|
||||
-out:
|
||||
sun6i_spi_write(sspi, SUN6I_INT_CTL_REG, 0);
|
||||
|
||||
return ret;
|
||||
@@ -368,7 +377,8 @@ out:
|
||||
|
||||
static irqreturn_t sun6i_spi_handler(int irq, void *dev_id)
|
||||
{
|
||||
- struct sun6i_spi *sspi = dev_id;
|
||||
+ struct spi_master *master = dev_id;
|
||||
+ struct sun6i_spi *sspi = spi_master_get_devdata(master);
|
||||
u32 status;
|
||||
|
||||
status = sun6i_spi_read(sspi, SUN6I_INT_STA_REG);
|
||||
@@ -377,7 +387,7 @@ static irqreturn_t sun6i_spi_handler(int irq, void *dev_id)
|
||||
if (status & SUN6I_INT_CTL_TC) {
|
||||
sun6i_spi_write(sspi, SUN6I_INT_STA_REG, SUN6I_INT_CTL_TC);
|
||||
sun6i_spi_drain_fifo(sspi, sspi->fifo_depth);
|
||||
- complete(&sspi->done);
|
||||
+ spi_finalize_current_transfer(master);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
@@ -476,7 +486,7 @@ static int sun6i_spi_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
ret = devm_request_irq(&pdev->dev, irq, sun6i_spi_handler,
|
||||
- 0, dev_name(&pdev->dev), sspi);
|
||||
+ 0, dev_name(&pdev->dev), master);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "Cannot request IRQ\n");
|
||||
goto err_free_master;
|
||||
@@ -498,8 +508,6 @@ static int sun6i_spi_probe(struct platform_device *pdev)
|
||||
goto err_free_master;
|
||||
}
|
||||
|
||||
- init_completion(&sspi->done);
|
||||
-
|
||||
sspi->rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL);
|
||||
if (IS_ERR(sspi->rstc)) {
|
||||
dev_err(&pdev->dev, "Couldn't get reset controller\n");
|
||||
@ -1,82 +0,0 @@
|
||||
diff --git a/drivers/spi/spi-sun6i.c b/drivers/spi/spi-sun6i.c
|
||||
index 210cef9..18f9344 100644
|
||||
--- a/drivers/spi/spi-sun6i.c
|
||||
+++ b/drivers/spi/spi-sun6i.c
|
||||
@@ -115,29 +115,29 @@ static inline void sun6i_spi_write(struct sun6i_spi *sspi, u32 reg, u32 value)
|
||||
writel(value, sspi->base_addr + reg);
|
||||
}
|
||||
|
||||
-static inline u32 sun6i_spi_get_tx_fifo_count(struct sun6i_spi *sspi)
|
||||
+static inline void sun6i_spi_set(struct sun6i_spi *sspi, u32 addr, u32 val)
|
||||
{
|
||||
- u32 reg = sun6i_spi_read(sspi, SUN6I_FIFO_STA_REG);
|
||||
-
|
||||
- reg >>= SUN6I_FIFO_STA_TF_CNT_BITS;
|
||||
+ u32 reg = sun6i_spi_read(sspi, addr);
|
||||
|
||||
- return reg & SUN6I_FIFO_STA_TF_CNT_MASK;
|
||||
+ reg |= val;
|
||||
+ sun6i_spi_write(sspi, addr, reg);
|
||||
}
|
||||
|
||||
-static inline void sun6i_spi_enable_interrupt(struct sun6i_spi *sspi, u32 mask)
|
||||
+static inline void sun6i_spi_unset(struct sun6i_spi *sspi, u32 addr, u32 val)
|
||||
{
|
||||
- u32 reg = sun6i_spi_read(sspi, SUN6I_INT_CTL_REG);
|
||||
+ u32 reg = sun6i_spi_read(sspi, addr);
|
||||
|
||||
- reg |= mask;
|
||||
- sun6i_spi_write(sspi, SUN6I_INT_CTL_REG, reg);
|
||||
+ reg &= ~val;
|
||||
+ sun6i_spi_write(sspi, addr, reg);
|
||||
}
|
||||
|
||||
-static inline void sun6i_spi_disable_interrupt(struct sun6i_spi *sspi, u32 mask)
|
||||
+static inline u32 sun6i_spi_get_tx_fifo_count(struct sun6i_spi *sspi)
|
||||
{
|
||||
- u32 reg = sun6i_spi_read(sspi, SUN6I_INT_CTL_REG);
|
||||
+ u32 reg = sun6i_spi_read(sspi, SUN6I_FIFO_STA_REG);
|
||||
|
||||
- reg &= ~mask;
|
||||
- sun6i_spi_write(sspi, SUN6I_INT_CTL_REG, reg);
|
||||
+ reg >>= SUN6I_FIFO_STA_TF_CNT_BITS;
|
||||
+
|
||||
+ return reg & SUN6I_FIFO_STA_TF_CNT_MASK;
|
||||
}
|
||||
|
||||
static inline void sun6i_spi_drain_fifo(struct sun6i_spi *sspi, int len)
|
||||
@@ -299,18 +299,14 @@ static int sun6i_spi_transfer_one(struct spi_master *master,
|
||||
sun6i_spi_write(sspi, SUN6I_FIFO_CTL_REG,
|
||||
SUN6I_FIFO_CTL_RF_RST | SUN6I_FIFO_CTL_TF_RST);
|
||||
|
||||
-
|
||||
- reg = sun6i_spi_read(sspi, SUN6I_TFR_CTL_REG);
|
||||
/*
|
||||
* If it's a TX only transfer, we don't want to fill the RX
|
||||
* FIFO with bogus data
|
||||
*/
|
||||
if (sspi->rx_buf)
|
||||
- reg &= ~SUN6I_TFR_CTL_DHB;
|
||||
+ sun6i_spi_unset(sspi, SUN6I_TFR_CTL_REG, SUN6I_TFR_CTL_DHB);
|
||||
else
|
||||
- reg |= SUN6I_TFR_CTL_DHB;
|
||||
-
|
||||
- sun6i_spi_write(sspi, SUN6I_TFR_CTL_REG, reg);
|
||||
+ sun6i_spi_set(sspi, SUN6I_TFR_CTL_REG, SUN6I_TFR_CTL_DHB);
|
||||
|
||||
|
||||
/* Ensure that we have a parent clock fast enough */
|
||||
@@ -361,11 +357,10 @@ static int sun6i_spi_transfer_one(struct spi_master *master,
|
||||
sun6i_spi_fill_fifo(sspi, sspi->fifo_depth);
|
||||
|
||||
/* Enable transfer complete interrupt */
|
||||
- sun6i_spi_enable_interrupt(sspi, SUN6I_INT_CTL_TC);
|
||||
+ sun6i_spi_set(sspi, SUN6I_INT_CTL_REG, SUN6I_INT_CTL_TC);
|
||||
|
||||
/* Start the transfer */
|
||||
- reg = sun6i_spi_read(sspi, SUN6I_TFR_CTL_REG);
|
||||
- sun6i_spi_write(sspi, SUN6I_TFR_CTL_REG, reg | SUN6I_TFR_CTL_XCH);
|
||||
+ sun6i_spi_set(sspi, SUN6I_TFR_CTL_REG, SUN6I_TFR_CTL_XCH);
|
||||
|
||||
/* Wait for completion */
|
||||
ret = sun6i_spi_wait_for_transfer(spi, tfr);
|
||||
@ -1,390 +0,0 @@
|
||||
diff --git a/drivers/spi/spi-sun6i.c b/drivers/spi/spi-sun6i.c
|
||||
index 18f9344..5665c84 100644
|
||||
--- a/drivers/spi/spi-sun6i.c
|
||||
+++ b/drivers/spi/spi-sun6i.c
|
||||
@@ -14,6 +14,8 @@
|
||||
#include <linux/clk.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/device.h>
|
||||
+#include <linux/dmaengine.h>
|
||||
+#include <linux/dma-mapping.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/module.h>
|
||||
@@ -55,11 +57,14 @@
|
||||
|
||||
#define SUN6I_FIFO_CTL_REG 0x18
|
||||
#define SUN6I_FIFO_CTL_RF_RDY_TRIG_LEVEL_MASK 0xff
|
||||
-#define SUN6I_FIFO_CTL_RF_RDY_TRIG_LEVEL_BITS 0
|
||||
+#define SUN6I_FIFO_CTL_RF_RDY_TRIG_LEVEL_POS 0
|
||||
+#define SUN6I_FIFO_CTL_RF_DRQ_EN BIT(8)
|
||||
#define SUN6I_FIFO_CTL_RF_RST BIT(15)
|
||||
#define SUN6I_FIFO_CTL_TF_ERQ_TRIG_LEVEL_MASK 0xff
|
||||
-#define SUN6I_FIFO_CTL_TF_ERQ_TRIG_LEVEL_BITS 16
|
||||
+#define SUN6I_FIFO_CTL_TF_ERQ_TRIG_LEVEL_POS 16
|
||||
+#define SUN6I_FIFO_CTL_TF_DRQ_EN BIT(24)
|
||||
#define SUN6I_FIFO_CTL_TF_RST BIT(31)
|
||||
+#define SUN6I_FIFO_CTL_DMA_DEDICATE BIT(9)|BIT(25)
|
||||
|
||||
#define SUN6I_FIFO_STA_REG 0x1c
|
||||
#define SUN6I_FIFO_STA_RF_CNT_MASK 0x7f
|
||||
@@ -177,6 +182,15 @@ static inline void sun6i_spi_fill_fifo(struct sun6i_spi *sspi, int len)
|
||||
}
|
||||
}
|
||||
|
||||
+static bool sun6i_spi_can_dma(struct spi_master *master,
|
||||
+ struct spi_device *spi,
|
||||
+ struct spi_transfer *tfr)
|
||||
+{
|
||||
+ struct sun6i_spi *sspi = spi_master_get_devdata(master);
|
||||
+
|
||||
+ return tfr->len > sspi->fifo_depth;
|
||||
+}
|
||||
+
|
||||
static void sun6i_spi_set_cs(struct spi_device *spi, bool enable)
|
||||
{
|
||||
struct sun6i_spi *sspi = spi_master_get_devdata(spi->master);
|
||||
@@ -208,6 +222,9 @@ static size_t sun6i_spi_max_transfer_size(struct spi_device *spi)
|
||||
struct spi_master *master = spi->master;
|
||||
struct sun6i_spi *sspi = spi_master_get_devdata(master);
|
||||
|
||||
+ if (master->can_dma)
|
||||
+ return SUN6I_MAX_XFER_SIZE;
|
||||
+
|
||||
return sspi->fifo_depth;
|
||||
}
|
||||
|
||||
@@ -268,15 +285,174 @@ static int sun6i_spi_wait_for_transfer(struct spi_device *spi,
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static void sun6i_spi_dma_callback(void *param)
|
||||
+{
|
||||
+ struct spi_master *master = param;
|
||||
+
|
||||
+ dev_dbg(&master->dev, "DMA transfer complete\n");
|
||||
+ spi_finalize_current_transfer(master);
|
||||
+}
|
||||
+
|
||||
+static int sun6i_spi_dmap_prep_tx(struct spi_master *master,
|
||||
+ struct spi_transfer *tfr,
|
||||
+ dma_cookie_t *cookie)
|
||||
+{
|
||||
+ struct dma_async_tx_descriptor *chan_desc = NULL;
|
||||
+
|
||||
+ chan_desc = dmaengine_prep_slave_sg(master->dma_tx,
|
||||
+ tfr->tx_sg.sgl, tfr->tx_sg.nents,
|
||||
+ DMA_TO_DEVICE,
|
||||
+ DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
|
||||
+ if (!chan_desc) {
|
||||
+ dev_err(&master->dev,
|
||||
+ "Couldn't prepare TX DMA slave\n");
|
||||
+ return -EIO;
|
||||
+ }
|
||||
+
|
||||
+ chan_desc->callback = sun6i_spi_dma_callback;
|
||||
+ chan_desc->callback_param = master;
|
||||
+
|
||||
+ *cookie = dmaengine_submit(chan_desc);
|
||||
+ dma_async_issue_pending(master->dma_tx);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int sun6i_spi_dmap_prep_rx(struct spi_master *master,
|
||||
+ struct spi_transfer *tfr,
|
||||
+ dma_cookie_t *cookie)
|
||||
+{
|
||||
+ struct dma_async_tx_descriptor *chan_desc = NULL;
|
||||
+
|
||||
+ chan_desc = dmaengine_prep_slave_sg(master->dma_rx,
|
||||
+ tfr->rx_sg.sgl, tfr->rx_sg.nents,
|
||||
+ DMA_FROM_DEVICE,
|
||||
+ DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
|
||||
+ if (!chan_desc) {
|
||||
+ dev_err(&master->dev,
|
||||
+ "Couldn't prepare RX DMA slave\n");
|
||||
+ return -EIO;
|
||||
+ }
|
||||
+
|
||||
+ chan_desc->callback = sun6i_spi_dma_callback;
|
||||
+ chan_desc->callback_param = master;
|
||||
+
|
||||
+ *cookie = dmaengine_submit(chan_desc);
|
||||
+ dma_async_issue_pending(master->dma_rx);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int sun6i_spi_transfer_one_dma(struct spi_device *spi,
|
||||
+ struct spi_transfer *tfr)
|
||||
+{
|
||||
+ struct spi_master *master = spi->master;
|
||||
+ struct sun6i_spi *sspi = spi_master_get_devdata(master);
|
||||
+ dma_cookie_t tx_cookie = 0,rx_cookie = 0;
|
||||
+ enum dma_status status;
|
||||
+ int ret;
|
||||
+ u32 reg, trig_level = 0;
|
||||
+
|
||||
+ dev_dbg(&master->dev, "Using DMA mode for transfer\n");
|
||||
+
|
||||
+ reg = sun6i_spi_read(sspi, SUN6I_FIFO_CTL_REG);
|
||||
+
|
||||
+ if (sspi->tx_buf) {
|
||||
+ ret = sun6i_spi_dmap_prep_tx(master, tfr, &tx_cookie);
|
||||
+ if (ret)
|
||||
+ goto out;
|
||||
+
|
||||
+ reg |= SUN6I_FIFO_CTL_TF_DRQ_EN;
|
||||
+
|
||||
+ trig_level = sspi->fifo_depth;
|
||||
+ reg &= ~SUN6I_FIFO_CTL_TF_ERQ_TRIG_LEVEL_MASK;
|
||||
+ reg |= (trig_level << SUN6I_FIFO_CTL_TF_ERQ_TRIG_LEVEL_POS);
|
||||
+ }
|
||||
+
|
||||
+ if (sspi->rx_buf) {
|
||||
+ ret = sun6i_spi_dmap_prep_rx(master, tfr, &rx_cookie);
|
||||
+ if (ret)
|
||||
+ goto out;
|
||||
+
|
||||
+ reg |= SUN6I_FIFO_CTL_RF_DRQ_EN;
|
||||
+
|
||||
+ trig_level = 1;
|
||||
+ reg &= ~SUN6I_FIFO_CTL_RF_RDY_TRIG_LEVEL_MASK;
|
||||
+ reg |= (trig_level << SUN6I_FIFO_CTL_RF_RDY_TRIG_LEVEL_POS);
|
||||
+ }
|
||||
+
|
||||
+ /* Enable Dedicated DMA requests */
|
||||
+ sun6i_spi_write(sspi, SUN6I_FIFO_CTL_REG,
|
||||
+ reg | SUN6I_FIFO_CTL_DMA_DEDICATE);
|
||||
+
|
||||
+ /* Start transfer */
|
||||
+ sun6i_spi_set(sspi, SUN6I_TFR_CTL_REG, SUN6I_TFR_CTL_XCH);
|
||||
+
|
||||
+ ret = sun6i_spi_wait_for_transfer(spi, tfr);
|
||||
+ if (ret)
|
||||
+ goto out;
|
||||
+
|
||||
+ if (sspi->tx_buf && (status = dma_async_is_tx_complete(master->dma_tx,
|
||||
+ tx_cookie, NULL, NULL))) {
|
||||
+ dev_warn(&master->dev,
|
||||
+ "DMA returned completion status of: %s\n",
|
||||
+ status == DMA_ERROR ? "error" : "in progress");
|
||||
+ }
|
||||
+ if (sspi->rx_buf && (status = dma_async_is_tx_complete(master->dma_rx,
|
||||
+ rx_cookie, NULL, NULL))) {
|
||||
+ dev_warn(&master->dev,
|
||||
+ "DMA returned completion status of: %s\n",
|
||||
+ status == DMA_ERROR ? "error" : "in progress");
|
||||
+ }
|
||||
+
|
||||
+out:
|
||||
+ if (ret) {
|
||||
+ dev_dbg(&master->dev, "DMA channel teardown\n");
|
||||
+ if (sspi->tx_buf)
|
||||
+ dmaengine_terminate_sync(master->dma_tx);
|
||||
+ if (sspi->rx_buf)
|
||||
+ dmaengine_terminate_sync(master->dma_rx);
|
||||
+ }
|
||||
+
|
||||
+ sun6i_spi_drain_fifo(sspi, sspi->fifo_depth);
|
||||
+
|
||||
+ sun6i_spi_write(sspi, SUN6I_INT_CTL_REG, 0);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int sun6i_spi_transfer_one_pio(struct spi_device *spi,
|
||||
+ struct spi_transfer *tfr)
|
||||
+{
|
||||
+ struct spi_master *master = spi->master;
|
||||
+ struct sun6i_spi *sspi = spi_master_get_devdata(master);
|
||||
+ int ret;
|
||||
+
|
||||
+ /* Disable DMA requests */
|
||||
+ sun6i_spi_write(sspi, SUN6I_FIFO_CTL_REG, 0);
|
||||
+
|
||||
+ sun6i_spi_fill_fifo(sspi, sspi->fifo_depth);
|
||||
+
|
||||
+ /* Enable transfer complete IRQ */
|
||||
+ sun6i_spi_set(sspi, SUN6I_INT_CTL_REG, SUN6I_INT_CTL_TC);
|
||||
+
|
||||
+ /* Start transfer */
|
||||
+ sun6i_spi_set(sspi, SUN6I_TFR_CTL_REG, SUN6I_TFR_CTL_XCH);
|
||||
+
|
||||
+ ret = sun6i_spi_wait_for_transfer(spi, tfr);
|
||||
+
|
||||
+ sun6i_spi_write(sspi, SUN6I_INT_CTL_REG, 0);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
static int sun6i_spi_transfer_one(struct spi_master *master,
|
||||
struct spi_device *spi,
|
||||
struct spi_transfer *tfr)
|
||||
{
|
||||
struct sun6i_spi *sspi = spi_master_get_devdata(master);
|
||||
- unsigned int mclk_rate, div, timeout;
|
||||
- unsigned int start, end, tx_time;
|
||||
+ unsigned int mclk_rate, div;
|
||||
unsigned int tx_len = 0;
|
||||
- int ret = 0;
|
||||
u32 reg;
|
||||
|
||||
/* A zero length transfer never finishes if programmed
|
||||
@@ -284,10 +460,15 @@ static int sun6i_spi_transfer_one(struct spi_master *master,
|
||||
if (!tfr->len)
|
||||
return 0;
|
||||
|
||||
- /* Don't support transfer larger than the FIFO */
|
||||
- if (tfr->len > sspi->fifo_depth)
|
||||
+ if (tfr->len > SUN6I_MAX_XFER_SIZE)
|
||||
return -EMSGSIZE;
|
||||
|
||||
+ if (!master->can_dma) {
|
||||
+ /* Don't support transfer larger than the FIFO */
|
||||
+ if (tfr->len > sspi->fifo_depth)
|
||||
+ return -EMSGSIZE;
|
||||
+ }
|
||||
+
|
||||
sspi->tx_buf = tfr->tx_buf;
|
||||
sspi->rx_buf = tfr->rx_buf;
|
||||
sspi->len = tfr->len;
|
||||
@@ -353,21 +534,10 @@ static int sun6i_spi_transfer_one(struct spi_master *master,
|
||||
sun6i_spi_write(sspi, SUN6I_BURST_CTL_CNT_REG,
|
||||
SUN6I_BURST_CTL_CNT_STC(tx_len));
|
||||
|
||||
- /* Fill the TX FIFO */
|
||||
- sun6i_spi_fill_fifo(sspi, sspi->fifo_depth);
|
||||
-
|
||||
- /* Enable transfer complete interrupt */
|
||||
- sun6i_spi_set(sspi, SUN6I_INT_CTL_REG, SUN6I_INT_CTL_TC);
|
||||
-
|
||||
- /* Start the transfer */
|
||||
- sun6i_spi_set(sspi, SUN6I_TFR_CTL_REG, SUN6I_TFR_CTL_XCH);
|
||||
-
|
||||
- /* Wait for completion */
|
||||
- ret = sun6i_spi_wait_for_transfer(spi, tfr);
|
||||
-
|
||||
- sun6i_spi_write(sspi, SUN6I_INT_CTL_REG, 0);
|
||||
+ if (sun6i_spi_can_dma(master, spi, tfr))
|
||||
+ return sun6i_spi_transfer_one_dma(spi, tfr);
|
||||
|
||||
- return ret;
|
||||
+ return sun6i_spi_transfer_one_pio(spi, tfr);
|
||||
}
|
||||
|
||||
static irqreturn_t sun6i_spi_handler(int irq, void *dev_id)
|
||||
@@ -389,6 +559,76 @@ static irqreturn_t sun6i_spi_handler(int irq, void *dev_id)
|
||||
return IRQ_NONE;
|
||||
}
|
||||
|
||||
+static int sun6i_spi_dma_setup(struct platform_device *pdev,
|
||||
+ struct resource *res)
|
||||
+{
|
||||
+ struct spi_master *master = platform_get_drvdata(pdev);
|
||||
+ struct dma_slave_config dma_sconf;
|
||||
+ int ret;
|
||||
+
|
||||
+ master->dma_tx = dma_request_slave_channel_reason(&pdev->dev, "tx");
|
||||
+ if (IS_ERR(master->dma_tx)) {
|
||||
+ dev_err(&pdev->dev, "Unable to acquire DMA TX channel\n");
|
||||
+ ret = PTR_ERR(master->dma_tx);
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ dma_sconf.direction = DMA_MEM_TO_DEV;
|
||||
+ dma_sconf.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
|
||||
+ dma_sconf.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
|
||||
+ dma_sconf.dst_addr = res->start + SUN6I_TXDATA_REG;
|
||||
+ dma_sconf.src_maxburst = 1;
|
||||
+ dma_sconf.dst_maxburst = 1;
|
||||
+
|
||||
+ ret = dmaengine_slave_config(master->dma_tx, &dma_sconf);
|
||||
+ if (ret) {
|
||||
+ dev_err(&pdev->dev, "Unable to configure DMA TX slave\n");
|
||||
+ goto err_rel_tx;
|
||||
+ }
|
||||
+
|
||||
+ master->dma_rx = dma_request_slave_channel_reason(&pdev->dev, "rx");
|
||||
+ if (IS_ERR(master->dma_rx)) {
|
||||
+ dev_err(&pdev->dev, "Unable to acquire DMA RX channel\n");
|
||||
+ ret = PTR_ERR(master->dma_rx);
|
||||
+ goto err_rel_tx;
|
||||
+ }
|
||||
+
|
||||
+ dma_sconf.direction = DMA_DEV_TO_MEM;
|
||||
+ dma_sconf.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
|
||||
+ dma_sconf.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
|
||||
+ dma_sconf.src_addr = res->start + SUN6I_RXDATA_REG;
|
||||
+ dma_sconf.src_maxburst = 1;
|
||||
+ dma_sconf.dst_maxburst = 1;
|
||||
+
|
||||
+ ret = dmaengine_slave_config(master->dma_rx, &dma_sconf);
|
||||
+ if (ret) {
|
||||
+ dev_err(&pdev->dev, "Unable to configure DMA RX slave\n");
|
||||
+ goto err_rel_rx;
|
||||
+ }
|
||||
+
|
||||
+ /* don't set can_dma unless both channels are valid*/
|
||||
+ master->can_dma = sun6i_spi_can_dma;
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+err_rel_rx:
|
||||
+ dma_release_channel(master->dma_rx);
|
||||
+err_rel_tx:
|
||||
+ dma_release_channel(master->dma_tx);
|
||||
+out:
|
||||
+ master->dma_tx = NULL;
|
||||
+ master->dma_rx = NULL;
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static void sun6i_spi_dma_release(struct spi_master *master)
|
||||
+{
|
||||
+ if (master->can_dma) {
|
||||
+ dma_release_channel(master->dma_rx);
|
||||
+ dma_release_channel(master->dma_tx);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static int sun6i_spi_runtime_resume(struct device *dev)
|
||||
{
|
||||
struct spi_master *master = dev_get_drvdata(dev);
|
||||
@@ -510,6 +750,15 @@ static int sun6i_spi_probe(struct platform_device *pdev)
|
||||
goto err_free_master;
|
||||
}
|
||||
|
||||
+ ret = sun6i_spi_dma_setup(pdev, res);
|
||||
+ if (ret) {
|
||||
+ if (ret == -EPROBE_DEFER) {
|
||||
+ /* wait for the dma driver to load */
|
||||
+ goto err_free_master;
|
||||
+ }
|
||||
+ dev_warn(&pdev->dev, "DMA transfer not supported\n");
|
||||
+ }
|
||||
+
|
||||
/*
|
||||
* This wake-up/shutdown pattern is to be able to have the
|
||||
* device woken up, even if runtime_pm is disabled
|
||||
@@ -536,14 +785,19 @@ err_pm_disable:
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
sun6i_spi_runtime_suspend(&pdev->dev);
|
||||
err_free_master:
|
||||
+ sun6i_spi_dma_release(master);
|
||||
spi_master_put(master);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int sun6i_spi_remove(struct platform_device *pdev)
|
||||
{
|
||||
+ struct spi_master *master = platform_get_drvdata(pdev);
|
||||
+
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
|
||||
+ sun6i_spi_dma_release(master);
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1,55 +0,0 @@
|
||||
From 3b489a63e4e05489411a032cb60d8939a81f14b7 Mon Sep 17 00:00:00 2001
|
||||
From: vincent <vbusoenseirb@gmail.com>
|
||||
Date: Tue, 5 Nov 2019 18:53:47 +0100
|
||||
Subject: [PATCH] added SPI DMA declaration in device tree and bigger tx_buf
|
||||
size in fbtft (1 byte more to support start byte)
|
||||
|
||||
---
|
||||
arch/arm/boot/dts/sun8i-v3s-funkey.dts | 3 ++-
|
||||
arch/arm/boot/dts/sun8i-v3s.dtsi | 2 ++
|
||||
drivers/staging/fbtft/fbtft-core.c | 2 +-
|
||||
3 files changed, 5 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/arch/arm/boot/dts/sun8i-v3s-funkey.dts b/arch/arm/boot/dts/sun8i-v3s-funkey.dts
|
||||
index 78f4d6a..19062fc 100644
|
||||
--- a/arch/arm/boot/dts/sun8i-v3s-funkey.dts
|
||||
+++ b/arch/arm/boot/dts/sun8i-v3s-funkey.dts
|
||||
@@ -176,7 +176,8 @@
|
||||
compatible = "sitronix,st7789v";
|
||||
reg = <0>;
|
||||
spi-max-frequency = <50000000>;
|
||||
- txbuflen = <115200>;
|
||||
+ txbuflen = <115202>;
|
||||
+// txbuflen = <0>;
|
||||
rotate = <0>;
|
||||
fps = <50>;
|
||||
buswidth = <8>;
|
||||
diff --git a/arch/arm/boot/dts/sun8i-v3s.dtsi b/arch/arm/boot/dts/sun8i-v3s.dtsi
|
||||
index 02f6c84..f5ca5a5 100644
|
||||
--- a/arch/arm/boot/dts/sun8i-v3s.dtsi
|
||||
+++ b/arch/arm/boot/dts/sun8i-v3s.dtsi
|
||||
@@ -539,6 +539,8 @@
|
||||
interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&ccu CLK_BUS_SPI0>, <&ccu CLK_SPI0>;
|
||||
clock-names = "ahb", "mod";
|
||||
+ dmas = <&dma 23>, <&dma 23>;
|
||||
+ dma-names = "rx", "tx";
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&spi0_pins>;
|
||||
resets = <&ccu RST_BUS_SPI0>;
|
||||
diff --git a/drivers/staging/fbtft/fbtft-core.c b/drivers/staging/fbtft/fbtft-core.c
|
||||
index 7fbf92e..7dce967 100755
|
||||
--- a/drivers/staging/fbtft/fbtft-core.c
|
||||
+++ b/drivers/staging/fbtft/fbtft-core.c
|
||||
@@ -840,7 +840,7 @@ struct fb_info *fbtft_framebuffer_alloc(struct fbtft_display *display,
|
||||
/* Transmit buffer */
|
||||
if (txbuflen == -1)
|
||||
txbuflen = vmem_size + 2; /* add in case startbyte is used */
|
||||
- if (txbuflen >= vmem_size + 2)
|
||||
+ if (txbuflen > vmem_size + 2)
|
||||
txbuflen = 0;
|
||||
|
||||
#ifdef __LITTLE_ENDIAN
|
||||
--
|
||||
1.9.1
|
||||
|
||||
@ -1,27 +0,0 @@
|
||||
From ff9cbaaeb217a6cf2e2fffde614abfdfb3f6cf5d Mon Sep 17 00:00:00 2001
|
||||
From: vincent <vbusoenseirb@gmail.com>
|
||||
Date: Tue, 19 Nov 2019 14:02:56 +0100
|
||||
Subject: [PATCH] changed st7789v gamma
|
||||
|
||||
---
|
||||
drivers/staging/fbtft/fb_st7789v.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/drivers/staging/fbtft/fb_st7789v.c b/drivers/staging/fbtft/fb_st7789v.c
|
||||
index 00756de..212836f 100755
|
||||
--- a/drivers/staging/fbtft/fb_st7789v.c
|
||||
+++ b/drivers/staging/fbtft/fb_st7789v.c
|
||||
@@ -26,8 +26,8 @@
|
||||
#define DRVNAME "fb_st7789v"
|
||||
|
||||
#define DEFAULT_GAMMA \
|
||||
- "70 2C 2E 15 10 09 48 33 53 0B 19 18 20 25\n" \
|
||||
- "70 2C 2E 15 10 09 48 33 53 0B 19 18 20 25"
|
||||
+ "f0 19 1e 0A 09 15 3D 44 51 19 14 13 2c 31\n" \
|
||||
+ "f0 18 1E 0A 09 25 3F 43 52 19 14 13 2c 31"
|
||||
|
||||
/**
|
||||
* enum st7789v_command - ST7789V display controller commands
|
||||
--
|
||||
1.9.1
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,851 +0,0 @@
|
||||
From 71fc9be7b624c13355d37fa85162ba4f24e5d248 Mon Sep 17 00:00:00 2001
|
||||
From: vincent <vbusoenseirb@gmail.com>
|
||||
Date: Thu, 26 Dec 2019 17:29:03 +0100
|
||||
Subject: [PATCH] added fbtft boot logo, soft rotate and fixed soft tearing
|
||||
issue
|
||||
|
||||
---
|
||||
arch/arm/boot/dts/sun8i-v3s-funkey.dts | 3 +-
|
||||
drivers/staging/fbtft/fb_st7789v.c | 5 +-
|
||||
drivers/staging/fbtft/fb_text.c | 59 ++++++++
|
||||
drivers/staging/fbtft/fb_text.h | 2 +-
|
||||
drivers/staging/fbtft/fbtft-bus.c | 256 ++++++++++++++++++++++++++++-----
|
||||
drivers/staging/fbtft/fbtft-core.c | 148 +++++++++++++++----
|
||||
drivers/staging/fbtft/fbtft-io.c | 5 +-
|
||||
drivers/staging/fbtft/fbtft-sysfs.c | 31 ++++
|
||||
drivers/staging/fbtft/fbtft.h | 16 ++-
|
||||
9 files changed, 452 insertions(+), 73 deletions(-)
|
||||
|
||||
diff --git a/arch/arm/boot/dts/sun8i-v3s-funkey.dts b/arch/arm/boot/dts/sun8i-v3s-funkey.dts
|
||||
index 88f1c0f..d25521c 100644
|
||||
--- a/arch/arm/boot/dts/sun8i-v3s-funkey.dts
|
||||
+++ b/arch/arm/boot/dts/sun8i-v3s-funkey.dts
|
||||
@@ -179,8 +179,9 @@
|
||||
txbuflen = <115202>;
|
||||
// txbuflen = <0>;
|
||||
spi_async_mode = "true";
|
||||
+ //interlacing = "true";
|
||||
rotate = <0>;
|
||||
- rotate_soft = <0>;
|
||||
+ rotate_soft = <270>;
|
||||
fps = <100>;
|
||||
buswidth = <8>;
|
||||
reset-gpios = <&pio 4 1 GPIO_ACTIVE_LOW>; //PE1
|
||||
diff --git a/drivers/staging/fbtft/fb_st7789v.c b/drivers/staging/fbtft/fb_st7789v.c
|
||||
index ba21ab5..e2c9078 100755
|
||||
--- a/drivers/staging/fbtft/fb_st7789v.c
|
||||
+++ b/drivers/staging/fbtft/fb_st7789v.c
|
||||
@@ -157,12 +157,15 @@ static int init_display(struct fbtft_par *par)
|
||||
//write_reg(par, 0xC6,0x1F); //39Hz
|
||||
//write_reg(par, 0xC6,0x1A); //44Hz
|
||||
//write_reg(par, 0xC6,0x17); //48Hz
|
||||
+ //write_reg(par, 0xC6,0x16); //49Hz
|
||||
//write_reg(par, 0xC6,0x15); //50Hz
|
||||
+ //write_reg(par, 0xC6,0x14); //52Hz
|
||||
//write_reg(par, 0xC6,0x12); //55Hz
|
||||
//write_reg(par, 0xC6,0x10); //58Hz
|
||||
//write_reg(par, 0xC6,0x0F); //60Hz
|
||||
- write_reg(par, 0xC6,0x09); //60Hz
|
||||
+ //write_reg(par, 0xC6,0x09); //60Hz
|
||||
//write_reg(par, 0xC6,0x03); //99Hz
|
||||
+ write_reg(par, 0xC6,0x02); //105Hz
|
||||
|
||||
write_reg(par, MIPI_DCS_SET_DISPLAY_ON);
|
||||
|
||||
diff --git a/drivers/staging/fbtft/fb_text.c b/drivers/staging/fbtft/fb_text.c
|
||||
index 9f873b5..650535d 100644
|
||||
--- a/drivers/staging/fbtft/fb_text.c
|
||||
+++ b/drivers/staging/fbtft/fb_text.c
|
||||
@@ -4,6 +4,38 @@
|
||||
#define MIN(a,b) (((a)<(b))?(a):(b))
|
||||
#define MAX(a,b) (((a)>(b))?(a):(b))
|
||||
|
||||
+#define LOW_BATTERY_ICON_TOP_LEFT_X 10
|
||||
+#define LOW_BATTERY_ICON_TOP_LEFT_Y 10
|
||||
+#define LOW_BATTERY_ICON_WIDTH 35
|
||||
+#define LOW_BATTERY_ICON_HEIGHT 20
|
||||
+//#define LOW_BATTERY_FORE_COLOR 65535
|
||||
+#define LOW_BATTERY_FORE_COLOR 0xF800
|
||||
+#define LOW_BATTERY_BACK_COLOR 0
|
||||
+
|
||||
+
|
||||
+// Battery icon from: https://github.com/martinohanlon/grrl-bat-monitor
|
||||
+static u16 lowBatteryIcon [LOW_BATTERY_ICON_HEIGHT][LOW_BATTERY_ICON_WIDTH] = {
|
||||
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
+ {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0},
|
||||
+ {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0},
|
||||
+ {0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0},
|
||||
+ {0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0},
|
||||
+ {0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0},
|
||||
+ {0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0},
|
||||
+ {0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0},
|
||||
+ {0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0},
|
||||
+ {0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0},
|
||||
+ {0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0},
|
||||
+ {0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0},
|
||||
+ {0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0},
|
||||
+ {0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0},
|
||||
+ {0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0},
|
||||
+ {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0},
|
||||
+ {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0},
|
||||
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};
|
||||
+
|
||||
|
||||
|
||||
static u8 monaco_font[] = {
|
||||
@@ -1548,3 +1580,30 @@ void DrawText(u16 *framebuffer, int framebufferWidth, int framebufferStrideBytes
|
||||
x += 6;
|
||||
}
|
||||
}
|
||||
+
|
||||
+void draw_low_battery(u16 *framebuffer, int framebufferWidth, int framebufferHeight)
|
||||
+{
|
||||
+ int x_offset = LOW_BATTERY_ICON_TOP_LEFT_X;
|
||||
+ int y_offset = LOW_BATTERY_ICON_TOP_LEFT_Y;
|
||||
+ int x, y;
|
||||
+
|
||||
+ /* Sanity check - width */
|
||||
+ if(x_offset >= framebufferWidth ){
|
||||
+ x_offset = framebufferWidth-1-LOW_BATTERY_ICON_WIDTH;
|
||||
+ }
|
||||
+
|
||||
+ /* Sanity check - height */
|
||||
+ if(y_offset >= framebufferHeight ){
|
||||
+ y_offset = framebufferHeight-1-LOW_BATTERY_ICON_HEIGHT;
|
||||
+ }
|
||||
+
|
||||
+ /* Printing low battery icon */
|
||||
+ for(y = 0; y < MIN(LOW_BATTERY_ICON_HEIGHT, framebufferHeight-y_offset); ++y){
|
||||
+ for(x = 0; x < MIN(LOW_BATTERY_ICON_WIDTH, framebufferWidth-x_offset); ++x){
|
||||
+ if(lowBatteryIcon[y][x]){
|
||||
+ framebuffer[(y+y_offset)*framebufferWidth + (x+x_offset)] = LOW_BATTERY_FORE_COLOR;
|
||||
+ }
|
||||
+ //lowBatteryIcon[y][x] = lowBatteryIcon[y][x] ? LOW_BATTERY_FORE_COLOR : LOW_BATTERY_BACK_COLOR;
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
\ No newline at end of file
|
||||
diff --git a/drivers/staging/fbtft/fb_text.h b/drivers/staging/fbtft/fb_text.h
|
||||
index 1352bdb..e03df39 100644
|
||||
--- a/drivers/staging/fbtft/fb_text.h
|
||||
+++ b/drivers/staging/fbtft/fb_text.h
|
||||
@@ -10,7 +10,7 @@
|
||||
#define RGB565(r, g, b) (((r&0x1f) << 11) | ((g&0x3f) << 5) | (b&0x1f))
|
||||
|
||||
void DrawText(u16 *framebuffer, int framebufferWidth, int framebufferStrideBytes, int framebufferHeight, const char *text, int x, int y, u16 color, u16 bgColor);
|
||||
-
|
||||
+void draw_low_battery(u16 *framebuffer, int framebufferWidth, int framebufferHeight);
|
||||
|
||||
/*extern unsigned char fontdata8x8[64*16];
|
||||
extern unsigned char fontdata6x8[256-32][8];*/
|
||||
diff --git a/drivers/staging/fbtft/fbtft-bus.c b/drivers/staging/fbtft/fbtft-bus.c
|
||||
index 23488ea..ce865ed 100644
|
||||
--- a/drivers/staging/fbtft/fbtft-bus.c
|
||||
+++ b/drivers/staging/fbtft/fbtft-bus.c
|
||||
@@ -7,6 +7,8 @@
|
||||
#include <video/mipi_display.h>
|
||||
#include "fbtft.h"
|
||||
#include "fb_text.h"
|
||||
+#include <linux/rmap.h>
|
||||
+#include <linux/pagemap.h>
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
@@ -110,38 +112,203 @@ void fbtft_write_reg8_bus9(struct fbtft_par *par, int len, ...)
|
||||
|
||||
|
||||
|
||||
-static void spi_complete_cmd_init_data_write(void *arg)
|
||||
-{
|
||||
- struct fbtft_par *par = (struct fbtft_par *) arg;
|
||||
+
|
||||
+
|
||||
+static int prev_write_line_start = -1;
|
||||
+static int prev_write_line_end = -1;
|
||||
+static int write_line_start = -1;
|
||||
+static int write_line_end = -1;
|
||||
+static bool lock = false;
|
||||
+
|
||||
+
|
||||
+
|
||||
+int fbtft_start_new_screen_transfer_async(struct fbtft_par *par){
|
||||
//printk("%s\n", __func__);
|
||||
+ if(lock){
|
||||
+ return -1;
|
||||
+ }
|
||||
+ lock = true;
|
||||
+
|
||||
+ /*if(par->write_line_start == -1 || par->write_line_end == -1){
|
||||
+ lock = false;
|
||||
+ return;
|
||||
+ }*/
|
||||
+
|
||||
+ /* Debug fps */
|
||||
+#define FPS_DEBUG 1
|
||||
+#if FPS_DEBUG
|
||||
+ long fps;
|
||||
+ ktime_t ts_now = ktime_get();
|
||||
+
|
||||
+ /* First measurement */
|
||||
+ if (!ktime_to_ns(par->update_time))
|
||||
+ par->update_time = ts_now;
|
||||
+
|
||||
+ fps = ktime_us_delta(ts_now, par->update_time);
|
||||
+ par->update_time = ts_now;
|
||||
+ fps = fps ? 1000000 / fps : 0;
|
||||
+
|
||||
+ if(fps){
|
||||
+ par->avg_fps += fps;
|
||||
+ par->nb_fps_values++;
|
||||
+
|
||||
+ if(par->nb_fps_values == 200){
|
||||
+ fbtft_par_dbg(DEBUG_TIME_EACH_UPDATE, par,
|
||||
+ "Display update: fps=%ld\n", par->avg_fps/par->nb_fps_values);
|
||||
+ par->avg_fps = 0;
|
||||
+ par->nb_fps_values = 0;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+#endif //FPS_DEBUG
|
||||
+
|
||||
+ /* Post process screen for doufle buf cpy, notifs, rotation soft... */
|
||||
+ fbtft_post_process_screen(par);
|
||||
+
|
||||
+ /* new line to write */
|
||||
+ write_line_start = par->write_line_start;
|
||||
+ write_line_end = par->write_line_end;
|
||||
+ par->write_line_start = -1;
|
||||
+ par->write_line_end = -1;
|
||||
+
|
||||
+ /* Set window for interlacing */
|
||||
+ if(par->interlacing){
|
||||
+ par->length_data_transfer = par->info->var.yres * 2;
|
||||
+ write_line_start = par->odd_line?1:0;
|
||||
+ write_line_end = write_line_start;
|
||||
+ fbtft_write_cmd_window_line(par);
|
||||
+
|
||||
+ } /* Start sending full screen */
|
||||
+ else{
|
||||
+ /*par->length_data_transfer = (write_line_end - write_line_start + 1) * par->info->fix.line_length;
|
||||
+ if(write_line_start != prev_write_line_start || write_line_end != prev_write_line_end){
|
||||
+ prev_write_line_start = write_line_start;
|
||||
+ prev_write_line_end = write_line_end;
|
||||
+ fbtft_write_cmd_window_line(par);
|
||||
+ }
|
||||
+ else{
|
||||
+ fbtft_write_init_cmd_data_transfers(par);
|
||||
+ }*/
|
||||
+
|
||||
+
|
||||
+ par->length_data_transfer = par->info->var.yres * par->info->fix.line_length;
|
||||
+ write_line_start = 0;
|
||||
+ write_line_end = par->info->var.yres-1;
|
||||
+ fbtft_write_init_cmd_data_transfers(par);
|
||||
+ }
|
||||
+
|
||||
|
||||
- /* Start new data write (full display) */
|
||||
- int len = par->info->var.yres * par->info->fix.line_length;
|
||||
- fbtft_write_vmem16_bus8_async(par, 0, len);
|
||||
-
|
||||
+ return 0;
|
||||
}
|
||||
+EXPORT_SYMBOL(fbtft_start_new_screen_transfer_async);
|
||||
|
||||
-static void spi_complete_data_write(void *arg)
|
||||
+
|
||||
+
|
||||
+
|
||||
+
|
||||
+
|
||||
+
|
||||
+
|
||||
+static u8 cmd_window_line = MIPI_DCS_SET_PAGE_ADDRESS;
|
||||
+static u8 buf_ylim[4];
|
||||
+
|
||||
+
|
||||
+static void spi_complete_cmd_window_line(void *arg)
|
||||
{
|
||||
struct fbtft_par *par = (struct fbtft_par *) arg;
|
||||
//printk("%s\n", __func__);
|
||||
|
||||
- /* sleep */
|
||||
- //msleep(1);
|
||||
+ /* Start data write for line info */
|
||||
+ fbtft_write_data_window_line(par);
|
||||
+}
|
||||
+
|
||||
+int fbtft_write_cmd_window_line(struct fbtft_par *par){
|
||||
+
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ //printk("%s\n", __func__);
|
||||
+
|
||||
+ /* Resetting to 0 for incoming cmd init data write */
|
||||
+ if (gpio_is_valid(par->gpio.dc))
|
||||
+ gpio_set_value(par->gpio.dc, 0);
|
||||
|
||||
/* Start sending cmd init data */
|
||||
+ ret = par->fbtftops.write_async(par, &cmd_window_line, 1, spi_complete_cmd_window_line);
|
||||
+ if (ret < 0)
|
||||
+ dev_err(par->info->device,
|
||||
+ "write() failed and returned %d\n", ret);
|
||||
+
|
||||
+ return ret;
|
||||
+
|
||||
+}
|
||||
+EXPORT_SYMBOL(fbtft_write_cmd_window_line);
|
||||
+
|
||||
+
|
||||
+
|
||||
+
|
||||
+
|
||||
+
|
||||
+
|
||||
+
|
||||
+
|
||||
+static void spi_complete_data_window_line(void *arg)
|
||||
+{
|
||||
+ struct fbtft_par *par = (struct fbtft_par *) arg;
|
||||
+ //printk("%s\n", __func__);
|
||||
+
|
||||
+ /* Start sending cmd for real data transfer */
|
||||
fbtft_write_init_cmd_data_transfers(par);
|
||||
}
|
||||
|
||||
+int fbtft_write_data_window_line(struct fbtft_par *par){
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ /* Setting new line coordinates */
|
||||
+ buf_ylim[0] = (write_line_start >> 8) & 0xFF;
|
||||
+ buf_ylim[1] = write_line_start & 0xFF;
|
||||
+ buf_ylim[2] = (write_line_end >> 8) & 0xFF;
|
||||
+ buf_ylim[3] = write_line_end & 0xFF;
|
||||
+
|
||||
+ //printk("%s, buf[0] = %d, buf[1] = %d, buf[2] = %d, buf[3] = %d\n", __func__, buf[0], buf[1], buf[2], buf[3]);
|
||||
+
|
||||
+ /* Resetting to 1 for incoming data */
|
||||
+ if (gpio_is_valid(par->gpio.dc))
|
||||
+ gpio_set_value(par->gpio.dc, 1);
|
||||
+
|
||||
+ /* Start sending window_line data */
|
||||
+ ret = par->fbtftops.write_async(par, buf_ylim, 4, spi_complete_data_window_line);
|
||||
+ if (ret < 0)
|
||||
+ dev_err(par->info->device,
|
||||
+ "write() failed and returned %d\n", ret);
|
||||
+
|
||||
+ return ret;
|
||||
+
|
||||
+}
|
||||
+EXPORT_SYMBOL(fbtft_write_data_window_line);
|
||||
+
|
||||
+
|
||||
+
|
||||
+
|
||||
+
|
||||
+
|
||||
+
|
||||
+
|
||||
+
|
||||
+
|
||||
+static void spi_complete_cmd_init_data_write(void *arg)
|
||||
+{
|
||||
+ struct fbtft_par *par = (struct fbtft_par *) arg;
|
||||
+ //printk("%s\n", __func__);
|
||||
+
|
||||
+ fbtft_write_vmem16_bus8_async(par, write_line_start * par->info->fix.line_length, par->length_data_transfer);
|
||||
+}
|
||||
+
|
||||
int fbtft_write_init_cmd_data_transfers(struct fbtft_par *par){
|
||||
static u8 init_data_cmd_buf = MIPI_DCS_WRITE_MEMORY_START;
|
||||
int ret = 0;
|
||||
|
||||
//printk("%s\n", __func__);
|
||||
|
||||
- /* Post process */
|
||||
- fbtft_post_process_screen(par, 0, par->info->var.yres-1);
|
||||
-
|
||||
/* Resetting to 0 for incoming cmd init data write */
|
||||
if (gpio_is_valid(par->gpio.dc))
|
||||
gpio_set_value(par->gpio.dc, 0);
|
||||
@@ -152,37 +319,52 @@ int fbtft_write_init_cmd_data_transfers(struct fbtft_par *par){
|
||||
dev_err(par->info->device,
|
||||
"write() failed and returned %d\n", ret);
|
||||
|
||||
- /* Debug fps */
|
||||
-#define FPS_DEBUG 0
|
||||
-#if FPS_DEBUG
|
||||
- ktime_t ts_now = ktime_get();
|
||||
+ return ret;
|
||||
+
|
||||
+}
|
||||
+EXPORT_SYMBOL(fbtft_write_init_cmd_data_transfers);
|
||||
|
||||
- /* First measurement */
|
||||
- if (!ktime_to_ns(par->update_time))
|
||||
- par->update_time = ts_now;
|
||||
|
||||
- long fps = ktime_us_delta(ts_now, par->update_time);
|
||||
- par->update_time = ts_now;
|
||||
- fps = fps ? 1000000 / fps : 0;
|
||||
|
||||
- if(fps){
|
||||
- par->avg_fps += fps;
|
||||
- par->nb_fps_values++;
|
||||
|
||||
- if(par->nb_fps_values == 200){
|
||||
- dev_info(par->info->device,
|
||||
- "Display update: fps=%ld\n", par->avg_fps/par->nb_fps_values);
|
||||
- par->avg_fps = 0;
|
||||
- par->nb_fps_values = 0;
|
||||
- }
|
||||
- }
|
||||
|
||||
-#endif //FPS_DEBUG
|
||||
|
||||
- return ret;
|
||||
|
||||
+
|
||||
+
|
||||
+
|
||||
+static void spi_complete_data_write(void *arg)
|
||||
+{
|
||||
+ struct fbtft_par *par = (struct fbtft_par *) arg;
|
||||
+ //printk("%s, par->interlacing=%d, write_line_start=%d\n", __func__, par->interlacing?1:0, write_line_start);
|
||||
+
|
||||
+ /* sleep */
|
||||
+ //msleep(1);
|
||||
+
|
||||
+ if(par->interlacing){
|
||||
+ /* Check if last line */
|
||||
+ bool last_line = (par->odd_line && write_line_start >= par->info->var.yres-1) ||
|
||||
+ (!par->odd_line && write_line_start >= par->info->var.yres-2);
|
||||
+
|
||||
+ if(last_line){
|
||||
+ /* Start sending cmd init data */
|
||||
+ par->odd_line = !par->odd_line;
|
||||
+ lock = false;
|
||||
+ fbtft_start_new_screen_transfer_async(par);
|
||||
+ }
|
||||
+ else{
|
||||
+ write_line_start += 2;
|
||||
+ write_line_end = write_line_start;
|
||||
+
|
||||
+ /* Setting window for next line */
|
||||
+ fbtft_write_cmd_window_line(par);
|
||||
+ }
|
||||
+ }
|
||||
+ else{
|
||||
+ lock = false;
|
||||
+ fbtft_start_new_screen_transfer_async(par);
|
||||
+ }
|
||||
}
|
||||
-EXPORT_SYMBOL(fbtft_write_init_cmd_data_transfers);
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
@@ -206,8 +388,6 @@ int fbtft_write_vmem16_bus8_async(struct fbtft_par *par, size_t offset, size_t l
|
||||
__func__, offset, len);
|
||||
|
||||
remain = len / 2;
|
||||
- //vmem16 = (u16 *)(par->info->screen_buffer + offset);
|
||||
- //vmem16 = (u16 *)(par->vmem_post_process + offset);
|
||||
vmem16 = (u16 *)(par->vmem_ptr + offset);
|
||||
|
||||
if (par->gpio.dc != -1)
|
||||
diff --git a/drivers/staging/fbtft/fbtft-core.c b/drivers/staging/fbtft/fbtft-core.c
|
||||
index d576d0c..bcfa8c4 100755
|
||||
--- a/drivers/staging/fbtft/fbtft-core.c
|
||||
+++ b/drivers/staging/fbtft/fbtft-core.c
|
||||
@@ -344,18 +344,27 @@ static void fbtft_set_addr_win(struct fbtft_par *par, int xs, int ys, int xe,
|
||||
static int prev_ye = -1;
|
||||
|
||||
// Check if values need to be sent
|
||||
- if(prev_xs!=xs || prev_ys!=ys || prev_xe!=xe || prev_ye!=ye){
|
||||
+ if(prev_xs!=xs || prev_xe!=xe){
|
||||
|
||||
// Save prev bounding box values
|
||||
prev_xs = xs;
|
||||
- prev_ys = ys;
|
||||
prev_xe = xe;
|
||||
- prev_ye = ye;
|
||||
|
||||
//Set new bounding Box
|
||||
+ //printk(" [%s] First write_reg: xs = %d, xe = %d\r\n", __func__, xs, xe);
|
||||
write_reg(par, MIPI_DCS_SET_COLUMN_ADDRESS,
|
||||
(xs >> 8) & 0xFF, xs & 0xFF, (xe >> 8) & 0xFF, xe & 0xFF);
|
||||
+ }
|
||||
+
|
||||
+ // Check if values need to be sent
|
||||
+ if(prev_ys!=ys || prev_ye!=ye){
|
||||
+
|
||||
+ // Save prev bounding box values
|
||||
+ prev_ys = ys;
|
||||
+ prev_ye = ye;
|
||||
|
||||
+ //Set new bounding Box
|
||||
+ //printk(" [%s] 2nd write_reg: ys = %d, ye = %d\r\n", __func__, ys, ye);
|
||||
write_reg(par, MIPI_DCS_SET_PAGE_ADDRESS,
|
||||
(ys >> 8) & 0xFF, ys & 0xFF, (ye >> 8) & 0xFF, ye & 0xFF);
|
||||
}
|
||||
@@ -539,38 +548,55 @@ static void fbtft_mkdirty(struct fb_info *info, int y, int height)
|
||||
schedule_delayed_work(&info->deferred_work, fbdefio->delay);
|
||||
}
|
||||
|
||||
-void fbtft_post_process_screen(struct fbtft_par *par, unsigned int dirty_lines_start, unsigned int dirty_lines_end){
|
||||
+void fbtft_post_process_screen(struct fbtft_par *par){
|
||||
int x_notif = 0;
|
||||
int y_notif = 0;
|
||||
bool screen_post_process = false;
|
||||
|
||||
- /* Reset default write buffer */
|
||||
- par->vmem_ptr = par->info->screen_buffer;
|
||||
+ /* bypass */
|
||||
+ screen_post_process = true;
|
||||
+ par->write_line_start = 0;
|
||||
+ par->write_line_end = par->info->var.yres-1;
|
||||
|
||||
/* If soft rotation, mark whole screen to update to avoid data non rotated */
|
||||
if(par->pdata->rotate_soft)
|
||||
{
|
||||
- dirty_lines_start = 0;
|
||||
- dirty_lines_end = par->info->var.yres-1;
|
||||
- par->vmem_ptr = par->vmem_post_process;
|
||||
+ par->write_line_start = 0;
|
||||
+ par->write_line_end = par->info->var.yres-1;
|
||||
screen_post_process = true;
|
||||
}
|
||||
+
|
||||
+ /* If notification, mark whole screen to update */
|
||||
if(par->notification[0]){
|
||||
- if (y_notif < dirty_lines_start)
|
||||
- dirty_lines_start = y_notif;
|
||||
- if (y_notif + MONACO_HEIGHT > dirty_lines_end){
|
||||
- dirty_lines_end = y_notif + MONACO_HEIGHT;
|
||||
- }
|
||||
- par->vmem_ptr = par->vmem_post_process;
|
||||
+ /*if (y_notif < par->write_line_start)
|
||||
+ par->write_line_start = y_notif;
|
||||
+ if (y_notif + MONACO_HEIGHT > par->write_line_end){
|
||||
+ par->write_line_end = y_notif + MONACO_HEIGHT;
|
||||
+ }*/
|
||||
+
|
||||
+ /* bypass*/
|
||||
+ par->write_line_start = 0;
|
||||
+ par->write_line_end = par->info->var.yres-1;
|
||||
+ screen_post_process = true;
|
||||
+ }
|
||||
+
|
||||
+ /* Low battery icon */
|
||||
+ if(par->low_battery)
|
||||
+ {
|
||||
+ par->write_line_start = 0;
|
||||
+ par->write_line_end = par->info->var.yres-1;
|
||||
screen_post_process = true;
|
||||
}
|
||||
|
||||
/* Post process */
|
||||
if(screen_post_process){
|
||||
+ /* Change vmem ptr to send by SPI */
|
||||
+ par->vmem_ptr = par->vmem_post_process;
|
||||
+
|
||||
/* Copy buffer */
|
||||
- memcpy(par->vmem_post_process + dirty_lines_start * par->info->fix.line_length,
|
||||
- par->info->screen_buffer + dirty_lines_start * par->info->fix.line_length,
|
||||
- (dirty_lines_end-dirty_lines_start+1) * par->info->fix.line_length);
|
||||
+ memcpy(par->vmem_post_process + par->write_line_start * par->info->fix.line_length,
|
||||
+ par->info->screen_buffer + par->write_line_start * par->info->fix.line_length,
|
||||
+ (par->write_line_end-par->write_line_start+1) * par->info->fix.line_length);
|
||||
|
||||
/* Notifications */
|
||||
if(par->notification[0]){
|
||||
@@ -579,10 +605,16 @@ void fbtft_post_process_screen(struct fbtft_par *par, unsigned int dirty_lines_s
|
||||
basic_text_out16_bg((u16*)par->vmem_post_process, par->info->var.xres, par->info->var.yres,
|
||||
x_notif, y_notif, RGB565(255, 255, 255), RGB565(0, 0, 0), par->notification);
|
||||
|
||||
- if (y_notif < dirty_lines_start)
|
||||
- dirty_lines_start = y_notif;
|
||||
- if (y_notif + MONACO_HEIGHT > dirty_lines_end)
|
||||
- dirty_lines_end = y_notif + MONACO_HEIGHT;
|
||||
+ if (y_notif < par->write_line_start)
|
||||
+ par->write_line_start = y_notif;
|
||||
+ if (y_notif + MONACO_HEIGHT > par->write_line_end)
|
||||
+ par->write_line_end = y_notif + MONACO_HEIGHT;
|
||||
+ }
|
||||
+
|
||||
+ /* Low battery icon */
|
||||
+ if(par->low_battery)
|
||||
+ {
|
||||
+ draw_low_battery((u16*)par->vmem_post_process, par->info->var.xres, par->info->var.yres);
|
||||
}
|
||||
|
||||
/* Soft rotation */
|
||||
@@ -602,6 +634,36 @@ static void fbtft_deferred_io(struct fb_info *info, struct list_head *pagelist)
|
||||
unsigned int y_low = 0, y_high = 0;
|
||||
int count = 0;
|
||||
|
||||
+ //#define FPS_DEBUG
|
||||
+ #if 0
|
||||
+ long fps;
|
||||
+ static ktime_t update_time;
|
||||
+ static int nb_fps_values = 0;
|
||||
+ static long avg_fps = 0;
|
||||
+ ktime_t ts_now = ktime_get();
|
||||
+
|
||||
+ /* First measurement */
|
||||
+ if (!ktime_to_ns(update_time))
|
||||
+ update_time = ts_now;
|
||||
+
|
||||
+ fps = ktime_us_delta(ts_now, update_time);
|
||||
+ update_time = ts_now;
|
||||
+ fps = fps ? 1000000 / fps : 0;
|
||||
+
|
||||
+ if(fps){
|
||||
+ avg_fps += fps;
|
||||
+ nb_fps_values++;
|
||||
+
|
||||
+ if(nb_fps_values == 200){
|
||||
+ fbtft_par_dbg(DEBUG_TIME_EACH_UPDATE, par,
|
||||
+ "fbtft_deferred_io update: fps=%ld\n", avg_fps/nb_fps_values);
|
||||
+ avg_fps = 0;
|
||||
+ nb_fps_values = 0;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ #endif //FPS_DEBUG
|
||||
+
|
||||
spin_lock(&par->dirty_lock);
|
||||
dirty_lines_start = par->dirty_lines_start;
|
||||
dirty_lines_end = par->dirty_lines_end;
|
||||
@@ -627,10 +689,32 @@ static void fbtft_deferred_io(struct fb_info *info, struct list_head *pagelist)
|
||||
dirty_lines_end = y_high;
|
||||
}
|
||||
|
||||
- fbtft_post_process_screen(par, dirty_lines_start, dirty_lines_end);
|
||||
+ /* Copy buffer */
|
||||
+ if(dirty_lines_start!=0 || dirty_lines_end!=par->info->var.yres - 1){
|
||||
+ printk("dirty_lines_start = %d, dirty_lines_end = %d\n", dirty_lines_start, dirty_lines_end);
|
||||
+ }
|
||||
+ /*dirty_lines_start = 0;
|
||||
+ dirty_lines_end = par->info->var.yres - 1;*/
|
||||
+ par->write_line_start = dirty_lines_start;
|
||||
+ par->write_line_end = dirty_lines_end;
|
||||
+ memcpy(par->vmem_post_process + dirty_lines_start * par->info->fix.line_length,
|
||||
+ par->info->screen_buffer + dirty_lines_start * par->info->fix.line_length,
|
||||
+ (dirty_lines_end-dirty_lines_start+1) * par->info->fix.line_length);
|
||||
+ par->vmem_ptr = par->vmem_post_process;
|
||||
+
|
||||
|
||||
- /* Screen upgrade */
|
||||
- par->fbtftops.update_display(par, dirty_lines_start, dirty_lines_end);
|
||||
+ /* Exit in SPI async mode, otherwise update screen now */
|
||||
+ if (par->spi_async_mode){
|
||||
+ fbtft_start_new_screen_transfer_async(par);
|
||||
+ return;
|
||||
+ }
|
||||
+ else{
|
||||
+ /* Post process screen for doufle buf cpy, notifs, rotation soft... */
|
||||
+ fbtft_post_process_screen(par);
|
||||
+
|
||||
+ /* Screen upgrade */
|
||||
+ par->fbtftops.update_display(par, dirty_lines_start, dirty_lines_end);
|
||||
+ }
|
||||
}
|
||||
|
||||
static void fbtft_fb_fillrect(struct fb_info *info,
|
||||
@@ -739,11 +823,13 @@ static int fb_deferred_io_mkwrite(struct vm_fault *vmf)
|
||||
struct page *cur;
|
||||
struct fbtft_par *par = info->par;
|
||||
|
||||
+#if 1
|
||||
/* This disables fbtft's defered io, useful in spi_async mode or
|
||||
if any other driver handles screens updates instead of fbtft */
|
||||
if (par->spi_async_mode){
|
||||
return VM_FAULT_LOCKED;
|
||||
}
|
||||
+#endif
|
||||
|
||||
/* this is a callback we get when userspace first tries to
|
||||
write to the page. we schedule a workqueue. that workqueue
|
||||
@@ -1101,6 +1187,7 @@ struct fb_info *fbtft_framebuffer_alloc(struct fbtft_display *display,
|
||||
spin_lock_init(&par->dirty_lock);
|
||||
par->bgr = pdata->bgr;
|
||||
par->spi_async_mode = pdata->spi_async_mode;
|
||||
+ par->interlacing = pdata->interlacing;
|
||||
par->startbyte = pdata->startbyte;
|
||||
par->init_sequence = init_sequence;
|
||||
par->gamma.curves = gamma_curves;
|
||||
@@ -1262,10 +1349,12 @@ int fbtft_register_framebuffer(struct fb_info *fb_info)
|
||||
sprintf(text2, ", spi%d.%d at %d MHz", spi->master->bus_num,
|
||||
spi->chip_select, spi->max_speed_hz / 1000000);
|
||||
dev_info(fb_info->dev,
|
||||
- "%s frame buffer, %dx%d, %d KiB video memory%s, fps=%lu%s\n",
|
||||
+ "%s frame buffer, %dx%d, %d KiB video memory%s, fps=%lu%s, %s%s\n",
|
||||
fb_info->fix.id, fb_info->var.xres, fb_info->var.yres,
|
||||
fb_info->fix.smem_len >> 10, text1,
|
||||
- HZ / fb_info->fbdefio->delay, text2);
|
||||
+ HZ / fb_info->fbdefio->delay, text2,
|
||||
+ par->spi_async_mode?"SPI mode asynchrone, ":"",
|
||||
+ par->interlacing?"Interlaced":"");
|
||||
|
||||
#ifdef CONFIG_FB_BACKLIGHT
|
||||
/* Turn on backlight if available */
|
||||
@@ -1584,6 +1673,7 @@ static struct fbtft_platform_data *fbtft_probe_dt(struct device *dev)
|
||||
pdata->rotate_soft = fbtft_of_value(node, "rotate_soft");
|
||||
pdata->bgr = of_property_read_bool(node, "bgr");
|
||||
pdata->spi_async_mode = of_property_read_bool(node, "spi_async_mode");
|
||||
+ pdata->interlacing = of_property_read_bool(node, "interlacing");
|
||||
pdata->fps = fbtft_of_value(node, "fps");
|
||||
pdata->txbuflen = fbtft_of_value(node, "txbuflen");
|
||||
pdata->startbyte = fbtft_of_value(node, "startbyte");
|
||||
@@ -1725,7 +1815,9 @@ int fbtft_probe_common(struct fbtft_display *display,
|
||||
|
||||
if (par->spi_async_mode){
|
||||
/* Start constant Display update using spi async*/
|
||||
- fbtft_write_init_cmd_data_transfers(par);
|
||||
+ par->write_line_start = 0;
|
||||
+ par->write_line_end = par->info->var.yres - 1;
|
||||
+ fbtft_start_new_screen_transfer_async(par);
|
||||
}
|
||||
|
||||
return 0;
|
||||
diff --git a/drivers/staging/fbtft/fbtft-io.c b/drivers/staging/fbtft/fbtft-io.c
|
||||
index 1b269ee..40d31b5 100644
|
||||
--- a/drivers/staging/fbtft/fbtft-io.c
|
||||
+++ b/drivers/staging/fbtft/fbtft-io.c
|
||||
@@ -6,7 +6,7 @@
|
||||
#include "fbtft.h"
|
||||
|
||||
/* Ugly static declarations for now */
|
||||
-#define NB_STORED_SPI_MSG 100
|
||||
+#define NB_STORED_SPI_MSG 1
|
||||
static int idx_spi_msg = 0;
|
||||
static struct spi_transfer stored_spi_transfers[NB_STORED_SPI_MSG];
|
||||
static struct spi_message stored_spi_msg[NB_STORED_SPI_MSG];
|
||||
@@ -84,8 +84,9 @@ int fbtft_write_spi(struct fbtft_par *par, void *buf, size_t len)
|
||||
|
||||
spi_message_init(&m);
|
||||
spi_message_add_tail(&t, &m);
|
||||
+ //spi_sync(par->spi, &m);
|
||||
return spi_sync(par->spi, &m);
|
||||
- //return spi_async(par->spi, &m);
|
||||
+ //return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(fbtft_write_spi);
|
||||
|
||||
diff --git a/drivers/staging/fbtft/fbtft-sysfs.c b/drivers/staging/fbtft/fbtft-sysfs.c
|
||||
index 5141b32..b73a26d 100644
|
||||
--- a/drivers/staging/fbtft/fbtft-sysfs.c
|
||||
+++ b/drivers/staging/fbtft/fbtft-sysfs.c
|
||||
@@ -387,6 +387,35 @@ static ssize_t show_notification(struct device *device,
|
||||
static struct device_attribute notification_device_attr =
|
||||
__ATTR(notification, 0660, show_notification, store_notification);
|
||||
|
||||
+static ssize_t store_low_battery(struct device *device,
|
||||
+ struct device_attribute *attr,
|
||||
+ const char *buf, size_t count)
|
||||
+{
|
||||
+ struct fb_info *fb_info = dev_get_drvdata(device);
|
||||
+ struct fbtft_par *par = fb_info->par;
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = kstrtoul(buf, 10, &par->low_battery);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ par->low_battery = par->low_battery?1:0;
|
||||
+
|
||||
+ return count;
|
||||
+}
|
||||
+
|
||||
+static ssize_t show_low_battery(struct device *device,
|
||||
+ struct device_attribute *attr, char *buf)
|
||||
+{
|
||||
+ struct fb_info *fb_info = dev_get_drvdata(device);
|
||||
+ struct fbtft_par *par = fb_info->par;
|
||||
+
|
||||
+ return snprintf(buf, PAGE_SIZE, "%lu\n", par->low_battery);
|
||||
+}
|
||||
+
|
||||
+static struct device_attribute low_battery_device_attr =
|
||||
+ __ATTR(low_battery, 0660, show_low_battery, store_low_battery);
|
||||
+
|
||||
void fbtft_expand_debug_value(unsigned long *debug)
|
||||
{
|
||||
switch (*debug & 0x7) {
|
||||
@@ -448,6 +477,7 @@ static ssize_t show_debug(struct device *device,
|
||||
void fbtft_sysfs_init(struct fbtft_par *par)
|
||||
{
|
||||
device_create_file(par->info->dev, &debug_device_attr);
|
||||
+ device_create_file(par->info->dev, &low_battery_device_attr);
|
||||
device_create_file(par->info->dev, &rotate_soft_device_attr);
|
||||
device_create_file(par->info->dev, ¬ification_device_attr);
|
||||
device_create_file(par->info->dev, &overlay_device_attrs[0]);
|
||||
@@ -458,6 +488,7 @@ void fbtft_sysfs_init(struct fbtft_par *par)
|
||||
void fbtft_sysfs_exit(struct fbtft_par *par)
|
||||
{
|
||||
device_remove_file(par->info->dev, &debug_device_attr);
|
||||
+ device_remove_file(par->info->dev, &low_battery_device_attr);
|
||||
device_remove_file(par->info->dev, &rotate_soft_device_attr);
|
||||
device_remove_file(par->info->dev, ¬ification_device_attr);
|
||||
device_remove_file(par->info->dev, &overlay_device_attrs[0]);
|
||||
diff --git a/drivers/staging/fbtft/fbtft.h b/drivers/staging/fbtft/fbtft.h
|
||||
index e6b4c59..64dec83 100644
|
||||
--- a/drivers/staging/fbtft/fbtft.h
|
||||
+++ b/drivers/staging/fbtft/fbtft.h
|
||||
@@ -154,6 +154,7 @@ struct fbtft_platform_data {
|
||||
unsigned long rotate_soft;
|
||||
bool bgr;
|
||||
bool spi_async_mode;
|
||||
+ bool interlacing;
|
||||
unsigned int fps;
|
||||
int txbuflen;
|
||||
u8 startbyte;
|
||||
@@ -252,13 +253,22 @@ struct fbtft_par {
|
||||
} overlay;
|
||||
char notification[FBTFT_NOTIF_MAX_SIZE+1];
|
||||
unsigned long debug;
|
||||
+ unsigned long low_battery;
|
||||
bool first_update_done;
|
||||
ktime_t update_time;
|
||||
long avg_fps;
|
||||
int nb_fps_values;
|
||||
bool bgr;
|
||||
void *extra;
|
||||
+
|
||||
+ /* SPI async */
|
||||
bool spi_async_mode;
|
||||
+ bool interlacing;
|
||||
+ bool odd_line;
|
||||
+ int cur_line;
|
||||
+ int write_line_start;
|
||||
+ int write_line_end;
|
||||
+ u32 length_data_transfer;
|
||||
};
|
||||
|
||||
#define NUMARGS(...) (sizeof((int[]){__VA_ARGS__})/sizeof(int))
|
||||
@@ -283,8 +293,7 @@ int fbtft_probe_common(struct fbtft_display *display, struct spi_device *sdev,
|
||||
struct platform_device *pdev);
|
||||
int fbtft_remove_common(struct device *dev, struct fb_info *info);
|
||||
void fbtft_rotate_soft(u16 *mat, int size, int rotation);
|
||||
-void fbtft_post_process_screen(struct fbtft_par *par,
|
||||
- unsigned int dirty_lines_start, unsigned int dirty_lines_end);
|
||||
+void fbtft_post_process_screen(struct fbtft_par *par);
|
||||
|
||||
/* fbtft-io.c */
|
||||
int fbtft_write_spi(struct fbtft_par *par, void *buf, size_t len);
|
||||
@@ -296,6 +305,9 @@ void fbtft_post_process_screen(struct fbtft_par *par,
|
||||
int fbtft_write_gpio16_wr_latched(struct fbtft_par *par, void *buf, size_t len);
|
||||
|
||||
/* fbtft-bus.c */
|
||||
+int fbtft_start_new_screen_transfer_async(struct fbtft_par *par);
|
||||
+int fbtft_write_cmd_window_line(struct fbtft_par *par);
|
||||
+int fbtft_write_data_window_line(struct fbtft_par *par);
|
||||
int fbtft_write_init_cmd_data_transfers(struct fbtft_par *par);
|
||||
int fbtft_write_vmem8_bus8(struct fbtft_par *par, size_t offset, size_t len);
|
||||
int fbtft_write_vmem16_bus16(struct fbtft_par *par, size_t offset, size_t len);
|
||||
--
|
||||
1.9.1
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,75 +0,0 @@
|
||||
From 2505384b62b599da8cf234a14bdbab54f603083b Mon Sep 17 00:00:00 2001
|
||||
From: vincent <vbusoenseirb@gmail.com>
|
||||
Date: Wed, 19 Feb 2020 08:32:46 +0100
|
||||
Subject: [PATCH] changed battery logo
|
||||
|
||||
---
|
||||
drivers/staging/fbtft/fb_text.c | 47 ++++++++++++++++++-----------------------
|
||||
1 file changed, 21 insertions(+), 26 deletions(-)
|
||||
|
||||
diff --git a/drivers/staging/fbtft/fb_text.c b/drivers/staging/fbtft/fb_text.c
|
||||
index 650535d..b1ecdd4 100644
|
||||
--- a/drivers/staging/fbtft/fb_text.c
|
||||
+++ b/drivers/staging/fbtft/fb_text.c
|
||||
@@ -4,37 +4,32 @@
|
||||
#define MIN(a,b) (((a)<(b))?(a):(b))
|
||||
#define MAX(a,b) (((a)>(b))?(a):(b))
|
||||
|
||||
-#define LOW_BATTERY_ICON_TOP_LEFT_X 10
|
||||
-#define LOW_BATTERY_ICON_TOP_LEFT_Y 10
|
||||
-#define LOW_BATTERY_ICON_WIDTH 35
|
||||
-#define LOW_BATTERY_ICON_HEIGHT 20
|
||||
+#define LOW_BATTERY_ICON_WIDTH 34
|
||||
+#define LOW_BATTERY_ICON_HEIGHT 16
|
||||
+#define LOW_BATTERY_ICON_TOP_LEFT_X (240-LOW_BATTERY_ICON_WIDTH-5)
|
||||
+#define LOW_BATTERY_ICON_TOP_LEFT_Y (13 - LOW_BATTERY_ICON_HEIGHT/2)
|
||||
//#define LOW_BATTERY_FORE_COLOR 65535
|
||||
#define LOW_BATTERY_FORE_COLOR 0xF800
|
||||
#define LOW_BATTERY_BACK_COLOR 0
|
||||
|
||||
|
||||
-// Battery icon from: https://github.com/martinohanlon/grrl-bat-monitor
|
||||
-static u16 lowBatteryIcon [LOW_BATTERY_ICON_HEIGHT][LOW_BATTERY_ICON_WIDTH] = {
|
||||
- {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
- {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
- {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0},
|
||||
- {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0},
|
||||
- {0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0},
|
||||
- {0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0},
|
||||
- {0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0},
|
||||
- {0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0},
|
||||
- {0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0},
|
||||
- {0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0},
|
||||
- {0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0},
|
||||
- {0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0},
|
||||
- {0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0},
|
||||
- {0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0},
|
||||
- {0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0},
|
||||
- {0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0},
|
||||
- {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0},
|
||||
- {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0},
|
||||
- {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
- {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};
|
||||
+static uint32_t lowBatteryIcon [LOW_BATTERY_ICON_HEIGHT][LOW_BATTERY_ICON_WIDTH] = {
|
||||
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
+ {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0},
|
||||
+ {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0},
|
||||
+ {0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0},
|
||||
+ {0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0},
|
||||
+ {0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0},
|
||||
+ {0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0},
|
||||
+ {0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0},
|
||||
+ {0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0},
|
||||
+ {0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0},
|
||||
+ {0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0},
|
||||
+ {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0},
|
||||
+ {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0},
|
||||
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};
|
||||
|
||||
|
||||
|
||||
--
|
||||
1.9.1
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,394 +0,0 @@
|
||||
From fc4a5c2f32f088e23d0078d2e1867ed6708b66f3 Mon Sep 17 00:00:00 2001
|
||||
From: vincent <vbusoenseirb@gmail.com>
|
||||
Date: Sat, 26 Sep 2020 02:11:52 +0200
|
||||
Subject: [PATCH] fbtft with TE working
|
||||
|
||||
---
|
||||
arch/arm/boot/dts/sun8i-v3s-funkey.dts | 1 +
|
||||
drivers/staging/fbtft/fb_st7789v.c | 10 ++-
|
||||
drivers/staging/fbtft/fbtft-bus.c | 22 ++++--
|
||||
drivers/staging/fbtft/fbtft-core.c | 128 ++++++++++++++++++++++++++-------
|
||||
drivers/staging/fbtft/fbtft.h | 3 +
|
||||
5 files changed, 129 insertions(+), 35 deletions(-)
|
||||
|
||||
diff --git a/arch/arm/boot/dts/sun8i-v3s-funkey.dts b/arch/arm/boot/dts/sun8i-v3s-funkey.dts
|
||||
index 20f9913..24e26b2 100644
|
||||
--- a/arch/arm/boot/dts/sun8i-v3s-funkey.dts
|
||||
+++ b/arch/arm/boot/dts/sun8i-v3s-funkey.dts
|
||||
@@ -186,6 +186,7 @@
|
||||
buswidth = <8>;
|
||||
reset-gpios = <&pio 1 2 GPIO_ACTIVE_HIGH>; //PB2
|
||||
dc-gpios = <&pio 2 0 GPIO_ACTIVE_LOW>; //PC0 (MISO)
|
||||
+ te-irq = <&pio 1 1 GPIO_ACTIVE_LOW>; //PB1
|
||||
debug = <0>;
|
||||
};
|
||||
};
|
||||
diff --git a/drivers/staging/fbtft/fb_st7789v.c b/drivers/staging/fbtft/fb_st7789v.c
|
||||
index e2c9078..f33f8e3 100755
|
||||
--- a/drivers/staging/fbtft/fb_st7789v.c
|
||||
+++ b/drivers/staging/fbtft/fb_st7789v.c
|
||||
@@ -52,6 +52,8 @@
|
||||
* out as well to avoid duplicate entries.
|
||||
*/
|
||||
enum st7789v_command {
|
||||
+ TEOFF = 0x34,
|
||||
+ TEON = 0x35,
|
||||
PORCTRL = 0xB2,
|
||||
GCTRL = 0xB7,
|
||||
VCOMS = 0xBB,
|
||||
@@ -153,10 +155,14 @@ static int init_display(struct fbtft_par *par)
|
||||
/* Display Inversion of colors */
|
||||
write_reg(par, 0x21);
|
||||
|
||||
+ /* Activate TE signal for Vsync only */
|
||||
+ write_reg(par, TEON, 0x00);
|
||||
+
|
||||
/* refresh rate */
|
||||
//write_reg(par, 0xC6,0x1F); //39Hz
|
||||
//write_reg(par, 0xC6,0x1A); //44Hz
|
||||
- //write_reg(par, 0xC6,0x17); //48Hz
|
||||
+ //write_reg(par, 0xC6,0x18); //46Hz
|
||||
+ write_reg(par, 0xC6,0x17); //48Hz
|
||||
//write_reg(par, 0xC6,0x16); //49Hz
|
||||
//write_reg(par, 0xC6,0x15); //50Hz
|
||||
//write_reg(par, 0xC6,0x14); //52Hz
|
||||
@@ -165,7 +171,7 @@ static int init_display(struct fbtft_par *par)
|
||||
//write_reg(par, 0xC6,0x0F); //60Hz
|
||||
//write_reg(par, 0xC6,0x09); //60Hz
|
||||
//write_reg(par, 0xC6,0x03); //99Hz
|
||||
- write_reg(par, 0xC6,0x02); //105Hz
|
||||
+ //write_reg(par, 0xC6,0x02); //105Hz -> good one when no TE signal
|
||||
|
||||
write_reg(par, MIPI_DCS_SET_DISPLAY_ON);
|
||||
|
||||
diff --git a/drivers/staging/fbtft/fbtft-bus.c b/drivers/staging/fbtft/fbtft-bus.c
|
||||
index ce865ed..801cdf4 100644
|
||||
--- a/drivers/staging/fbtft/fbtft-bus.c
|
||||
+++ b/drivers/staging/fbtft/fbtft-bus.c
|
||||
@@ -124,6 +124,10 @@ void fbtft_write_reg8_bus9(struct fbtft_par *par, int len, ...)
|
||||
|
||||
int fbtft_start_new_screen_transfer_async(struct fbtft_par *par){
|
||||
//printk("%s\n", __func__);
|
||||
+ if(par->pdata->te_irq && !par->ready_for_spi_async){
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
if(lock){
|
||||
return -1;
|
||||
}
|
||||
@@ -135,8 +139,8 @@ int fbtft_start_new_screen_transfer_async(struct fbtft_par *par){
|
||||
}*/
|
||||
|
||||
/* Debug fps */
|
||||
-#define FPS_DEBUG 1
|
||||
-#if FPS_DEBUG
|
||||
+//#define FPS_DEBUG
|
||||
+#ifdef FPS_DEBUG
|
||||
long fps;
|
||||
ktime_t ts_now = ktime_get();
|
||||
|
||||
@@ -153,13 +157,13 @@ int fbtft_start_new_screen_transfer_async(struct fbtft_par *par){
|
||||
par->nb_fps_values++;
|
||||
|
||||
if(par->nb_fps_values == 200){
|
||||
- fbtft_par_dbg(DEBUG_TIME_EACH_UPDATE, par,
|
||||
- "Display update: fps=%ld\n", par->avg_fps/par->nb_fps_values);
|
||||
+ /*fbtft_par_dbg(DEBUG_TIME_EACH_UPDATE, par,
|
||||
+ "Display update: fps=%ld\n", par->avg_fps/par->nb_fps_values);*/
|
||||
+ printk("Display update: fps=%ld\n", par->avg_fps/par->nb_fps_values);
|
||||
par->avg_fps = 0;
|
||||
par->nb_fps_values = 0;
|
||||
}
|
||||
}
|
||||
-
|
||||
#endif //FPS_DEBUG
|
||||
|
||||
/* Post process screen for doufle buf cpy, notifs, rotation soft... */
|
||||
@@ -350,7 +354,9 @@ static void spi_complete_data_write(void *arg)
|
||||
/* Start sending cmd init data */
|
||||
par->odd_line = !par->odd_line;
|
||||
lock = false;
|
||||
- fbtft_start_new_screen_transfer_async(par);
|
||||
+ if(!par->pdata->te_irq){
|
||||
+ fbtft_start_new_screen_transfer_async(par);
|
||||
+ }
|
||||
}
|
||||
else{
|
||||
write_line_start += 2;
|
||||
@@ -362,7 +368,9 @@ static void spi_complete_data_write(void *arg)
|
||||
}
|
||||
else{
|
||||
lock = false;
|
||||
- fbtft_start_new_screen_transfer_async(par);
|
||||
+ if(!par->pdata->te_irq){
|
||||
+ fbtft_start_new_screen_transfer_async(par);
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/drivers/staging/fbtft/fbtft-core.c b/drivers/staging/fbtft/fbtft-core.c
|
||||
index bcfa8c4..b362bc0 100755
|
||||
--- a/drivers/staging/fbtft/fbtft-core.c
|
||||
+++ b/drivers/staging/fbtft/fbtft-core.c
|
||||
@@ -37,6 +37,7 @@
|
||||
#include <video/mipi_display.h>
|
||||
#include <linux/hrtimer.h>
|
||||
#include <linux/list.h>
|
||||
+#include <linux/interrupt.h>
|
||||
|
||||
/* to support deferred IO */
|
||||
#include <linux/rmap.h>
|
||||
@@ -432,12 +433,16 @@ static void fbtft_update_display(struct fbtft_par *par, unsigned int start_line,
|
||||
|
||||
fbtft_par_dbg(DEBUG_UPDATE_DISPLAY, par, "%s(start_line=%u, end_line=%u)\n",
|
||||
__func__, start_line, end_line);
|
||||
- par->fbtftops.set_addr_win(par, 0, start_line,
|
||||
- par->info->var.xres - 1, end_line);
|
||||
- /*if (par->fbtftops.set_addr_win){
|
||||
+
|
||||
+ if(par->pdata->rotate == 90){
|
||||
par->fbtftops.set_addr_win(par, 80, start_line,
|
||||
- 320 - 1, end_line);
|
||||
- }*/
|
||||
+ 320 - 1, end_line);
|
||||
+ }
|
||||
+ else{
|
||||
+ par->fbtftops.set_addr_win(par, 0, start_line,
|
||||
+ par->info->var.xres - 1, end_line);
|
||||
+ }
|
||||
+
|
||||
}
|
||||
|
||||
/* Send cmd to start transfer */
|
||||
@@ -500,7 +505,7 @@ void fbtft_rotate_soft(u16 *mat, int size, int rotation){
|
||||
mat[AT(i, j)] = mat[AT(N - 1 - j, i)];
|
||||
mat[AT(N - 1 - j, i)] = mat[AT(N - 1 - i, N - 1 - j)];
|
||||
mat[AT(N - 1 - i, N - 1 - j)] = mat[AT(j, N - 1 - i)];
|
||||
- mat[AT(j, N - 1 - i)] = temp;
|
||||
+ mat[AT(j, N - 1 - i)] = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -524,7 +529,7 @@ static void fbtft_mkdirty(struct fb_info *info, int y, int height)
|
||||
struct fbtft_par *par = info->par;
|
||||
struct fb_deferred_io *fbdefio = info->fbdefio;
|
||||
|
||||
- /* This disables fbtft's defered io, useful in spi_asyn mode or
|
||||
+ /* This disables fbtft's defered io, useful in spi_async mode or
|
||||
if any other driver handles screens updates instead of fbtft */
|
||||
if (par->spi_async_mode){
|
||||
return;
|
||||
@@ -554,9 +559,12 @@ void fbtft_post_process_screen(struct fbtft_par *par){
|
||||
bool screen_post_process = false;
|
||||
|
||||
/* bypass */
|
||||
+//#define FORCE_POSTPROCESS
|
||||
+#ifdef FORCE_POSTPROCESS
|
||||
screen_post_process = true;
|
||||
par->write_line_start = 0;
|
||||
par->write_line_end = par->info->var.yres-1;
|
||||
+#endif //FORCE_POSTPROCESS
|
||||
|
||||
/* If soft rotation, mark whole screen to update to avoid data non rotated */
|
||||
if(par->pdata->rotate_soft)
|
||||
@@ -594,6 +602,15 @@ void fbtft_post_process_screen(struct fbtft_par *par){
|
||||
par->vmem_ptr = par->vmem_post_process;
|
||||
|
||||
/* Copy buffer */
|
||||
+ /* This should be handled using a double buffer (or triple depending on game fps vs screen fps) */
|
||||
+ /* pointed by par->info->screen_buffer. The buffer pointed (the one being written) should */
|
||||
+ /* change using the FBIOPAN_DISPLAY ioctl called by SDL_Flip() (in FB_FlipHWSurface) */
|
||||
+ /* This is a dirty but very efficient alternative for now: we make a quick memcpy of the */
|
||||
+ /* screen_buffer in another one. It goes so fast that the "applicative" */
|
||||
+ /* tearing that could happen if this function were to launch in the middle of a */
|
||||
+ /* user space SDL_BlitSurface(sw_surface, NULL, hw_surface, NULL) call */
|
||||
+ /* is so unbelievably rare that completey unnoticeable and it takes up so little CPU */
|
||||
+ /* that really, it's worth the compromise for now */
|
||||
memcpy(par->vmem_post_process + par->write_line_start * par->info->fix.line_length,
|
||||
par->info->screen_buffer + par->write_line_start * par->info->fix.line_length,
|
||||
(par->write_line_end-par->write_line_start+1) * par->info->fix.line_length);
|
||||
@@ -623,6 +640,9 @@ void fbtft_post_process_screen(struct fbtft_par *par){
|
||||
fbtft_rotate_soft((u16*)par->vmem_post_process, par->info->var.yres, par->pdata->rotate_soft);
|
||||
}
|
||||
}
|
||||
+ else{
|
||||
+ par->vmem_ptr = par->info->screen_buffer;
|
||||
+ }
|
||||
}
|
||||
|
||||
static void fbtft_deferred_io(struct fb_info *info, struct list_head *pagelist)
|
||||
@@ -690,31 +710,19 @@ static void fbtft_deferred_io(struct fb_info *info, struct list_head *pagelist)
|
||||
}
|
||||
|
||||
/* Copy buffer */
|
||||
- if(dirty_lines_start!=0 || dirty_lines_end!=par->info->var.yres - 1){
|
||||
+ /*if(dirty_lines_start!=0 || dirty_lines_end!=par->info->var.yres - 1){
|
||||
printk("dirty_lines_start = %d, dirty_lines_end = %d\n", dirty_lines_start, dirty_lines_end);
|
||||
- }
|
||||
+ }*/
|
||||
/*dirty_lines_start = 0;
|
||||
dirty_lines_end = par->info->var.yres - 1;*/
|
||||
par->write_line_start = dirty_lines_start;
|
||||
par->write_line_end = dirty_lines_end;
|
||||
- memcpy(par->vmem_post_process + dirty_lines_start * par->info->fix.line_length,
|
||||
- par->info->screen_buffer + dirty_lines_start * par->info->fix.line_length,
|
||||
- (dirty_lines_end-dirty_lines_start+1) * par->info->fix.line_length);
|
||||
- par->vmem_ptr = par->vmem_post_process;
|
||||
|
||||
+ /* Post process screen for doufle buf cpy, notifs, rotation soft... */
|
||||
+ fbtft_post_process_screen(par);
|
||||
|
||||
- /* Exit in SPI async mode, otherwise update screen now */
|
||||
- if (par->spi_async_mode){
|
||||
- fbtft_start_new_screen_transfer_async(par);
|
||||
- return;
|
||||
- }
|
||||
- else{
|
||||
- /* Post process screen for doufle buf cpy, notifs, rotation soft... */
|
||||
- fbtft_post_process_screen(par);
|
||||
-
|
||||
- /* Screen upgrade */
|
||||
- par->fbtftops.update_display(par, dirty_lines_start, dirty_lines_end);
|
||||
- }
|
||||
+ /* Screen upgrade */
|
||||
+ par->fbtftops.update_display(par, dirty_lines_start, dirty_lines_end);
|
||||
}
|
||||
|
||||
static void fbtft_fb_fillrect(struct fb_info *info,
|
||||
@@ -1182,11 +1190,13 @@ struct fb_info *fbtft_framebuffer_alloc(struct fbtft_display *display,
|
||||
par->vmem_post_process = vmem_post_process;
|
||||
par->vmem_ptr = par->info->screen_buffer;
|
||||
par->pdata = pdata;
|
||||
+ pdata->par = par;
|
||||
par->debug = display->debug;
|
||||
par->buf = buf;
|
||||
spin_lock_init(&par->dirty_lock);
|
||||
par->bgr = pdata->bgr;
|
||||
par->spi_async_mode = pdata->spi_async_mode;
|
||||
+ par->ready_for_spi_async = false;
|
||||
par->interlacing = pdata->interlacing;
|
||||
par->startbyte = pdata->startbyte;
|
||||
par->init_sequence = init_sequence;
|
||||
@@ -1648,10 +1658,40 @@ static u32 fbtft_of_value(struct device_node *node, const char *propname)
|
||||
return val;
|
||||
}
|
||||
|
||||
+
|
||||
+static irqreturn_t irq_TE_handler(int irq_no, void *dev_id)
|
||||
+{
|
||||
+ struct fbtft_platform_data *pdata = (struct fbtft_platform_data *) dev_id;
|
||||
+
|
||||
+//#define DEBUG_TE_IRQ_COUNT
|
||||
+#ifdef DEBUG_TE_IRQ_COUNT
|
||||
+ static ktime_t prev_ts = 0;
|
||||
+ static int te_count = 0;
|
||||
+ static int nb_sec = 5;
|
||||
+ te_count++;
|
||||
+
|
||||
+ ktime_t ts_now = ktime_get();
|
||||
+ if(ktime_us_delta(ts_now, prev_ts) > nb_sec*1000000){
|
||||
+ prev_ts = ts_now;
|
||||
+ printk("TE irq: %d times/sec\n", te_count/nb_sec);
|
||||
+ te_count = 0;
|
||||
+ }
|
||||
+#endif //DEBUG_TE_IRQ_COUNT
|
||||
+
|
||||
+ fbtft_start_new_screen_transfer_async(pdata->par);
|
||||
+
|
||||
+ return IRQ_HANDLED;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+
|
||||
static struct fbtft_platform_data *fbtft_probe_dt(struct device *dev)
|
||||
{
|
||||
struct device_node *node = dev->of_node;
|
||||
struct fbtft_platform_data *pdata;
|
||||
+ int gpio, irq_id, err;
|
||||
+ enum of_gpio_flags of_flags;
|
||||
+ char *te_irq_name;
|
||||
|
||||
if (!node) {
|
||||
dev_err(dev, "Missing platform data or DT\n");
|
||||
@@ -1685,6 +1725,37 @@ static struct fbtft_platform_data *fbtft_probe_dt(struct device *dev)
|
||||
pdata->display.fbtftops.init_display = fbtft_init_display_dt;
|
||||
pdata->display.fbtftops.request_gpios = fbtft_request_gpios_dt;
|
||||
|
||||
+ /* TE signal for Vsync */
|
||||
+ pdata->te_irq = false;
|
||||
+ te_irq_name = "te-irq";
|
||||
+ if (of_find_property(node, te_irq_name, NULL)) {
|
||||
+ gpio = of_get_named_gpio_flags(node, te_irq_name, 0, &of_flags);
|
||||
+ if (gpio == -ENOENT || gpio == -EPROBE_DEFER || gpio < 0) {
|
||||
+ dev_err(dev,
|
||||
+ "failed to get '%s' from DT\n", te_irq_name);
|
||||
+ }
|
||||
+ else{
|
||||
+ pr_info("%s: '%s' = GPIO%d\n", __func__, te_irq_name, gpio);
|
||||
+
|
||||
+ irq_id = gpio_to_irq(gpio);
|
||||
+ if(irq_id < 0) {
|
||||
+ dev_err(dev,"%s - Unable to request IRQ: %d\n", __func__, irq_id);
|
||||
+ }
|
||||
+ else{
|
||||
+ pr_info("TE GPIO%d, IRQ id = %d\n", gpio, irq_id);
|
||||
+
|
||||
+ err = request_irq(irq_id, irq_TE_handler, IRQF_SHARED | IRQF_TRIGGER_RISING,
|
||||
+ "TE", pdata);
|
||||
+ if (err < 0) {
|
||||
+ dev_err(dev,"ERROR initializing TE signal irq\n");
|
||||
+ }
|
||||
+ else{
|
||||
+ pdata->te_irq = true;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
return pdata;
|
||||
}
|
||||
#else
|
||||
@@ -1817,7 +1888,12 @@ int fbtft_probe_common(struct fbtft_display *display,
|
||||
/* Start constant Display update using spi async*/
|
||||
par->write_line_start = 0;
|
||||
par->write_line_end = par->info->var.yres - 1;
|
||||
- fbtft_start_new_screen_transfer_async(par);
|
||||
+ if(par->pdata->te_irq){
|
||||
+ par->ready_for_spi_async = true;
|
||||
+ }
|
||||
+ else{
|
||||
+ fbtft_start_new_screen_transfer_async(par);
|
||||
+ }
|
||||
}
|
||||
|
||||
return 0;
|
||||
diff --git a/drivers/staging/fbtft/fbtft.h b/drivers/staging/fbtft/fbtft.h
|
||||
index 64dec83..8a9daee 100644
|
||||
--- a/drivers/staging/fbtft/fbtft.h
|
||||
+++ b/drivers/staging/fbtft/fbtft.h
|
||||
@@ -154,12 +154,14 @@ struct fbtft_platform_data {
|
||||
unsigned long rotate_soft;
|
||||
bool bgr;
|
||||
bool spi_async_mode;
|
||||
+ bool te_irq;
|
||||
bool interlacing;
|
||||
unsigned int fps;
|
||||
int txbuflen;
|
||||
u8 startbyte;
|
||||
char *gamma;
|
||||
void *extra;
|
||||
+ struct fbtft_par *par;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -263,6 +265,7 @@ struct fbtft_par {
|
||||
|
||||
/* SPI async */
|
||||
bool spi_async_mode;
|
||||
+ bool ready_for_spi_async;
|
||||
bool interlacing;
|
||||
bool odd_line;
|
||||
int cur_line;
|
||||
--
|
||||
1.9.1
|
||||
|
||||
@ -1,45 +0,0 @@
|
||||
From 709159a6428f696915df4ff9795af86ddc328740 Mon Sep 17 00:00:00 2001
|
||||
From: vincent <vbusoenseirb@gmail.com>
|
||||
Date: Mon, 28 Sep 2020 15:05:59 +0200
|
||||
Subject: [PATCH] battery charge current set to 400mA
|
||||
|
||||
---
|
||||
arch/arm/boot/dts/sun8i-v3s-funkey.dts | 8 +++++++-
|
||||
1 file changed, 7 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/arch/arm/boot/dts/sun8i-v3s-funkey.dts b/arch/arm/boot/dts/sun8i-v3s-funkey.dts
|
||||
index 24e26b2..ffff865 100644
|
||||
--- a/arch/arm/boot/dts/sun8i-v3s-funkey.dts
|
||||
+++ b/arch/arm/boot/dts/sun8i-v3s-funkey.dts
|
||||
@@ -63,6 +63,11 @@
|
||||
default-brightness-level = <11>;
|
||||
power-supply = <®_vcc5v0>;
|
||||
};
|
||||
+
|
||||
+ bat: battery {
|
||||
+ compatible = "simple-battery";
|
||||
+ constant_charge_current_max_microamp = <400000>;
|
||||
+ };
|
||||
};
|
||||
|
||||
&codec {
|
||||
@@ -121,6 +126,7 @@
|
||||
|
||||
&battery_power_supply {
|
||||
status = "okay";
|
||||
+ monitored-battery = <&bat>;
|
||||
};
|
||||
|
||||
&usb_power_supply {
|
||||
@@ -177,7 +183,7 @@
|
||||
reg = <0>;
|
||||
spi-max-frequency = <50000000>;
|
||||
txbuflen = <115202>;
|
||||
-// txbuflen = <0>;
|
||||
+ //txbuflen = <0>;
|
||||
spi_async_mode = "true";
|
||||
//interlacing = "true";
|
||||
rotate = <0>;
|
||||
--
|
||||
1.9.1
|
||||
|
||||
@ -1,25 +0,0 @@
|
||||
From 4e80937d23c58478e8a3ffe3a5cdb4114497c638 Mon Sep 17 00:00:00 2001
|
||||
From: vincent <vbusoenseirb@gmail.com>
|
||||
Date: Tue, 29 Sep 2020 08:32:44 +0200
|
||||
Subject: [PATCH] increasd buffer size for fb_tft_notif zone to 400
|
||||
|
||||
---
|
||||
drivers/staging/fbtft/fbtft.h | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/staging/fbtft/fbtft.h b/drivers/staging/fbtft/fbtft.h
|
||||
index 8a9daee..4638ad9 100644
|
||||
--- a/drivers/staging/fbtft/fbtft.h
|
||||
+++ b/drivers/staging/fbtft/fbtft.h
|
||||
@@ -28,7 +28,7 @@
|
||||
#define FBTFT_GAMMA_MAX_VALUES_TOTAL 128
|
||||
#define FBTFT_OVERLAY_NB_VALUES 4
|
||||
|
||||
-#define FBTFT_NOTIF_MAX_SIZE 256
|
||||
+#define FBTFT_NOTIF_MAX_SIZE 400
|
||||
|
||||
#define FBTFT_OF_INIT_CMD BIT(24)
|
||||
#define FBTFT_OF_INIT_DELAY BIT(25)
|
||||
--
|
||||
1.9.1
|
||||
|
||||
@ -1,207 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Michel Stempin <michel.stempin@wanadoo.fr>
|
||||
*
|
||||
* This file is dual-licensed: you can use it either under the terms
|
||||
* of the GPL or the X11 license, at your option. Note that this dual
|
||||
* licensing only applies to this file, and not this project as a
|
||||
* whole.
|
||||
*
|
||||
* a) This file 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.
|
||||
*
|
||||
* This file is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* Or, alternatively,
|
||||
*
|
||||
* b) Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use,
|
||||
* copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following
|
||||
* conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/dts-v1/;
|
||||
#include "sun8i-v3s.dtsi"
|
||||
#include "sunxi-common-regulators.dtsi"
|
||||
|
||||
/ {
|
||||
model = "FunKey";
|
||||
compatible = "funkey", "allwinner,sun8i-v3s";
|
||||
|
||||
aliases {
|
||||
serial0 = &uart0;
|
||||
};
|
||||
|
||||
chosen {
|
||||
stdout-path = "serial0:115200n8";
|
||||
};
|
||||
|
||||
backlight: backlight {
|
||||
compatible = "pwm-backlight";
|
||||
pwms = <&pwm 0 1000000 0>;
|
||||
brightness-levels = <0 10 20 30 40 50 60 70 80 90 100>;
|
||||
default-brightness-level = <10>;
|
||||
power-supply = <®_vcc5v0>;
|
||||
};
|
||||
};
|
||||
|
||||
&codec {
|
||||
allwinner,audio-routing =
|
||||
"Headphone", "HP",
|
||||
"Headphone", "HPCOM",
|
||||
"MIC1", "Mic",
|
||||
"Mic", "HBIAS";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&ehci0 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&i2c0 {
|
||||
status = "okay";
|
||||
|
||||
axp209: pmic@34 {
|
||||
compatible = "x-powers,axp209";
|
||||
reg = <0x34>;
|
||||
interrupt-parent = <&pio>;
|
||||
interrupts = <1 5 IRQ_TYPE_EDGE_FALLING>;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <1>;
|
||||
};
|
||||
};
|
||||
|
||||
&mmc0 {
|
||||
pinctrl-0 = <&mmc0_pins_a>;
|
||||
pinctrl-names = "default";
|
||||
broken-cd;
|
||||
bus-width = <4>;
|
||||
vmmc-supply = <®_vcc3v3>;
|
||||
vqmmc-supply = <®_vcc3v3>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&ohci0 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
#include "axp209.dtsi"
|
||||
|
||||
&ac_power_supply {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&axp_gpio {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&battery_power_supply {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&usb_power_supply {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
®_dcdc2 {
|
||||
regulator-always-on;
|
||||
regulator-min-microvolt = <1000000>;
|
||||
regulator-max-microvolt = <1400000>;
|
||||
regulator-name = "vdd-cpu-sys-ephy";
|
||||
};
|
||||
|
||||
®_dcdc3 {
|
||||
regulator-always-on;
|
||||
regulator-min-microvolt = <3000000>;
|
||||
regulator-max-microvolt = <3450000>;
|
||||
regulator-name = "vcc-io-ephy-mcsi-usb";
|
||||
};
|
||||
|
||||
®_ldo1 {
|
||||
regulator-min-microvolt = <3000000>;
|
||||
regulator-max-microvolt = <3600000>;
|
||||
regulator-name = "vcc-rtc";
|
||||
};
|
||||
|
||||
®_ldo2 {
|
||||
regulator-always-on;
|
||||
regulator-min-microvolt = <2800000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
regulator-name = "avcc-pll";
|
||||
};
|
||||
|
||||
®_vcc3v0 {
|
||||
regulator-always-on;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
®_vcc3v3 {
|
||||
regulator-always-on;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
®_vcc5v0 {
|
||||
regulator-always-on;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&spi0 {
|
||||
status = "okay";
|
||||
|
||||
st7789v@0 {
|
||||
compatible = "sitronix,st7789v";
|
||||
reg = <0>;
|
||||
spi-max-frequency = <40000000>;
|
||||
txbuflen = <115200>;
|
||||
rotate = <0>;
|
||||
fps = <39>;
|
||||
buswidth = <8>;
|
||||
reset-gpios = <&pio 4 1 GPIO_ACTIVE_LOW>; //PE1
|
||||
dc-gpios = <&pio 2 0 GPIO_ACTIVE_LOW>; //PC0 (MISO)
|
||||
debug = <0>;
|
||||
};
|
||||
};
|
||||
|
||||
&uart0 {
|
||||
pinctrl-0 = <&uart0_pins_a>;
|
||||
pinctrl-names = "default";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&pwm {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pwm0_pins>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&usb_otg {
|
||||
dr_mode = "peripheral";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&usbphy {
|
||||
usb0_vbus-supply = <®_vcc5v0>;
|
||||
phy-supply = <®_vcc5v0>;
|
||||
vcc = <®_vcc5v0>;
|
||||
status = "okay";
|
||||
};
|
||||
File diff suppressed because it is too large
Load Diff
@ -19,7 +19,7 @@ BR2_ROOTFS_POST_SCRIPT_ARGS="-c $(BR2_EXTERNAL_FUNKEY_PATH)/board/funkey/genimag
|
||||
BR2_LINUX_KERNEL=y
|
||||
BR2_LINUX_KERNEL_CUSTOM_GIT=y
|
||||
BR2_LINUX_KERNEL_CUSTOM_REPO_URL="https://github.com/FunKey-Project/linux"
|
||||
BR2_LINUX_KERNEL_CUSTOM_REPO_VERSION="cda44c146b9b87290bc7c636ffa7d88cbfb03ace"
|
||||
BR2_LINUX_KERNEL_CUSTOM_REPO_VERSION="932bc41a1a2ce477855240d39edbf7a9af5b7490"
|
||||
BR2_LINUX_KERNEL_USE_CUSTOM_CONFIG=y
|
||||
BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE="$(BR2_EXTERNAL_FUNKEY_PATH)/board/funkey/linux.config"
|
||||
BR2_LINUX_KERNEL_LZO=y
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user