Jump to content

Tinker Board and the RPI 7" touchscreen


enki

Recommended Posts

I don't have any hardware for the DSI interface, I'm assuming that's how the display is attached?  There will be some necessary device tree adjustment for it, but without the hardware I can't do any testing.

Link to comment
Share on other sites

Initial test resulted in an "oops": 

Spoiler

[    3.317656] Internal error: Oops: 80000005 [#1] PREEMPT SMP ARM
[    3.324275] Modules linked in:
[    3.327692] CPU: 0 PID: 3 Comm: kworker/0:0 Not tainted 4.13.0-rockchip #16
[    3.335471] Hardware name: Rockchip (Device Tree)
[    3.340735] Workqueue: events deferred_probe_work_func
[    3.346477] task: ee948e80 task.stack: ee960000
[    3.351536] PC is at 0x4
[    3.354368] LR is at drm_mode_config_cleanup+0x48/0x254
[    3.360196] pc : [<00000004>]    lr : [<c0742134>]    psr: 20000033
[    3.367199] sp : ee961ce0  ip : ee961d08  fp : ee961d04
[    3.373035] r10: eeaa5a10  r9 : 00000000  r8 : 00000000
[    3.378873] r7 : 00000001  r6 : ed9d6660  r5 : fffffffc  r4 : ed9d6400
[    3.386167] r3 : 00000005  r2 : c11de1ac  r1 : 00007500  r0 : ed9e6720
[    3.393463] Flags: nzCv  IRQs on  FIQs on  Mode SVC_32  ISA Thumb  Segment none
[    3.401631] Control: 10c5387d  Table: 0000406a  DAC: 00000051
[    3.408050] Process kworker/0:0 (pid: 3, stack limit = 0xee960218)
[    3.414956] Stack: (0xee961ce0 to 0xee962000)
[    3.419827] 1ce0: eda1c018 00000000 00000001 ed9d6400 fffffdfb 00000000 ee961d44 ee961d08
[    3.428961] 1d00: c07483fc c07420f8 00000000 00000001 ffffffff 00000000 ee961d44 eda45640
[    3.438104] 1d20: ee27ff80 eda2303c 00000004 eda450d8 00000000 c12929e0 ee961d7c ee961d48
[    3.447247] 1d40: c0758ecc c07482c0 eeb0fe10 c074810c c0758af4 eda45640 00000000 c12929e0
[    3.456390] 1d60: c0d7aaf0 eeaa5a10 c1292414 c1292ed8 ee961da4 ee961d80 c0759098 c0758dac
[    3.465533] 1d80: 00000003 eeaa5a10 eeb0fe10 00000000 c176afac c1292414 ee961de4 ee961da8
[    3.474676] 1da0: c0748604 c075901c eeb0fe10 eeaa5a10 eeaa5a10 eda450d8 00000000 c07484a0
[    3.483819] 1dc0: eeaa5a10 c12921a8 00000000 c12921a8 00000131 00000000 ee961e04 ee961de8
[    3.492963] 1de0: c07606d8 c07484ac eeaa5a10 c176b020 00000000 00000000 ee961e2c ee961e08
[    3.502107] 1e00: c075e764 c0760684 c12921a8 eeaa5a10 ee961e78 eeaa5a44 eed9a300 c12e7294
[    3.511251] 1e20: ee961e4c ee961e30 c075ea94 c075e610 00000000 ee961e78 c075e9e4 eeaa5a44
[    3.520395] 1e40: ee961e74 ee961e50 c075cde8 c075e9f0 ee802090 ee27abc4 eeaa5a10 eeaa5a10
[    3.529537] 1e60: c1292ed8 00000001 ee961e9c ee961e78 c075e53c c075cd60 eeaa5a10 00000001
[    3.538680] 1e80: c1292c74 c1292ed8 eeaa5a10 00000000 ee961eac ee961ea0 c075eabc c075e4ac
[    3.547823] 1ea0: ee961ecc ee961eb0 c075dadc c075eaac c1292c74 eeaa5a10 c1292c9c 00000000
[    3.556966] 1ec0: ee961eec ee961ed0 c075df84 c075dab0 ee91f080 c1292ca4 eed97040 00000000
[    3.566109] 1ee0: ee961f2c ee961ef0 c013a23c c075df20 c0ce7e80 c120a34c ee961f44 00000004
[    3.575251] 1f00: c013a3f8 ee91f080 ee91f098 eed97040 c1203900 eed97064 ee91f098 00000008
[    3.584394] 1f20: ee961f44 ee961f30 c013a4c4 c0139ff4 ee91f080 eed97040 ee961f74 ee961f48
[    3.593538] 1f40: c013b0bc c013a498 ee948e80 ee91f100 ee92b040 ee960000 00000000 ee91f080
[    3.602682] 1f60: c013add0 ee951e7c ee961fac ee961f78 c013fe90 c013addc ee91f128 ee91f128
[    3.611824] 1f80: ee961fac ee92b040 c013fd40 00000000 00000000 00000000 00000000 00000000
[    3.620967] 1fa0: 00000000 ee961fb0 c01079d8 c013fd4c 00000000 00000000 00000000 00000000
[    3.630109] 1fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[    3.639252] 1fe0: 00000000 00000000 00000000 00000000 00000013 00000000 00000000 00000000
[    3.648406] [<c0742134>] (drm_mode_config_cleanup) from [<c07483fc>] (rockchip_drm_bind+0x148/0x1ec)
[    3.658621] [<c07483fc>] (rockchip_drm_bind) from [<c0758ecc>] (try_to_bring_up_master+0x12c/0x174)
[    3.668739] [<c0758ecc>] (try_to_bring_up_master) from [<c0759098>] (component_master_add_with_match+0x88/0xc4)
[    3.680021] [<c0759098>] (component_master_add_with_match) from [<c0748604>] (rockchip_drm_platform_probe+0x164/0x19c)
[    3.691982] [<c0748604>] (rockchip_drm_platform_probe) from [<c07606d8>] (platform_drv_probe+0x60/0xb0)
[    3.702487] [<c07606d8>] (platform_drv_probe) from [<c075e764>] (driver_probe_device+0x160/0x2e0)
[    3.712410] [<c075e764>] (driver_probe_device) from [<c075ea94>] (__device_attach_driver+0xb0/0xbc)
[    3.722527] [<c075ea94>] (__device_attach_driver) from [<c075cde8>] (bus_for_each_drv+0x94/0xa4)
[    3.732353] [<c075cde8>] (bus_for_each_drv) from [<c075e53c>] (__device_attach+0x9c/0x114)
[    3.741596] [<c075e53c>] (__device_attach) from [<c075eabc>] (device_initial_probe+0x1c/0x20)
[    3.751129] [<c075eabc>] (device_initial_probe) from [<c075dadc>] (bus_probe_device+0x38/0x90)
[    3.760761] [<c075dadc>] (bus_probe_device) from [<c075df84>] (deferred_probe_work_func+0x70/0x94)
[    3.770783] [<c075df84>] (deferred_probe_work_func) from [<c013a23c>] (process_one_work+0x254/0x4a4)
[    3.780996] [<c013a23c>] (process_one_work) from [<c013a4c4>] (process_scheduled_works+0x38/0x40)
[    3.790918] [<c013a4c4>] (process_scheduled_works) from [<c013b0bc>] (worker_thread+0x2ec/0x404)
[    3.800743] [<c013b0bc>] (worker_thread) from [<c013fe90>] (kthread+0x150/0x170)
[    3.809015] [<c013fe90>] (kthread) from [<c01079d8>] (ret_from_fork+0x14/0x3c)
[    3.817088] Code: bad PC value

 

I'll start digging around.  The "ASUS" screen appears to be functionally identical to the RPI one, using the TC358762XBG display bridge.  I will say up front, powering the screen via the Tinker Board or the Tinker Board via the screen will be nothing but trouble, it would be best to feed both independently.

 

Looking through, there were some DRM commits related to display on the Tinkerboard Kernel.  I'll see what if they can move to the mainline.  If not, this will probably have to become a discussion about adding support to the legacy kernel.

Link to comment
Share on other sites

Patched in the driver, however the function of_get_drm_display_mode() has an added parameter (u32 *bus_flags), keeping it from building (could be more, this is just the first one).    <---resolved

It's device tree parameter related, has pixel clock and DE polarity information, according to the source file.

 

Had to add an I2C "tinker_mcu" driver and the panel driver.  So far, I'm getting a collection of errors and a mess on the screen, but it is commanding the backlight on and off, so that's something.

 

Spoiler

[    2.663139] tinker-mcu: send_cmds: 8501
[    2.685132] tinker-mcu: send_cmds: 8104
[    2.689758] tinker-mcu: send_cmds: send command failed, ret = -6
[    2.689772] dw-mipi-dsi ff960000.mipi: unsupported message type 0x29
[    2.689780] bridge-tc358762-dsi ff960000.mipi.0: failed to writing gen seq
[    2.689789] dw-mipi-dsi ff960000.mipi: unsupported message type 0x29
[    2.689796] bridge-tc358762-dsi ff960000.mipi.0: failed to writing gen seq
[    2.689803] dw-mipi-dsi ff960000.mipi: unsupported message type 0x29
[    2.689810] bridge-tc358762-dsi ff960000.mipi.0: failed to writing gen seq
[    2.689818] dw-mipi-dsi ff960000.mipi: unsupported message type 0x29
[    2.689824] bridge-tc358762-dsi ff960000.mipi.0: failed to writing gen seq
[    2.689832] dw-mipi-dsi ff960000.mipi: unsupported message type 0x29
[    2.689838] bridge-tc358762-dsi ff960000.mipi.0: failed to writing gen seq
[    2.689846] dw-mipi-dsi ff960000.mipi: unsupported message type 0x29
[    2.689852] bridge-tc358762-dsi ff960000.mipi.0: failed to writing gen seq
[    2.689860] dw-mipi-dsi ff960000.mipi: unsupported message type 0x29
[    2.689866] bridge-tc358762-dsi ff960000.mipi.0: failed to writing gen seq
[    2.689874] dw-mipi-dsi ff960000.mipi: unsupported message type 0x29
[    2.689880] bridge-tc358762-dsi ff960000.mipi.0: failed to writing gen seq
[    2.689888] dw-mipi-dsi ff960000.mipi: unsupported message type 0x29
[    2.689895] bridge-tc358762-dsi ff960000.mipi.0: failed to writing gen seq
[    2.689902] dw-mipi-dsi ff960000.mipi: unsupported message type 0x29
[    2.689908] bridge-tc358762-dsi ff960000.mipi.0: failed to writing gen seq
[    2.689916] dw-mipi-dsi ff960000.mipi: unsupported message type 0x29
[    2.689922] bridge-tc358762-dsi ff960000.mipi.0: failed to writing gen seq
[    2.689930] dw-mipi-dsi ff960000.mipi: unsupported message type 0x29
[    2.689936] bridge-tc358762-dsi ff960000.mipi.0: failed to writing gen seq
[    2.689944] dw-mipi-dsi ff960000.mipi: unsupported message type 0x29
[    2.689950] bridge-tc358762-dsi ff960000.mipi.0: failed to writing gen seq
[    2.689958] dw-mipi-dsi ff960000.mipi: unsupported message type 0x29
[    2.689964] bridge-tc358762-dsi ff960000.mipi.0: failed to writing gen seq
[    2.689972] dw-mipi-dsi ff960000.mipi: unsupported message type 0x29
[    2.689978] bridge-tc358762-dsi ff960000.mipi.0: failed to writing gen seq
[    2.689986] dw-mipi-dsi ff960000.mipi: unsupported message type 0x29
[    2.689992] bridge-tc358762-dsi ff960000.mipi.0: failed to writing gen seq
[    2.690044] tinker-mcu: tinker_mcu_set_bright: bright = 0xff

 

 

Tracking down what I2C command failed, I think it's probably the mode set command before sending data.

Link to comment
Share on other sites

The ASUS driver and the RPi driver, despite "doing the same thing", do it quite differently.  I'm going to try this in the 4.4 first to reduce the amount of extra work and possible incompatibilities.

Link to comment
Share on other sites

Well, this "driver" was written like quite a lot of ASUS's Tinker OS code, full of "magic numbers" and hackish shortcuts.  For instance, using the numeric value "8500" instead of having an enumerated "register" and setting the proper bits.  "8500" tells the atmega micro on the display control board to power up the device)

Link to comment
Share on other sites

Trying on 4.4 kernel tonight, I got an entirely different behavior, no backlights or anything, and a command received message.  I am going to review the code tomorrow to make sure I didn't miss a patch, it should be saying more than that.

 

[    3.052832] tinker-mcu: tinker_mcu_probe: address = 0x45
[    3.052849] tinker-mcu: send_cmds: 80
[    3.105012] tinker-mcu: init_cmd_check: recv_cmds: 0xC3

 

Link to comment
Share on other sites

On 31. 7. 2017 at 10:41 PM, enki said:

great h/w

 

With a great hardware design failure - powering power hungry chip via micro USB which leads to instability. This is a fail even in less power hunger design. And we pay the price for this, since people think it's a software problem. :angry:

Link to comment
Share on other sites

Sadly @tkaiser is right, the advertised specs and potential of such a board is great, but the reality is lacking any attention to detail or due diligence.  It is a terribly disappointing board in my honest opinion.  

 

Now, to the task at hand: behold Armbian legacy with DSI display.  4.4 kernel 

 

I'm going to have to take a look at why this doesn't work on later kernels.

 

No HID device yet, so still to-do items. [EDIT]  I found the touchscreen driver, we'll see.  Then I'll have to have someone with a MiQi test that everything is still ok on their side.

 

 

 

1502167778277737718430.jpg

Link to comment
Share on other sites

HID is now working, of course the touch input does not rotate with the screen (perfect compatibility with raspberry pi! :rolleyes:)

 

I can link to the Deb packages for the kernel/dtb if anyone wants to try them out, and if anyone with a MiQi can make sure they don't break anything before I push the patch to the repo.

Link to comment
Share on other sites

I'm not worried about the dts or the drivers themselves, it's this chunk in particular:

 

diff --git a/arch/arm/mach-rockchip/rockchip.c b/arch/arm/mach-rockchip/rockchip.c
index 7fbecd0..4a81c18 100644
--- a/arch/arm/mach-rockchip/rockchip.c
+++ b/arch/arm/mach-rockchip/rockchip.c
@@ -23,6 +23,7 @@
 #include <linux/clocksource.h>
 #include <linux/mfd/syscon.h>
 #include <linux/regmap.h>
+#include <linux/i2c.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 #include <asm/hardware/cache-l2x0.h>
@@ -33,6 +34,18 @@
 #define RK3288_GRF_SOC_CON2 0x24C
 #define RK3288_TIMER6_7_PHYS 0xff810000
 
+static struct i2c_board_info __initdata i2c_devices_tinker_mcu[] = {
+      {
+               I2C_BOARD_INFO("tinker_mcu", 0x45),
+      },
+};
+
+static struct i2c_board_info __initdata i2c_devices_tinker_ft5406[] = {
+      {
+               I2C_BOARD_INFO("tinker_ft5406", 0x38),
+      },
+};
+
 static void __init rockchip_timer_init(void)
 {
 	if (of_machine_is_compatible("rockchip,rk3288")) {
@@ -80,6 +93,9 @@ static void __init rockchip_dt_init(void)
 	rockchip_suspend_init();
 	of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
 	platform_device_register_simple("cpufreq-dt", 0, NULL, 0);
+
+	i2c_register_board_info(3, i2c_devices_tinker_mcu, ARRAY_SIZE(i2c_devices_tinker_mcu));
+	i2c_register_board_info(3, i2c_devices_tinker_ft5406, ARRAY_SIZE(i2c_devices_tinker_ft5406));
 }
 
 static const char * const rockchip_board_dt_compat[] = {

 

Link to comment
Share on other sites

Yeah, in the case of Rockchip 3288 boards, which are quite versatile, this is evil IMHO. Worst case, check if the board is the ASUS Tinky.

Now I think that, for the best case, the definition should be done in the DTS files and, if needed, additional detection code should be added in the i2c drivers used. The static init seems to be only good if you're selling one special hardware which has all the things integrated and don't have any alternative (or the alternatives also have the same I2C hardware) like a TV + DVR recorder or some industrial thingy.

 

See Method 1 and Method 2 for details :

http://elixir.free-electrons.com/linux/latest/source/Documentation/i2c/instantiating-devices

 

Quote

 


Method 1b: Declare the I2C devices via devicetree
-------------------------------------------------

This method has the same implications as method 1a. The declaration of I2C
devices is here done via devicetree as subnodes of the master controller.

Example:

	i2c1: i2c@400a0000 {
		/* ... master properties skipped ... */
		clock-frequency = <100000>;

		flash@50 {
			compatible = "atmel,24c256";
			reg = <0x50>;
		};

		pca9532: gpio@60 {
			compatible = "nxp,pca9532";
			gpio-controller;
			#gpio-cells = <2>;
			reg = <0x60>;
		};
	};

Here, two devices are attached to the bus using a speed of 100kHz. For
additional properties which might be needed to set up the device, please refer
to its devicetree documentation in Documentation/devicetree/bindings/.

Method 2: Instantiate the devices explicitly
--------------------------------------------

This method is appropriate when a larger device uses an I2C bus for
internal communication. A typical case is TV adapters. These can have a
tuner, a video decoder, an audio decoder, etc. usually connected to the
main chip by the means of an I2C bus. You won't know the number of the I2C
bus in advance, so the method 1 described above can't be used. Instead,
you can instantiate your I2C devices explicitly. This is done by filling
a struct i2c_board_info and calling i2c_new_device().

Example (from the sfe4001 network driver):

static struct i2c_board_info sfe4001_hwmon_info = {
	I2C_BOARD_INFO("max6647", 0x4e),
};

int sfe4001_init(struct efx_nic *efx)
{
	(...)
	efx->board_info.hwmon_client =
		i2c_new_device(&efx->i2c_adap, &sfe4001_hwmon_info);

	(...)
}

The above code instantiates 1 I2C device on the I2C bus which is on the
network adapter in question.

A variant of this is when you don't know for sure if an I2C device is
present or not (for example for an optional feature which is not present
on cheap variants of a board but you have no way to tell them apart), or
it may have different addresses from one board to the next (manufacturer
changing its design without notice). In this case, you can call
i2c_new_probed_device() instead of i2c_new_device().

Example (from the nxp OHCI driver):

static const unsigned short normal_i2c[] = { 0x2c, 0x2d, I2C_CLIENT_END };

static int usb_hcd_nxp_probe(struct platform_device *pdev)
{
	(...)
	struct i2c_adapter *i2c_adap;
	struct i2c_board_info i2c_info;

	(...)
	i2c_adap = i2c_get_adapter(2);
	memset(&i2c_info, 0, sizeof(struct i2c_board_info));
	strlcpy(i2c_info.type, "isp1301_nxp", I2C_NAME_SIZE);
	isp1301_i2c_client = i2c_new_probed_device(i2c_adap, &i2c_info,
						   normal_i2c, NULL);
	i2c_put_adapter(i2c_adap);
	(...)
}

The above code instantiates up to 1 I2C device on the I2C bus which is on
the OHCI adapter in question. It first tries at address 0x2c, if nothing
is found there it tries address 0x2d, and if still nothing is found, it
simply gives up.

The driver which instantiated the I2C device is responsible for destroying
it on cleanup. This is done by calling i2c_unregister_device() on the
pointer that was earlier returned by i2c_new_device() or
i2c_new_probed_device().

 

 

Link to comment
Share on other sites

Circling back on this one, I've had quite a lot to do around the house with winter approaching, here in a few weeks it should settle down. (Just in time for the holiday season here in the US...)

 

@Myy, thanks for the info, I will attempt this with the DT rather than the explicit code.  I might drop a line to Wzyy about it too, since they are now using DT overlays on their kernel.  What this means is that, for now, this would have to be enabled via editing the DT file by the user after I get it working in this manner.

Link to comment
Share on other sites

OK, some progress on 4.4 using device tree.  Not much, but a start. 

 

[    3.063423] tinker-mcu: tinker_mcu_probe: address = 0x45
[    3.063440] tinker-mcu: send_cmds: 80
[    3.115505] tinker-mcu: init_cmd_check: recv_cmds: 0xC3
...
[    3.197508] tinker-ft5406: tinker_ft5406_probe: address = 0x38
[    3.197774] input: fts_ts as /devices/platform/ff150000.i2c/i2c-3/3-0038/input/input0
[    3.198446] tinker-ft5406: fts_i2c_read: i2c read error, -6
[    3.198458] tinker-ft5406: tinker_ft5406_work: checking touch ic, countdown: 8

 

Basically the drivers are being loaded, but the touchscreen driver is not thrilled.  I also could find nothing from the DSI system itself, looking for what I assume is a silly mistake on my part.

 

Ah, I forgot the dsi entry in the DTS.  Like I said, silly mistake.  Also need to track the rockchip changes to the dtsi, it appears the renamed some things...  Still no display, but at least it appears everything is attempting to load up.

 

[edit]

Small update

 

[    3.061366] tinker-mcu: tinker_mcu_probe: address = 0x45
[    3.061381] tinker-mcu: send_cmds: 80
[    3.113595] tinker-mcu: init_cmd_check: recv_cmds: 0xC3
[    3.195831] tinker-ft5406: tinker_ft5406_probe: address = 0x38
[    3.196727] tinker-ft5406: fts_i2c_read: i2c read error, -6
[    3.196740] tinker-ft5406: tinker_ft5406_work: checking touch ic, countdown: 8
[    3.303832] tinker_mcu_screen_power_up
[    3.303835] tinker-mcu: tinker_mcu_screen_power_up:
[    3.303851] tinker-mcu: send_cmds: 8500
[    4.143734] tinker-mcu: send_cmds: 8501
[    4.173772] tinker-mcu: send_cmds: 8104
[    4.205022] tinker-mcu: tinker_mcu_set_bright: bright = 0xff
[    4.225881] tinker-ft5406: fts_check_fw_ver: Firmware version = 0.0.0
[    6.894450] systemd[1]: Set hostname to <tinkerboard>.

OK, I'd forgotten how creative some of the Rockchip code was.  I'm getting closer, the screen is powering up at this point, but showing junk instead of image.

 

The touchscreen driver is working, it is acting like a touchpad for the HDMI display....  :rolleyes:

Link to comment
Share on other sites

OK, testing against MiQi to make sure nothing outrageous is going on, screen is working with DRM rather nicely.  Plugging in the HDMI at the same time is...  well unique, the 7" display just lives in the top left corner of the larger external display, and the touch feature applies to the full larger desktop.  In any case, if it passes testing on 4.4 it might be fun to get it to work on 4.13/14

 

[Edit]  MiQi is working perfectly, no issues with the entries in the Tinker DT if the screen is not connected, I'll upload the patch.

Link to comment
Share on other sites

OK, going into settings you can pull the two displays apart and get a primary and secondary monitor.  Only bug I can see is the touchscreen, which tries to cover the entire viewable area of both monitors...  So if using a second display you will not be able to use the touchscreen.  Reboot does maintain the desktop configuration set.

 

Oh, and the extended monitor has a strange rodent on it.  I honestly never thought I'd have a multiple-monitor SBC, I must admit it is cool.

Link to comment
Share on other sites

Guest
This topic is now closed to further replies.
×
×
  • Create New...

Important Information

Terms of Use - Privacy Policy - Guidelines