^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Bosch BMC150 three-axis magnetic field sensor driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (c) 2015, Intel Corporation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * This code is based on bmm050_api.c authored by contact@bosch.sensortec.com:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * (C) Copyright 2011~2014 Bosch Sensortec GmbH All Rights Reserved
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/i2c.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/acpi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/pm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/pm_runtime.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/iio/iio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/iio/sysfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/iio/buffer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/iio/events.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/iio/trigger.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/iio/trigger_consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/iio/triggered_buffer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/regmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include "bmc150_magn.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define BMC150_MAGN_DRV_NAME "bmc150_magn"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define BMC150_MAGN_IRQ_NAME "bmc150_magn_event"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define BMC150_MAGN_REG_CHIP_ID 0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define BMC150_MAGN_CHIP_ID_VAL 0x32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define BMC150_MAGN_REG_X_L 0x42
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define BMC150_MAGN_REG_X_M 0x43
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define BMC150_MAGN_REG_Y_L 0x44
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define BMC150_MAGN_REG_Y_M 0x45
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define BMC150_MAGN_SHIFT_XY_L 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define BMC150_MAGN_REG_Z_L 0x46
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define BMC150_MAGN_REG_Z_M 0x47
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define BMC150_MAGN_SHIFT_Z_L 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define BMC150_MAGN_REG_RHALL_L 0x48
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define BMC150_MAGN_REG_RHALL_M 0x49
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define BMC150_MAGN_SHIFT_RHALL_L 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define BMC150_MAGN_REG_INT_STATUS 0x4A
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define BMC150_MAGN_REG_POWER 0x4B
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define BMC150_MAGN_MASK_POWER_CTL BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define BMC150_MAGN_REG_OPMODE_ODR 0x4C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define BMC150_MAGN_MASK_OPMODE GENMASK(2, 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define BMC150_MAGN_SHIFT_OPMODE 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define BMC150_MAGN_MODE_NORMAL 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define BMC150_MAGN_MODE_FORCED 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define BMC150_MAGN_MODE_SLEEP 0x03
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #define BMC150_MAGN_MASK_ODR GENMASK(5, 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define BMC150_MAGN_SHIFT_ODR 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define BMC150_MAGN_REG_INT 0x4D
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define BMC150_MAGN_REG_INT_DRDY 0x4E
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #define BMC150_MAGN_MASK_DRDY_EN BIT(7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #define BMC150_MAGN_SHIFT_DRDY_EN 7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #define BMC150_MAGN_MASK_DRDY_INT3 BIT(6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #define BMC150_MAGN_MASK_DRDY_Z_EN BIT(5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #define BMC150_MAGN_MASK_DRDY_Y_EN BIT(4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define BMC150_MAGN_MASK_DRDY_X_EN BIT(3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define BMC150_MAGN_MASK_DRDY_DR_POLARITY BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define BMC150_MAGN_MASK_DRDY_LATCHING BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #define BMC150_MAGN_MASK_DRDY_INT3_POLARITY BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #define BMC150_MAGN_REG_LOW_THRESH 0x4F
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #define BMC150_MAGN_REG_HIGH_THRESH 0x50
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #define BMC150_MAGN_REG_REP_XY 0x51
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #define BMC150_MAGN_REG_REP_Z 0x52
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #define BMC150_MAGN_REG_REP_DATAMASK GENMASK(7, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #define BMC150_MAGN_REG_TRIM_START 0x5D
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) #define BMC150_MAGN_REG_TRIM_END 0x71
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) #define BMC150_MAGN_XY_OVERFLOW_VAL -4096
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) #define BMC150_MAGN_Z_OVERFLOW_VAL -16384
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) /* Time from SUSPEND to SLEEP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) #define BMC150_MAGN_START_UP_TIME_MS 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) #define BMC150_MAGN_AUTO_SUSPEND_DELAY_MS 2000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) #define BMC150_MAGN_REGVAL_TO_REPXY(regval) (((regval) * 2) + 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) #define BMC150_MAGN_REGVAL_TO_REPZ(regval) ((regval) + 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) #define BMC150_MAGN_REPXY_TO_REGVAL(rep) (((rep) - 1) / 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) #define BMC150_MAGN_REPZ_TO_REGVAL(rep) ((rep) - 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) enum bmc150_magn_axis {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) AXIS_X,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) AXIS_Y,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) AXIS_Z,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) RHALL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) AXIS_XYZ_MAX = RHALL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) AXIS_XYZR_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) enum bmc150_magn_power_modes {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) BMC150_MAGN_POWER_MODE_SUSPEND,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) BMC150_MAGN_POWER_MODE_SLEEP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) BMC150_MAGN_POWER_MODE_NORMAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) struct bmc150_magn_trim_regs {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) s8 x1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) s8 y1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) __le16 reserved1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) u8 reserved2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) __le16 z4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) s8 x2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) s8 y2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) __le16 reserved3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) __le16 z2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) __le16 z1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) __le16 xyz1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) __le16 z3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) s8 xy2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) u8 xy1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) } __packed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) struct bmc150_magn_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) * 1. Protect this structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) * 2. Serialize sequences that power on/off the device and access HW.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) struct mutex mutex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) struct regmap *regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) struct iio_mount_matrix orientation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) /* Ensure timestamp is naturally aligned */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) s32 chans[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) s64 timestamp __aligned(8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) } scan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) struct iio_trigger *dready_trig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) bool dready_trigger_on;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) int max_odr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) int irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) static const struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) int freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) u8 reg_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) } bmc150_magn_samp_freq_table[] = { {2, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) {6, 0x02},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) {8, 0x03},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) {10, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) {15, 0x04},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) {20, 0x05},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) {25, 0x06},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) {30, 0x07} };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) enum bmc150_magn_presets {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) LOW_POWER_PRESET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) REGULAR_PRESET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) ENHANCED_REGULAR_PRESET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) HIGH_ACCURACY_PRESET
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) static const struct bmc150_magn_preset {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) u8 rep_xy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) u8 rep_z;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) u8 odr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) } bmc150_magn_presets_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) [LOW_POWER_PRESET] = {3, 3, 10},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) [REGULAR_PRESET] = {9, 15, 10},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) [ENHANCED_REGULAR_PRESET] = {15, 27, 10},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) [HIGH_ACCURACY_PRESET] = {47, 83, 20},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) #define BMC150_MAGN_DEFAULT_PRESET REGULAR_PRESET
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) static bool bmc150_magn_is_writeable_reg(struct device *dev, unsigned int reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) switch (reg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) case BMC150_MAGN_REG_POWER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) case BMC150_MAGN_REG_OPMODE_ODR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) case BMC150_MAGN_REG_INT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) case BMC150_MAGN_REG_INT_DRDY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) case BMC150_MAGN_REG_LOW_THRESH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) case BMC150_MAGN_REG_HIGH_THRESH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) case BMC150_MAGN_REG_REP_XY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) case BMC150_MAGN_REG_REP_Z:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) static bool bmc150_magn_is_volatile_reg(struct device *dev, unsigned int reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) switch (reg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) case BMC150_MAGN_REG_X_L:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) case BMC150_MAGN_REG_X_M:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) case BMC150_MAGN_REG_Y_L:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) case BMC150_MAGN_REG_Y_M:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) case BMC150_MAGN_REG_Z_L:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) case BMC150_MAGN_REG_Z_M:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) case BMC150_MAGN_REG_RHALL_L:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) case BMC150_MAGN_REG_RHALL_M:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) case BMC150_MAGN_REG_INT_STATUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) const struct regmap_config bmc150_magn_regmap_config = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) .reg_bits = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) .val_bits = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) .max_register = BMC150_MAGN_REG_TRIM_END,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) .cache_type = REGCACHE_RBTREE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) .writeable_reg = bmc150_magn_is_writeable_reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) .volatile_reg = bmc150_magn_is_volatile_reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) EXPORT_SYMBOL(bmc150_magn_regmap_config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) static int bmc150_magn_set_power_mode(struct bmc150_magn_data *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) enum bmc150_magn_power_modes mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) bool state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) switch (mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) case BMC150_MAGN_POWER_MODE_SUSPEND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) ret = regmap_update_bits(data->regmap, BMC150_MAGN_REG_POWER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) BMC150_MAGN_MASK_POWER_CTL, !state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) usleep_range(BMC150_MAGN_START_UP_TIME_MS * 1000, 20000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) case BMC150_MAGN_POWER_MODE_SLEEP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) return regmap_update_bits(data->regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) BMC150_MAGN_REG_OPMODE_ODR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) BMC150_MAGN_MASK_OPMODE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) BMC150_MAGN_MODE_SLEEP <<
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) BMC150_MAGN_SHIFT_OPMODE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) case BMC150_MAGN_POWER_MODE_NORMAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) return regmap_update_bits(data->regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) BMC150_MAGN_REG_OPMODE_ODR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) BMC150_MAGN_MASK_OPMODE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) BMC150_MAGN_MODE_NORMAL <<
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) BMC150_MAGN_SHIFT_OPMODE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) static int bmc150_magn_set_power_state(struct bmc150_magn_data *data, bool on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) if (on) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) ret = pm_runtime_resume_and_get(data->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) pm_runtime_mark_last_busy(data->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) ret = pm_runtime_put_autosuspend(data->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) dev_err(data->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) "failed to change power state to %d\n", on);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) static int bmc150_magn_get_odr(struct bmc150_magn_data *data, int *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) int ret, reg_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) u8 i, odr_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) ret = regmap_read(data->regmap, BMC150_MAGN_REG_OPMODE_ODR, ®_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) odr_val = (reg_val & BMC150_MAGN_MASK_ODR) >> BMC150_MAGN_SHIFT_ODR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) for (i = 0; i < ARRAY_SIZE(bmc150_magn_samp_freq_table); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) if (bmc150_magn_samp_freq_table[i].reg_val == odr_val) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) *val = bmc150_magn_samp_freq_table[i].freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) static int bmc150_magn_set_odr(struct bmc150_magn_data *data, int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) u8 i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) for (i = 0; i < ARRAY_SIZE(bmc150_magn_samp_freq_table); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) if (bmc150_magn_samp_freq_table[i].freq == val) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) ret = regmap_update_bits(data->regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) BMC150_MAGN_REG_OPMODE_ODR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) BMC150_MAGN_MASK_ODR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) bmc150_magn_samp_freq_table[i].
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) reg_val <<
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) BMC150_MAGN_SHIFT_ODR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) static int bmc150_magn_set_max_odr(struct bmc150_magn_data *data, int rep_xy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) int rep_z, int odr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) int ret, reg_val, max_odr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) if (rep_xy <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) ret = regmap_read(data->regmap, BMC150_MAGN_REG_REP_XY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) ®_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) rep_xy = BMC150_MAGN_REGVAL_TO_REPXY(reg_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) if (rep_z <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) ret = regmap_read(data->regmap, BMC150_MAGN_REG_REP_Z,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) ®_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) rep_z = BMC150_MAGN_REGVAL_TO_REPZ(reg_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) if (odr <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) ret = bmc150_magn_get_odr(data, &odr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) /* the maximum selectable read-out frequency from datasheet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) max_odr = 1000000 / (145 * rep_xy + 500 * rep_z + 980);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) if (odr > max_odr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) dev_err(data->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) "Can't set oversampling with sampling freq %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) odr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) data->max_odr = max_odr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) static s32 bmc150_magn_compensate_x(struct bmc150_magn_trim_regs *tregs, s16 x,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) u16 rhall)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) s16 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) u16 xyz1 = le16_to_cpu(tregs->xyz1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) if (x == BMC150_MAGN_XY_OVERFLOW_VAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) return S32_MIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) if (!rhall)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) rhall = xyz1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) val = ((s16)(((u16)((((s32)xyz1) << 14) / rhall)) - ((u16)0x4000)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) val = ((s16)((((s32)x) * ((((((((s32)tregs->xy2) * ((((s32)val) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) ((s32)val)) >> 7)) + (((s32)val) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) ((s32)(((s16)tregs->xy1) << 7)))) >> 9) + ((s32)0x100000)) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) ((s32)(((s16)tregs->x2) + ((s16)0xA0)))) >> 12)) >> 13)) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) (((s16)tregs->x1) << 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) return (s32)val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) static s32 bmc150_magn_compensate_y(struct bmc150_magn_trim_regs *tregs, s16 y,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) u16 rhall)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) s16 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) u16 xyz1 = le16_to_cpu(tregs->xyz1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) if (y == BMC150_MAGN_XY_OVERFLOW_VAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) return S32_MIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) if (!rhall)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) rhall = xyz1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) val = ((s16)(((u16)((((s32)xyz1) << 14) / rhall)) - ((u16)0x4000)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) val = ((s16)((((s32)y) * ((((((((s32)tregs->xy2) * ((((s32)val) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) ((s32)val)) >> 7)) + (((s32)val) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) ((s32)(((s16)tregs->xy1) << 7)))) >> 9) + ((s32)0x100000)) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) ((s32)(((s16)tregs->y2) + ((s16)0xA0)))) >> 12)) >> 13)) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) (((s16)tregs->y1) << 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) return (s32)val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) static s32 bmc150_magn_compensate_z(struct bmc150_magn_trim_regs *tregs, s16 z,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) u16 rhall)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) s32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) u16 xyz1 = le16_to_cpu(tregs->xyz1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) u16 z1 = le16_to_cpu(tregs->z1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) s16 z2 = le16_to_cpu(tregs->z2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) s16 z3 = le16_to_cpu(tregs->z3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) s16 z4 = le16_to_cpu(tregs->z4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) if (z == BMC150_MAGN_Z_OVERFLOW_VAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) return S32_MIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) val = (((((s32)(z - z4)) << 15) - ((((s32)z3) * ((s32)(((s16)rhall) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) ((s16)xyz1)))) >> 2)) / (z2 + ((s16)(((((s32)z1) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) ((((s16)rhall) << 1))) + (1 << 15)) >> 16))));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) static int bmc150_magn_read_xyz(struct bmc150_magn_data *data, s32 *buffer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) __le16 values[AXIS_XYZR_MAX];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) s16 raw_x, raw_y, raw_z;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) u16 rhall;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) struct bmc150_magn_trim_regs tregs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) ret = regmap_bulk_read(data->regmap, BMC150_MAGN_REG_X_L,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) values, sizeof(values));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) raw_x = (s16)le16_to_cpu(values[AXIS_X]) >> BMC150_MAGN_SHIFT_XY_L;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) raw_y = (s16)le16_to_cpu(values[AXIS_Y]) >> BMC150_MAGN_SHIFT_XY_L;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) raw_z = (s16)le16_to_cpu(values[AXIS_Z]) >> BMC150_MAGN_SHIFT_Z_L;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) rhall = le16_to_cpu(values[RHALL]) >> BMC150_MAGN_SHIFT_RHALL_L;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) ret = regmap_bulk_read(data->regmap, BMC150_MAGN_REG_TRIM_START,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) &tregs, sizeof(tregs));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) buffer[AXIS_X] = bmc150_magn_compensate_x(&tregs, raw_x, rhall);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) buffer[AXIS_Y] = bmc150_magn_compensate_y(&tregs, raw_y, rhall);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) buffer[AXIS_Z] = bmc150_magn_compensate_z(&tregs, raw_z, rhall);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) static int bmc150_magn_read_raw(struct iio_dev *indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) struct iio_chan_spec const *chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) int *val, int *val2, long mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) struct bmc150_magn_data *data = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) int ret, tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) s32 values[AXIS_XYZ_MAX];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) switch (mask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) case IIO_CHAN_INFO_RAW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) if (iio_buffer_enabled(indio_dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) mutex_lock(&data->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) ret = bmc150_magn_set_power_state(data, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) mutex_unlock(&data->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) ret = bmc150_magn_read_xyz(data, values);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) bmc150_magn_set_power_state(data, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) mutex_unlock(&data->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) *val = values[chan->scan_index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) ret = bmc150_magn_set_power_state(data, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) mutex_unlock(&data->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) mutex_unlock(&data->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) return IIO_VAL_INT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) case IIO_CHAN_INFO_SCALE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) * The API/driver performs an off-chip temperature
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) * compensation and outputs x/y/z magnetic field data in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) * 16 LSB/uT to the upper application layer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) *val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) *val2 = 625;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) return IIO_VAL_INT_PLUS_MICRO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) case IIO_CHAN_INFO_SAMP_FREQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) ret = bmc150_magn_get_odr(data, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) return IIO_VAL_INT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) switch (chan->channel2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) case IIO_MOD_X:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) case IIO_MOD_Y:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) ret = regmap_read(data->regmap, BMC150_MAGN_REG_REP_XY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) &tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) *val = BMC150_MAGN_REGVAL_TO_REPXY(tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) return IIO_VAL_INT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) case IIO_MOD_Z:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) ret = regmap_read(data->regmap, BMC150_MAGN_REG_REP_Z,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) &tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) *val = BMC150_MAGN_REGVAL_TO_REPZ(tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) return IIO_VAL_INT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) static int bmc150_magn_write_raw(struct iio_dev *indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) struct iio_chan_spec const *chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) int val, int val2, long mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) struct bmc150_magn_data *data = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) switch (mask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) case IIO_CHAN_INFO_SAMP_FREQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) if (val > data->max_odr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) mutex_lock(&data->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) ret = bmc150_magn_set_odr(data, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) mutex_unlock(&data->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) switch (chan->channel2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) case IIO_MOD_X:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) case IIO_MOD_Y:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) if (val < 1 || val > 511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) mutex_lock(&data->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) ret = bmc150_magn_set_max_odr(data, val, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) mutex_unlock(&data->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) ret = regmap_update_bits(data->regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) BMC150_MAGN_REG_REP_XY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) BMC150_MAGN_REG_REP_DATAMASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) BMC150_MAGN_REPXY_TO_REGVAL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) (val));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) mutex_unlock(&data->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) case IIO_MOD_Z:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) if (val < 1 || val > 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) mutex_lock(&data->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) ret = bmc150_magn_set_max_odr(data, 0, val, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) mutex_unlock(&data->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) ret = regmap_update_bits(data->regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) BMC150_MAGN_REG_REP_Z,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) BMC150_MAGN_REG_REP_DATAMASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) BMC150_MAGN_REPZ_TO_REGVAL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) (val));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) mutex_unlock(&data->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) static ssize_t bmc150_magn_show_samp_freq_avail(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) struct iio_dev *indio_dev = dev_to_iio_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) struct bmc150_magn_data *data = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) size_t len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) u8 i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) for (i = 0; i < ARRAY_SIZE(bmc150_magn_samp_freq_table); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) if (bmc150_magn_samp_freq_table[i].freq > data->max_odr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) len += scnprintf(buf + len, PAGE_SIZE - len, "%d ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) bmc150_magn_samp_freq_table[i].freq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) /* replace last space with a newline */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) buf[len - 1] = '\n';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) static const struct iio_mount_matrix *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) bmc150_magn_get_mount_matrix(const struct iio_dev *indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) const struct iio_chan_spec *chan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) struct bmc150_magn_data *data = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) return &data->orientation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) static const struct iio_chan_spec_ext_info bmc150_magn_ext_info[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) IIO_MOUNT_MATRIX(IIO_SHARED_BY_DIR, bmc150_magn_get_mount_matrix),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) static IIO_DEV_ATTR_SAMP_FREQ_AVAIL(bmc150_magn_show_samp_freq_avail);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) static struct attribute *bmc150_magn_attributes[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) &iio_dev_attr_sampling_frequency_available.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) static const struct attribute_group bmc150_magn_attrs_group = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) .attrs = bmc150_magn_attributes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) #define BMC150_MAGN_CHANNEL(_axis) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) .type = IIO_MAGN, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) .modified = 1, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) .channel2 = IIO_MOD_##_axis, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SAMP_FREQ) | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) BIT(IIO_CHAN_INFO_SCALE), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) .scan_index = AXIS_##_axis, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) .scan_type = { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) .sign = 's', \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) .realbits = 32, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) .storagebits = 32, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) .endianness = IIO_LE \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) }, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) .ext_info = bmc150_magn_ext_info, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) static const struct iio_chan_spec bmc150_magn_channels[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) BMC150_MAGN_CHANNEL(X),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) BMC150_MAGN_CHANNEL(Y),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) BMC150_MAGN_CHANNEL(Z),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) IIO_CHAN_SOFT_TIMESTAMP(3),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) static const struct iio_info bmc150_magn_info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) .attrs = &bmc150_magn_attrs_group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) .read_raw = bmc150_magn_read_raw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) .write_raw = bmc150_magn_write_raw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) static const unsigned long bmc150_magn_scan_masks[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) BIT(AXIS_X) | BIT(AXIS_Y) | BIT(AXIS_Z),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) 0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) static irqreturn_t bmc150_magn_trigger_handler(int irq, void *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) struct iio_poll_func *pf = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) struct iio_dev *indio_dev = pf->indio_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) struct bmc150_magn_data *data = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) mutex_lock(&data->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) ret = bmc150_magn_read_xyz(data, data->scan.chans);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) iio_push_to_buffers_with_timestamp(indio_dev, &data->scan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) pf->timestamp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) mutex_unlock(&data->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) iio_trigger_notify_done(indio_dev->trig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) static int bmc150_magn_init(struct bmc150_magn_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) int ret, chip_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) struct bmc150_magn_preset preset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) ret = bmc150_magn_set_power_mode(data, BMC150_MAGN_POWER_MODE_SUSPEND,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) dev_err(data->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) "Failed to bring up device from suspend mode\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) ret = regmap_read(data->regmap, BMC150_MAGN_REG_CHIP_ID, &chip_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) dev_err(data->dev, "Failed reading chip id\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) goto err_poweroff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) if (chip_id != BMC150_MAGN_CHIP_ID_VAL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) dev_err(data->dev, "Invalid chip id 0x%x\n", chip_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) goto err_poweroff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) dev_dbg(data->dev, "Chip id %x\n", chip_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) preset = bmc150_magn_presets_table[BMC150_MAGN_DEFAULT_PRESET];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) ret = bmc150_magn_set_odr(data, preset.odr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) dev_err(data->dev, "Failed to set ODR to %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) preset.odr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) goto err_poweroff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) ret = regmap_write(data->regmap, BMC150_MAGN_REG_REP_XY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) BMC150_MAGN_REPXY_TO_REGVAL(preset.rep_xy));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) dev_err(data->dev, "Failed to set REP XY to %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) preset.rep_xy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) goto err_poweroff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) ret = regmap_write(data->regmap, BMC150_MAGN_REG_REP_Z,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) BMC150_MAGN_REPZ_TO_REGVAL(preset.rep_z));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) dev_err(data->dev, "Failed to set REP Z to %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) preset.rep_z);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) goto err_poweroff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) ret = bmc150_magn_set_max_odr(data, preset.rep_xy, preset.rep_z,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) preset.odr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) goto err_poweroff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) ret = bmc150_magn_set_power_mode(data, BMC150_MAGN_POWER_MODE_NORMAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) dev_err(data->dev, "Failed to power on device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) goto err_poweroff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) err_poweroff:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) bmc150_magn_set_power_mode(data, BMC150_MAGN_POWER_MODE_SUSPEND, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) static int bmc150_magn_reset_intr(struct bmc150_magn_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) int tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) * Data Ready (DRDY) is always cleared after
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) * readout of data registers ends.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) return regmap_read(data->regmap, BMC150_MAGN_REG_X_L, &tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) static int bmc150_magn_trig_try_reen(struct iio_trigger *trig)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) struct bmc150_magn_data *data = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) if (!data->dready_trigger_on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) mutex_lock(&data->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) ret = bmc150_magn_reset_intr(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) mutex_unlock(&data->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) static int bmc150_magn_data_rdy_trigger_set_state(struct iio_trigger *trig,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) bool state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) struct bmc150_magn_data *data = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) mutex_lock(&data->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) if (state == data->dready_trigger_on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) goto err_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) ret = regmap_update_bits(data->regmap, BMC150_MAGN_REG_INT_DRDY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) BMC150_MAGN_MASK_DRDY_EN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) state << BMC150_MAGN_SHIFT_DRDY_EN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) goto err_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) data->dready_trigger_on = state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) if (state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) ret = bmc150_magn_reset_intr(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) goto err_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) mutex_unlock(&data->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) err_unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) mutex_unlock(&data->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) static const struct iio_trigger_ops bmc150_magn_trigger_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) .set_trigger_state = bmc150_magn_data_rdy_trigger_set_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) .try_reenable = bmc150_magn_trig_try_reen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) static int bmc150_magn_buffer_preenable(struct iio_dev *indio_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) struct bmc150_magn_data *data = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) return bmc150_magn_set_power_state(data, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) static int bmc150_magn_buffer_postdisable(struct iio_dev *indio_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) struct bmc150_magn_data *data = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) return bmc150_magn_set_power_state(data, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) static const struct iio_buffer_setup_ops bmc150_magn_buffer_setup_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) .preenable = bmc150_magn_buffer_preenable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) .postdisable = bmc150_magn_buffer_postdisable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) static const char *bmc150_magn_match_acpi_device(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) const struct acpi_device_id *id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) id = acpi_match_device(dev->driver->acpi_match_table, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) if (!id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) return dev_name(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) int bmc150_magn_probe(struct device *dev, struct regmap *regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) int irq, const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) struct bmc150_magn_data *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) struct iio_dev *indio_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) indio_dev = devm_iio_device_alloc(dev, sizeof(*data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) if (!indio_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) data = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) dev_set_drvdata(dev, indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) data->regmap = regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) data->irq = irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) data->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) ret = iio_read_mount_matrix(dev, "mount-matrix",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) &data->orientation);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) if (!name && ACPI_HANDLE(dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) name = bmc150_magn_match_acpi_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) mutex_init(&data->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) ret = bmc150_magn_init(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) indio_dev->channels = bmc150_magn_channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) indio_dev->num_channels = ARRAY_SIZE(bmc150_magn_channels);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) indio_dev->available_scan_masks = bmc150_magn_scan_masks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) indio_dev->name = name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) indio_dev->modes = INDIO_DIRECT_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) indio_dev->info = &bmc150_magn_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) if (irq > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) data->dready_trig = devm_iio_trigger_alloc(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) "%s-dev%d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) indio_dev->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) indio_dev->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) if (!data->dready_trig) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) dev_err(dev, "iio trigger alloc failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) goto err_poweroff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) data->dready_trig->dev.parent = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) data->dready_trig->ops = &bmc150_magn_trigger_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) iio_trigger_set_drvdata(data->dready_trig, indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) ret = iio_trigger_register(data->dready_trig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) dev_err(dev, "iio trigger register failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) goto err_poweroff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) ret = request_threaded_irq(irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) iio_trigger_generic_data_rdy_poll,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) IRQF_TRIGGER_RISING | IRQF_ONESHOT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) BMC150_MAGN_IRQ_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) data->dready_trig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) dev_err(dev, "request irq %d failed\n", irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) goto err_trigger_unregister;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) ret = iio_triggered_buffer_setup(indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) iio_pollfunc_store_time,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) bmc150_magn_trigger_handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) &bmc150_magn_buffer_setup_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) dev_err(dev, "iio triggered buffer setup failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) goto err_free_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) ret = pm_runtime_set_active(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) goto err_buffer_cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) pm_runtime_enable(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) pm_runtime_set_autosuspend_delay(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) BMC150_MAGN_AUTO_SUSPEND_DELAY_MS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) pm_runtime_use_autosuspend(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) ret = iio_device_register(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) dev_err(dev, "unable to register iio device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) goto err_pm_cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) dev_dbg(dev, "Registered device %s\n", name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) err_pm_cleanup:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) pm_runtime_dont_use_autosuspend(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) pm_runtime_disable(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) err_buffer_cleanup:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) iio_triggered_buffer_cleanup(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) err_free_irq:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) if (irq > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) free_irq(irq, data->dready_trig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) err_trigger_unregister:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) if (data->dready_trig)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) iio_trigger_unregister(data->dready_trig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) err_poweroff:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) bmc150_magn_set_power_mode(data, BMC150_MAGN_POWER_MODE_SUSPEND, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) EXPORT_SYMBOL(bmc150_magn_probe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) int bmc150_magn_remove(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) struct iio_dev *indio_dev = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) struct bmc150_magn_data *data = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) iio_device_unregister(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) pm_runtime_disable(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) pm_runtime_set_suspended(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) iio_triggered_buffer_cleanup(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) if (data->irq > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) free_irq(data->irq, data->dready_trig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) if (data->dready_trig)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) iio_trigger_unregister(data->dready_trig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) mutex_lock(&data->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) bmc150_magn_set_power_mode(data, BMC150_MAGN_POWER_MODE_SUSPEND, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) mutex_unlock(&data->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) EXPORT_SYMBOL(bmc150_magn_remove);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) static int bmc150_magn_runtime_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) struct iio_dev *indio_dev = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) struct bmc150_magn_data *data = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) mutex_lock(&data->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) ret = bmc150_magn_set_power_mode(data, BMC150_MAGN_POWER_MODE_SLEEP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) mutex_unlock(&data->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) dev_err(dev, "powering off device failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) * Should be called with data->mutex held.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) static int bmc150_magn_runtime_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) struct iio_dev *indio_dev = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) struct bmc150_magn_data *data = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) return bmc150_magn_set_power_mode(data, BMC150_MAGN_POWER_MODE_NORMAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) #ifdef CONFIG_PM_SLEEP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) static int bmc150_magn_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) struct iio_dev *indio_dev = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) struct bmc150_magn_data *data = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) mutex_lock(&data->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) ret = bmc150_magn_set_power_mode(data, BMC150_MAGN_POWER_MODE_SLEEP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) mutex_unlock(&data->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) static int bmc150_magn_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) struct iio_dev *indio_dev = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) struct bmc150_magn_data *data = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) mutex_lock(&data->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) ret = bmc150_magn_set_power_mode(data, BMC150_MAGN_POWER_MODE_NORMAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) mutex_unlock(&data->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) const struct dev_pm_ops bmc150_magn_pm_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) SET_SYSTEM_SLEEP_PM_OPS(bmc150_magn_suspend, bmc150_magn_resume)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) SET_RUNTIME_PM_OPS(bmc150_magn_runtime_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) bmc150_magn_runtime_resume, NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) EXPORT_SYMBOL(bmc150_magn_pm_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) MODULE_AUTHOR("Irina Tirdea <irina.tirdea@intel.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) MODULE_LICENSE("GPL v2");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) MODULE_DESCRIPTION("BMC150 magnetometer core driver");