diff options
author | Gregor Boirie <gregor.boirie@parrot.com> | 2016-04-20 19:23:44 +0200 |
---|---|---|
committer | Jonathan Cameron <jic23@kernel.org> | 2016-04-23 22:14:34 +0100 |
commit | 97eacb9166f4810368e180073dcbceeff0de34df (patch) | |
tree | 6acfa9d79d34ba1d141a9e73b8f94bec42c183b2 | |
parent | dfc57732ad38f93ae6232a3b4e64fd077383a0f1 (diff) | |
download | op-kernel-dev-97eacb9166f4810368e180073dcbceeff0de34df.zip op-kernel-dev-97eacb9166f4810368e180073dcbceeff0de34df.tar.gz |
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: Gregor Boirie <gregor.boirie@parrot.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Jonathan Cameron <jic23@kernel.org>
-rw-r--r-- | Documentation/devicetree/bindings/iio/magnetometer/ak8975.txt | 10 | ||||
-rw-r--r-- | drivers/iio/magnetometer/ak8975.c | 34 | ||||
-rw-r--r-- | include/linux/iio/magnetometer/ak8975.h | 16 |
3 files changed, 56 insertions, 4 deletions
diff --git a/Documentation/devicetree/bindings/iio/magnetometer/ak8975.txt b/Documentation/devicetree/bindings/iio/magnetometer/ak8975.txt index 34a3206..e1e7dd32 100644 --- a/Documentation/devicetree/bindings/iio/magnetometer/ak8975.txt +++ b/Documentation/devicetree/bindings/iio/magnetometer/ak8975.txt @@ -9,6 +9,7 @@ Optional properties: - gpios : should be device tree identifier of the magnetometer DRDY pin - vdd-supply: an optional regulator that needs to be on to provide VDD + - mount-matrix: an optional 3x3 mounting rotation matrix Example: @@ -17,4 +18,13 @@ ak8975@0c { reg = <0x0c>; gpios = <&gpj0 7 0>; 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 */ }; diff --git a/drivers/iio/magnetometer/ak8975.c b/drivers/iio/magnetometer/ak8975.c index a2aac50..dbf0661 100644 --- a/drivers/iio/magnetometer/ak8975.c +++ b/drivers/iio/magnetometer/ak8975.c @@ -40,7 +40,8 @@ #include <linux/iio/trigger.h> #include <linux/iio/trigger_consumer.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 @@ -376,6 +377,7 @@ struct ak8975_data { wait_queue_head_t data_ready_queue; unsigned long flags; u8 cntl_cache; + struct iio_mount_matrix orientation; struct regulator *vdd; }; @@ -726,6 +728,18 @@ static int ak8975_read_raw(struct iio_dev *indio_dev, 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) \ { \ .type = IIO_MAGN, \ @@ -740,7 +754,8 @@ static int ak8975_read_raw(struct iio_dev *indio_dev, .realbits = 16, \ .storagebits = 16, \ .endianness = IIO_CPU \ - } \ + }, \ + .ext_info = ak8975_ext_info, \ } static const struct iio_chan_spec ak8975_channels[] = { @@ -837,10 +852,12 @@ static int ak8975_probe(struct i2c_client *client, int err; const char *name = NULL; enum asahi_compass_chipset chipset; + const struct ak8975_platform_data *pdata = + dev_get_platdata(&client->dev); /* Grab and set up the supplied GPIO. */ - if (client->dev.platform_data) - eoc_gpio = *(int *)(client->dev.platform_data); + if (pdata) + eoc_gpio = pdata->eoc_gpio; else if (client->dev.of_node) eoc_gpio = of_get_gpio(client->dev.of_node, 0); else @@ -874,6 +891,15 @@ static int ak8975_probe(struct i2c_client *client, data->eoc_gpio = eoc_gpio; 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 */ if (id) { chipset = (enum asahi_compass_chipset)(id->driver_data); diff --git a/include/linux/iio/magnetometer/ak8975.h b/include/linux/iio/magnetometer/ak8975.h new file mode 100644 index 0000000..c840095 --- /dev/null +++ b/include/linux/iio/magnetometer/ak8975.h @@ -0,0 +1,16 @@ +#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 |