1 /* 2 * ADXL345 3-Axis Digital Accelerometer IIO core driver 3 * 4 * Copyright (c) 2017 Eva Rachel Retuya <eraretuya@gmail.com> 5 * 6 * This file is subject to the terms and conditions of version 2 of 7 * the GNU General Public License. See the file COPYING in the main 8 * directory of this archive for more details. 9 */ 10 11 #include <linux/module.h> 12 #include <linux/regmap.h> 13 14 #include <linux/iio/iio.h> 15 16 #include "adxl345.h" 17 18 #define ADXL345_REG_DEVID 0x00 19 #define ADXL345_REG_POWER_CTL 0x2D 20 #define ADXL345_REG_DATA_FORMAT 0x31 21 #define ADXL345_REG_DATAX0 0x32 22 #define ADXL345_REG_DATAY0 0x34 23 #define ADXL345_REG_DATAZ0 0x36 24 25 #define ADXL345_POWER_CTL_MEASURE BIT(3) 26 #define ADXL345_POWER_CTL_STANDBY 0x00 27 28 #define ADXL345_DATA_FORMAT_FULL_RES BIT(3) /* Up to 13-bits resolution */ 29 #define ADXL345_DATA_FORMAT_2G 0 30 #define ADXL345_DATA_FORMAT_4G 1 31 #define ADXL345_DATA_FORMAT_8G 2 32 #define ADXL345_DATA_FORMAT_16G 3 33 34 #define ADXL345_DEVID 0xE5 35 36 /* 37 * In full-resolution mode, scale factor is maintained at ~4 mg/LSB 38 * in all g ranges. 39 * 40 * At +/- 16g with 13-bit resolution, scale is computed as: 41 * (16 + 16) * 9.81 / (2^13 - 1) = 0.0383 42 */ 43 static const int adxl345_uscale = 38300; 44 45 struct adxl345_data { 46 struct regmap *regmap; 47 u8 data_range; 48 }; 49 50 #define ADXL345_CHANNEL(reg, axis) { \ 51 .type = IIO_ACCEL, \ 52 .modified = 1, \ 53 .channel2 = IIO_MOD_##axis, \ 54 .address = reg, \ 55 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ 56 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ 57 } 58 59 static const struct iio_chan_spec adxl345_channels[] = { 60 ADXL345_CHANNEL(ADXL345_REG_DATAX0, X), 61 ADXL345_CHANNEL(ADXL345_REG_DATAY0, Y), 62 ADXL345_CHANNEL(ADXL345_REG_DATAZ0, Z), 63 }; 64 65 static int adxl345_read_raw(struct iio_dev *indio_dev, 66 struct iio_chan_spec const *chan, 67 int *val, int *val2, long mask) 68 { 69 struct adxl345_data *data = iio_priv(indio_dev); 70 __le16 regval; 71 int ret; 72 73 switch (mask) { 74 case IIO_CHAN_INFO_RAW: 75 /* 76 * Data is stored in adjacent registers: 77 * ADXL345_REG_DATA(X0/Y0/Z0) contain the least significant byte 78 * and ADXL345_REG_DATA(X0/Y0/Z0) + 1 the most significant byte 79 */ 80 ret = regmap_bulk_read(data->regmap, chan->address, ®val, 81 sizeof(regval)); 82 if (ret < 0) 83 return ret; 84 85 *val = sign_extend32(le16_to_cpu(regval), 12); 86 return IIO_VAL_INT; 87 case IIO_CHAN_INFO_SCALE: 88 *val = 0; 89 *val2 = adxl345_uscale; 90 91 return IIO_VAL_INT_PLUS_MICRO; 92 } 93 94 return -EINVAL; 95 } 96 97 static const struct iio_info adxl345_info = { 98 .driver_module = THIS_MODULE, 99 .read_raw = adxl345_read_raw, 100 }; 101 102 int adxl345_core_probe(struct device *dev, struct regmap *regmap, 103 const char *name) 104 { 105 struct adxl345_data *data; 106 struct iio_dev *indio_dev; 107 u32 regval; 108 int ret; 109 110 ret = regmap_read(regmap, ADXL345_REG_DEVID, ®val); 111 if (ret < 0) { 112 dev_err(dev, "Error reading device ID: %d\n", ret); 113 return ret; 114 } 115 116 if (regval != ADXL345_DEVID) { 117 dev_err(dev, "Invalid device ID: %x, expected %x\n", 118 regval, ADXL345_DEVID); 119 return -ENODEV; 120 } 121 122 indio_dev = devm_iio_device_alloc(dev, sizeof(*data)); 123 if (!indio_dev) 124 return -ENOMEM; 125 126 data = iio_priv(indio_dev); 127 dev_set_drvdata(dev, indio_dev); 128 data->regmap = regmap; 129 /* Enable full-resolution mode */ 130 data->data_range = ADXL345_DATA_FORMAT_FULL_RES; 131 132 ret = regmap_write(data->regmap, ADXL345_REG_DATA_FORMAT, 133 data->data_range); 134 if (ret < 0) { 135 dev_err(dev, "Failed to set data range: %d\n", ret); 136 return ret; 137 } 138 139 indio_dev->dev.parent = dev; 140 indio_dev->name = name; 141 indio_dev->info = &adxl345_info; 142 indio_dev->modes = INDIO_DIRECT_MODE; 143 indio_dev->channels = adxl345_channels; 144 indio_dev->num_channels = ARRAY_SIZE(adxl345_channels); 145 146 /* Enable measurement mode */ 147 ret = regmap_write(data->regmap, ADXL345_REG_POWER_CTL, 148 ADXL345_POWER_CTL_MEASURE); 149 if (ret < 0) { 150 dev_err(dev, "Failed to enable measurement mode: %d\n", ret); 151 return ret; 152 } 153 154 ret = iio_device_register(indio_dev); 155 if (ret < 0) { 156 dev_err(dev, "iio_device_register failed: %d\n", ret); 157 regmap_write(data->regmap, ADXL345_REG_POWER_CTL, 158 ADXL345_POWER_CTL_STANDBY); 159 } 160 161 return ret; 162 } 163 EXPORT_SYMBOL_GPL(adxl345_core_probe); 164 165 int adxl345_core_remove(struct device *dev) 166 { 167 struct iio_dev *indio_dev = dev_get_drvdata(dev); 168 struct adxl345_data *data = iio_priv(indio_dev); 169 170 iio_device_unregister(indio_dev); 171 172 return regmap_write(data->regmap, ADXL345_REG_POWER_CTL, 173 ADXL345_POWER_CTL_STANDBY); 174 } 175 EXPORT_SYMBOL_GPL(adxl345_core_remove); 176 177 MODULE_AUTHOR("Eva Rachel Retuya <eraretuya@gmail.com>"); 178 MODULE_DESCRIPTION("ADXL345 3-Axis Digital Accelerometer core driver"); 179 MODULE_LICENSE("GPL v2"); 180