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 return -ENOMEM; 197 198 data = iio_priv(indio_dev); 199 data->client = client; 200 i2c_set_clientdata(client, indio_dev); 201 mutex_init(&data->lock); 202 data->mode = MMA7660_MODE_STANDBY; 203 204 ret = iio_read_mount_matrix(&client->dev, &data->orientation); 205 if (ret) 206 return ret; 207 208 indio_dev->info = &mma7660_info; 209 indio_dev->name = MMA7660_DRIVER_NAME; 210 indio_dev->modes = INDIO_DIRECT_MODE; 211 indio_dev->channels = mma7660_channels; 212 indio_dev->num_channels = ARRAY_SIZE(mma7660_channels); 213 214 ret = mma7660_set_mode(data, MMA7660_MODE_ACTIVE); 215 if (ret < 0) 216 return ret; 217 218 ret = iio_device_register(indio_dev); 219 if (ret < 0) { 220 dev_err(&client->dev, "device_register failed\n"); 221 mma7660_set_mode(data, MMA7660_MODE_STANDBY); 222 } 223 224 return ret; 225 } 226 227 static void mma7660_remove(struct i2c_client *client) 228 { 229 struct iio_dev *indio_dev = i2c_get_clientdata(client); 230 int ret; 231 232 iio_device_unregister(indio_dev); 233 234 ret = mma7660_set_mode(iio_priv(indio_dev), MMA7660_MODE_STANDBY); 235 if (ret) 236 dev_warn(&client->dev, "Failed to put device in stand-by mode (%pe), ignoring\n", 237 ERR_PTR(ret)); 238 } 239 240 static int mma7660_suspend(struct device *dev) 241 { 242 struct mma7660_data *data; 243 244 data = iio_priv(i2c_get_clientdata(to_i2c_client(dev))); 245 246 return mma7660_set_mode(data, MMA7660_MODE_STANDBY); 247 } 248 249 static int mma7660_resume(struct device *dev) 250 { 251 struct mma7660_data *data; 252 253 data = iio_priv(i2c_get_clientdata(to_i2c_client(dev))); 254 255 return mma7660_set_mode(data, MMA7660_MODE_ACTIVE); 256 } 257 258 static DEFINE_SIMPLE_DEV_PM_OPS(mma7660_pm_ops, mma7660_suspend, 259 mma7660_resume); 260 261 static const struct i2c_device_id mma7660_i2c_id[] = { 262 { "mma7660" }, 263 { } 264 }; 265 MODULE_DEVICE_TABLE(i2c, mma7660_i2c_id); 266 267 static const struct of_device_id mma7660_of_match[] = { 268 { .compatible = "fsl,mma7660" }, 269 { } 270 }; 271 MODULE_DEVICE_TABLE(of, mma7660_of_match); 272 273 static const struct acpi_device_id mma7660_acpi_id[] = { 274 {"MMA7660", 0}, 275 { } 276 }; 277 278 MODULE_DEVICE_TABLE(acpi, mma7660_acpi_id); 279 280 static struct i2c_driver mma7660_driver = { 281 .driver = { 282 .name = "mma7660", 283 .pm = pm_sleep_ptr(&mma7660_pm_ops), 284 .of_match_table = mma7660_of_match, 285 .acpi_match_table = mma7660_acpi_id, 286 }, 287 .probe = mma7660_probe, 288 .remove = mma7660_remove, 289 .id_table = mma7660_i2c_id, 290 }; 291 292 module_i2c_driver(mma7660_driver); 293 294 MODULE_AUTHOR("Constantin Musca <constantin.musca@intel.com>"); 295 MODULE_DESCRIPTION("Freescale MMA7660FC 3-Axis Accelerometer driver"); 296 MODULE_LICENSE("GPL v2"); 297