da311.c (7295B)
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 78static 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 89static 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 96struct da311_data { 97 struct i2c_client *client; 98}; 99 100static 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 */ 137static 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 176static 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 184static 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 211static const struct iio_info da311_info = { 212 .read_raw = da311_read_raw, 213}; 214 215static void da311_disable(void *client) 216{ 217 da311_enable(client, false); 218} 219 220static int da311_probe(struct i2c_client *client, 221 const struct i2c_device_id *id) 222{ 223 int ret; 224 struct iio_dev *indio_dev; 225 struct da311_data *data; 226 227 ret = i2c_smbus_read_byte_data(client, DA311_REG_CHIP_ID); 228 if (ret != DA311_CHIP_ID) 229 return (ret < 0) ? ret : -ENODEV; 230 231 indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data)); 232 if (!indio_dev) 233 return -ENOMEM; 234 235 data = iio_priv(indio_dev); 236 data->client = client; 237 238 indio_dev->info = &da311_info; 239 indio_dev->name = "da311"; 240 indio_dev->modes = INDIO_DIRECT_MODE; 241 indio_dev->channels = da311_channels; 242 indio_dev->num_channels = ARRAY_SIZE(da311_channels); 243 244 ret = da311_reset(client); 245 if (ret < 0) 246 return ret; 247 248 ret = da311_enable(client, true); 249 if (ret < 0) 250 return ret; 251 252 ret = devm_add_action_or_reset(&client->dev, da311_disable, client); 253 if (ret) 254 return ret; 255 256 return devm_iio_device_register(&client->dev, indio_dev); 257} 258 259static int da311_suspend(struct device *dev) 260{ 261 return da311_enable(to_i2c_client(dev), false); 262} 263 264static int da311_resume(struct device *dev) 265{ 266 return da311_enable(to_i2c_client(dev), true); 267} 268 269static DEFINE_SIMPLE_DEV_PM_OPS(da311_pm_ops, da311_suspend, da311_resume); 270 271static const struct i2c_device_id da311_i2c_id[] = { 272 {"da311", 0}, 273 {} 274}; 275MODULE_DEVICE_TABLE(i2c, da311_i2c_id); 276 277static struct i2c_driver da311_driver = { 278 .driver = { 279 .name = "da311", 280 .pm = pm_sleep_ptr(&da311_pm_ops), 281 }, 282 .probe = da311_probe, 283 .id_table = da311_i2c_id, 284}; 285 286module_i2c_driver(da311_driver); 287 288MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>"); 289MODULE_DESCRIPTION("MiraMEMS DA311 3-Axis Accelerometer driver"); 290MODULE_LICENSE("GPL v2");