[ar71xx]: Support for D-Link DCH-G020 - gpio_request_one via kmod-gpio-pca953x?

Hi everyone,

I'm trying to add support for the DCH-G020 Z-Wave gateway:

Current progress:

It has an I2C GPIO expander (PCA9554A) at address 0x38 that needs to have pins 1 and 3 output low to enable the USB Hub itself and the Z-Wave controller attached to it (ttyACM0). The I2C port is correctly set up by the kernel

[    0.384124] i2c-gpio i2c-gpio.0: using pins 0 (SDA) and 1 (SCL)

and I can set the desired outputs manually by writing 0xF5 to the PCA9554A config and output registers respectively:

root@OpenWrt:/# i2cset -y 0 0x38 0x03 0xF5 && i2cset -y 0 0x38 0x01 0xF5
root@OpenWrt:/# [ 1773.224921] usb 1-1: new high-speed USB device number 2 using ehci-platform
[ 1773.418719] hub 1-1:1.0: USB hub found
[ 1773.423388] hub 1-1:1.0: 4 ports detected
[ 1773.744919] usb 1-1.1: new full-speed USB device number 3 using ehci-platform
[ 1773.898364] cdc_acm 1-1.1:1.0: ttyACM0: USB ACM device

Now I'm trying to do this automatically on boot using kmod-gpio-pca953x.

The machine file is loosely based on dap-1330-a1 and rut9xx (the latter uses i2c gpio, but only for LED outputs), with the i2c expander pins being mapped to GPIO base 32.

#define DCH_G020_PCA9554_GPIO_BASE           32
#define DCH_G020_PCA9554_GPIO_ZWAVE          (1 + DCH_G020_PCA9554_GPIO_BASE)
#define DCH_G020_PCA9554_GPIO_USB_HUB_RESET  (3 + DCH_G020_PCA9554_GPIO_BASE)

static struct i2c_gpio_platform_data dch_g020_i2c_gpio_data = {
	.sda_pin	= DCH_G020_GPIO_I2C_SDA,
	.scl_pin	= DCH_G020_GPIO_I2C_SCL,
	.udelay		= 10,

static struct platform_device dch_g020_i2c_device = {
	.name	= "i2c-gpio",
	.id	= 0,
	.dev	= {
		.platform_data = &dch_g020_i2c_gpio_data,

static struct pca953x_platform_data dch_g020_pca9554_data = {
	.gpio_base	= DCH_G020_PCA9554_GPIO_BASE,
	.irq_base	= -1,

static struct i2c_board_info dch_g020_i2c_devs[] __initdata = {
		I2C_BOARD_INFO("pca9554a", 0x38),
		.platform_data = &dch_g020_pca9554_data,

end eventually in setup:

	i2c_register_board_info(0, dch_g020_i2c_devs,
			"Enable USB Hub");
			"Enable Z-Wave");

I also tried both GPIOF_OUT_INIT_HIGH and GPIOF_OUT_INIT_LOW since the PCA9554A also seems to support "Polarity Inversion", but there was no difference.

So I wonder if there is any difference when using gpio_request_one() with non-native GPIO, or maybe I'm just missing something else? :slightly_smiling_face:

Hi @s_2,
Did you managed to solve the problem? Any chances to flash the hub with openwrt? I would love to add the hub into my Home Assistant and not to rely on Dlinks cloud app?

Hi @ValiE,
welcome to the OpenWRT forums.

I had not really continued porting after I couldn't fit the Domoticz package and all its dependencies into the image so easily, and especially since the ar71xx target is kind of a dead end for adding new devices now...

Back then I had crafted my first factory image by adding the D-Link header and manually fixing the checksum, for the latest state of the repo I only have the sysupgrade (since I could do all further flashing of my hub from the previous OpenWRT).

I could build a factory image for you, but you'd have to enable usb pins on each boot (see above), and there is currently no stand-alone solution for doing anything related to z-wave with this hub.

How much experience do you have with OpenWRT? I think the next step would be to start over with adding support for this device in the ath79 target (which hopefully allows for the gpio settings to work automagically on boot, even with the i2c expander) and also automate the creation of factory images.

Which other z-wave devices do you own / what's the plan for integration so far?

Hi @s_2
Thanks a lot for your warm welcome and for such a quick reply,
To answer your questions:

  1. my only experience with OpenWRT is as an enduser, back on WRT54GL ages.
  2. currently I own the hub, 5 door/window sensors and a PIR motion detector.
    My idea is/was to integrate into Home Assistant also this Zwave system - I might try also to find a good zwave USB stick to plug into Raspberry PI where the HA is running - i know there is a good zwave stick (i can't remember its name), that works perfectly in HA but is design for US and i'm living in Europe where (correct me if i'm wrong) zwave freq. is different.

The DCH-G020 contains a Sigma Devices (now Silabs) SD3503A, which is basically the same hardware as the Z-Wave UZB Dongle, it is also attached to the QCA9531 via USB inside the hub.

I found that hub years ago when I was searching for z-wave devices on ebay, as the typical USB sticks were so expensive. My first idea was to just cut the traces on the board and solder wires to it, so you can have a usb stick and just discard the rest of the hub, since the hubs were cheaper to get on ebay than the individual usb sticks :sweat_smile: (because the D-Link software was so crappy that many people discarded them).

Hass.io looks interesting, haven't heard of it before. It should also support the USB controller built into the hub, but when I read the minimum requirements are 32 GB of disk space and 1 GB of RAM, I'm no longer sure whether this would be the software I wanted to be in control of all devices in my home :grin:

So it definitely wouldn't run on OpenWRT itself, maybe there could be some agent running on the hub to attach its z-wave functionality to hass.io (a serial port tunnel over tcp!? the controller actually enumerates as ttyACM0), but the easiest way would probably be to cut the traces and solder a usb cable, rather than having two devices running at the same time.

I think i'll look for a cheap Zwave stick that can be directly attached to the Raspberry Pi where the Hassio is running.
Yep, Hassio is a very nice piece of software that can run on all kind of platforms (even though Raspberry Pi is the king - cheap and very low power consumption). It's a bit tricky to add different sensors into the app but is getting better and better with every version they release. Now it also supports Node-red integration making automation way easier then before. If you are into home automation then Hassio can be a good way of centralizing different ecosystems / sensors / all kind of small ESP8266/ESP32 developer boards etc