Skip to content

Latest commit

 

History

History
297 lines (228 loc) · 10.5 KB

how-to-add-a-monitor.md

File metadata and controls

297 lines (228 loc) · 10.5 KB

How to add a monitor

This document is intended as a hands-on introduction on how to add a monitor to the database.

  1. Install DDC Control
  2. Clone and install ddccontrol-db
  3. Make a change
    1. Verify the change using ddccontrol
    2. Verify the change using the GUI
  4. Identify your monitor's I2C bus
  5. Identify your monitor
  6. Add your monitor to the database
  7. Add a capabilities string
  8. Add controls
    1. Query monitor capabilities
    2. Add a control
    3. Try out the change
  9. Debugging
    1. Troubleshooting checklist
    2. Capabilities string syntax

Install DDC Control

Install DDC Control according to its installation instructions. You don't need to compile it, so using a pre-built package is fine. Example:

sudo apt install ddccontrol gddccontrol ddccontrol-db i2c-tools

Clone and install ddccontrol-db

Clone, build and install ddccontrol-db according to the Installation from sources section in the readme.

Make a change

This section describes how to make changes and have them take effect. You need to perform these steps every time you've made a change to the database.

If your monitor is not yet in the database, DDC Control uses the VESA standard monitor profile (described in db/monitor/VESA.xml). Modifying its name is probably the easiest way to verify that changes are applied correctly:

--- a/db/monitor/VESA.xml
+++ b/db/monitor/VESA.xml
@@ -1,16 +1,16 @@
 <?xml version="1.0"?>
 <!--- "Standard" controls -->
-<monitor name="VESA standard monitor" init="standard">
+<monitor name="Cool unknown monitor" init="standard">
        <controls>
                <control id="degauss" address="0x00"/>
                <control id="newcontrolvalue" address="0x02"/>

Once you've made the change, install the database:

sudo make install

Verify the change using ddccontrol

When you've installed the modified database, do a probe for monitors:

$ sudo ddccontrol -p
[...]
Detected monitors :
 - Device: dev:/dev/i2c-5
   DDC/CI supported: Yes
   Monitor Name: Cool unknown monitor
   Input type: Digital
  (Automatically selected)
[...]

You should see Cool unknown monitor somewhere in the output.

Verify the change using the GUI

Launch the DDC Control GUI from your application launcher or from the command line:

sudo gddccontrol

Click the blue arrow button at the top to probe for monitors. You should now be able to select Cool unknown monitor in the Current monitor dropdown.

Identify your monitor's I2C bus

Knowing which I2C bus your monitor is using will simplify development. The output of sudo ddccontrol -p (shown above) reveals that, in this case, the monitor is on the i2c-5 bus.

Identify your monitor

To add a monitor to the database, you need to know its Plug and Play ID. It consists of a 3- or 4-character vendor ID and a 4-character hexadecimal product ID, e.g. ACR06B1. To find it, query the capabilities of your monitor and look for these lines:

$ sudo ddccontrol -c dev:/dev/i2c-5
[...]
EDID readings:
	Plug and Play ID: ACR06B1 [VESA standard monitor]
	Input type: Digital
[...]

In this case, the ID is indeed ACR06B1.

Add your monitor to the database

Add your monitor by creating the file db/monitor/<PLUG_AND_PLAY_ID>.xml, for example:

touch db/monitor/ACR06B1.xml

The file content below is a good starting point:

<?xml version="1.0"?>
<monitor name="Acer Nitro XV273K" init="standard">
	<include file="VESA"/>
</monitor>

Apply the changes:

sudo make install

DDC Control should now recognize your monitor:

$ sudo ddccontrol -p
[...]
Detected monitors :
 - Device: dev:/dev/i2c-5
   DDC/CI supported: Yes
   Monitor Name: Acer Nitro XV273K
   Input type: Digital
  (Automatically selected)
[...]

Add a capabilities string

The capabilities string helps DDC Control understand what the monitor supports. Acquire it like this:

$ sudo ddccontrol -c dev:/dev/i2c-5
[...]
Capabilities:
Raw output: (prot(monitor)type(lcd)model(XV273K)cmds(01 02 03 07 0C E3 F3)vcp(02 04 05 08 0B 0C 10 12 14(05 06 08 0B 0C) 16 18 1A 52 54(00 01) 59 5A 5B 5C 5D 5E 60(03 11 0F 10) 62 9B 9C 9D 9E 9F A0 AC AE B6 C0 C6 C8 C9 CC(01 02 03 04 05 06 08 09 0A 0C 0D 0E 14 16 1E)D6(01 04 05) DF E3 E5 E6 E7(00 01 02) E8(00 01 02) )mswhql(1)asset_eep(32)mccs_ver(2.1))
Parsed output:
        VCP: 02 04 05 08 0b 0c 10 12 14 16 18 1a 52 54 59 5a 5b 5c 5d 5e 60 62 9b 9c 9d 9e 9f a0 ac ae b6 c0 c6 c8 c9 cc d6 df e3 e5 e6 e7 e8
        Type: LCD

The Raw output value is the capabilities string. Add it to your database entry:

--- a/db/monitor/ACR06B1.xml
+++ b/db/monitor/ACR06B1.xml
@@ -1,4 +1,5 @@
 <?xml version="1.0"?>
 <monitor name="Acer Nitro XV273K" init="standard">
