edison-fw / meta-intel-edison

Here is the meta-intel-edison that builds, tries to stay up to date. Master is based on Yocto Poky Gatesgarth LTS 5.10.yy vanilla kernels. It builds a 32bit kernel (Gatesgarth branch 64bit) with ACPI enabled and corresponding rootfs. Telegram group: https://t.me/IntelEdison Web-site:
https://edison-fw.github.io/meta-intel-edison/
MIT License
60 stars 38 forks source link

how to get spi screen work in ACPI enable kernel. #74

Closed xlla closed 4 years ago

xlla commented 4 years ago

I want to driver oled screen in spi mode, it is need additional pins, RST and D/C in master(thud) branch, x86 32bit mode,

acpi settings: ACPI_TABLES ?= "arduino.asl spidev.asl" ACPI_FEATURES_edison ?= "uart_2w i2c spi"

should I use arduino-all.asl? I saw there is a macro for spi, #define MUX_SPI

to simplify operation, I choice pin7 & pin8 for D/C , RST; so I don't need set any Mux or Soc pin mode. I think I should set these pins to output by set gpio255/223 and gpio256/224, but I don't know how to find them with libgpiod, root@edison:~# gpiofind 'U34_IO0.7' nothing found.

or if I set mode to LINE_REQ_DIR_OUT in libgpiod for gpio48/49 , all necessary setting will done automatically?

and I guest name of gpio48/49 is DIG7_PU_PD/DIG8_PU_PD, is it right? and if I choice some pin need configure mux and soc pin mode, how find their name in libgpiod? and if I want made all those operation automatically, how to write correct asl file? I found adafruit.asl is very close to my goal, but I don't know how to get start, would you please give me some advice.

xlla commented 4 years ago

I didn't see the patch to add MUX30 support to arduino.asli. Are you sure it's there?

This thread is starting to become a help page on how to write an acpi table. When @xlla is done I'll try to see if I can rewrite it into a page for our documentation.

I want to learn how to drive a car first, at last, I am learned how to make a wheel :)

xlla commented 4 years ago

Are you sure you have my last patches to fbtft in your kernel build?

Yes, I have checked fbtft-core.c in build/tmp/work-shared/edison/kernel-source/drivers/staging/fbtft/, it does include all amendment of those two patches.

andy-shev commented 4 years ago

@andy-shev

I also just realized that you probably have v5.4 kernel, you need either plenty of patches or latest one, i.e. v5.5 or any newer (v5.6-rc2 or v5.6-rc3 next Monday).

I have upgrade kernel to v5.5, still can't see anything on spi screen.

