Cyberphone K USB protocol

The intended audience for this page is strictly people who know what they are doing and who are prepared to take their own risks. I cannot accept any responsibility for any damage to your computer or any connected equipment resulting from use of the following information.

The Cyberphone K is a USB telephone handset designed for VoIP. The device works well as a USB sound device under Linux, but I have not found any driver for the Keypad and related functions. Some time in 2007 I took the time to identify the USB protocol which these functions used, with the intention of writing a Linux driver. As a result of identifying the necessary commands to drive these functions I determined that a kernel driver is neither required nor appropriate for this device. All that is required is a userspace program which talks to the device using EP0 control messages. None the less, I still haven't written a useful program to control these functions. See the end of this page for a simple demo in C. Perhaps if I publish my findings, someone else will develop something useful. What I have in mind is some sort of interface between the handset and the system D-Bus...

My system for discovering the following values was to use a Linux host computer running a copy of VMWare Workstation. Two virtual machines were created. One of these ran Microsoft Windows and the other ran Linux. The differences between how these two operating systems communicated with the USB device were compared by monitoring the USB traffic on the host system.

Accessing the registers

The basic form of the libusb usb_control_message function is:

int usb_control_msg(usb_dev_handle *dev, int requesttype, int request, int value, int index, char *bytes, int size, int timeout);

Some of the parameters in the above function are common to all of the following calls.

A handle for the phone USB device determined by searching through a list of the available USB devices.
Always 0 for accessing the control and status registers described here.
A timeout in milliseconds for receiving a response from the USB device being accessed. 5000 (five seconds) is a reasonable starting value.

The return value is either the number of bytes transfered or -1 on an error. Not having sufficient priveledge (perhaps the function needs to be called as root) is a likely cause of an error return.

The Control register - read / write

The hex value 0xa201 to access the control register.
The name of an array consisting of one 8-bit char (in effect, the address of a single char). This is the data which is transfered to (write) or from (read) the device.
The value 1, which corresponds to the size of the parameter bytes in bytes.

Values specific to read

Logical OR of the libusb constants USB_ENDPOINT_IN and USB_TYPE_VENDOR
The value 5
#include <usb.h>
#define USB_CTRL_GET_TIMEOUT    5000

char buf[1];
usb_control_msg(dev, USB_ENDPOINT_IN | USB_TYPE_VENDOR, 5, 0, 0xa201, buf, 1, USB_CTRL_GET_TIMEOUT);

Values specific to write

Logical OR of the libusb constants USB_ENDPOINT_OUT and USB_TYPE_VENDOR
The value 4
#include <usb.h>
#define USB_CTRL_SET_TIMEOUT    5000

char buf[1];
usb_control_msg(dev, USB_ENDPOINT_OUT | USB_TYPE_VENDOR, 4, 0, 0xa201, buf, 1, USB_CTRL_SET_TIMEOUT);

Bit values of buf[0]

BitSet (1)Clear (0)
D7 (MSB)HID EnabledHID Disabled
D6Mic mute LED onMic mute LED off
D5Always reads 1-
D4Always reads 1-
D3-Always reads 0
D2Always reads 1-
D1-Always reads 0
D0 (LSB)Ringer soundingRinger silent

Bit D7 is useful to disable reporting of the Vol + and Vol - keys via the Cyberphone's interrupt interface. When HID Enabled is set, volume changes are fed to the generic input subsystem of the operating system. Having these events reported is not generally very useful as it may change the volume of the default sound device instead of the volume of the phone.

It is worth noting that the Ringer and the Mic led are gated with the Hook switch. The Ringer will only sound when the handset is On hook and is silenced by lifting the handset. Conversely, the Mic led will only illuminate when the handset is Off hook and is extinguished by replacing the handset. Both the Ringer and the Mic led can be switched off by writing a 0 to their respective bits.

I have no idea what function (if any) the bits D1 to D5 perform. It is possible that writing values to these bits may result in permanent damage to the device. My approach has been only to write back the same values as those that have been read. This works for me, YMMV.

The Status register - read only

Logical OR of the libusb constants USB_ENDPOINT_IN and USB_TYPE_VENDOR
The value 5
The hex value 0xa202 to access the status register.
The name of an array consisting of two 8-bit chars. This is the data which is transfered from the device (read).
The value 2, which corresponds to the size of the parameter bytes in bytes.
#include <usb.h>
#define USB_CTRL_GET_TIMEOUT    5000

char buf[2];
usb_control_msg(dev, USB_ENDPOINT_IN | USB_TYPE_VENDOR, 5, 0, 0xa202, buf, 2, USB_CTRL_GET_TIMEOUT);

First byte (buf[0])

BitSet (1)Clear (0)
D7 (MSB)-Always reads 0
D6-Always reads 0
D5-Always reads 0
D4-Always reads 0
D3-Always reads 0
D2-Always reads 0
D1Keypad key downKeypad key up
D0 (LSB)Handset off hookHandset on hook

Second byte (buf[1])

0x44Vol +
0x35Mic mute
0x46Vol -

When the phone is powered on, buf[1] reads 0 until the first keypress occurs.

Example code

You may download and compile (at your own risk) a short C program which demonstrates some of the above commands.

Also in this section


Please submit comments and questions about this site to

If you enjoyed this site, small donations towards running costs are always gratefully received (well, I can hope...). Joking aside, thank you for chosing to visit my website.