1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Freescale MMA7660FC 3-Axis Accelerometer 4 * 5 * Copyright (c) 2016, Intel Corporation. 6 * 7 * IIO driver for Freescale MMA7660FC; 7-bit I2C address: 0x4c. 8 */ 9 10 #include <linux/i2c.h> 11 #include <linux/mod_devicetable.h> 12 #include <linux/module.h> 13 #include <linux/iio/iio.h> 14 #include <linux/iio/sysfs.h> 15 16 #define MMA7660_DRIVER_NAME "mma7660" 17 18 #define MMA7660_REG_XOUT 0x00 19 #define MMA7660_REG_YOUT 0x01 20 #define MMA7660_REG_ZOUT 0x02 21 #define MMA7660_REG_OUT_BIT_ALERT BIT(6) 22 23 #define MMA7660_REG_MODE 0x07 24 #define MMA7660_REG_MODE_BIT_MODE BIT(0) 25 #define MMA7660_REG_MODE_BIT_TON BIT(2) 26 27 #define MMA7660_I2C_READ_RETRIES 5 28 29 /* 30 * The accelerometer has one measurement range: 31 * 32 * -1.5g - +1.5g (6-bit, signed) 33 * 34 * scale = (1.5 + 1.5) * 9.81 / (2^6 - 1) = 0.467142857 35 */ 36 37 #define MMA7660_SCALE_AVAIL "0.467142857" 38 39 static const int mma7660_nscale = 467142857; 40 41 enum mma7660_mode { 42 MMA7660_MODE_STANDBY, 43 MMA7660_MODE_ACTIVE 44 }; 45 46 struct mma7660_data { 47 struct i2c_client *client; 48 struct mutex lock; 49 enum mma7660_mode mode; 50 struct iio_mount_matrix orientation; 51 }; 52 53 static const struct iio_mount_matrix * 54 mma7660_get_mount_matrix(const struct iio_dev *indio_dev, 55 const struct iio_chan_spec *chan) 56 { 57 struct mma7660_data *data = iio_priv(indio_dev); 58 59 return &data->orientation; 60 } 61 62 static const struct iio_chan_spec_ext_info mma7660_ext_info[] = { 63 IIO_MOUNT_MATRIX(IIO_SHARED_BY_DIR, mma7660_get_mount_matrix), 64 { } 65 }; 66 67 static IIO_CONST_ATTR(in_accel_scale_available, MMA7660_SCALE_AVAIL); 68 69 static struct attribute *mma7660_attributes[] = { 70 &iio_const_attr_in_accel_scale_available.dev_attr.attr, 71 NULL, 72 }; 73 74 static const struct attribute_group mma7660_attribute_group = { 75 .attrs = mma7660_attributes 76 }; 77 78 #define MMA7660_CHANNEL(reg, axis) { \ 79 .type = IIO_ACCEL, \ 80 .address = reg, \ 81 .modified = 1, \ 82 .channel2 = IIO_MOD_##axis, \ 83 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ 84 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ 85 .ext_info = mma7660_ext_info, \ 86 } 87 88 static const struct iio_chan_spec mma7660_channels[] = { 89 MMA7660_CHANNEL(MMA7660_REG_XOUT, X), 90 MMA7660_CHANNEL(MMA7660_REG_YOUT, Y), 91 MMA7660_CHANNEL(MMA7660_REG_ZOUT, Z), 92 }; 93 94 static int mma7660_set_mode(struct mma7660_data *data, 95 enum mma7660_mode mode) 96 { 97 int ret; 98 struct i2c_client *client = data->client; 99 100 if (mode == data->mode) 101 return 0; 102 103 ret = i2c_smbus_read_byte_data(client, MMA7660_REG_MODE); 104 if (ret < 0) { 105 dev_err(&client->dev, "failed to read sensor mode\n"); 106 return ret; 107 } 108 109 if (mode == MMA7660_MODE_ACTIVE) { 110 ret &= ~MMA7660_REG_MODE_BIT_TON; 111 ret |= MMA7660_REG_MODE_BIT_MODE; 112 } else { 113 ret &= ~MMA7660_REG_MODE_BIT_TON; 114 ret &= ~MMA7660_REG_MODE_BIT_MODE; 115 } 116 117 ret = i2c_smbus_write_byte_data(client, MMA7660_REG_MODE, ret); 118 if (ret < 0) { 119 dev_err(&client->dev, "failed to change sensor mode\n"); 120 return ret; 121 } 122 123 data->mode = mode; 124 125 return ret; 126 } 127 128 static int mma7660_read_accel(struct mma7660_data *data, u8 address) 129 { 130 int ret, retries = MMA7660_I2C_READ_RETRIES; 131 struct i2c_client *client = data->client; 132 133 /* 134 * Read data. If the Alert bit is set, the register was read at 135 * the same time as the device was attempting to update the content. 136 * The solution is to read the register again. Do this only 137 * MMA7660_I2C_READ_RETRIES times to avoid spending too much time 138 * in the kernel. 139 */ 140 do { 141 ret = i2c_smbus_read_byte_data(client, address); 142 if (ret < 0) { 143 dev_err(&client->dev, "register read failed\n"); 144 return ret; 145 } 146 } while (retries-- > 0 && ret & MMA7660_REG_OUT_BIT_ALERT); 147 148 if (ret & MMA7660_REG_OUT_BIT_ALERT) { 149 dev_err(&client->dev, "all register read retries failed\n"); 150 return -ETIMEDOUT; 151 } 152 153 return ret; 154 } 155 156 static int mma7660_read_raw(struct iio_dev *indio_dev, 157 struct iio_chan_spec const *chan, 158 int *val, int *val2, long mask) 159 { 160 struct mma7660_data *data = iio_priv(indio_dev); 161 int ret; 162 163 switch (mask) { 164 case IIO_CHAN_INFO_RAW: 165 mutex_lock(&data->lock); 166 ret = mma7660_read_accel(data, chan->address); 167 mutex_unlock(&data->lock); 168 if (ret < 0) 169 return ret; 170 *val = sign_extend32(ret, 5); 171 return IIO_VAL_INT; 172 case IIO_CHAN_INFO_SCALE: 173 *val = 0; 174 *val2 = mma7660_nscale; 175 return IIO_VAL_INT_PLUS_NANO; 176 default: 177 return -EINVAL; 178 } 179 180 return -EINVAL; 181 } 182 183 static const struct iio_info mma7660_info = { 184 .read_raw = mma7660_read_raw, 185 .attrs = &mma7660_attribute_group, 186 }; 187 188 static int mma7660_probe(struct i2c_client *client) 189 { 190 int ret; 191 struct iio_dev *indio_dev; 192 struct mma7660_data *data; 193 194 indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data)); 195 if (!indio_dev) { 196 dev_err(&client->dev, "iio allocation failed!\n"); 197 return -ENOMEM; 198 } 199 200 data = iio_priv(indio_dev); 201 data->client = client; 202 i2c_set_clientdata(client, indio_dev); 203 mutex_init(&data->lock); 204 data->mode = MMA7660_MODE_STANDBY; 205 206 ret = iio_read_mount_matrix(&client->dev, &data->orientation); 207 if (ret) 208 return ret; 209 210 indio_dev->info = &mma7660_info; 211 indio_dev->name = MMA7660_DRIVER_NAME; 212 indio_dev->modes = INDIO_DIRECT_MODE; 213 indio_dev->channels = mma7660_channels; 214 indio_dev->num_channels = ARRAY_SIZE(mma7660_channels); 215 216 ret = mma7660_set_mode(data, MMA7660_MODE_ACTIVE); 217 if (ret < 0) 218 return ret; 219 220 ret = iio_device_register(indio_dev); 221 if (ret < 0) { 222 dev_err(&client->dev, "device_register failed\n"); 223 mma7660_set_mode(data, MMA7660_MODE_STANDBY); 224 } 225 226 return ret; 227 } 228 229 static void mma7660_remove(struct i2c_client *client) 230 { 231 struct iio_dev *indio_dev = i2c_get_clientdata(client); 232 int ret; 233 234 iio_device_unregister(indio_dev); 235 236 ret = mma7660_set_mode(iio_priv(indio_dev), MMA7660_MODE_STANDBY); 237 if (ret) 238 dev_warn(&client->dev, "Failed to put device in stand-by mode (%pe), ignoring\n", 239 ERR_PTR(ret)); 240 } 241 242 static int mma7660_suspend(struct device *dev) 243 { 244 struct mma7660_data *data; 245 246 data = iio_priv(i2c_get_clientdata(to_i2c_client(dev))); 247 248 return mma7660_set_mode(data, MMA7660_MODE_STANDBY); 249 } 250 251 static int mma7660_resume(struct device *dev) 252 { 253 struct mma7660_data *data; 254 255 data = iio_priv(i2c_get_clientdata(to_i2c_client(dev))); 256 257 return mma7660_set_mode(data, MMA7660_MODE_ACTIVE); 258 } 259 260 static DEFINE_SIMPLE_DEV_PM_OPS(mma7660_pm_ops, mma7660_suspend, 261 mma7660_resume); 262 263 static const struct i2c_device_id mma7660_i2c_id[] = { 264 { "mma7660" }, 265 {} 266 }; 267 MODULE_DEVICE_TABLE(i2c, mma7660_i2c_id); 268 269 static const struct of_device_id mma7660_of_match[] = { 270 { .compatible = "fsl,mma7660" }, 271 { } 272 }; 273 MODULE_DEVICE_TABLE(of, mma7660_of_match); 274 275 static const struct acpi_device_id mma7660_acpi_id[] = { 276 {"MMA7660", 0}, 277 {} 278 }; 279 280 MODULE_DEVICE_TABLE(acpi, mma7660_acpi_id); 281 282 static struct i2c_driver mma7660_driver = { 283 .driver = { 284 .name = "mma7660", 285 .pm = pm_sleep_ptr(&mma7660_pm_ops), 286 .of_match_table = mma7660_of_match, 287 .acpi_match_table = mma7660_acpi_id, 288 }, 289 .probe = mma7660_probe, 290 .remove = mma7660_remove, 291 .id_table = mma7660_i2c_id, 292 }; 293 294 module_i2c_driver(mma7660_driver); 295 296 MODULE_AUTHOR("Constantin Musca <constantin.musca@intel.com>"); 297 MODULE_DESCRIPTION("Freescale MMA7660FC 3-Axis Accelerometer driver"); 298 MODULE_LICENSE("GPL v2"); 299