Since you have fbtft patches applied I think that the problem in the muxing and pin configuration. Of course as one more try you can take my kernel from GitHub (https://github.com/andy-shev/linux/tree/eds-acpi) and try with it.

Linux edison 5.5.0-edison-acpi-standard #1 SMP Wed Mar 4 15:25:14 UTC 2020 i686 i686 i386 GNU/Linux

Hmm... It's 32-bit one. Maybe I have to check 32-bit build with my SSD1306 OLED module. Any possibility to take my kernel (see above) built as 64-bit?

[ 13.539565] Modules linked in: spi_pxa2xx_platform dw_dmac usb_f_mass_storage usb_f_rndis u_ether usb_f_acm u_serial libcomposite pwm_lpss_pci pwm_lpss snd_sof_pci snd_sof_intel_byt snd_sof_intel_hda_common snd_sof_intel_ipc intel_mrfld_adc snd_sof intel_mrfld_pwrbtn snd_sof_xtensa_dsp snd_soc_acpi_intel_match snd_soc_acpi spi_pxa2xx_pci brcmfmac brcmutil hci_uart btbcm ti_ads7950 fb_ssd1331(C) industrialio_triggered_buffer kfifo_buf fbtft(C) mmc_block extcon_intel_mrfld sdhci_pci cqhci sdhci led_class mmc_core intel_soc_pmic_mrfld [ 13.540090] EIP: 0xb7efb8e5

Hmm... You have crash somewhere, can you share full dmesg?

root@edison:~# gpioinfo 4 line 7: "MUX32_DIR" "oled-reset-mux" output active-high [used] line 8: "MUX30_DIR" "oled-cmd-mux" output active-high [used]

By the way, have you checked Edison/Arduino schematics to understand which GPIO line is actually muxed by these settings? Okay, I see that D7 and D8 is easy to connect, there is no complex muxing on top of them. So, above should be correct then.

line 7: "DIG7_PU_PD" "oled-reset-pu" output active-high [used] line 8: "DIG8_PU_PD" "oled-cmd-pu" input active-high [used]

I think you may leave DIG8 pull down (or whatever I have for SSD1306 case).

I have notice /usr/bin/blink-led will operate "MUX18_DIR", I manual change it to another free pin D6, and /usr/bin/blink-led will pull down TRI_STATE_ALL always, I have amend it too, but can't display anything to device /dev/fb0

Hmm... I lack of ideas. As a last resort somebody can send me the module I will try myself.

xlla commented 4 years ago

@andy-shev to isolate problems, I attach another ssd1306 i2c oled display. use this table, build a new acpi-tables.deb disable kernel acpi table load. install new acpi-tables.deb create a config file to auto load i2c-dev mod, /etc/modules-load.d/fb.conf in this round, even /dev/fb0 was missing

root@edison:~# dmesg |grep fb
[    0.175322] pci 0000:00:01.3: reg 0x10: [mem 0xff3fb000-0xff3fb0ff]
[    8.138422] systemd-journald[470]: File /var/log/journal/ecbca1259a044761b2fb3d992c250b0d/system.journal corrupted or uncleanly shut down, renaming and replacing.
[   14.171535] fbtft: module is from the staging directory, the quality is unknown, you have been warned.
[   14.195576] fb_ssd1306: module is from the staging directory, the quality is unknown, you have been warned.
root@edison:~# lsmod |grep i2c
i2c_dev                20480  0
root@edison:~# modinfo fbtft
filename:       /lib/modules/5.5.0-edison-acpi-standard/kernel/drivers/staging/fbtft/fbtft.ko
license:        GPL
depends:        
staging:        Y
retpoline:      Y
intree:         Y
name:           fbtft
vermagic:       5.5.0-edison-acpi-standard SMP mod_unload 686 
parm:           debug:override device debug level (ulong)
root@edison:~# modinfo fb_ssd1306
filename:       /lib/modules/5.5.0-edison-acpi-standard/kernel/drivers/staging/fbtft/fb_ssd1306.ko
license:        GPL
author:         Noralf Tronnes
description:    SSD1306 OLED Driver
alias:          platform:ssd1306
alias:          spi:ssd1306
alias:          platform:fb_ssd1306
alias:          spi:fb_ssd1306
alias:          of:N*T*Csolomon,ssd1306C*
alias:          of:N*T*Csolomon,ssd1306
depends:        fbtft
staging:        Y
retpoline:      Y
intree:         Y
name:           fb_ssd1306
vermagic:       5.5.0-edison-acpi-standard SMP mod_unload 686 
root@edison:~# modinfo i2c-dev   
filename:       /lib/modules/5.5.0-edison-acpi-standard/kernel/drivers/i2c/i2c-dev.ko
license:        GPL
description:    I2C /dev entries driver
author:         Frodo Looijaard  and Simon G. Vogl 
depends:        
retpoline:      Y
intree:         Y
name:           i2c_dev
vermagic:       5.5.0-edison-acpi-standard SMP mod_unload 686 

I can use a python project to test spi screen now, keep the hardware wires untouched, the screen works.

root@edison:~# welcome.py --display ssd1331 --width 96 --gpio-data-command 8 --gpio-reset 7 --spi-port 5 --spi-device 1 --interface spi --gpio gpiod --spi-bus-speed 1000000
Version: luma.oled 3.4.0 (luma.core 1.13.0)
Display: ssd1331
Interface: spi
Dimensions: 96 x 64
------------------------------------------------------------
using libgpiod...
no need cleanup
init spi... 
init bitbang ...
clk:None, sda:None, ce:None
config luma.core.dc, 8 - mux30
config luma.core.reset, 7 - mux32
spi port-5, device-1

    line  48:      unnamed "luma.core.reset" output active-high [used]
    line  49:      unnamed "luma.core.dc" output active-high [used]

    line   7: "DIG7_PU_PD"       unused  output  active-high 
    line   8: "DIG8_PU_PD"       unused   input  active-high 

    line   7:  "MUX32_DIR"       unused  output  active-high 
    line   8:  "MUX30_DIR"       unused  output  active-high 

I can driven another i2c ssd1306 screen simultaneously in another session.

welcome.py --display ssd1306 --i2c-port 6
Version: luma.oled 3.4.0 (luma.core 1.13.0)
Display: ssd1306
Interface: i2c
Dimensions: 128 x 64

both screen works well, it prove my hardware was fine, wires connection was right.

oled-2
xlla commented 4 years ago

For now it can be done only thru U-Boot (with expanding pin control driver to cover it), or via hard coded board file in the Linux kernel (former is slightly better, since it can be upstreamed, the latter won't be upstreamed ever)

so, can we change those Soc pin mode by setting some u-boot env variables ? otherwise, we can't restore arduino sketch function. #78

for ardunio edison board, it was designed to study principle or verify ideas, we want to change pin's function in user space.

xlla commented 4 years ago

Under PWM0 node, PinFunction(Exclusive, PullUp, 0x0001, "_SB.FLIS", 0, ResourceConsumer, , ) { 144 } what is the meaning of "144"? refer to manual, 4 pwm pin just related to (GP12, GP13, GP182, GP183)

144 is a pin number: https://elixir.bootlin.com/linux/latest/source/drivers/pinctrl/intel/pinctrl-merrifield.c#L242

PinFunction, is this section used to switch Soc pin mode? 144 - GP12 (pwm0) , parameter 3 - 0x0001 switch to pwm mode.

andy-shev commented 4 years ago

@andy-shev to isolate problems, I attach another ssd1306 i2c oled display. use this table, build a new acpi-tables.deb disable kernel acpi table load. install new acpi-tables.deb create a config file to auto load i2c-dev mod, /etc/modules-load.d/fb.conf in this round, even /dev/fb0 was missing

I'm afraid fbtft does not support I2C bus connected devices.

I can use a python project to test spi screen now, keep the hardware wires untouched, the screen works.

This is actually good news!

root@edison:~# welcome.py --display ssd1331 --width 96 --gpio-data-command 8 --gpio-reset 7 --spi-port 5 --spi-device 1 --interface spi --gpio gpiod --spi-bus-speed 1000000 Version: luma.oled 3.4.0 (luma.core 1.13.0) Display: ssd1331 Interface: spi Dimensions: 96 x 64

using libgpiod... no need cleanup init spi... init bitbang ... clk:None, sda:None, ce:None config luma.core.dc, 8 - mux30 config luma.core.reset, 7 - mux32 spi port-5, device-1

line 48: unnamed "luma.core.reset" output active-high [used] line 49: unnamed "luma.core.dc" output active-high [used]

line 7: "DIG7_PU_PD" unused output active-high line 8: "DIG8_PU_PD" unused input active-high

line 7: "MUX32_DIR" unused output active-high line 8: "MUX30_DIR" unused output active-high

What about polarity of reset signal? Is it active low or high? Same question about DC pin.

andy-shev commented 4 years ago

For now it can be done only thru U-Boot (with expanding pin control driver to cover it), or via hard coded board file in the Linux kernel (former is slightly better, since it can be upstreamed, the latter won't be upstreamed ever)

so, can we change those Soc pin mode by setting some u-boot env variables ?

No, in DTS (and it requires to have support in pin control driver in U-Boot, which is absent right now).

otherwise, we can't restore arduino sketch function. #78

For now the only thing to configure pins is a boot time (from Linux perspective). In the Linux driver may only switch pins to GPIO mode, and that's it.

for ardunio edison board, it was designed to study principle or verify ideas, we want to change pin's function in user space.

I understand that. Unfortunately Intel abandoned IoT sector and thus there is a little activity in the direction of supporting pin reconfiguration at run-time.

andy-shev commented 4 years ago

Under PWM0 node, PinFunction(Exclusive, PullUp, 0x0001, "_SB.FLIS", 0, ResourceConsumer, , ) { 144 } what is the meaning of "144"? refer to manual, 4 pwm pin just related to (GP12, GP13, GP182, GP183)

144 is a pin number: https://elixir.bootlin.com/linux/latest/source/drivers/pinctrl/intel/pinctrl-merrifield.c#L242

PinFunction, is this section used to switch Soc pin mode? 144 - GP12 (pwm0) , parameter 3 - 0x0001 switch to pwm mode.

Yes, that is the idea, but as I told above there is no ACPI <--> pin control bridge to accomplish it.

xlla commented 4 years ago

I'm afraid fbtft does not support I2C bus connected devices.

at first I think it can switch underlay device transparently, now I found ssd1307fb.c or ssd1306fb-i2c does support I2C device, but absence in our kernel tree.

Reset - active low , pull up need
dc - data mode ,  pull up
       command,  pull down 

Yes, that is the idea, but as I told above there is no ACPI <--> pin control bridge to accomplish it.

I saw acpi-tables-load.service can dynamic load aml and take effect. how about this idea #76

If that just is an idea then _SB.PCI0.pwm0 and _SB.PCI0.SPI6 does not work in now?

I am not found more PinFunction usage other than pwm0 and spi6, but i2c and spi does work, so their related Soc pin mode must be switch correctly via hard code in kernel?

andy-shev commented 4 years ago

I'm afraid fbtft does not support I2C bus connected devices.

at first I think it can switch underlay device transparently, now I found ssd1307fb.c or ssd1306fb-i2c does support I2C device, but absence in our kernel tree.

It's interesting, but I don't think I2C is very popular for OLED / TFT screens. And basically fbtft in the upstream in the frozen state (only bug fixes are accepted).

Nevertheless we may have it in the kernel here, if @htot will have time and will to do that. But see above, priority of that would be low, since we have more important back log (for me, upstreaming USB DR is #1 now, followed by true switch to ACPI (removing SFI and friends from upstream completely).

Reset - active low , pull up need dc - data mode , pull up command, pull down

Yes, that is the idea, but as I told above there is no ACPI <--> pin control bridge to accomplish it.

I saw acpi-tables-load.service can dynamic load aml and take effect. how about this idea #76

This is doubtful feature, because it means you have not fixed hardware and from electrical point of view it can make the real damages to the hardware. The mechanism: 1) power off; 2) change tables / boot loader / etc; 3) boot again pretty much workable solution.

That's why pin muxing will be quite unlikely upstreamed. Though, ACPI table mechanism (as been showed by these special keywords, like PinFunction()) is in the TODO list.

If that just is an idea then _SB.PCI0.pwm0 and _SB.PCI0.SPI6 does not work in now?

I am not found more PinFunction usage other than pwm0 and spi6, but i2c and spi does work, so their related Soc pin mode must be switch correctly via hard code in kernel?

We rely on the firmware (or in our case firmware followed by U-Boot) to set pin muxing correctly.

htot commented 4 years ago

at first I think it can switch underlay device transparently, now I found ssd1307fb.c or ssd1306fb-i2c does support I2C device, but absence in our kernel tree.

It's interesting, but I don't think I2C is very popular for OLED / TFT screens. And basically fbtft in the upstream in the frozen state (only bug fixes are accepted).

Nevertheless we may have it in the kernel here, if @htot will have time and will to do that. But see above, priority of that would be low, since we have more important back log (for me, upstreaming USB DR is #1 now, followed by true switch to ACPI (removing SFI and friends from upstream completely).

If the driver is in the vanilla kernel, we can add a 'kernel fragment' to build it. I would take that patch from @xlla. But if it is out of tree you need to patch the kernel yourself.

I saw acpi-tables-load.service can dynamic load aml and take effect. how about this idea #76

That is not really the idea. But configfs allows loading/unloading tables on the fly. Afaik there is a limit to the # of load/unloads (256?).

This is doubtful feature, because it means you have not fixed hardware and from electrical point of view it can make the real damages to the hardware. The mechanism: 1) power off; 2) change tables / boot loader / etc; 3) boot again pretty much workable solution.

