The etzkx driver's documentation contains some basic information about - accelerometer chip overview - driver interfaces - driver usage Signed-off-by: Andi Shyti <andi@xxxxxxxxxxx> Reviewed-by: Onur Atilla <oatilla@xxxxxxxxx> --- Documentation/misc-devices/etzkx.txt | 325 ++++++++++++++++++++++++++++++++++ 1 file changed, 325 insertions(+) create mode 100644 Documentation/misc-devices/etzkx.txt diff --git a/Documentation/misc-devices/etzkx.txt b/Documentation/misc-devices/etzkx.txt new file mode 100644 index 0000000..5d2017c --- /dev/null +++ b/Documentation/misc-devices/etzkx.txt @@ -0,0 +1,325 @@ + ETZKX - State Machine Interrupt Driven Accelerometer + ==================================================== + +Author: Andi Shyti <andi@xxxxxxxxxxx> + +The etzkx driver provides support for the programmable state machine interrupt +driven 3-axis accelerometer. +The chip is manifactured by: + + ROHM Semiconductor: kxcnl-1010 + +Device description +------------------ +The kxcnl-1010 accelerometer is an ultra low-power device based on a +differential capacitance arising from acceleration-induced motion of the sensor +element. The device has a dynamically user selectable sensitivity scale of ++-2/+-4/+-6/+-8g. Moreover the user has the possibility to select the sampling +frequency (odr) from 3.125Hz to 1.6kHz. + +The X, Y, Z coordinates are accessible by polling the device. Interrupt +generation on data ready is also possible if preferred. + +The device is capable of running two state machines for gesture recognition +such as orientation change, shake, tap, etc. Two sets of registers are used to +load the algorithms for the state machine. + +The communication with the CPU is done via I2C bus. Two interrupt lines allow +signalling the state machines behavior and possibly the presence of new +data. + +The device implements a hardware selftest functionality which allows testing of +the reliability of the device. + +The driver +---------- +The driver is located under + + driver/misc/etzkx.c + include/linux/i2c/etzkx.h + +and is placed in between the i2c driver and the userspace interfaces + + __________________________ + | | | | + | input | sysfs | char | + | device | | device | + |________|________|________| + | | + | etzkx | + |__________________________| + | | + | i2c smbus | + |__________________________| + | | + | i2c xfer | + | | + +==========================+ + | | + | kxcnl-1010 | + |__________________________| + + +In the menuconfig the driver is reachable + + Device Drivers ---> + [*] Misc devices ---> + <*> ETZKX kxcnl 3d digital accelerometer + +The interfaces +-------------- +The driver generates three types of interfaces: + + * sysfs: provides information related to the device and sets some basic + parameters like output data rate (odr) and range. + + * input event: provides the X, Y, Z coordinates. + + * character device: provides state machine related information. + +Sysfs interfaces +---------------- +Here is a list of all the sysfs interfaces generated by the driver + +hwid + RO - shows the chip installed on the board + +enable + RW - enables/disables the streaming of X, Y, Z coordinates which are + readable from the input event file + 1 enables the the streaming + 0 disables the streaming + +odr + RW - sets the output data rate of the chip, i.e. sets the frequency of + working of the chip. The available data rates are (in Hz) 3.125, + 6.25, 12.5, 25, 50, 100, 400, 1600. It is possible to write a + generic frequency and the driver will normalize it to the closest + available. When a state machine is running the user is prevented + form changing the odr. + +delay + RW - sets the driver polling rate in ms. Usually is + + 1 + delay = ----- + odr + + but depending of some state machine conditions, odr and delay + might not be synchronized. + +range + RW - sets the sensitivity measured in g. The available g range are + +-2g, +-4g, +-6g, +-8g. When a state machine is running, the user + is prevented from changing the range. + +self_test + RW - enables/disables the self-test functionality. When the self_test is + enabled the X, Y, Z axes are affected by an offset, that offset + allows to evaluate the liability of the device (refer to the + datasheets for the self test patterns) + 1 enables self test + 0 disables self test + +drv_version + RO - shows the driver version + +Input event interface +--------------------- +The input event is generated under /dev/input/eventX, where X is an incremental +number chosen by the input driver framework. + +To eventX file is associated the 'etzkx' name which is discoverable using an +ioctl function with EVIOCGNAME flag. + + DIR *dir; + struct dirent *de; + char *fname; + [...] + + dir = opendir("/dev/input"); + while ( (de = readdir(dir)) ) + { + fd = open(de->d_name, O_RDONLY)) + ioctl(fd, EVIOCGNAME(sizeof(fname) - 1), &fname) + + if (!strcmp(fname, "etzkx")) + /*** found it! ***/ + + close (fd); + } + +The driver streams the coordinates every "delay" ms (or "odr" Hz) through this +interface. The input driver sends a struct input_event to the interface buffer, +which has the following structure: + + #include <linux/input.h> + + struct input_event { + struct timeval time; + __u16 type; + __u16 code; + __s32 value; + }; + +where the type event is EV_ABS, the code of the event is ABS_X, ABS_Y, ABS_Z +corresponding to the X, Y, Z coordiantes and in the end the value field is the +specific coordinate value. The driver sends three different events for each +coordinate followed by a synchronization event which has type=0, code=0 and +value=0. + +A possible reading algorithm can be + + struct input_event ev; + + while (1) + { + do + { + read(fd, &ev, sizeof(struct input_event)); + + if (ev.type == EV_ABS) + switch (ev.code) + { + case ABS_X: + X = ev.value; + break; + case ABS_Y: + Y = ev.value; + break; + case ABS_Z: + Z = ev.value; + break; + } + } while (ev.type != EV_SYN); + } + +Character device +---------------- +The character device is used to report to the userspace the running state +machine's outcome. The interface is capable of polling so that it is possible to +use select() or poll() on it. The character interface is generated as + + /dev/etzkx_stm + +The driver communicates with userspace by writing 64 bit structure on the +interface + + +-----+--------------------------+ + | 32 | algorithm id | + +-----+--------------------------+ + | 32 | specific algorithm data | + +-----+--------------------------+ + +Currently, three algorithms are implemented: + + - algorithm id + ETZKX_STM_ID_TIMING: timing algorithm used for testing. It sends an interrupt + every 16 odr. + + ETZKX_STM_ID_ORIENTATION: sends an interrupt every orientation change + (portrait or landscape) + + ETZKX_STM_ID_DOUBLE_TAP: sends an interrupt every time that a double tap + is detected + + - specific algorithm data + timing (bit order) + 32 bit: not relevant, uninitialized + + orientation (bit order) + 16 bit: 1 if portrait, 0 otherwise + 16 bit: 1 if landscape, 0 otherwise + + double tap (bit order) + 8 bit: 1 if +x, 2 if -x, 0 otherwise + 8 bit: 1 if +y, 2 if -y, 0 otherwise + 8 bit: 1 if +z, 2 if -z, 0 otherwise + 8 bit: double tap peak + +The /dev/etzkx_stm file is capable of ioctl with the following flags + + ETZKXIO_ENABLE_TIMING: enables timing algorithm + ETZKXIO_DISABLE_TIMING: disable timing algorithm + ETZKXIO_ENABLE_ORIENTATION: enables orientation algorithm + ETZKXIO_DISABLE_ORIENTATION: disables orientation algorithm + ETZKXIO_ENABLE_DOUBLE_TAP: enables double tap algorithm + ETZKXIO_DISABLE_DOUBLE_TAP: disables double tap algorithm + + ETZKXIO_WHICH_ORIENTATION: asks to the driver the actual orientation + status. The driver provides via ioctl an algorithm structure like + this: + + 32 bit: ETZKX_STM_ID_ORIENTATION + 16 bit: 1 if portrait, 0 otherwise + 16 bit: 1 if landscape, 0 otherwise + + ETZKXIO_INSTANT_ORIENTATION: like ETZKXIO_WHICH_ORIENTATION, with the + difference that the calculation of the orientation is calculated by + comparing the X and Y coordinates. + + ETZKXIO_RUNNING_ALGO: reports to the userspace the two running + algorithms for each state machine slot: + + 32 bit: running algorithm id on slot 1 + 32 bit: running algorithm id on slot 2 + + if no state machine is loaded, the id is equal to ETZKX_STM_ID_NO_STM + +Driver usage +------------ +The driver follows a state machine way of working and at any time it tracks the +state which the driver is in. + + __STRM --- STRM + STM1 + / \/ \ + / /\ \ + STBY --- ACTIVE --- STM1 STRM + STM2 --- STRM + STM1 + STM2 + \ \/ / + \__ /\ / + STM2 --- STM1 + STM2 + +To reach each driver state, userspace applications have to enable/disable the +available features using the related interfaces. + +Enable/disable streaming (STRM state): + echo 1 > /sys/.../enable + echo 0 > /sys/.../enable + +Enable/disable state machine (STM1/STM2 state): + ioctl (fd, ETZKXIO_ENABLE_ORIENTATION, 0); + ioctl (fd, ETZKXIO_ENABLE_DOUBLE_TAP, 0); + ioctl (fd, ETZKXIO_DISABLE_ORIENTATION, 0); + ioctl (fd, ETZKXIO_DISABLE_DOUBLE_TAP, 0); + +Self test +--------- +The self test checks the electromechanical functionality of the sensor. The +driver sets the self test state as a specific branch of the driver state +machine: + + _ + / ST + / ^ + STDBY <---> ACTIVE | + \ | + \_ v + STRM + +To enable/disable the self test + + echo 1 > /sys/.../self_test + echo 0 > /sys/.../self_test + +This applies an extra capacitance to every axes which adds an offset to the X, +Y, Z output, it can be different for each coordinate. + +The suppliers provides the minimum Dx, Dy, Dz offset in order to consider the +device reliable. The evaluation should be done like follows: + + |Xst - X| > Dx + |Yst - Y| > Dy + |Zst - Z| > Dz + +where Xst, Yst and Zst are the coordinates measured after applying the self test +on the accelerometer. -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-doc" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html