+       <caps add="(prot(monitor)type(lcd)model(XV273K)cmds(01 02 03 07 0C E3 F3)vcp(02 04 05 08 0B 0C 10 12 14(05 06 08 0B 0C) 16 18 1A 52 54(00 01) 59 5A 5B 5C 5D 5E 60(03 11 0F 10) 62 9B 9C 9D 9E 9F A0 AC AE B6 C0 C6 C8 C9 CC(01 02 03 04 05 06 08 09 0A 0C 0D 0E 14 16 1E)D6(01 04 05) DF E3 E5 E6 E7(00 01 02) E8(00 01 02) )mswhql(1)asset_eep(32)mccs_ver(2.1))" />
        <include file="VESA"/>
 </monitor>

Add controls

This is the tricky part. Identifying which controls a monitor supports via DDC/CI and how it supports them is a process of trial and error. It's often helpful to take inspiration from other database entries, especially from the same vendor (ACR = Acer, SAM = Samsung, etc).

Query monitor capabilities

DDC Control can help you figure out what controls you can add and how they should be defined:

$ sudo ddccontrol -d dev:/dev/i2c-5
[...]
EDID readings:
        Plug and Play ID: ACR06B1 [Acer Nitro NV273K]
        Input type: Digital

Controls (valid/current/max) [Description - Value name]:
[...]
Control 0x10: +/91/100 C [Brightness]
Control 0x12: +/50/100 C [Contrast]
Control 0x14: +/5/11 C [???]
Control 0x16: +/50/100 C [Red maximum level]
Control 0x18: +/50/100 C [Green maximum level]
Control 0x1a: +/50/100 C [Blue maximum level]
[...]

Add a control

The <include file="VESA"/> line includes a set of standard control definitions that may or may not work on your monitor. You can override its definitions by adding your own ones before it, or remove it altogether.

The change below will remove the standard VESA definitions and add a single MCCS-compliant brightness control using address 0x10 (which the monitor does indeed support, according to the ddccontrol -d output above):

--- a/db/monitor/ACR06B1.xml
+++ b/db/monitor/ACR06B1.xml
@@ -1,5 +1,7 @@
 <?xml version="1.0"?>
 <monitor name="Acer Nitro XV273K" init="standard">
        <caps add="(prot(monitor)type(lcd)model(XV273K)cmds(01 02 03 07 0C E3 F3)vcp(02 04 05 08 0B 0C 10 12 14(05 06 08 0B 0C) 16 18 1A 52 54(00 01) 59 5A 5B 5C 5D 5E 60(03 11 0F 10) 62 9B 9C 9D 9E 9F A0 AC AE B6 C0 C6 C8 C9 CC(01 02 03 04 05 06 08 09 0A 0C 0D 0E 14 16 1E)D6(01 04 05) DF E3 E5 E6 E7(00 01 02) E8(00 01 02) )mswhql(1)asset_eep(32)mccs_ver(2.1))" />
-       <include file="VESA"/>
+       <controls>
+               <control id="brightness" address="0x10"/>
+       </controls>
 </monitor>

You should generally try to reuse code from db/options.xml.in (accomplished by id="brightness" in the example above). You can add controls and/or values in db/options.xml.in if necessary.

Try out the change

Apply the change as described in the Make a change section. The DDC Control GUI should now contain a single brightness control that you can use to control monitor brightness. You can also use the command line:

sudo ddccontrol dev:/dev/i2c-5 -r 0x10 -w 42

Note that even if a definition shows up in DDC Control, it may not be interpreted correctly by your monitor. For example, 6-axis Hue colors may be ordered differently for different monitors.

Debugging

Mistakes can be made in a database entry, for example XML syntax errors and non-parsable integer values. Many of these are pointed out by ddccontrol, but the error messages can be somewhat hard to spot amidst other output, so make sure to look closely. The verbosity flags (-v, -vv, ...) can be helpful.

Troubleshooting checklist

  • Run sudo make install.
  • Re-probe for monitors in the DDC Control GUI.
  • Check if controls are being discarded by the capabilities string:
    $ sudo ddccontrol -v dev:/dev/i2c-5
    [...]
    Control foobar has been discarded by the caps string.
    [...]
  • Run sudo ddccontrol -vvv -p and look for error messages.
  • Try restarting the GUI.
  • Make sure you haven't mixed up hexadecimal and decimal notation. Both are used in database entries.

Capabilities string syntax

The raw capabilities string doesn't say a lot by itself, but it can sometimes aid in debugging.

The vcp part of the capabilities string contains the control addresses supported by the monitor, and sometimes the allowed values for a specific control. Consider for example the following made-up capabilities string:

[...]vcp(02 12 14(05 08 0B) 16 )[...]

This fictional monitor would support controls at addresses 0x02, 0x12, 0x14 and 0x16, with the control at address 0x14 accepting values 0x05, 0x08 and 0x0B.

Disabling controls

Sometimes, you may want to force-disable a control for one reason or another. For example, to disable the newcontrolvalue control, which has address 0x02:

--- a/db/monitor/ACR06B1.xml
+++ b/db/monitor/ACR06B1.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0"?>
 <monitor name="Acer Nitro XV273K" init="standard">
-       <caps add="(prot(monitor)type(lcd)vcp(02 12 14(05 08 0B) 16 ))" />
+       <caps add="(prot(monitor)type(lcd)vcp(12 14(05 08 0B) 16 ))" remove="(vcp(02))" />
        <include file="VESA"/>
 </monitor>

Note that you may need to both remove the control from the add attribute and specify it in the remove attribute, as shown above.