That's why pin muxing will be quite unlikely upstreamed. Though, ACPI table mechanism (as been showed by these special keywords, like PinFunction()) is in the TODO list.

If that just is an idea then _SB.PCI0.pwm0 and _SB.PCI0.SPI6 does not work in now? I am not found more PinFunction usage other than pwm0 and spi6, but i2c and spi does work, so their related Soc pin mode must be switch correctly via hard code in kernel?

There was the idea where we could create a method in acpi that changes pin mode. And that we could trigger from user space. I forgot about the details.

We rely on the firmware (or in our case firmware followed by U-Boot) to set pin muxing correctly.

xlla commented 4 years ago

now I found ssd1307fb.c or ssd1306fb-i2c does support I2C device, but absence in our kernel tree.

I found it in another path, drivers/video/fbdev/ssd1307fb.c I have built it, change acpi device to point it, but could not load it correctly.

root@edison:~# modprobe ssd1307fb
root@edison:~# lsmod |grep fb
ssd1307fb              24576  0
backlight              20480  1 ssd1307fb

root@edison:~# modprobe fbtft
root@edison:~# lsmod |grep fb
fbtft                  32768  0
ssd1307fb              24576  0
backlight              20480  1 ssd1307fb

root@edison:~# ls /dev/fb
ls: cannot access '/dev/fb': No such file or directory
root@edison:~# lsmod |grep i2c
i2c_dev                20480  0

