| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Bosch BMC150 three-axis magnetic field sensor driver |
|---|
| 3 | 4 | * |
|---|
| .. | .. |
|---|
| 6 | 7 | * This code is based on bmm050_api.c authored by contact@bosch.sensortec.com: |
|---|
| 7 | 8 | * |
|---|
| 8 | 9 | * (C) Copyright 2011~2014 Bosch Sensortec GmbH All Rights Reserved |
|---|
| 9 | | - * |
|---|
| 10 | | - * This program is free software; you can redistribute it and/or modify it |
|---|
| 11 | | - * under the terms and conditions of the GNU General Public License, |
|---|
| 12 | | - * version 2, as published by the Free Software Foundation. |
|---|
| 13 | | - * |
|---|
| 14 | | - * This program is distributed in the hope it will be useful, but WITHOUT |
|---|
| 15 | | - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|---|
| 16 | | - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
|---|
| 17 | | - * more details. |
|---|
| 18 | 10 | */ |
|---|
| 19 | 11 | |
|---|
| 20 | 12 | #include <linux/module.h> |
|---|
| .. | .. |
|---|
| 143 | 135 | */ |
|---|
| 144 | 136 | struct mutex mutex; |
|---|
| 145 | 137 | struct regmap *regmap; |
|---|
| 146 | | - /* 4 x 32 bits for x, y z, 4 bytes align, 64 bits timestamp */ |
|---|
| 147 | | - s32 buffer[6]; |
|---|
| 138 | + struct iio_mount_matrix orientation; |
|---|
| 139 | + /* Ensure timestamp is naturally aligned */ |
|---|
| 140 | + struct { |
|---|
| 141 | + s32 chans[3]; |
|---|
| 142 | + s64 timestamp __aligned(8); |
|---|
| 143 | + } scan; |
|---|
| 148 | 144 | struct iio_trigger *dready_trig; |
|---|
| 149 | 145 | bool dready_trigger_on; |
|---|
| 150 | 146 | int max_odr; |
|---|
| .. | .. |
|---|
| 267 | 263 | int ret; |
|---|
| 268 | 264 | |
|---|
| 269 | 265 | if (on) { |
|---|
| 270 | | - ret = pm_runtime_get_sync(data->dev); |
|---|
| 266 | + ret = pm_runtime_resume_and_get(data->dev); |
|---|
| 271 | 267 | } else { |
|---|
| 272 | 268 | pm_runtime_mark_last_busy(data->dev); |
|---|
| 273 | 269 | ret = pm_runtime_put_autosuspend(data->dev); |
|---|
| .. | .. |
|---|
| 276 | 272 | if (ret < 0) { |
|---|
| 277 | 273 | dev_err(data->dev, |
|---|
| 278 | 274 | "failed to change power state to %d\n", on); |
|---|
| 279 | | - if (on) |
|---|
| 280 | | - pm_runtime_put_noidle(data->dev); |
|---|
| 281 | | - |
|---|
| 282 | 275 | return ret; |
|---|
| 283 | 276 | } |
|---|
| 284 | 277 | #endif |
|---|
| .. | .. |
|---|
| 612 | 605 | return len; |
|---|
| 613 | 606 | } |
|---|
| 614 | 607 | |
|---|
| 608 | +static const struct iio_mount_matrix * |
|---|
| 609 | +bmc150_magn_get_mount_matrix(const struct iio_dev *indio_dev, |
|---|
| 610 | + const struct iio_chan_spec *chan) |
|---|
| 611 | +{ |
|---|
| 612 | + struct bmc150_magn_data *data = iio_priv(indio_dev); |
|---|
| 613 | + |
|---|
| 614 | + return &data->orientation; |
|---|
| 615 | +} |
|---|
| 616 | + |
|---|
| 617 | +static const struct iio_chan_spec_ext_info bmc150_magn_ext_info[] = { |
|---|
| 618 | + IIO_MOUNT_MATRIX(IIO_SHARED_BY_DIR, bmc150_magn_get_mount_matrix), |
|---|
| 619 | + { } |
|---|
| 620 | +}; |
|---|
| 621 | + |
|---|
| 615 | 622 | static IIO_DEV_ATTR_SAMP_FREQ_AVAIL(bmc150_magn_show_samp_freq_avail); |
|---|
| 616 | 623 | |
|---|
| 617 | 624 | static struct attribute *bmc150_magn_attributes[] = { |
|---|
| .. | .. |
|---|
| 638 | 645 | .storagebits = 32, \ |
|---|
| 639 | 646 | .endianness = IIO_LE \ |
|---|
| 640 | 647 | }, \ |
|---|
| 648 | + .ext_info = bmc150_magn_ext_info, \ |
|---|
| 641 | 649 | } |
|---|
| 642 | 650 | |
|---|
| 643 | 651 | static const struct iio_chan_spec bmc150_magn_channels[] = { |
|---|
| .. | .. |
|---|
| 665 | 673 | int ret; |
|---|
| 666 | 674 | |
|---|
| 667 | 675 | mutex_lock(&data->mutex); |
|---|
| 668 | | - ret = bmc150_magn_read_xyz(data, data->buffer); |
|---|
| 676 | + ret = bmc150_magn_read_xyz(data, data->scan.chans); |
|---|
| 669 | 677 | if (ret < 0) |
|---|
| 670 | 678 | goto err; |
|---|
| 671 | 679 | |
|---|
| 672 | | - iio_push_to_buffers_with_timestamp(indio_dev, data->buffer, |
|---|
| 680 | + iio_push_to_buffers_with_timestamp(indio_dev, &data->scan, |
|---|
| 673 | 681 | pf->timestamp); |
|---|
| 674 | 682 | |
|---|
| 675 | 683 | err: |
|---|
| .. | .. |
|---|
| 828 | 836 | |
|---|
| 829 | 837 | static const struct iio_buffer_setup_ops bmc150_magn_buffer_setup_ops = { |
|---|
| 830 | 838 | .preenable = bmc150_magn_buffer_preenable, |
|---|
| 831 | | - .postenable = iio_triggered_buffer_postenable, |
|---|
| 832 | | - .predisable = iio_triggered_buffer_predisable, |
|---|
| 833 | 839 | .postdisable = bmc150_magn_buffer_postdisable, |
|---|
| 834 | 840 | }; |
|---|
| 835 | 841 | |
|---|
| .. | .. |
|---|
| 861 | 867 | data->irq = irq; |
|---|
| 862 | 868 | data->dev = dev; |
|---|
| 863 | 869 | |
|---|
| 870 | + ret = iio_read_mount_matrix(dev, "mount-matrix", |
|---|
| 871 | + &data->orientation); |
|---|
| 872 | + if (ret) |
|---|
| 873 | + return ret; |
|---|
| 874 | + |
|---|
| 864 | 875 | if (!name && ACPI_HANDLE(dev)) |
|---|
| 865 | 876 | name = bmc150_magn_match_acpi_device(dev); |
|---|
| 866 | 877 | |
|---|
| .. | .. |
|---|
| 870 | 881 | if (ret < 0) |
|---|
| 871 | 882 | return ret; |
|---|
| 872 | 883 | |
|---|
| 873 | | - indio_dev->dev.parent = dev; |
|---|
| 874 | 884 | indio_dev->channels = bmc150_magn_channels; |
|---|
| 875 | 885 | indio_dev->num_channels = ARRAY_SIZE(bmc150_magn_channels); |
|---|
| 876 | 886 | indio_dev->available_scan_masks = bmc150_magn_scan_masks; |
|---|
| .. | .. |
|---|
| 931 | 941 | ret = iio_device_register(indio_dev); |
|---|
| 932 | 942 | if (ret < 0) { |
|---|
| 933 | 943 | dev_err(dev, "unable to register iio device\n"); |
|---|
| 934 | | - goto err_buffer_cleanup; |
|---|
| 944 | + goto err_pm_cleanup; |
|---|
| 935 | 945 | } |
|---|
| 936 | 946 | |
|---|
| 937 | 947 | dev_dbg(dev, "Registered device %s\n", name); |
|---|
| 938 | 948 | return 0; |
|---|
| 939 | 949 | |
|---|
| 950 | +err_pm_cleanup: |
|---|
| 951 | + pm_runtime_dont_use_autosuspend(dev); |
|---|
| 952 | + pm_runtime_disable(dev); |
|---|
| 940 | 953 | err_buffer_cleanup: |
|---|
| 941 | 954 | iio_triggered_buffer_cleanup(indio_dev); |
|---|
| 942 | 955 | err_free_irq: |
|---|
| .. | .. |
|---|
| 960 | 973 | |
|---|
| 961 | 974 | pm_runtime_disable(dev); |
|---|
| 962 | 975 | pm_runtime_set_suspended(dev); |
|---|
| 963 | | - pm_runtime_put_noidle(dev); |
|---|
| 964 | 976 | |
|---|
| 965 | 977 | iio_triggered_buffer_cleanup(indio_dev); |
|---|
| 966 | 978 | |
|---|