D-Link DSP-W215

The DSP-W215 is a discontinued WiFi power plug from D-Link. It is an 8MB flash and/or 64MB RAM device. It has the characteristics below:

  • EU version: qca9531-bl3a: Qualcomm QCA9531 14 Chipset | 2×2 802.11n Wi-Fi SoC
  • US/AU version: AR93xx SoC
  • Winbond W9751G6KB-25: DRAM Chip DDR2 SDRAM 512M-Bit 32Mx16 1.8V 84-Pin WBGA

OpenWRT does not officially support the D-Link DSP-W215 in the main tree. That being said, some members of the community have added support for it in branches.

  1. Download the firmware file (*factory.bin) and save it on your computer.
  2. Remove DSP-W215 from power socket.
  3. Press and hold the WPS button (rev A) or the reset button (rev B) on the side of the DSP-W215A and plug it into power socket.
  4. Continue holding the WPS/reset button until the LED is flashing red.
  5. Connect to Wi-Fi network broadcasted by the DSP-W215 (the network name should start with DSP-xxxx)
  6. Open a Web Browser and go to http://192.168.0.60
  7. Upgrade the firmware by selecting the file downloaded in Step 1.

Note: a factory reset is recommended after upgrading to ensure correct configuration is applied

Factory reset can be performed by holding the WPS button for 10 seconds.

http://sebastianschaper.net/openwrt/openwrt-ath79-tiny-dlink_dsp-w215-b1-squashfs-factory.bin

http://sebastianschaper.net/openwrt/openwrt-ath79-tiny-dlink_dsp-w215-b1-squashfs-sysupgrade.bin

https://github.com/s-2/openwrt/commit/0c162e7e482ebc92c8c4f5661c62771555399fc8 As per the support page, the password is since this device has no ethernet port, wifi is enabled on boot using a PSK concatenated from SSID + 6-digit pin code printed on the label, e.g.: DSP-XXXXnnnnnn (X being the last two octets of MAC address)

You need to become the user homeassistant first. Then get into the env/space of homeassistant, change into the configuration directory. Due to the fact that HA (HomeAssistant) needs to connect to your DSP through ssh, you need to run in your console just once the command to send the off or on and save the rsa key. Then it will be stored and HA will be doing it normally. The commands below are doing what we said above.

 sudo -u homeassistant -H -s 
 /srv/homeassistant/bin/activate 
 cd .homeassistant 
 ssh root@192.168.xx.xx 'echo "1" > /sys/class/gpio/gpio:ac_output_enable/value' 

where 192.168.xx.xx is your own DSP-W215. Click on yes to save the rsa.

Then edit the conf file with your favorite editor (here we use nano)

  • nano configuration.yaml

And append the following, while changing 192.168.xx.xx to your DSP's IP address.

switch:
 - platform: command_line
   switches:
      dlink_powerplug:
        command_on: ssh root@192.168.xx.xx ' echo "1" > /sys/class/gpio/gpio:ac_output_enable/value && echo "255" > /sys/devices/platform/leds/leds/green:power/brightness'
        command_off: ssh root@192.168.xx.xx ' echo "0" > /sys/class/gpio/gpio:ac_output_enable/value && echo "0" > /sys/devices/platform/leds/leds/green:power/brightness'

S-2 did some fantastic work with the “rev B” variant of this device, but his “rev A” variant work was somewhat incomplete at that time. A2 was not dealt with, and factory images for A1 were not created. (Although, flash layout on A1/A2 is such that factory images are pretty restrictive in size. More on that below.)

In 2025, another person started tinkering with the A2 (US) variant of the device and resurrected s-2's branch. The A2 flash layout appears to be identical to A1 (although the author has not confirmed this).

Branch adding support against 24.10: https://github.com/accwebs/openwrt/commits/feature/dsp-w215/

Branch making tweaks to s-2's branch (against 22.03): https://github.com/accwebs/openwrt/commits/feature/dsp-w215-old-openwrt

