Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

iio:core: mounting matrix support

Expose a rotation matrix to indicate userspace the chip placement with
respect to the overall hardware system. This is needed to adjust
coordinates sampled from a sensor chip when its position deviates from the
main hardware system.

Final coordinates computation is delegated to userspace since:
* computation may involve floating point arithmetics ;
* it allows an application to combine adjustments with arbitrary
transformations.

This 3 dimentional space rotation matrix is expressed as 3x3 array of
strings to support floating point numbers. It may be retrieved from a
"[<dir>_][<type>_]mount_matrix" sysfs attribute file. It is declared into a
device / driver specific DTS property or platform data.

Signed-off-by: Gregor Boirie <gregor.boirie@parrot.com>
Signed-off-by: Jonathan Cameron <jic23@kernel.org>

authored by

Gregor Boirie and committed by
Jonathan Cameron
dfc57732 dc2c5715

+164
+51
Documentation/ABI/testing/sysfs-bus-iio
··· 1512 1512 Description: 1513 1513 Raw (unscaled no offset etc.) pH reading of a substance as a negative 1514 1514 base-10 logarithm of hydrodium ions in a litre of water. 1515 + 1516 + What: /sys/bus/iio/devices/iio:deviceX/mount_matrix 1517 + What: /sys/bus/iio/devices/iio:deviceX/in_mount_matrix 1518 + What: /sys/bus/iio/devices/iio:deviceX/out_mount_matrix 1519 + KernelVersion: 4.6 1520 + Contact: linux-iio@vger.kernel.org 1521 + Description: 1522 + Mounting matrix for IIO sensors. This is a rotation matrix which 1523 + informs userspace about sensor chip's placement relative to the 1524 + main hardware it is mounted on. 1525 + Main hardware placement is defined according to the local 1526 + reference frame related to the physical quantity the sensor 1527 + measures. 1528 + Given that the rotation matrix is defined in a board specific 1529 + way (platform data and / or device-tree), the main hardware 1530 + reference frame definition is left to the implementor's choice 1531 + (see below for a magnetometer example). 1532 + Applications should apply this rotation matrix to samples so 1533 + that when main hardware reference frame is aligned onto local 1534 + reference frame, then sensor chip reference frame is also 1535 + perfectly aligned with it. 1536 + Matrix is a 3x3 unitary matrix and typically looks like 1537 + [0, 1, 0; 1, 0, 0; 0, 0, -1]. Identity matrix 1538 + [1, 0, 0; 0, 1, 0; 0, 0, 1] means sensor chip and main hardware 1539 + are perfectly aligned with each other. 1540 + 1541 + For example, a mounting matrix for a magnetometer sensor informs 1542 + userspace about sensor chip's ORIENTATION relative to the main 1543 + hardware. 1544 + More specifically, main hardware orientation is defined with 1545 + respect to the LOCAL EARTH GEOMAGNETIC REFERENCE FRAME where : 1546 + * Y is in the ground plane and positive towards magnetic North ; 1547 + * X is in the ground plane, perpendicular to the North axis and 1548 + positive towards the East ; 1549 + * Z is perpendicular to the ground plane and positive upwards. 1550 + 1551 + An implementor might consider that for a hand-held device, a 1552 + 'natural' orientation would be 'front facing camera at the top'. 1553 + The main hardware reference frame could then be described as : 1554 + * Y is in the plane of the screen and is positive towards the 1555 + top of the screen ; 1556 + * X is in the plane of the screen, perpendicular to Y axis, and 1557 + positive towards the right hand side of the screen ; 1558 + * Z is perpendicular to the screen plane and positive out of the 1559 + screen. 1560 + Another example for a quadrotor UAV might be : 1561 + * Y is in the plane of the propellers and positive towards the 1562 + front-view camera; 1563 + * X is in the plane of the propellers, perpendicular to Y axis, 1564 + and positive towards the starboard side of the UAV ; 1565 + * Z is perpendicular to propellers plane and positive upwards.
+82
drivers/iio/industrialio-core.c
··· 412 412 } 413 413 EXPORT_SYMBOL_GPL(iio_enum_write); 414 414 415 + static const struct iio_mount_matrix iio_mount_idmatrix = { 416 + .rotation = { 417 + "1", "0", "0", 418 + "0", "1", "0", 419 + "0", "0", "1" 420 + } 421 + }; 422 + 423 + static int iio_setup_mount_idmatrix(const struct device *dev, 424 + struct iio_mount_matrix *matrix) 425 + { 426 + *matrix = iio_mount_idmatrix; 427 + dev_info(dev, "mounting matrix not found: using identity...\n"); 428 + return 0; 429 + } 430 + 431 + ssize_t iio_show_mount_matrix(struct iio_dev *indio_dev, uintptr_t priv, 432 + const struct iio_chan_spec *chan, char *buf) 433 + { 434 + const struct iio_mount_matrix *mtx = ((iio_get_mount_matrix_t *) 435 + priv)(indio_dev, chan); 436 + 437 + if (IS_ERR(mtx)) 438 + return PTR_ERR(mtx); 439 + 440 + if (!mtx) 441 + mtx = &iio_mount_idmatrix; 442 + 443 + return snprintf(buf, PAGE_SIZE, "%s, %s, %s; %s, %s, %s; %s, %s, %s\n", 444 + mtx->rotation[0], mtx->rotation[1], mtx->rotation[2], 445 + mtx->rotation[3], mtx->rotation[4], mtx->rotation[5], 446 + mtx->rotation[6], mtx->rotation[7], mtx->rotation[8]); 447 + } 448 + EXPORT_SYMBOL_GPL(iio_show_mount_matrix); 449 + 450 + /** 451 + * of_iio_read_mount_matrix() - retrieve iio device mounting matrix from 452 + * device-tree "mount-matrix" property 453 + * @dev: device the mounting matrix property is assigned to 454 + * @propname: device specific mounting matrix property name 455 + * @matrix: where to store retrieved matrix 456 + * 457 + * If device is assigned no mounting matrix property, a default 3x3 identity 458 + * matrix will be filled in. 459 + * 460 + * Return: 0 if success, or a negative error code on failure. 461 + */ 462 + #ifdef CONFIG_OF 463 + int of_iio_read_mount_matrix(const struct device *dev, 464 + const char *propname, 465 + struct iio_mount_matrix *matrix) 466 + { 467 + if (dev->of_node) { 468 + int err = of_property_read_string_array(dev->of_node, 469 + propname, matrix->rotation, 470 + ARRAY_SIZE(iio_mount_idmatrix.rotation)); 471 + 472 + if (err == ARRAY_SIZE(iio_mount_idmatrix.rotation)) 473 + return 0; 474 + 475 + if (err >= 0) 476 + /* Invalid number of matrix entries. */ 477 + return -EINVAL; 478 + 479 + if (err != -EINVAL) 480 + /* Invalid matrix declaration format. */ 481 + return err; 482 + } 483 + 484 + /* Matrix was not declared at all: fallback to identity. */ 485 + return iio_setup_mount_idmatrix(dev, matrix); 486 + } 487 + #else 488 + int of_iio_read_mount_matrix(const struct device *dev, 489 + const char *propname, 490 + struct iio_mount_matrix *matrix) 491 + { 492 + return iio_setup_mount_idmatrix(dev, matrix); 493 + } 494 + #endif 495 + EXPORT_SYMBOL(of_iio_read_mount_matrix); 496 + 415 497 /** 416 498 * iio_format_value() - Formats a IIO value into its string representation 417 499 * @buf: The buffer to which the formatted value gets written
+31
include/linux/iio/iio.h
··· 148 148 } 149 149 150 150 /** 151 + * struct iio_mount_matrix - iio mounting matrix 152 + * @rotation: 3 dimensional space rotation matrix defining sensor alignment with 153 + * main hardware 154 + */ 155 + struct iio_mount_matrix { 156 + const char *rotation[9]; 157 + }; 158 + 159 + ssize_t iio_show_mount_matrix(struct iio_dev *indio_dev, uintptr_t priv, 160 + const struct iio_chan_spec *chan, char *buf); 161 + int of_iio_read_mount_matrix(const struct device *dev, const char *propname, 162 + struct iio_mount_matrix *matrix); 163 + 164 + typedef const struct iio_mount_matrix * 165 + (iio_get_mount_matrix_t)(const struct iio_dev *indio_dev, 166 + const struct iio_chan_spec *chan); 167 + 168 + /** 169 + * IIO_MOUNT_MATRIX() - Initialize mount matrix extended channel attribute 170 + * @_shared: Whether the attribute is shared between all channels 171 + * @_get: Pointer to an iio_get_mount_matrix_t accessor 172 + */ 173 + #define IIO_MOUNT_MATRIX(_shared, _get) \ 174 + { \ 175 + .name = "mount_matrix", \ 176 + .shared = (_shared), \ 177 + .read = iio_show_mount_matrix, \ 178 + .private = (uintptr_t)(_get), \ 179 + } 180 + 181 + /** 151 182 * struct iio_event_spec - specification for a channel event 152 183 * @type: Type of the event 153 184 * @dir: Direction of the event