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