root@edison:~# ls -l /sys/class/graphics/
total 0
lrwxrwxrwx 1 root root 0 Mar 19 23:58 fbcon -> ../../devices/virtual/graphics/fbcon

I think maybe it does not support acpi entry, then I try to load by manual

root@edison:~# echo ssd1306fb 0x3c > /sys/class/i2c-adapter/i2c-1/new_device
[ 1679.686402] ssd1307fb 1-003c: No device tree data found!
root@edison:~# echo ssd1307fb 0x3c > /sys/class/i2c-adapter/i2c-1/new_device
[ 1699.797480] i2c i2c-1: Failed to register i2c client ssd1307fb at 0x3c (-16)
-sh: echo: write error: Device or resource busy
root@edison:~# echo ssd1306fb 0x3c > /sys/class/i2c-adapter/i2c-1/new_device
[ 1717.675712] i2c i2c-1: Failed to register i2c client ssd1306fb at 0x3c (-16)
-sh: echo: write error: Device or resource busy

xlla commented 4 years ago

@andy-shev @htot I recheck the asli file and change RST pin to Active Low mode, it works now! it's wonderful! thank you so much!

Last login: Fri Mar 20 01:41:51 CST 2020 on ttyS2
root@edison:~# /usr/bin/acpi-tables-load oled-spi
install oled-spi ...
done.
root@edison:~# lsmod |grep fb  
fb_ssd1331             16384  1
fbtft                  32768  1 fb_ssd1331
root@edison:~# ls /dev/fb0 
/dev/fb0

