Commit 97eacb91 authored by Gregor Boirie's avatar Gregor Boirie Committed by Jonathan Cameron

iio:ak8975: add mounting matrix support

Expose a rotation matrix to indicate userspace the chip orientation with
respect to the overall hardware system.
Matrix is retrieved from "in_mount_matrix". It is declared into ak8975 DTS
entry as a "mount-matrix" property.
Signed-off-by: default avatarGregor Boirie <gregor.boirie@parrot.com>
Acked-by: default avatarRob Herring <robh@kernel.org>
Signed-off-by: default avatarJonathan Cameron <jic23@kernel.org>
parent dfc57732
...@@ -9,6 +9,7 @@ Optional properties: ...@@ -9,6 +9,7 @@ Optional properties:
- gpios : should be device tree identifier of the magnetometer DRDY pin - gpios : should be device tree identifier of the magnetometer DRDY pin
- vdd-supply: an optional regulator that needs to be on to provide VDD - vdd-supply: an optional regulator that needs to be on to provide VDD
- mount-matrix: an optional 3x3 mounting rotation matrix
Example: Example:
...@@ -17,4 +18,13 @@ ak8975@0c { ...@@ -17,4 +18,13 @@ ak8975@0c {
reg = <0x0c>; reg = <0x0c>;
gpios = <&gpj0 7 0>; gpios = <&gpj0 7 0>;
vdd-supply = <&ldo_3v3_gnss>; vdd-supply = <&ldo_3v3_gnss>;
mount-matrix = "-0.984807753012208", /* x0 */
"0", /* y0 */
"-0.173648177666930", /* z0 */
"0", /* x1 */
"-1", /* y1 */
"0", /* z1 */
"-0.173648177666930", /* x2 */
"0", /* y2 */
"0.984807753012208"; /* z2 */
}; };
...@@ -40,7 +40,8 @@ ...@@ -40,7 +40,8 @@
#include <linux/iio/trigger.h> #include <linux/iio/trigger.h>
#include <linux/iio/trigger_consumer.h> #include <linux/iio/trigger_consumer.h>
#include <linux/iio/triggered_buffer.h> #include <linux/iio/triggered_buffer.h>
#include <linux/regulator/consumer.h>
#include <linux/iio/magnetometer/ak8975.h>
/* /*
* Register definitions, as well as various shifts and masks to get at the * Register definitions, as well as various shifts and masks to get at the
...@@ -376,6 +377,7 @@ struct ak8975_data { ...@@ -376,6 +377,7 @@ struct ak8975_data {
wait_queue_head_t data_ready_queue; wait_queue_head_t data_ready_queue;
unsigned long flags; unsigned long flags;
u8 cntl_cache; u8 cntl_cache;
struct iio_mount_matrix orientation;
struct regulator *vdd; struct regulator *vdd;
}; };
...@@ -726,6 +728,18 @@ static int ak8975_read_raw(struct iio_dev *indio_dev, ...@@ -726,6 +728,18 @@ static int ak8975_read_raw(struct iio_dev *indio_dev,
return -EINVAL; return -EINVAL;
} }
static const struct iio_mount_matrix *
ak8975_get_mount_matrix(const struct iio_dev *indio_dev,
const struct iio_chan_spec *chan)
{
return &((struct ak8975_data *)iio_priv(indio_dev))->orientation;
}
static const struct iio_chan_spec_ext_info ak8975_ext_info[] = {
IIO_MOUNT_MATRIX(IIO_SHARED_BY_DIR, ak8975_get_mount_matrix),
{ },
};
#define AK8975_CHANNEL(axis, index) \ #define AK8975_CHANNEL(axis, index) \
{ \ { \
.type = IIO_MAGN, \ .type = IIO_MAGN, \
...@@ -740,7 +754,8 @@ static int ak8975_read_raw(struct iio_dev *indio_dev, ...@@ -740,7 +754,8 @@ static int ak8975_read_raw(struct iio_dev *indio_dev,
.realbits = 16, \ .realbits = 16, \
.storagebits = 16, \ .storagebits = 16, \
.endianness = IIO_CPU \ .endianness = IIO_CPU \
} \ }, \
.ext_info = ak8975_ext_info, \
} }
static const struct iio_chan_spec ak8975_channels[] = { static const struct iio_chan_spec ak8975_channels[] = {
...@@ -837,10 +852,12 @@ static int ak8975_probe(struct i2c_client *client, ...@@ -837,10 +852,12 @@ static int ak8975_probe(struct i2c_client *client,
int err; int err;
const char *name = NULL; const char *name = NULL;
enum asahi_compass_chipset chipset; enum asahi_compass_chipset chipset;
const struct ak8975_platform_data *pdata =
dev_get_platdata(&client->dev);
/* Grab and set up the supplied GPIO. */ /* Grab and set up the supplied GPIO. */
if (client->dev.platform_data) if (pdata)
eoc_gpio = *(int *)(client->dev.platform_data); eoc_gpio = pdata->eoc_gpio;
else if (client->dev.of_node) else if (client->dev.of_node)
eoc_gpio = of_get_gpio(client->dev.of_node, 0); eoc_gpio = of_get_gpio(client->dev.of_node, 0);
else else
...@@ -874,6 +891,15 @@ static int ak8975_probe(struct i2c_client *client, ...@@ -874,6 +891,15 @@ static int ak8975_probe(struct i2c_client *client,
data->eoc_gpio = eoc_gpio; data->eoc_gpio = eoc_gpio;
data->eoc_irq = 0; data->eoc_irq = 0;
if (!pdata) {
err = of_iio_read_mount_matrix(&client->dev,
"mount-matrix",
&data->orientation);
if (err)
return err;
} else
data->orientation = pdata->orientation;
/* id will be NULL when enumerated via ACPI */ /* id will be NULL when enumerated via ACPI */
if (id) { if (id) {
chipset = (enum asahi_compass_chipset)(id->driver_data); chipset = (enum asahi_compass_chipset)(id->driver_data);
......
#ifndef __IIO_MAGNETOMETER_AK8975_H__
#define __IIO_MAGNETOMETER_AK8975_H__
#include <linux/iio/iio.h>
/**
* struct ak8975_platform_data - AK8975 magnetometer driver platform data
* @eoc_gpio: data ready event gpio
* @orientation: mounting matrix relative to main hardware
*/
struct ak8975_platform_data {
int eoc_gpio;
struct iio_mount_matrix orientation;
};
#endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment