11a59d1b8SThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-or-later */ 2ff606677SJean Delvare /* 3ff606677SJean Delvare * lis3lv02d.h - ST LIS3LV02DL accelerometer driver 4ff606677SJean Delvare * 5ff606677SJean Delvare * Copyright (C) 2007-2008 Yan Burman 6ff606677SJean Delvare * Copyright (C) 2008-2009 Eric Piel 7ff606677SJean Delvare */ 8ff606677SJean Delvare #include <linux/platform_device.h> 9bb4d6e0eSDmitry Torokhov #include <linux/input.h> 10ff606677SJean Delvare #include <linux/regulator/consumer.h> 11895c156cSÉric Piel #include <linux/miscdevice.h> 12ff606677SJean Delvare 13ff606677SJean Delvare /* 14ff606677SJean Delvare * This driver tries to support the "digital" accelerometer chips from 15ff606677SJean Delvare * STMicroelectronics such as LIS3LV02DL, LIS302DL, LIS3L02DQ, LIS331DL, 160bf5a8beSAnilKumar Ch * LIS331DLH, LIS35DE, or LIS202DL. They are very similar in terms of 170bf5a8beSAnilKumar Ch * programming, with almost the same registers. In addition to differing 180bf5a8beSAnilKumar Ch * on physical properties, they differ on the number of axes (2/3), 190bf5a8beSAnilKumar Ch * precision (8/12 bits), and special features (freefall detection, 200bf5a8beSAnilKumar Ch * click...). Unfortunately, not all the differences can be probed via 210bf5a8beSAnilKumar Ch * a register. They can be connected either via I²C or SPI. 22ff606677SJean Delvare */ 23ff606677SJean Delvare 24ff606677SJean Delvare #include <linux/lis3lv02d.h> 25ff606677SJean Delvare 26ff606677SJean Delvare enum lis3_reg { 27ff606677SJean Delvare WHO_AM_I = 0x0F, 28ff606677SJean Delvare OFFSET_X = 0x16, 29ff606677SJean Delvare OFFSET_Y = 0x17, 30ff606677SJean Delvare OFFSET_Z = 0x18, 31ff606677SJean Delvare GAIN_X = 0x19, 32ff606677SJean Delvare GAIN_Y = 0x1A, 33ff606677SJean Delvare GAIN_Z = 0x1B, 34ff606677SJean Delvare CTRL_REG1 = 0x20, 35ff606677SJean Delvare CTRL_REG2 = 0x21, 36ff606677SJean Delvare CTRL_REG3 = 0x22, 37ff606677SJean Delvare CTRL_REG4 = 0x23, 38ff606677SJean Delvare HP_FILTER_RESET = 0x23, 39ff606677SJean Delvare STATUS_REG = 0x27, 40ff606677SJean Delvare OUTX_L = 0x28, 41ff606677SJean Delvare OUTX_H = 0x29, 42ff606677SJean Delvare OUTX = 0x29, 43ff606677SJean Delvare OUTY_L = 0x2A, 44ff606677SJean Delvare OUTY_H = 0x2B, 45ff606677SJean Delvare OUTY = 0x2B, 46ff606677SJean Delvare OUTZ_L = 0x2C, 47ff606677SJean Delvare OUTZ_H = 0x2D, 48ff606677SJean Delvare OUTZ = 0x2D, 49ff606677SJean Delvare }; 50ff606677SJean Delvare 51ff606677SJean Delvare enum lis302d_reg { 52ff606677SJean Delvare FF_WU_CFG_1 = 0x30, 53ff606677SJean Delvare FF_WU_SRC_1 = 0x31, 54ff606677SJean Delvare FF_WU_THS_1 = 0x32, 55ff606677SJean Delvare FF_WU_DURATION_1 = 0x33, 56ff606677SJean Delvare FF_WU_CFG_2 = 0x34, 57ff606677SJean Delvare FF_WU_SRC_2 = 0x35, 58ff606677SJean Delvare FF_WU_THS_2 = 0x36, 59ff606677SJean Delvare FF_WU_DURATION_2 = 0x37, 60ff606677SJean Delvare CLICK_CFG = 0x38, 61ff606677SJean Delvare CLICK_SRC = 0x39, 62ff606677SJean Delvare CLICK_THSY_X = 0x3B, 63ff606677SJean Delvare CLICK_THSZ = 0x3C, 64ff606677SJean Delvare CLICK_TIMELIMIT = 0x3D, 65ff606677SJean Delvare CLICK_LATENCY = 0x3E, 66ff606677SJean Delvare CLICK_WINDOW = 0x3F, 67ff606677SJean Delvare }; 68ff606677SJean Delvare 69ff606677SJean Delvare enum lis3lv02d_reg { 70ff606677SJean Delvare FF_WU_CFG = 0x30, 71ff606677SJean Delvare FF_WU_SRC = 0x31, 72ff606677SJean Delvare FF_WU_ACK = 0x32, 73ff606677SJean Delvare FF_WU_THS_L = 0x34, 74ff606677SJean Delvare FF_WU_THS_H = 0x35, 75ff606677SJean Delvare FF_WU_DURATION = 0x36, 76ff606677SJean Delvare DD_CFG = 0x38, 77ff606677SJean Delvare DD_SRC = 0x39, 78ff606677SJean Delvare DD_ACK = 0x3A, 79ff606677SJean Delvare DD_THSI_L = 0x3C, 80ff606677SJean Delvare DD_THSI_H = 0x3D, 81ff606677SJean Delvare DD_THSE_L = 0x3E, 82ff606677SJean Delvare DD_THSE_H = 0x3F, 83ff606677SJean Delvare }; 84ff606677SJean Delvare 85ff606677SJean Delvare enum lis3_who_am_i { 860bf5a8beSAnilKumar Ch WAI_3DLH = 0x32, /* 16 bits: LIS331DLH */ 87ff606677SJean Delvare WAI_3DC = 0x33, /* 8 bits: LIS3DC, HP3DC */ 88ff606677SJean Delvare WAI_12B = 0x3A, /* 12 bits: LIS3LV02D[LQ]... */ 89ff606677SJean Delvare WAI_8B = 0x3B, /* 8 bits: LIS[23]02D[LQ]... */ 90ff606677SJean Delvare WAI_6B = 0x52, /* 6 bits: LIS331DLF - not supported */ 91ff606677SJean Delvare }; 92ff606677SJean Delvare 930bf5a8beSAnilKumar Ch enum lis3_type { 94e2b2ed83SAnilKumar Ch LIS3LV02D, 950bf5a8beSAnilKumar Ch LIS3DC, 960bf5a8beSAnilKumar Ch HP3DC, 970bf5a8beSAnilKumar Ch LIS2302D, 980bf5a8beSAnilKumar Ch LIS331DLF, 990bf5a8beSAnilKumar Ch LIS331DLH, 1000bf5a8beSAnilKumar Ch }; 1010bf5a8beSAnilKumar Ch 102ff606677SJean Delvare enum lis3lv02d_ctrl1_12b { 103ff606677SJean Delvare CTRL1_Xen = 0x01, 104ff606677SJean Delvare CTRL1_Yen = 0x02, 105ff606677SJean Delvare CTRL1_Zen = 0x04, 106ff606677SJean Delvare CTRL1_ST = 0x08, 107ff606677SJean Delvare CTRL1_DF0 = 0x10, 108ff606677SJean Delvare CTRL1_DF1 = 0x20, 109ff606677SJean Delvare CTRL1_PD0 = 0x40, 110ff606677SJean Delvare CTRL1_PD1 = 0x80, 111ff606677SJean Delvare }; 112ff606677SJean Delvare 113ff606677SJean Delvare /* Delta to ctrl1_12b version */ 114ff606677SJean Delvare enum lis3lv02d_ctrl1_8b { 115ff606677SJean Delvare CTRL1_STM = 0x08, 116ff606677SJean Delvare CTRL1_STP = 0x10, 117ff606677SJean Delvare CTRL1_FS = 0x20, 118ff606677SJean Delvare CTRL1_PD = 0x40, 119ff606677SJean Delvare CTRL1_DR = 0x80, 120ff606677SJean Delvare }; 121ff606677SJean Delvare 122ff606677SJean Delvare enum lis3lv02d_ctrl1_3dc { 123ff606677SJean Delvare CTRL1_ODR0 = 0x10, 124ff606677SJean Delvare CTRL1_ODR1 = 0x20, 125ff606677SJean Delvare CTRL1_ODR2 = 0x40, 126ff606677SJean Delvare CTRL1_ODR3 = 0x80, 127ff606677SJean Delvare }; 128ff606677SJean Delvare 1290bf5a8beSAnilKumar Ch enum lis331dlh_ctrl1 { 1300bf5a8beSAnilKumar Ch CTRL1_DR0 = 0x08, 1310bf5a8beSAnilKumar Ch CTRL1_DR1 = 0x10, 1320bf5a8beSAnilKumar Ch CTRL1_PM0 = 0x20, 1330bf5a8beSAnilKumar Ch CTRL1_PM1 = 0x40, 1340bf5a8beSAnilKumar Ch CTRL1_PM2 = 0x80, 1350bf5a8beSAnilKumar Ch }; 1360bf5a8beSAnilKumar Ch 1370bf5a8beSAnilKumar Ch enum lis331dlh_ctrl2 { 1380bf5a8beSAnilKumar Ch CTRL2_HPEN1 = 0x04, 1390bf5a8beSAnilKumar Ch CTRL2_HPEN2 = 0x08, 1400bf5a8beSAnilKumar Ch CTRL2_FDS_3DLH = 0x10, 1410bf5a8beSAnilKumar Ch CTRL2_BOOT_3DLH = 0x80, 1420bf5a8beSAnilKumar Ch }; 1430bf5a8beSAnilKumar Ch 1440bf5a8beSAnilKumar Ch enum lis331dlh_ctrl4 { 1450bf5a8beSAnilKumar Ch CTRL4_STSIGN = 0x08, 1460bf5a8beSAnilKumar Ch CTRL4_BLE = 0x40, 1470bf5a8beSAnilKumar Ch CTRL4_BDU = 0x80, 1480bf5a8beSAnilKumar Ch }; 1490bf5a8beSAnilKumar Ch 150ff606677SJean Delvare enum lis3lv02d_ctrl2 { 151ff606677SJean Delvare CTRL2_DAS = 0x01, 152ff606677SJean Delvare CTRL2_SIM = 0x02, 153ff606677SJean Delvare CTRL2_DRDY = 0x04, 154ff606677SJean Delvare CTRL2_IEN = 0x08, 155ff606677SJean Delvare CTRL2_BOOT = 0x10, 156ff606677SJean Delvare CTRL2_BLE = 0x20, 157ff606677SJean Delvare CTRL2_BDU = 0x40, /* Block Data Update */ 158ff606677SJean Delvare CTRL2_FS = 0x80, /* Full Scale selection */ 159ff606677SJean Delvare }; 160ff606677SJean Delvare 161ff606677SJean Delvare enum lis3lv02d_ctrl4_3dc { 162ff606677SJean Delvare CTRL4_SIM = 0x01, 163ff606677SJean Delvare CTRL4_ST0 = 0x02, 164ff606677SJean Delvare CTRL4_ST1 = 0x04, 165ff606677SJean Delvare CTRL4_FS0 = 0x10, 166ff606677SJean Delvare CTRL4_FS1 = 0x20, 167ff606677SJean Delvare }; 168ff606677SJean Delvare 169ff606677SJean Delvare enum lis302d_ctrl2 { 170ff606677SJean Delvare HP_FF_WU2 = 0x08, 171ff606677SJean Delvare HP_FF_WU1 = 0x04, 172ff606677SJean Delvare CTRL2_BOOT_8B = 0x40, 173ff606677SJean Delvare }; 174ff606677SJean Delvare 175ff606677SJean Delvare enum lis3lv02d_ctrl3 { 176ff606677SJean Delvare CTRL3_CFS0 = 0x01, 177ff606677SJean Delvare CTRL3_CFS1 = 0x02, 178ff606677SJean Delvare CTRL3_FDS = 0x10, 179ff606677SJean Delvare CTRL3_HPFF = 0x20, 180ff606677SJean Delvare CTRL3_HPDD = 0x40, 181ff606677SJean Delvare CTRL3_ECK = 0x80, 182ff606677SJean Delvare }; 183ff606677SJean Delvare 184ff606677SJean Delvare enum lis3lv02d_status_reg { 185ff606677SJean Delvare STATUS_XDA = 0x01, 186ff606677SJean Delvare STATUS_YDA = 0x02, 187ff606677SJean Delvare STATUS_ZDA = 0x04, 188ff606677SJean Delvare STATUS_XYZDA = 0x08, 189ff606677SJean Delvare STATUS_XOR = 0x10, 190ff606677SJean Delvare STATUS_YOR = 0x20, 191ff606677SJean Delvare STATUS_ZOR = 0x40, 192ff606677SJean Delvare STATUS_XYZOR = 0x80, 193ff606677SJean Delvare }; 194ff606677SJean Delvare 195ff606677SJean Delvare enum lis3lv02d_ff_wu_cfg { 196ff606677SJean Delvare FF_WU_CFG_XLIE = 0x01, 197ff606677SJean Delvare FF_WU_CFG_XHIE = 0x02, 198ff606677SJean Delvare FF_WU_CFG_YLIE = 0x04, 199ff606677SJean Delvare FF_WU_CFG_YHIE = 0x08, 200ff606677SJean Delvare FF_WU_CFG_ZLIE = 0x10, 201ff606677SJean Delvare FF_WU_CFG_ZHIE = 0x20, 202ff606677SJean Delvare FF_WU_CFG_LIR = 0x40, 203ff606677SJean Delvare FF_WU_CFG_AOI = 0x80, 204ff606677SJean Delvare }; 205ff606677SJean Delvare 206ff606677SJean Delvare enum lis3lv02d_ff_wu_src { 207ff606677SJean Delvare FF_WU_SRC_XL = 0x01, 208ff606677SJean Delvare FF_WU_SRC_XH = 0x02, 209ff606677SJean Delvare FF_WU_SRC_YL = 0x04, 210ff606677SJean Delvare FF_WU_SRC_YH = 0x08, 211ff606677SJean Delvare FF_WU_SRC_ZL = 0x10, 212ff606677SJean Delvare FF_WU_SRC_ZH = 0x20, 213ff606677SJean Delvare FF_WU_SRC_IA = 0x40, 214ff606677SJean Delvare }; 215ff606677SJean Delvare 216ff606677SJean Delvare enum lis3lv02d_dd_cfg { 217ff606677SJean Delvare DD_CFG_XLIE = 0x01, 218ff606677SJean Delvare DD_CFG_XHIE = 0x02, 219ff606677SJean Delvare DD_CFG_YLIE = 0x04, 220ff606677SJean Delvare DD_CFG_YHIE = 0x08, 221ff606677SJean Delvare DD_CFG_ZLIE = 0x10, 222ff606677SJean Delvare DD_CFG_ZHIE = 0x20, 223ff606677SJean Delvare DD_CFG_LIR = 0x40, 224ff606677SJean Delvare DD_CFG_IEND = 0x80, 225ff606677SJean Delvare }; 226ff606677SJean Delvare 227ff606677SJean Delvare enum lis3lv02d_dd_src { 228ff606677SJean Delvare DD_SRC_XL = 0x01, 229ff606677SJean Delvare DD_SRC_XH = 0x02, 230ff606677SJean Delvare DD_SRC_YL = 0x04, 231ff606677SJean Delvare DD_SRC_YH = 0x08, 232ff606677SJean Delvare DD_SRC_ZL = 0x10, 233ff606677SJean Delvare DD_SRC_ZH = 0x20, 234ff606677SJean Delvare DD_SRC_IA = 0x40, 235ff606677SJean Delvare }; 236ff606677SJean Delvare 237ff606677SJean Delvare enum lis3lv02d_click_src_8b { 238ff606677SJean Delvare CLICK_SINGLE_X = 0x01, 239ff606677SJean Delvare CLICK_DOUBLE_X = 0x02, 240ff606677SJean Delvare CLICK_SINGLE_Y = 0x04, 241ff606677SJean Delvare CLICK_DOUBLE_Y = 0x08, 242ff606677SJean Delvare CLICK_SINGLE_Z = 0x10, 243ff606677SJean Delvare CLICK_DOUBLE_Z = 0x20, 244ff606677SJean Delvare CLICK_IA = 0x40, 245ff606677SJean Delvare }; 246ff606677SJean Delvare 247ff606677SJean Delvare enum lis3lv02d_reg_state { 248ff606677SJean Delvare LIS3_REG_OFF = 0x00, 249ff606677SJean Delvare LIS3_REG_ON = 0x01, 250ff606677SJean Delvare }; 251ff606677SJean Delvare 252ff606677SJean Delvare union axis_conversion { 253ff606677SJean Delvare struct { 254ff606677SJean Delvare int x, y, z; 255ff606677SJean Delvare }; 256ff606677SJean Delvare int as_array[3]; 257ff606677SJean Delvare 258ff606677SJean Delvare }; 259ff606677SJean Delvare 260ff606677SJean Delvare struct lis3lv02d { 261ff606677SJean Delvare void *bus_priv; /* used by the bus layer only */ 262ff606677SJean Delvare struct device *pm_dev; /* for pm_runtime purposes */ 263ff606677SJean Delvare int (*init) (struct lis3lv02d *lis3); 264ff606677SJean Delvare int (*write) (struct lis3lv02d *lis3, int reg, u8 val); 265ff606677SJean Delvare int (*read) (struct lis3lv02d *lis3, int reg, u8 *ret); 266ff606677SJean Delvare int (*blkread) (struct lis3lv02d *lis3, int reg, int len, u8 *ret); 267ff606677SJean Delvare int (*reg_ctrl) (struct lis3lv02d *lis3, bool state); 268ff606677SJean Delvare 269ff606677SJean Delvare int *odrs; /* Supported output data rates */ 270ff606677SJean Delvare u8 *regs; /* Regs to store / restore */ 271ff606677SJean Delvare int regs_size; 272ff606677SJean Delvare u8 *reg_cache; 273ff606677SJean Delvare bool regs_stored; 274ff606677SJean Delvare u8 odr_mask; /* ODR bit mask */ 275ff606677SJean Delvare u8 whoami; /* indicates measurement precision */ 276ff606677SJean Delvare s16 (*read_data) (struct lis3lv02d *lis3, int reg); 277ff606677SJean Delvare int mdps_max_val; 278ff606677SJean Delvare int pwron_delay; 279ff606677SJean Delvare int scale; /* 280ff606677SJean Delvare * relationship between 1 LBS and mG 281ff606677SJean Delvare * (1/1000th of earth gravity) 282ff606677SJean Delvare */ 283ff606677SJean Delvare 284bb4d6e0eSDmitry Torokhov struct input_dev *idev; /* input device */ 285ff606677SJean Delvare struct platform_device *pdev; /* platform device */ 286ff606677SJean Delvare struct regulator_bulk_data regulators[2]; 287ff606677SJean Delvare atomic_t count; /* interrupt count after last read */ 288ff606677SJean Delvare union axis_conversion ac; /* hw -> logical axis */ 289ff606677SJean Delvare int mapped_btns[3]; 290ff606677SJean Delvare 291ff606677SJean Delvare u32 irq; /* IRQ number */ 292ff606677SJean Delvare struct fasync_struct *async_queue; /* queue for the misc device */ 293ff606677SJean Delvare wait_queue_head_t misc_wait; /* Wait queue for the misc device */ 294ff606677SJean Delvare unsigned long misc_opened; /* bit0: whether the device is open */ 295895c156cSÉric Piel struct miscdevice miscdev; 296895c156cSÉric Piel 297ff606677SJean Delvare int data_ready_count[2]; 298ff606677SJean Delvare atomic_t wake_thread; 299ff606677SJean Delvare unsigned char irq_cfg; 3000bf5a8beSAnilKumar Ch unsigned int shift_adj; 301ff606677SJean Delvare 302ff606677SJean Delvare struct lis3lv02d_platform_data *pdata; /* for passing board config */ 303ff606677SJean Delvare struct mutex mutex; /* Serialize poll and selftest */ 304cbac1a8bSDaniel Mack 305cbac1a8bSDaniel Mack #ifdef CONFIG_OF 306cbac1a8bSDaniel Mack struct device_node *of_node; 307cbac1a8bSDaniel Mack #endif 308ff606677SJean Delvare }; 309ff606677SJean Delvare 310ff606677SJean Delvare int lis3lv02d_init_device(struct lis3lv02d *lis3); 311e1e5687dSÉric Piel int lis3lv02d_joystick_enable(struct lis3lv02d *lis3); 312e1e5687dSÉric Piel void lis3lv02d_joystick_disable(struct lis3lv02d *lis3); 313ff606677SJean Delvare void lis3lv02d_poweroff(struct lis3lv02d *lis3); 3141510dd59SÉric Piel int lis3lv02d_poweron(struct lis3lv02d *lis3); 315*4df4946dSUwe Kleine-König void lis3lv02d_remove_fs(struct lis3lv02d *lis3); 3160c83adbaSAnilKumar Ch int lis3lv02d_init_dt(struct lis3lv02d *lis3); 317ff606677SJean Delvare 318ff606677SJean Delvare extern struct lis3lv02d lis3_dev; 319