Open thekeith opened 3 years ago
Interesting, I don't have issues compiling ddcctl with "make intel" even on my M1 Mac, but the resulting binary does not work like expected (which I in turn expected, because I compiled with "make intel" even though it's an Apple Silicon Mac, because there currently is no Apple Silicon implementation). The program starts, shows the help, for example, and it even recognizes my external display, but it can't change the display's brightness or contrast. It can't poll the display's EDID apparently.
I would love to get Apple Silicon support in the future! :)
I wish I understood more about how this works. FWIW I was able to build this without Rosetta for all variants. Just can't figure out how to resolve the EDID error.
what does make framebuffers displaylist
say on your M1 machines?
rosetta emulation isn't helping here, make intel
refers to tuning a constant for Intel GPUs, not the runtime arch.
we could do something like this so we don't have to build to a specific vendor anymore, but that's a side issue.
the bigger deal is that IOFramebuffer and I2C userspace support is (guessing) a stub on ARM
My test with MacBook Air M1 connected to an external Dell monitor:
➜ make intel
rm -f *.o ddcctl
cc -Wall -Wno-unused-variable -DkDDCMinReplyDelay=1 -c -o DDC.o DDC.c
cc -Wall -Wno-unused-variable -DkDDCMinReplyDelay=1 -o ddcctl -lobjc -framework IOKit -framework AppKit -framework Foundation DDC.o ddcctl.m
➜ ./ddcctl
D: NSScreen #2 (1200x1600 90°) 95.00 DPI
I: found 1 external display
2020-11-26 15:26:35.810 ddcctl[32667:680154] Usage:
ddcctl -d <1-..> [display#]
-w 100000 [delay usecs between settings]
----- Basic settings -----
-b <1-..> [brightness]
-c <1-..> [contrast]
-rbc [reset brightness and contrast]
----- Settings that don't always work -----
-m <1|2> [mute speaker OFF/ON]
-v <1-254> [speaker volume]
-i <1-18> [select input source]
-p <1|2-5> [power on | standby/off]
-o [read-only orientation]
----- Settings (testing) -----
-rg <1-..> [red gain]
-gg <1-..> [green gain]
-bg <1-..> [blue gain]
-rrgb [reset color]
----- Setting grammar -----
-X ? (query value of setting X)
-X NN (put setting X to NN)
-X <NN>- (decrease setting X by NN)
-X <NN>+ (increase setting X by NN)
➜ make framebuffers displaylist
ioreg -c IOFramebuffer -k IOFBI2CInterfaceIDs -b -f -l -r -d 1
ioreg -c IODisplayConnect -b -f -r -l -i -d 2
@kfix here you go. This is to a Dell 2718Q.
$ ./ddcctl
D: NSScreen #1 (2560x1440 0°) HiDPI
D: NSScreen #2 (2560x1440 0°) HiDPI
I: found 2 external displays
2020-11-26 09:34:03.394 ddcctl[31747:5363539] Usage:
ddcctl -d <1-..> [display#]
-w 100000 [delay usecs between settings]
----- Basic settings -----
-b <1-..> [brightness]
-c <1-..> [contrast]
-rbc [reset brightness and contrast]
----- Settings that don't always work -----
-m <1|2> [mute speaker OFF/ON]
-v <1-254> [speaker volume]
-i <1-18> [select input source]
-p <1|2-5> [power on | standby/off]
-o [read-only orientation]
----- Settings (testing) -----
-rg <1-..> [red gain]
-gg <1-..> [green gain]
-bg <1-..> [blue gain]
-rrgb [reset color]
----- Setting grammar -----
-X ? (query value of setting X)
-X NN (put setting X to NN)
-X <NN>- (decrease setting X by NN)
-X <NN>+ (increase setting X by NN)
$ make framebuffers displaylist
ioreg -c IOFramebuffer -k IOFBI2CInterfaceIDs -b -f -l -r -d 1
ioreg -c IODisplayConnect -b -f -r -l -i -d 2```
I should update the "found external display" message because its only a count of high-level NSScreen objects, not the lower-level IOFramebuffers to send DDC (I2C) to.
Based on that empty ioreg
output, it doesn't look like they (IOFramebuffer) are being exposed - at least not in the same way as we expect on X86.
can an M1-owner run system_profiler SPDisplaysDataType
?
@kfix here you go.
$ system_profiler SPDisplaysDataType
Graphics/Displays:
Apple M1:
Chipset Model: Apple M1
Type: GPU
Bus: Built-In
Total Number of Cores: 8
Vendor: Apple (0x106b)
Metal Family: Supported, Metal GPUFamily Apple 7
Displays:
DELL U2718Q:
Resolution: 5120 x 2880 (5K/UHD+ - Ultra High Definition Plus)
UI Looks like: 2560 x 1440 @ 60Hz
Main Display: Yes
Mirror: Off
Online: Yes
Automatically Adjust Brightness: Yes
DELL U2718Q:
Resolution: 5120 x 2880 (5K/UHD+ - Ultra High Definition Plus)
UI Looks like: 2560 x 1440 @ 60Hz
Mirror: Off
Online: Yes
Automatically Adjust Brightness: Yes```
ooh, I just found that system_profiler SPDisplaysDataType -xml
displays WAY more info, including displayID and IOFramebuffer paths on x86.
please attach that as a text file!
@kfix here you go. display_data.txt
Mention me and I'll respond as fast as I can. Just turned notifications on for my phone. Will be around for a bit today.
Thanks, I'm down for the holidays as well. Its why I had some time to work on this..
It looks like there isn't any info in the M1 dump about IORegistryEntry paths,EDID, etc etc.
For comparison, here's the dump on my MBP 15" 2018: MBP_15_2018_SPDisplays.txt
Hopefully Apple gives us something to work with in a future MacOS-on-ARM version?
@kfix so we're SOL right now I guess? Any thoughts about some sort of config for the EDID and obtaining it manually some how?
@jclusso It might stash the blob somewhere so we could parse it and display some info, but we still don't have a path to the I2C device to send control & query commands.
I'm not surprised things are a bit more obscured & abstracted on the M1. Various forums relay similar problems with other apps that do the same kind of things (SwitchResX)
@kfix what does that other information look like. I can obtain the EDIDs by doing this ioreg -lw0 | grep "EDID UUID" -B 20
I'm not 100% familiar with what information we need, but here is the output of this. I'd give the whole ioreg -lw0
but it's huge and I don't know if any information I shouldn't share is in that.
$ ioreg -lw0 | grep "EDID UUID" -B 20
| | | | "BlendOutputCSCMethod" = 0
| | | | "IOMFBBrightnessCompensationEnable" = No
| | | | "ChargeValuesReset" = No
| | | | "VideoClock" = 297000000
| | | | "IdleCachingMethod" = 2
| | | | "DisplayPipePlaneBaseAlignment" = {"DefaultStride"=0,"LinearX_Alignment"=64,"LinearY_Alignment"=1,"PlaneBaseAlignmentLinear"=64}
| | | | "RuntimeProperty::registerTraceEnable" = No
| | | | "DisplayHeight" = 2160
| | | | "color-accuracy-index" = 0
| | | | "PDCGlobalTemp" = 0
| | | | "APTEnableEvents" = No
| | | | "ALSSSupported" = No
| | | | "IdleState" = 5
| | | | "APTLimitRefreshRate" = No
| | | | "IOMFBSupportsYFlip" = Yes
| | | | "IOMFBMaxSrcPixels" = {"PixelClock"=533333328,"MaxSrcRectTotal"=20971520,"MaxSrcBufferHeight"=16384,"IOMFBMaxCompressedSizeInBytes"=0,"VideoClock"=74250000,"MaxSrcRectWidth"=5120,"MaxSrcBufferWidth"=16384,"MaxVideoSrcDownscalingWidth"=27582}
| | | | "DisplayAttributes" = {"ProductAttributes"={"ManufacturerID"="DEL","YearOfManufacture"=2017,"SerialNumber"=811151436,"ProductName"="DELL U2718Q","AlphanumericSerialNumber"="4K8X77720Y0L","LegacyManufacturerID"=4268,"ProductID"=41193,"WeekOfManufacture"=27},"Chromaticity"={"Red"={"X"=41920,"Y"=21632},"Green"={"X"=19648,"Y"=39296},"Blue"={"X"=9856,"Y"=3904}},"DefaultWhitePoint"={"X"=20544,"Y"=21568,"Gamma"=144179},"SupportsStandby"=Yes,"PreciseAspectRatio"=114220,"MaxHorizontalImageSize"=61,"DefaultColorSpaceIsSRGB"=Yes,"SupportsSuspend"=Yes,"SupportsActiveOff"=Yes,"MaxVerticalImageSize"=35,"WhitePoints"=({"X"=20544,"Y"=21568,"Gamma"=144179}),"HasHDMILegacyEDID"=No,"NativeFormatVerticalPixels"=2160,"ContinuousFrequencySupport"="None","AspectRatio"=15,"NativeFormatHorizontalPixels"=3840}
| | | | "APTPDCEnablePM" = Yes
| | | | "SPLCSupported" = No
| | | | "APTPanicOnStuckPolarity" = No
| | | | "EDID UUID" = "10ACE9A0-0000-0000-1B1B-0103803D2378"
--
| | | | "BlendOutputCSCMethod" = 0
| | | | "IOMFBBrightnessCompensationEnable" = No
| | | | "ChargeValuesReset" = No
| | | | "VideoClock" = 0
| | | | "IdleCachingMethod" = 2
| | | | "DisplayPipePlaneBaseAlignment" = {"DefaultStride"=0,"LinearX_Alignment"=64,"LinearY_Alignment"=1,"PlaneBaseAlignmentLinear"=64}
| | | | "RuntimeProperty::registerTraceEnable" = No
| | | | "DisplayHeight" = 2160
| | | | "color-accuracy-index" = 0
| | | | "PDCGlobalTemp" = 0
| | | | "APTEnableEvents" = No
| | | | "ALSSSupported" = No
| | | | "IdleState" = 5
| | | | "APTLimitRefreshRate" = No
| | | | "IOMFBSupportsYFlip" = Yes
| | | | "IOMFBMaxSrcPixels" = {"PixelClock"=0,"MaxSrcRectTotal"=25165824,"MaxSrcBufferHeight"=16384,"IOMFBMaxCompressedSizeInBytes"=0,"VideoClock"=0,"MaxSrcRectWidth"=6144,"MaxSrcBufferWidth"=16384,"MaxVideoSrcDownscalingWidth"=0}
| | | | "DisplayAttributes" = {"ProductAttributes"={"ManufacturerID"="DEL","YearOfManufacture"=2017,"SerialNumber"=809055564,"ProductName"="DELL U2718Q","AlphanumericSerialNumber"="4K8X776T095L","LegacyManufacturerID"=4268,"ProductID"=41196,"WeekOfManufacture"=26},"Chromaticity"={"Red"={"X"=41920,"Y"=21632},"Green"={"X"=19648,"Y"=39296},"Blue"={"X"=9856,"Y"=3904}},"DefaultWhitePoint"={"X"=20544,"Y"=21568,"Gamma"=144179},"SupportsStandby"=Yes,"PreciseAspectRatio"=114220,"MaxHorizontalImageSize"=61,"DefaultColorSpaceIsSRGB"=Yes,"SupportsSuspend"=No,"SupportsActiveOff"=No,"MaxVerticalImageSize"=35,"WhitePoints"=({"X"=20544,"Y"=21568,"Gamma"=144179}),"HasHDMILegacyEDID"=No,"NativeFormatVerticalPixels"=2160,"ContinuousFrequencySupport"="None","AspectRatio"=15,"NativeFormatHorizontalPixels"=3840}
| | | | "APTPDCEnablePM" = Yes
| | | | "SPLCSupported" = No
| | | | "APTPanicOnStuckPolarity" = No
| | | | "EDID UUID" = "10ACECA0-0000-0000-1A1B-0104B53D2378"
@kfix also not sure if what's going on over here would be of any interest. Seems they are talking about some sort of Apple bug that needs to be fixed. I don't know how they're doing stuff in comparison.
Gonna keep guessing that "IOMFB" is short for IOMobileFramebuffer.
"IOMFB" also Seems to show up in iOS logdumps.
The GPU code that Apple might have ported from iThingsOS -> macOS probably didn't expose I2C apis to pesky app developers 😜
Wouldn't they have to expose it somehow on the MacBook Pro. Somehow the OS has to be able to control the screen brightness... right?
Is there an update of the possibility to bring this to M1 architecture?
I'll lock the thread if people want to keep asking when there's obviously no update...
I just read a comment on the app QuickShade (on app store) where controls worked on a M1. I have not found anything as to how it was accomplished.
Quoting from Lunar issue:
QuickShade adds a software black overlay over the whole screen which renders colors incorrectly, decreases contrast linearly instead of exponentially, and keeps the monitor LED backlight at the same strength which consumes more power and can heat up the monitor panel depending on how much time the monitor is kept on.
QuickShade adds a software black overlay over the whole screen which renders colors incorrectly, decreases contrast linearly instead of exponentially, and keeps the monitor LED backlight at the same strength which consumes more power and can heat up the monitor panel depending on how much time the monitor is kept on.
Beats going into my monitor’s menu and adjusting the brightness
Beats going into my monitor’s menu and adjusting the brightness
Indeed, It's incredible how they can make these menus so unusable, so I'm using QuickShade as well, but missing Lunar/ddcctl ¯\_(ツ)_/¯
hey, adding a comment to watch but also i'm more than happy to run commands on a m1 and to help debug/test.
+1
My life depends on ddcctl
multiple times a day :)
Any news with I2C interface on IOMobileFramebuffer with MacOS 11.3 ?
Same here, just got a m1 mac mini yesterday, now I can jump from my intel 16 inch macbook pro to the m1 mac mini using ddcctl
but not the other way around.
Let me know you need more info/test on the m1
Quoting my comment from Lunar issue, as we're all in this together:
Please do note that Apple has sent a survey for M1 Mac users on May 5 via Feedback Assistant (it's preinstalled in macOS betas). I have mentioned inaccessible DDC there.
I think we can make the difference, should enough people chime in with the problem.
Might worth relooking into the issue now with beta 2 MacOS Monterey. Per the issue from lunar, it's at least partially functional with DDC.
A working solution of DDC on M1
https://gist.github.com/tao-j/c7a3c1ec7c2f59ebe45d161d620d9169
Is that working on Big Sur or only on Monterey ? I tried the code on the link on my Mac Mini M1 with 11.4 and it did not seem to work.
Is that working on Big Sur or only on Monterey ?
The API works on Big Sur too, but on Mac Mini M1 you need additional logic to select an external display (or the external display).
See the thread on Lunar for more info.
Hey, just to let you know,
here is a small console tool for basic command line DDC control on the M1 Mini:
https://github.com/waydabber/m1ddc
here is a complete implementation of the matching logic and all the required basics in Swift (made it for MonitorControl but as it is self contained it can be used in a generic fashion):
https://github.com/MonitorControl/MonitorControl/blob/master/MonitorControl/Support/Arm64DDC.swift
These might be helpful for the ddcctl implementation as well. :)
@waydabber if you could add a LICENCE file, that'd be helpful when it comes time for me to ~copypaste~ use that.
I don't have an M1 yet - holding out for the next M1Air - so no timetable on that.
Hi @kfix - MonitorControl uses MIT license. Added it to m1ddc as well. :)
just got an M2Air, so maybe i'll get to this soon!
Any progress on supporting Apple silicon? (asking humbly)
i humbly request this feature! it actually works on one of my LG 4k displays but not the other
You can use this tool which works great ! It requires to connect the screen with DisplayPort. https://github.com/MonitorControl/MonitorControl#readme
I also make a version of NativeDisplayBrightness which works with Mac M1: https://superced.rb38.eu/files/NativeDisplayBrightnessWithM1Support.zip
I think it's possible to use the same tips for this project.
Im actually able to accomplish everything but changing the inputs on one of my displays. At this point I'm invested in HDMI (have an expensive dock and stuff) so I can't switch the DP. HDMI doesn't seem to be the problem though as it works fine on one of the LG 4k monitors.
I've been using this, @owens-ben: https://github.com/waydabber/m1ddc
Works great for switching inputs, setting brightness/contrast, etc. on my LG displays connected with DP over Type-C.
Just a note until Apple Silcion support is added: you can use BetterDisplay's CLI as well to send arbitrary DDC commands:
https://github.com/waydabber/BetterDisplay/wiki/Integration-features,-CLI
Key differences:
ddcctl
and m1ddc
, BetterDisplay requires a running app process (however you can hide the menu icon).ddcctl
and m1ddc
are open source.Hardware support:
ddcctl
- all Intel Macs except for the 2018 Intel mini's HDMI portm1ddc
- all Apple Silicon Macs except for the HDMI ports of M1 Macs and the entry level M2 mini.Some additional stuff:
m1ddc
and BetterDisplay also supports the special addressing required to change input sources on some newer LG displays.
Please update to allow an ARM64 target compatible with Apple Silicon Macs. Current implementation fails to compile, even when running terminal in Rosetta 2 mode.
Steps to reproduce:
Output:
Notes: I do understand that this is likely just due to the Apple GPU simply not being a valid target here, and get it if this ticket isn't super high priority.