Conceptual notes:

  • S-2's 22.03 branch adding support for DSP-W215 B1/A1 was based on an already significantly-diverging branch of OpenWRT.
    • This diverging work had added the concept of Wifi auto-enabling and dynamic password selection.
  • Fortunately, it seems that subsequent OpenWRT major releases incorporated nearly all of those Wifi-auto-enabling rule concepts in a similar way (with a few minor deviations).
    • Thus, when s-2's work from 22.03 was re-based on 24.10, all prior divergent commits (that s-2 built on) could be dropped and only s-2's commits retained, with a few minor adjustments made after to restore proper functionality in s-2's use of the Wifi auto-config logic.
    • The accwebs 'dsp-w215' branch attempts to faithfully track those changes (see accwebs' commits following the re-based s-2 commits).

Changes to s-2's work (on accwebs's 24.10 branch):

  • Rename the “A1” config to “A1/A2”.
    • Accwebs believes that A1 and A2 are the same flash and device layout; for the most part the author found the A2 device to be nearly identical to the A1 .dts files and settings built by s-2.
    • It's possible this assumption is incorrect:
      • There were a few discrepancies between the A2 device and the A1 configs on the original branch.
      • It is assumed these were simply mistakes in capturing the A1 device details properly, but no A1 device was available for the author to confirm.
      • If someone has an A1 device, please supply a flash layout :-)
  • Enable factory image assembly for A1/A2:
    • This allows install of images via the recovery flash HTTP interface.
  • Fix the A1/A2 board variant IMAGE_SIZE max to 4544k (64k less than prior, due to log5 partition being recognized by recovery OS; it is very likely the recovery image will not allow flashing over it).
  • Rename A1/A2 ac_output_enable GPIO to pl8331_chip_enable to better represent what it's doing:
    • Unlike with the B1 device, setting the GPIO on A2 does NOT turn power on; it enables the PL8331 'sister' chip, which then can control the power.
      • More on this in a later section.
    • It is believed this will likely be the case for the A1 device as well, but this needs to be confirmed. (S-2 couldn't remember what was the case for his A1 device.)
  • Fix A1/A2 green:switch LED to pin 20.
    • This is quite possibly not a valid change for A1.
  • Override the default boot args for WSP-215 A1/A2 to set console=null instead of console=ttyATH0.
    • Setting Linux to use ttyATH0 prevents clean communication with the PL8331 chip which uses the same serial port.
    • If you need to access your (modified) device over serial temporarily (e.g. for debugging purposes), build an image with this change removed.
  • Fix B1 board .dts file to allow build to work in modern build system.
  • Changes to adapt the DTS and build to a 16 MB flash chip, instead of 8 MB.
    • More on that in a section below!

Many thanks to s-2 for his help (via multiple rounds of correspondence) in getting the above figured out!

The B1 flash layout is as follows:

  • 64k(u-boot)
  • 64k(ART)
  • 64k(mp)
  • 64k(config)
  • 64k(log)
  • 2432k(recovery kernel + rootfs; likely two partitions on stock device but details uncertain)
  • 5440k(main image kernel + rootfs; likely two partitions on stock device but details uncertain)

The A1/A2 flash layout is as follows:

  • 64k(u-boot)
  • 64k(ART)
  • 64k(mac)
  • 64k(nvram)
  • 1024k(uImage) - main image kernel
  • 3520k(rootfs) - main image rootfs
  • 64k(log5)
  • 1024k(uImage2) - recovery image kernel
  • 1792k(rootfs2) - recovery image rootfs
  • 256k(language)
  • 256k(mylink)

The A1/A2 layout makes the situation of an already space-constrained chip (8 MB) worse because the manufacturer HTTP recovery interface will only allow writing of an image that fits within the combined uImage + rootfs partitions (i.e. 4544k). S-2 made the situation slightly better by configuring mtd-concat in the OpenWRT board layout to make use of the language and mylink partitions (512k) at the end of the flash memory (joining this extra space into the combined uImage + rootfs space), but this can only be used for sysupgrade-installed images (not recovery HTTP flashed factory images).

B1's partition layout is better (allowing 5440k), but it's still very small for modern OpenWRT.

Accwebs found that he could build OpenWRT 22.03 images that would fit within the A1/A2 4544k limit by just being careful about package selection. He used this to 'bootstrap' his subsequent image installs (i.e. upon getting locked out of the device and needed to start over, he would flash a 22.03 OpenWRT as a 'launching point' for a future sysupgrade).

Accwebs found that it was difficult to reduce the size of modern OpenWRT below about 6 MB. Even cutting quite a few stock packages would not make much progress; the remainder of the space seemed to largely be made up of libc and the kernel itself. Likely a 24.10 build would not even fit on the B1 devices (although it would be close!).

As discussed above, modern OpenWRT really cannot fit on the DSP-W215's 8 MB flash. What one really needs is a larger flash chip of - say - 16 MB.

Accwebs guessed that a MX25L12835FM2I-10g chip (16 MB) would be a suitable drop-in replacement for the A2's existing MX25L6406E chip. With a steady hand, it's very possible to use a hand soldering iron to de-solder the existing chip and drop it into a SPI programmer.

Example SPI programming set-up; there are many possibilities:

The original flash memory contents of each device's SPI must be uniquely read off of THAT device's original 8 MB chip and flashed to the first half of the replacement 16 MB chip. This is because various personalization data is included in each device's SPI flash contents.

Some examples of how this might be generally done:

# 8 MB chip reading:
flashrom --programmer ft2232_spi:type=232H -c "MX25L6406E/MX25L6408E" -r WSP-D215_orig_8m_flash_dump.bin

# image assembly
(dd if=WSP-D215_orig_8m_flash_dump.bin bs=1024; dd if=<(yes $'\377' | LC_CTYPE=C tr -d "\n") count=8192 bs=1024) > new.bin

# 16 MB chip:
flashrom --programmer ft2232_spi:type=232H -c 'MX25L12833F/MX25L12835F/MX25L12845E/MX25L12865E/MX25L12873F' -w new.bin

Once flashed, the 16 MB chip can be soldered onto the original board. Re-soldered 16 MB chip example:

Accwebs found that the board booted without issue with this chip swap. Notably the manufacturer software (U-Boot, stock firmware, recovery image HTTP flasher, etc.) will have no knowledge of the now-additional 8 MB space, and the factory image flashed by recovery HTTP must still remain very small.

But, the initially-flashed 'small' 22.03 OpenWRT image can contain a modified device tree (.dts) which incorporates the additional 8 MB space in the mtd-concat space S-2 set up. Thus, a sysupgrade from the 'small' 22.03 to the 'large' and fully-featured 24.10 install becomes possible. (The device's stock U-Boot still demands that the OpenWRT kernel begin at the uImage partition, but the root filesystem may extend into the mtd-concat space. Hence why this all works.)

Both of accwebs' branches incorporate the required device tree changes to adjust from the 8 MB chip to 16 MB:

As noted above, both the 22.03 and the 24.10 images need to have their expectations adjusted so as to allow a sysupgrade of larger images to work.

If you are relying on Accwebs's branch and do NOT have a modded device (replacing 8 MB with 16 MB), you MUST revert those device tree commits (changing 8 MB to 16 MB). The commits making those device tree changes are kept separate for easy reverting as needed. But Accwebs will be impressed if you somehow cram a 24.10 image into an unmodified (8 MB) device. Please reach out and tell him how you did it :-)

Accwebs found that he had no luck in-circuit programming (via SPI flash chip clip) updates to the 16 MB flash once soldered to the board. It is difficult to sufficiently power up the SPI chip without also powering-up the main CPU on the board.

As previously noted, the GPIO pin on A1/A2 does not appear to control power directly, but instead powers up the PL8331 “sister” chip. By default power will be “off” when PL8331 comes up. If the PL8331 GPIO gets unset later, power will remain in its current state (either on or off) but the PL8331 chip will shut off. If re-powered up, PL8331 will then immediately turn “off” the power relay (if it was left on up to that point).

Modern Linux seriously discourages the use of GPIO manipulation via the /sys/class/gpio/ filesystem. But OpenWRT as of 24.10 still seems to encourage it.

# enable PL8331
echo 1 >/sys/class/gpio/gpio:pl8331_chip_enable/value

# disable PL8331
echo 0 >/sys/class/gpio/gpio:pl8331_chip_enable/value

Accwebs had some difficulty in certain shell scripts setting the GPIO value. It seemed that echo was not writing to the GPIO always in a single write() syscall, thus causing problems. This hacky workaround helped:

dd if=<(echo 1) of=/sys/class/gpio/gpio:pl8331_chip_enable/value 2>/dev/null

There is a command structure to talk to PL8331 over the /dev/ttyATH0 device. In the limited reversing accwebs did, he saw that - for whatever reason - the stock software repeated the 'power on' and 'power off' commands three times when outputting them on the serial port. Testing tentatively indicated that this threefold repetition was superfluous, but perhaps occasional data corruption issues in the serial communications demanded it as a workaround.

  • Sending PL8331101 turns on the power.
  • Sending PL8331100 turns off the power.

Commands sent seem to be expected to end with a newline. But limited attempts were made to confirm this.

Consolidated example of controlling the power via the enabled PL8331 chip:

# set the baud -- assumes 'stty' installed :-)
stty -F /dev/ttyATH0 115200

# power on
echo "PL8331101 PL8331101 PL8331101" >/dev/ttyATH0

# power off
echo "PL8331100 PL8331100 PL8331100" >/dev/ttyATH0

The PL8331 chip periodically sends messages back to the main processor. They are again newline delimited in the form:

/var/sbin/meter status <various numbers>

(Likely the stock device's software takes all data received and directly executes it at the shell.)

No real effort has been made to reverse the client side software enough to understand the purpose/meaning of these values. Likely they are related to power metering and possibly temperature information.

The A2 device has a front 'power button' which is assumed to manually toggle the power state on the stock device. In OpenWRT, that button corresponds to the BTN_0 event. Place a script at /etc/rc.button/BTN_0 to implement whatever logic you want to execute as a result of a button press.

There is a TTL Serial header on the board that is semi-convenient to access. This can be quite useful because if the Wifi auto-enabling logic does not work for some reason, you are effectively “blind” to what happened on the device (since there is no physical NIC to connect to for accessing the console).

TTL Serial pinout:

  • Pin 1: VCC (3.3 V)
  • Pin 2: GND
  • Pin 3: TX
  • Pin 4: RX

Pins are numbered where “pin 1” is the side furthest away from the SPI Flash chip side of the board.

Pinout information credit: Connor Wolf. Video: https://www.youtube.com/watch?v=rjry28Ym7kI

U-Boot and OpenWRT use a baud of 115200.

Picture of the TTL serial pins:

If one is poking around the board to connect to its serial interface, it is advisable to avoid powering up the device via mains voltage. There are two boards in the A2 device. Accwebs found that disconnecting the low-voltage 'top' board from the rest of the A2 device was a simple matter. And the main CPU could easily power up temporarily via a moderate 3.3 V supply supplied via the TTL serial 3.3 V pin.

As noted above, accwebs' branches override the default boot args for WSP-215 A1/A2 to set console=null instead of console=ttyATH0. This is because the PL8331 chip uses the same serial port to communicate with the main application processor (OpenWRT), thus OpenWRT cannot use it as the default console output without preventing proper comms.

If you need to access your (modified) device over serial temporarily (e.g. for debugging purposes), build an image with this change removed. Figure out what's wrong & fix it. Then, re-flash with an image with a disabled console once again.

This website uses cookies. By using the website, you agree with storing cookies on your computer. Also you acknowledge that you have read and understand our Privacy Policy. If you do not agree leave the website.More information about cookies
  • Last modified: 2025/10/11 02:25
  • by accwebs