root@edison:/mnt/study/git/fbtest# ./fbtest 
Using drawops cfb16 (16 bpp packed pixels)
Available visuals:
  Monochrome
  Grayscale 32
  Truecolor 5:6:5:0
Using visops truecolor
Running all tests
test001: PASSED
test002: PASSED
test003: PASSED
test004: PASSED
test005: PASSED
test006: PASSED
test008: PASSED
Screen size too small for this test
test010: PASSED
Benchmarking... 10x10 squares: 15.41 Mpixels/s
Benchmarking... 20x20 squares: 31.62 Mpixels/s
Benchmarking... 50x50 squares: 69.86 Mpixels/s
test012: PASSED
Benchmarking... R5 circles: 5.33 Mpixels/s
Benchmarking... R10 circles: 12.31 Mpixels/s
Benchmarking... R25 circles: 24.88 Mpixels/s
test013: PASSED

root@edison:/mnt/study/git/fbtest# ls /sys/class/graphics/
fb0  fbcon
root@edison:/mnt/study/git/fbtest# cat /sys/class/vtconsole/vtcon1/name
(M) frame buffer device
root@edison:/mnt/study/git/fbtest# fbset 

mode "96x64-0"
    # D: 0.000 MHz, H: 0.000 kHz, V: 0.000 Hz
    geometry 96 64 96 64 16
    timings 0 0 0 0 0 0 0
    accel false
    rgba 5/11,6/5,5/0,0/0
endmode

    line  48:      unnamed      "reset"  output   active-low [used]
    line  49:      unnamed         "dc"  output  active-high [used]

    line   7: "DIG7_PU_PD" "oled-reset-pu" input active-high [used]
    line   8: "DIG8_PU_PD" "oled-dc-pu"   input  active-high [used]

Cheers~~ oled5 oled6

htot commented 4 years ago

Ok wow! This has been quite a journey you have undertaken. If you would write like a tutorial page on who to get such a device working that would be great!

xlla commented 4 years ago

Yes, it took me a long time to catch on to the ACPI tables, SSDT, aml, yocto development, oled screen spec, etc. And there still so many terminologies, theories, practices to learn. It can work is indeed a credit to you @htot @andy-shev

htot commented 4 years ago

Not me. But @andy-shev certainly.

andy-shev commented 4 years ago

@andy-shev @htot I recheck the asli file and change RST pin to Active Low mode, it works now! it's wonderful! thank you so much!

Glad to hear this! Now, can you cleanup and submit a PR with changes you have done so far? (first patch to amend arduino.asli, i.e. adding necessary muxes, second one adding two files. i.e. ssd1331.asli and ssd1331.asl)

xlla commented 4 years ago

In my adventure, many files was changed, to avoid lost my work , I have committed them all. I should to learn how pick up few files and create PR. all changes in here

andy-shev commented 4 years ago

In my adventure, many files was changed, to avoid lost my work , I have committed them all. I should to learn how pick up few files and create PR.

A good chance to dive into Git. Keywords to be helpful in this case: interactive rebase, squash, soft reset.

PtoGit is a very, very good book (and it's free): https://git-scm.com/book/en/v2

andy-shev commented 4 years ago

meta-acpi has now the patch to support SSD1331. Thanks!

htot commented 4 years ago

Great! @xlla would you like to write a page on getting "the ACPI tables, SSDT, aml, yocto development, oled screen spec, etc."? It would be of great benefit to other developers, starting from scratch to working device.