1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * IIO driver for the MiraMEMS DA311 3-axis accelerometer 4 * 5 * Copyright (c) 2016 Hans de Goede <hdegoede@redhat.com> 6 * Copyright (c) 2011-2013 MiraMEMS Sensing Technology Co., Ltd. 7 */ 8 9 #include <linux/module.h> 10 #include <linux/i2c.h> 11 #include <linux/iio/iio.h> 12 #include <linux/iio/sysfs.h> 13 #include <linux/byteorder/generic.h> 14 15 #define DA311_CHIP_ID 0x13 16 17 /* 18 * Note register addressed go from 0 - 0x3f and then wrap. 19 * For some reason there are 2 banks with 0 - 0x3f addresses, 20 * rather then a single 0-0x7f bank. 21 */ 22 23 /* Bank 0 regs */ 24 #define DA311_REG_BANK 0x0000 25 #define DA311_REG_LDO_REG 0x0006 26 #define DA311_REG_CHIP_ID 0x000f 27 #define DA311_REG_TEMP_CFG_REG 0x001f 28 #define DA311_REG_CTRL_REG1 0x0020 29 #define DA311_REG_CTRL_REG3 0x0022 30 #define DA311_REG_CTRL_REG4 0x0023 31 #define DA311_REG_CTRL_REG5 0x0024 32 #define DA311_REG_CTRL_REG6 0x0025 33 #define DA311_REG_STATUS_REG 0x0027 34 #define DA311_REG_OUT_X_L 0x0028 35 #define DA311_REG_OUT_X_H 0x0029 36 #define DA311_REG_OUT_Y_L 0x002a 37 #define DA311_REG_OUT_Y_H 0x002b 38 #define DA311_REG_OUT_Z_L 0x002c 39 #define DA311_REG_OUT_Z_H 0x002d 40 #define DA311_REG_INT1_CFG 0x0030 41 #define DA311_REG_INT1_SRC 0x0031 42 #define DA311_REG_INT1_THS 0x0032 43 #define DA311_REG_INT1_DURATION 0x0033 44 #define DA311_REG_INT2_CFG 0x0034 45 #define DA311_REG_INT2_SRC 0x0035 46 #define DA311_REG_INT2_THS 0x0036 47 #define DA311_REG_INT2_DURATION 0x0037 48 #define DA311_REG_CLICK_CFG 0x0038 49 #define DA311_REG_CLICK_SRC 0x0039 50 #define DA311_REG_CLICK_THS 0x003a 51 #define DA311_REG_TIME_LIMIT 0x003b 52 #define DA311_REG_TIME_LATENCY 0x003c 53 #define DA311_REG_TIME_WINDOW 0x003d 54 55 /* Bank 1 regs */ 56 #define DA311_REG_SOFT_RESET 0x0105 57 #define DA311_REG_OTP_XOFF_L 0x0110 58 #define DA311_REG_OTP_XOFF_H 0x0111 59 #define DA311_REG_OTP_YOFF_L 0x0112 60 #define DA311_REG_OTP_YOFF_H 0x0113 61 #define DA311_REG_OTP_ZOFF_L 0x0114 62 #define DA311_REG_OTP_ZOFF_H 0x0115 63 #define DA311_REG_OTP_XSO 0x0116 64 #define DA311_REG_OTP_YSO 0x0117 65 #define DA311_REG_OTP_ZSO 0x0118 66 #define DA311_REG_OTP_TRIM_OSC 0x011b 67 #define DA311_REG_LPF_ABSOLUTE 0x011c 68 #define DA311_REG_TEMP_OFF1 0x0127 69 #define DA311_REG_TEMP_OFF2 0x0128 70 #define DA311_REG_TEMP_OFF3 0x0129 71 #define DA311_REG_OTP_TRIM_THERM_H 0x011a 72 73 /* 74 * a value of + or -1024 corresponds to + or - 1G 75 * scale = 9.81 / 1024 = 0.009580078 76 */ 77 78 static const int da311_nscale = 9580078; 79 80 #define DA311_CHANNEL(reg, axis) { \ 81 .type = IIO_ACCEL, \ 82 .address = reg, \ 83 .modified = 1, \ 84 .channel2 = IIO_MOD_##axis, \ 85 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ 86 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ 87 } 88 89 static const struct iio_chan_spec da311_channels[] = { 90 /* | 0x80 comes from the android driver */ 91 DA311_CHANNEL(DA311_REG_OUT_X_L | 0x80, X), 92 DA311_CHANNEL(DA311_REG_OUT_Y_L | 0x80, Y), 93 DA311_CHANNEL(DA311_REG_OUT_Z_L | 0x80, Z), 94 }; 95 96 struct da311_data { 97 struct i2c_client *client; 98 }; 99 100 static int da311_register_mask_write(struct i2c_client *client, u16 addr, 101 u8 mask, u8 data) 102 { 103 int ret; 104 u8 tmp_data = 0; 105 106 if (addr & 0xff00) { 107 /* Select bank 1 */ 108 ret = i2c_smbus_write_byte_data(client, DA311_REG_BANK, 0x01); 109 if (ret < 0) 110 return ret; 111 } 112 113 if (mask != 0xff) { 114 ret = i2c_smbus_read_byte_data(client, addr); 115 if (ret < 0) 116 return ret; 117 tmp_data = ret; 118 } 119 120 tmp_data &= ~mask; 121 tmp_data |= data & mask; 122 ret = i2c_smbus_write_byte_data(client, addr & 0xff, tmp_data); 123 if (ret < 0) 124 return ret; 125 126 if (addr & 0xff00) { 127 /* Back to bank 0 */ 128 ret = i2c_smbus_write_byte_data(client, DA311_REG_BANK, 0x00); 129 if (ret < 0) 130 return ret; 131 } 132 133 return 0; 134 } 135 136 /* Init sequence taken from the android driver */ 137 static int da311_reset(struct i2c_client *client) 138 { 139 static const struct { 140 u16 addr; 141 u8 mask; 142 u8 data; 143 } init_data[] = { 144 { DA311_REG_TEMP_CFG_REG, 0xff, 0x08 }, 145 { DA311_REG_CTRL_REG5, 0xff, 0x80 }, 146 { DA311_REG_CTRL_REG4, 0x30, 0x00 }, 147 { DA311_REG_CTRL_REG1, 0xff, 0x6f }, 148 { DA311_REG_TEMP_CFG_REG, 0xff, 0x88 }, 149 { DA311_REG_LDO_REG, 0xff, 0x02 }, 150 { DA311_REG_OTP_TRIM_OSC, 0xff, 0x27 }, 151 { DA311_REG_LPF_ABSOLUTE, 0xff, 0x30 }, 152 { DA311_REG_TEMP_OFF1, 0xff, 0x3f }, 153 { DA311_REG_TEMP_OFF2, 0xff, 0xff }, 154 { DA311_REG_TEMP_OFF3, 0xff, 0x0f }, 155 }; 156 int i, ret; 157 158 /* Reset */ 159 ret = da311_register_mask_write(client, DA311_REG_SOFT_RESET, 160 0xff, 0xaa); 161 if (ret < 0) 162 return ret; 163 164 for (i = 0; i < ARRAY_SIZE(init_data); i++) { 165 ret = da311_register_mask_write(client, 166 init_data[i].addr, 167 init_data[i].mask, 168 init_data[i].data); 169 if (ret < 0) 170 return ret; 171 } 172 173 return 0; 174 } 175 176 static int da311_enable(struct i2c_client *client, bool enable) 177 { 178 u8 data = enable ? 0x00 : 0x20; 179 180 return da311_register_mask_write(client, DA311_REG_TEMP_CFG_REG, 181 0x20, data); 182 } 183 184 static int da311_read_raw(struct iio_dev *indio_dev, 185 struct iio_chan_spec const *chan, 186 int *val, int *val2, long mask) 187 { 188 struct da311_data *data = iio_priv(indio_dev); 189 int ret; 190 191 switch (mask) { 192 case IIO_CHAN_INFO_RAW: 193 ret = i2c_smbus_read_word_data(data->client, chan->address); 194 if (ret < 0) 195 return ret; 196 /* 197 * Values are 12 bits, stored as 16 bits with the 4 198 * least significant bits always 0. 199 */ 200 *val = (short)ret >> 4; 201 return IIO_VAL_INT; 202 case IIO_CHAN_INFO_SCALE: 203 *val = 0; 204 *val2 = da311_nscale; 205 return IIO_VAL_INT_PLUS_NANO; 206 default: 207 return -EINVAL; 208 } 209 } 210 211 static const struct iio_info da311_info = { 212 .read_raw = da311_read_raw, 213 }; 214 215 static void da311_disable(void *client) 216 { 217 da311_enable(client, false); 218 } 219 220 static int da311_probe(struct i2c_client *client) 221 { 222 int ret; 223 struct iio_dev *indio_dev; 224 struct da311_data *data; 225 226 ret = i2c_smbus_read_byte_data(client, DA311_REG_CHIP_ID); 227 if (ret != DA311_CHIP_ID) 228 return (ret < 0) ? ret : -ENODEV; 229 230 indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data)); 231 if (!indio_dev) 232 return -ENOMEM; 233 234 data = iio_priv(indio_dev); 235 data->client = client; 236 237 indio_dev->info = &da311_info; 238 indio_dev->name = "da311"; 239 indio_dev->modes = INDIO_DIRECT_MODE; 240 indio_dev->channels = da311_channels; 241 indio_dev->num_channels = ARRAY_SIZE(da311_channels); 242 243 ret = da311_reset(client); 244 if (ret < 0) 245 return ret; 246 247 ret = da311_enable(client, true); 248 if (ret < 0) 249 return ret; 250 251 ret = devm_add_action_or_reset(&client->dev, da311_disable, client); 252 if (ret) 253 return ret; 254 255 return devm_iio_device_register(&client->dev, indio_dev); 256 } 257 258 static int da311_suspend(struct device *dev) 259 { 260 return da311_enable(to_i2c_client(dev), false); 261 } 262 263 static int da311_resume(struct device *dev) 264 { 265 return da311_enable(to_i2c_client(dev), true); 266 } 267 268 static DEFINE_SIMPLE_DEV_PM_OPS(da311_pm_ops, da311_suspend, da311_resume); 269 270 static const struct i2c_device_id da311_i2c_id[] = { 271 { "da311" }, 272 {} 273 }; 274 MODULE_DEVICE_TABLE(i2c, da311_i2c_id); 275 276 static struct i2c_driver da311_driver = { 277 .driver = { 278 .name = "da311", 279 .pm = pm_sleep_ptr(&da311_pm_ops), 280 }, 281 .probe = da311_probe, 282 .id_table = da311_i2c_id, 283 }; 284 285 module_i2c_driver(da311_driver); 286 287 MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>"); 288 MODULE_DESCRIPTION("MiraMEMS DA311 3-Axis Accelerometer driver"); 289 MODULE_LICENSE("GPL v2"); 290