18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * STMicroelectronics st_lsm6dsx sensor driver 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright 2016 STMicroelectronics Inc. 68c2ecf20Sopenharmony_ci * 78c2ecf20Sopenharmony_ci * Lorenzo Bianconi <lorenzo.bianconi@st.com> 88c2ecf20Sopenharmony_ci * Denis Ciocca <denis.ciocca@st.com> 98c2ecf20Sopenharmony_ci */ 108c2ecf20Sopenharmony_ci 118c2ecf20Sopenharmony_ci#ifndef ST_LSM6DSX_H 128c2ecf20Sopenharmony_ci#define ST_LSM6DSX_H 138c2ecf20Sopenharmony_ci 148c2ecf20Sopenharmony_ci#include <linux/device.h> 158c2ecf20Sopenharmony_ci#include <linux/iio/iio.h> 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_ci#define ST_LSM6DS3_DEV_NAME "lsm6ds3" 188c2ecf20Sopenharmony_ci#define ST_LSM6DS3H_DEV_NAME "lsm6ds3h" 198c2ecf20Sopenharmony_ci#define ST_LSM6DSL_DEV_NAME "lsm6dsl" 208c2ecf20Sopenharmony_ci#define ST_LSM6DSM_DEV_NAME "lsm6dsm" 218c2ecf20Sopenharmony_ci#define ST_ISM330DLC_DEV_NAME "ism330dlc" 228c2ecf20Sopenharmony_ci#define ST_LSM6DSO_DEV_NAME "lsm6dso" 238c2ecf20Sopenharmony_ci#define ST_ASM330LHH_DEV_NAME "asm330lhh" 248c2ecf20Sopenharmony_ci#define ST_LSM6DSOX_DEV_NAME "lsm6dsox" 258c2ecf20Sopenharmony_ci#define ST_LSM6DSR_DEV_NAME "lsm6dsr" 268c2ecf20Sopenharmony_ci#define ST_LSM6DS3TRC_DEV_NAME "lsm6ds3tr-c" 278c2ecf20Sopenharmony_ci#define ST_ISM330DHCX_DEV_NAME "ism330dhcx" 288c2ecf20Sopenharmony_ci#define ST_LSM9DS1_DEV_NAME "lsm9ds1-imu" 298c2ecf20Sopenharmony_ci#define ST_LSM6DS0_DEV_NAME "lsm6ds0" 308c2ecf20Sopenharmony_ci#define ST_LSM6DSRX_DEV_NAME "lsm6dsrx" 318c2ecf20Sopenharmony_ci 328c2ecf20Sopenharmony_cienum st_lsm6dsx_hw_id { 338c2ecf20Sopenharmony_ci ST_LSM6DS3_ID, 348c2ecf20Sopenharmony_ci ST_LSM6DS3H_ID, 358c2ecf20Sopenharmony_ci ST_LSM6DSL_ID, 368c2ecf20Sopenharmony_ci ST_LSM6DSM_ID, 378c2ecf20Sopenharmony_ci ST_ISM330DLC_ID, 388c2ecf20Sopenharmony_ci ST_LSM6DSO_ID, 398c2ecf20Sopenharmony_ci ST_ASM330LHH_ID, 408c2ecf20Sopenharmony_ci ST_LSM6DSOX_ID, 418c2ecf20Sopenharmony_ci ST_LSM6DSR_ID, 428c2ecf20Sopenharmony_ci ST_LSM6DS3TRC_ID, 438c2ecf20Sopenharmony_ci ST_ISM330DHCX_ID, 448c2ecf20Sopenharmony_ci ST_LSM9DS1_ID, 458c2ecf20Sopenharmony_ci ST_LSM6DS0_ID, 468c2ecf20Sopenharmony_ci ST_LSM6DSRX_ID, 478c2ecf20Sopenharmony_ci ST_LSM6DSX_MAX_ID, 488c2ecf20Sopenharmony_ci}; 498c2ecf20Sopenharmony_ci 508c2ecf20Sopenharmony_ci#define ST_LSM6DSX_BUFF_SIZE 512 518c2ecf20Sopenharmony_ci#define ST_LSM6DSX_CHAN_SIZE 2 528c2ecf20Sopenharmony_ci#define ST_LSM6DSX_SAMPLE_SIZE 6 538c2ecf20Sopenharmony_ci#define ST_LSM6DSX_TAG_SIZE 1 548c2ecf20Sopenharmony_ci#define ST_LSM6DSX_TAGGED_SAMPLE_SIZE (ST_LSM6DSX_SAMPLE_SIZE + \ 558c2ecf20Sopenharmony_ci ST_LSM6DSX_TAG_SIZE) 568c2ecf20Sopenharmony_ci#define ST_LSM6DSX_MAX_WORD_LEN ((32 / ST_LSM6DSX_SAMPLE_SIZE) * \ 578c2ecf20Sopenharmony_ci ST_LSM6DSX_SAMPLE_SIZE) 588c2ecf20Sopenharmony_ci#define ST_LSM6DSX_MAX_TAGGED_WORD_LEN ((32 / ST_LSM6DSX_TAGGED_SAMPLE_SIZE) \ 598c2ecf20Sopenharmony_ci * ST_LSM6DSX_TAGGED_SAMPLE_SIZE) 608c2ecf20Sopenharmony_ci#define ST_LSM6DSX_SHIFT_VAL(val, mask) (((val) << __ffs(mask)) & (mask)) 618c2ecf20Sopenharmony_ci 628c2ecf20Sopenharmony_ci#define ST_LSM6DSX_CHANNEL_ACC(chan_type, addr, mod, scan_idx) \ 638c2ecf20Sopenharmony_ci{ \ 648c2ecf20Sopenharmony_ci .type = chan_type, \ 658c2ecf20Sopenharmony_ci .address = addr, \ 668c2ecf20Sopenharmony_ci .modified = 1, \ 678c2ecf20Sopenharmony_ci .channel2 = mod, \ 688c2ecf20Sopenharmony_ci .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ 698c2ecf20Sopenharmony_ci .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ 708c2ecf20Sopenharmony_ci .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), \ 718c2ecf20Sopenharmony_ci .scan_index = scan_idx, \ 728c2ecf20Sopenharmony_ci .scan_type = { \ 738c2ecf20Sopenharmony_ci .sign = 's', \ 748c2ecf20Sopenharmony_ci .realbits = 16, \ 758c2ecf20Sopenharmony_ci .storagebits = 16, \ 768c2ecf20Sopenharmony_ci .endianness = IIO_LE, \ 778c2ecf20Sopenharmony_ci }, \ 788c2ecf20Sopenharmony_ci .event_spec = &st_lsm6dsx_event, \ 798c2ecf20Sopenharmony_ci .ext_info = st_lsm6dsx_accel_ext_info, \ 808c2ecf20Sopenharmony_ci .num_event_specs = 1, \ 818c2ecf20Sopenharmony_ci} 828c2ecf20Sopenharmony_ci 838c2ecf20Sopenharmony_ci#define ST_LSM6DSX_CHANNEL(chan_type, addr, mod, scan_idx) \ 848c2ecf20Sopenharmony_ci{ \ 858c2ecf20Sopenharmony_ci .type = chan_type, \ 868c2ecf20Sopenharmony_ci .address = addr, \ 878c2ecf20Sopenharmony_ci .modified = 1, \ 888c2ecf20Sopenharmony_ci .channel2 = mod, \ 898c2ecf20Sopenharmony_ci .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ 908c2ecf20Sopenharmony_ci .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ 918c2ecf20Sopenharmony_ci .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), \ 928c2ecf20Sopenharmony_ci .scan_index = scan_idx, \ 938c2ecf20Sopenharmony_ci .scan_type = { \ 948c2ecf20Sopenharmony_ci .sign = 's', \ 958c2ecf20Sopenharmony_ci .realbits = 16, \ 968c2ecf20Sopenharmony_ci .storagebits = 16, \ 978c2ecf20Sopenharmony_ci .endianness = IIO_LE, \ 988c2ecf20Sopenharmony_ci }, \ 998c2ecf20Sopenharmony_ci} 1008c2ecf20Sopenharmony_ci 1018c2ecf20Sopenharmony_cistruct st_lsm6dsx_reg { 1028c2ecf20Sopenharmony_ci u8 addr; 1038c2ecf20Sopenharmony_ci u8 mask; 1048c2ecf20Sopenharmony_ci}; 1058c2ecf20Sopenharmony_ci 1068c2ecf20Sopenharmony_cistruct st_lsm6dsx_sensor; 1078c2ecf20Sopenharmony_cistruct st_lsm6dsx_hw; 1088c2ecf20Sopenharmony_ci 1098c2ecf20Sopenharmony_cistruct st_lsm6dsx_odr { 1108c2ecf20Sopenharmony_ci u32 milli_hz; 1118c2ecf20Sopenharmony_ci u8 val; 1128c2ecf20Sopenharmony_ci}; 1138c2ecf20Sopenharmony_ci 1148c2ecf20Sopenharmony_ci#define ST_LSM6DSX_ODR_LIST_SIZE 8 1158c2ecf20Sopenharmony_cistruct st_lsm6dsx_odr_table_entry { 1168c2ecf20Sopenharmony_ci struct st_lsm6dsx_reg reg; 1178c2ecf20Sopenharmony_ci 1188c2ecf20Sopenharmony_ci struct st_lsm6dsx_odr odr_avl[ST_LSM6DSX_ODR_LIST_SIZE]; 1198c2ecf20Sopenharmony_ci int odr_len; 1208c2ecf20Sopenharmony_ci}; 1218c2ecf20Sopenharmony_ci 1228c2ecf20Sopenharmony_cistruct st_lsm6dsx_fs { 1238c2ecf20Sopenharmony_ci u32 gain; 1248c2ecf20Sopenharmony_ci u8 val; 1258c2ecf20Sopenharmony_ci}; 1268c2ecf20Sopenharmony_ci 1278c2ecf20Sopenharmony_ci#define ST_LSM6DSX_FS_LIST_SIZE 4 1288c2ecf20Sopenharmony_cistruct st_lsm6dsx_fs_table_entry { 1298c2ecf20Sopenharmony_ci struct st_lsm6dsx_reg reg; 1308c2ecf20Sopenharmony_ci 1318c2ecf20Sopenharmony_ci struct st_lsm6dsx_fs fs_avl[ST_LSM6DSX_FS_LIST_SIZE]; 1328c2ecf20Sopenharmony_ci int fs_len; 1338c2ecf20Sopenharmony_ci}; 1348c2ecf20Sopenharmony_ci 1358c2ecf20Sopenharmony_ci/** 1368c2ecf20Sopenharmony_ci * struct st_lsm6dsx_fifo_ops - ST IMU FIFO settings 1378c2ecf20Sopenharmony_ci * @update_fifo: Update FIFO configuration callback. 1388c2ecf20Sopenharmony_ci * @read_fifo: Read FIFO callback. 1398c2ecf20Sopenharmony_ci * @fifo_th: FIFO threshold register info (addr + mask). 1408c2ecf20Sopenharmony_ci * @fifo_diff: FIFO diff status register info (addr + mask). 1418c2ecf20Sopenharmony_ci * @th_wl: FIFO threshold word length. 1428c2ecf20Sopenharmony_ci */ 1438c2ecf20Sopenharmony_cistruct st_lsm6dsx_fifo_ops { 1448c2ecf20Sopenharmony_ci int (*update_fifo)(struct st_lsm6dsx_sensor *sensor, bool enable); 1458c2ecf20Sopenharmony_ci int (*read_fifo)(struct st_lsm6dsx_hw *hw); 1468c2ecf20Sopenharmony_ci struct { 1478c2ecf20Sopenharmony_ci u8 addr; 1488c2ecf20Sopenharmony_ci u16 mask; 1498c2ecf20Sopenharmony_ci } fifo_th; 1508c2ecf20Sopenharmony_ci struct { 1518c2ecf20Sopenharmony_ci u8 addr; 1528c2ecf20Sopenharmony_ci u16 mask; 1538c2ecf20Sopenharmony_ci } fifo_diff; 1548c2ecf20Sopenharmony_ci u8 th_wl; 1558c2ecf20Sopenharmony_ci}; 1568c2ecf20Sopenharmony_ci 1578c2ecf20Sopenharmony_ci/** 1588c2ecf20Sopenharmony_ci * struct st_lsm6dsx_hw_ts_settings - ST IMU hw timer settings 1598c2ecf20Sopenharmony_ci * @timer_en: Hw timer enable register info (addr + mask). 1608c2ecf20Sopenharmony_ci * @hr_timer: Hw timer resolution register info (addr + mask). 1618c2ecf20Sopenharmony_ci * @fifo_en: Hw timer FIFO enable register info (addr + mask). 1628c2ecf20Sopenharmony_ci * @decimator: Hw timer FIFO decimator register info (addr + mask). 1638c2ecf20Sopenharmony_ci * @freq_fine: Difference in % of ODR with respect to the typical. 1648c2ecf20Sopenharmony_ci */ 1658c2ecf20Sopenharmony_cistruct st_lsm6dsx_hw_ts_settings { 1668c2ecf20Sopenharmony_ci struct st_lsm6dsx_reg timer_en; 1678c2ecf20Sopenharmony_ci struct st_lsm6dsx_reg hr_timer; 1688c2ecf20Sopenharmony_ci struct st_lsm6dsx_reg fifo_en; 1698c2ecf20Sopenharmony_ci struct st_lsm6dsx_reg decimator; 1708c2ecf20Sopenharmony_ci u8 freq_fine; 1718c2ecf20Sopenharmony_ci}; 1728c2ecf20Sopenharmony_ci 1738c2ecf20Sopenharmony_ci/** 1748c2ecf20Sopenharmony_ci * struct st_lsm6dsx_shub_settings - ST IMU hw i2c controller settings 1758c2ecf20Sopenharmony_ci * @page_mux: register page mux info (addr + mask). 1768c2ecf20Sopenharmony_ci * @master_en: master config register info (addr + mask). 1778c2ecf20Sopenharmony_ci * @pullup_en: i2c controller pull-up register info (addr + mask). 1788c2ecf20Sopenharmony_ci * @aux_sens: aux sensor register info (addr + mask). 1798c2ecf20Sopenharmony_ci * @wr_once: write_once register info (addr + mask). 1808c2ecf20Sopenharmony_ci * @emb_func: embedded function register info (addr + mask). 1818c2ecf20Sopenharmony_ci * @num_ext_dev: max number of slave devices. 1828c2ecf20Sopenharmony_ci * @shub_out: sensor hub first output register info. 1838c2ecf20Sopenharmony_ci * @slv0_addr: slave0 address in secondary page. 1848c2ecf20Sopenharmony_ci * @dw_slv0_addr: slave0 write register address in secondary page. 1858c2ecf20Sopenharmony_ci * @batch_en: Enable/disable FIFO batching. 1868c2ecf20Sopenharmony_ci * @pause: controller pause value. 1878c2ecf20Sopenharmony_ci */ 1888c2ecf20Sopenharmony_cistruct st_lsm6dsx_shub_settings { 1898c2ecf20Sopenharmony_ci struct st_lsm6dsx_reg page_mux; 1908c2ecf20Sopenharmony_ci struct { 1918c2ecf20Sopenharmony_ci bool sec_page; 1928c2ecf20Sopenharmony_ci u8 addr; 1938c2ecf20Sopenharmony_ci u8 mask; 1948c2ecf20Sopenharmony_ci } master_en; 1958c2ecf20Sopenharmony_ci struct { 1968c2ecf20Sopenharmony_ci bool sec_page; 1978c2ecf20Sopenharmony_ci u8 addr; 1988c2ecf20Sopenharmony_ci u8 mask; 1998c2ecf20Sopenharmony_ci } pullup_en; 2008c2ecf20Sopenharmony_ci struct st_lsm6dsx_reg aux_sens; 2018c2ecf20Sopenharmony_ci struct st_lsm6dsx_reg wr_once; 2028c2ecf20Sopenharmony_ci struct st_lsm6dsx_reg emb_func; 2038c2ecf20Sopenharmony_ci u8 num_ext_dev; 2048c2ecf20Sopenharmony_ci struct { 2058c2ecf20Sopenharmony_ci bool sec_page; 2068c2ecf20Sopenharmony_ci u8 addr; 2078c2ecf20Sopenharmony_ci } shub_out; 2088c2ecf20Sopenharmony_ci u8 slv0_addr; 2098c2ecf20Sopenharmony_ci u8 dw_slv0_addr; 2108c2ecf20Sopenharmony_ci u8 batch_en; 2118c2ecf20Sopenharmony_ci u8 pause; 2128c2ecf20Sopenharmony_ci}; 2138c2ecf20Sopenharmony_ci 2148c2ecf20Sopenharmony_cistruct st_lsm6dsx_event_settings { 2158c2ecf20Sopenharmony_ci struct st_lsm6dsx_reg enable_reg; 2168c2ecf20Sopenharmony_ci struct st_lsm6dsx_reg wakeup_reg; 2178c2ecf20Sopenharmony_ci u8 wakeup_src_reg; 2188c2ecf20Sopenharmony_ci u8 wakeup_src_status_mask; 2198c2ecf20Sopenharmony_ci u8 wakeup_src_z_mask; 2208c2ecf20Sopenharmony_ci u8 wakeup_src_y_mask; 2218c2ecf20Sopenharmony_ci u8 wakeup_src_x_mask; 2228c2ecf20Sopenharmony_ci}; 2238c2ecf20Sopenharmony_ci 2248c2ecf20Sopenharmony_cienum st_lsm6dsx_ext_sensor_id { 2258c2ecf20Sopenharmony_ci ST_LSM6DSX_ID_MAGN, 2268c2ecf20Sopenharmony_ci}; 2278c2ecf20Sopenharmony_ci 2288c2ecf20Sopenharmony_ci/** 2298c2ecf20Sopenharmony_ci * struct st_lsm6dsx_ext_dev_settings - i2c controller slave settings 2308c2ecf20Sopenharmony_ci * @i2c_addr: I2c slave address list. 2318c2ecf20Sopenharmony_ci * @wai: Wai address info. 2328c2ecf20Sopenharmony_ci * @id: external sensor id. 2338c2ecf20Sopenharmony_ci * @odr_table: Output data rate of the sensor [Hz]. 2348c2ecf20Sopenharmony_ci * @fs_table: Configured sensor sensitivity table depending on full scale. 2358c2ecf20Sopenharmony_ci * @temp_comp: Temperature compensation register info (addr + mask). 2368c2ecf20Sopenharmony_ci * @pwr_table: Power on register info (addr + mask). 2378c2ecf20Sopenharmony_ci * @off_canc: Offset cancellation register info (addr + mask). 2388c2ecf20Sopenharmony_ci * @bdu: Block data update register info (addr + mask). 2398c2ecf20Sopenharmony_ci * @out: Output register info. 2408c2ecf20Sopenharmony_ci */ 2418c2ecf20Sopenharmony_cistruct st_lsm6dsx_ext_dev_settings { 2428c2ecf20Sopenharmony_ci u8 i2c_addr[2]; 2438c2ecf20Sopenharmony_ci struct { 2448c2ecf20Sopenharmony_ci u8 addr; 2458c2ecf20Sopenharmony_ci u8 val; 2468c2ecf20Sopenharmony_ci } wai; 2478c2ecf20Sopenharmony_ci enum st_lsm6dsx_ext_sensor_id id; 2488c2ecf20Sopenharmony_ci struct st_lsm6dsx_odr_table_entry odr_table; 2498c2ecf20Sopenharmony_ci struct st_lsm6dsx_fs_table_entry fs_table; 2508c2ecf20Sopenharmony_ci struct st_lsm6dsx_reg temp_comp; 2518c2ecf20Sopenharmony_ci struct { 2528c2ecf20Sopenharmony_ci struct st_lsm6dsx_reg reg; 2538c2ecf20Sopenharmony_ci u8 off_val; 2548c2ecf20Sopenharmony_ci u8 on_val; 2558c2ecf20Sopenharmony_ci } pwr_table; 2568c2ecf20Sopenharmony_ci struct st_lsm6dsx_reg off_canc; 2578c2ecf20Sopenharmony_ci struct st_lsm6dsx_reg bdu; 2588c2ecf20Sopenharmony_ci struct { 2598c2ecf20Sopenharmony_ci u8 addr; 2608c2ecf20Sopenharmony_ci u8 len; 2618c2ecf20Sopenharmony_ci } out; 2628c2ecf20Sopenharmony_ci}; 2638c2ecf20Sopenharmony_ci 2648c2ecf20Sopenharmony_ci/** 2658c2ecf20Sopenharmony_ci * struct st_lsm6dsx_settings - ST IMU sensor settings 2668c2ecf20Sopenharmony_ci * @wai: Sensor WhoAmI default value. 2678c2ecf20Sopenharmony_ci * @reset: register address for reset. 2688c2ecf20Sopenharmony_ci * @boot: register address for boot. 2698c2ecf20Sopenharmony_ci * @bdu: register address for Block Data Update. 2708c2ecf20Sopenharmony_ci * @max_fifo_size: Sensor max fifo length in FIFO words. 2718c2ecf20Sopenharmony_ci * @id: List of hw id/device name supported by the driver configuration. 2728c2ecf20Sopenharmony_ci * @channels: IIO channels supported by the device. 2738c2ecf20Sopenharmony_ci * @irq_config: interrupts related registers. 2748c2ecf20Sopenharmony_ci * @drdy_mask: register info for data-ready mask (addr + mask). 2758c2ecf20Sopenharmony_ci * @odr_table: Hw sensors odr table (Hz + val). 2768c2ecf20Sopenharmony_ci * @fs_table: Hw sensors gain table (gain + val). 2778c2ecf20Sopenharmony_ci * @decimator: List of decimator register info (addr + mask). 2788c2ecf20Sopenharmony_ci * @batch: List of FIFO batching register info (addr + mask). 2798c2ecf20Sopenharmony_ci * @fifo_ops: Sensor hw FIFO parameters. 2808c2ecf20Sopenharmony_ci * @ts_settings: Hw timer related settings. 2818c2ecf20Sopenharmony_ci * @shub_settings: i2c controller related settings. 2828c2ecf20Sopenharmony_ci */ 2838c2ecf20Sopenharmony_cistruct st_lsm6dsx_settings { 2848c2ecf20Sopenharmony_ci u8 wai; 2858c2ecf20Sopenharmony_ci struct st_lsm6dsx_reg reset; 2868c2ecf20Sopenharmony_ci struct st_lsm6dsx_reg boot; 2878c2ecf20Sopenharmony_ci struct st_lsm6dsx_reg bdu; 2888c2ecf20Sopenharmony_ci u16 max_fifo_size; 2898c2ecf20Sopenharmony_ci struct { 2908c2ecf20Sopenharmony_ci enum st_lsm6dsx_hw_id hw_id; 2918c2ecf20Sopenharmony_ci const char *name; 2928c2ecf20Sopenharmony_ci } id[ST_LSM6DSX_MAX_ID]; 2938c2ecf20Sopenharmony_ci struct { 2948c2ecf20Sopenharmony_ci const struct iio_chan_spec *chan; 2958c2ecf20Sopenharmony_ci int len; 2968c2ecf20Sopenharmony_ci } channels[2]; 2978c2ecf20Sopenharmony_ci struct { 2988c2ecf20Sopenharmony_ci struct st_lsm6dsx_reg irq1; 2998c2ecf20Sopenharmony_ci struct st_lsm6dsx_reg irq2; 3008c2ecf20Sopenharmony_ci struct st_lsm6dsx_reg irq1_func; 3018c2ecf20Sopenharmony_ci struct st_lsm6dsx_reg irq2_func; 3028c2ecf20Sopenharmony_ci struct st_lsm6dsx_reg lir; 3038c2ecf20Sopenharmony_ci struct st_lsm6dsx_reg clear_on_read; 3048c2ecf20Sopenharmony_ci struct st_lsm6dsx_reg hla; 3058c2ecf20Sopenharmony_ci struct st_lsm6dsx_reg od; 3068c2ecf20Sopenharmony_ci } irq_config; 3078c2ecf20Sopenharmony_ci struct st_lsm6dsx_reg drdy_mask; 3088c2ecf20Sopenharmony_ci struct st_lsm6dsx_odr_table_entry odr_table[2]; 3098c2ecf20Sopenharmony_ci struct st_lsm6dsx_fs_table_entry fs_table[2]; 3108c2ecf20Sopenharmony_ci struct st_lsm6dsx_reg decimator[ST_LSM6DSX_MAX_ID]; 3118c2ecf20Sopenharmony_ci struct st_lsm6dsx_reg batch[ST_LSM6DSX_MAX_ID]; 3128c2ecf20Sopenharmony_ci struct st_lsm6dsx_fifo_ops fifo_ops; 3138c2ecf20Sopenharmony_ci struct st_lsm6dsx_hw_ts_settings ts_settings; 3148c2ecf20Sopenharmony_ci struct st_lsm6dsx_shub_settings shub_settings; 3158c2ecf20Sopenharmony_ci struct st_lsm6dsx_event_settings event_settings; 3168c2ecf20Sopenharmony_ci}; 3178c2ecf20Sopenharmony_ci 3188c2ecf20Sopenharmony_cienum st_lsm6dsx_sensor_id { 3198c2ecf20Sopenharmony_ci ST_LSM6DSX_ID_GYRO, 3208c2ecf20Sopenharmony_ci ST_LSM6DSX_ID_ACC, 3218c2ecf20Sopenharmony_ci ST_LSM6DSX_ID_EXT0, 3228c2ecf20Sopenharmony_ci ST_LSM6DSX_ID_EXT1, 3238c2ecf20Sopenharmony_ci ST_LSM6DSX_ID_EXT2, 3248c2ecf20Sopenharmony_ci ST_LSM6DSX_ID_MAX, 3258c2ecf20Sopenharmony_ci}; 3268c2ecf20Sopenharmony_ci 3278c2ecf20Sopenharmony_cienum st_lsm6dsx_fifo_mode { 3288c2ecf20Sopenharmony_ci ST_LSM6DSX_FIFO_BYPASS = 0x0, 3298c2ecf20Sopenharmony_ci ST_LSM6DSX_FIFO_CONT = 0x6, 3308c2ecf20Sopenharmony_ci}; 3318c2ecf20Sopenharmony_ci 3328c2ecf20Sopenharmony_ci/** 3338c2ecf20Sopenharmony_ci * struct st_lsm6dsx_sensor - ST IMU sensor instance 3348c2ecf20Sopenharmony_ci * @name: Sensor name. 3358c2ecf20Sopenharmony_ci * @id: Sensor identifier. 3368c2ecf20Sopenharmony_ci * @hw: Pointer to instance of struct st_lsm6dsx_hw. 3378c2ecf20Sopenharmony_ci * @gain: Configured sensor sensitivity. 3388c2ecf20Sopenharmony_ci * @odr: Output data rate of the sensor [Hz]. 3398c2ecf20Sopenharmony_ci * @watermark: Sensor watermark level. 3408c2ecf20Sopenharmony_ci * @decimator: Sensor decimation factor. 3418c2ecf20Sopenharmony_ci * @sip: Number of samples in a given pattern. 3428c2ecf20Sopenharmony_ci * @ts_ref: Sensor timestamp reference for hw one. 3438c2ecf20Sopenharmony_ci * @ext_info: Sensor settings if it is connected to i2c controller 3448c2ecf20Sopenharmony_ci */ 3458c2ecf20Sopenharmony_cistruct st_lsm6dsx_sensor { 3468c2ecf20Sopenharmony_ci char name[32]; 3478c2ecf20Sopenharmony_ci enum st_lsm6dsx_sensor_id id; 3488c2ecf20Sopenharmony_ci struct st_lsm6dsx_hw *hw; 3498c2ecf20Sopenharmony_ci 3508c2ecf20Sopenharmony_ci u32 gain; 3518c2ecf20Sopenharmony_ci u32 odr; 3528c2ecf20Sopenharmony_ci 3538c2ecf20Sopenharmony_ci u16 watermark; 3548c2ecf20Sopenharmony_ci u8 decimator; 3558c2ecf20Sopenharmony_ci u8 sip; 3568c2ecf20Sopenharmony_ci s64 ts_ref; 3578c2ecf20Sopenharmony_ci 3588c2ecf20Sopenharmony_ci struct { 3598c2ecf20Sopenharmony_ci const struct st_lsm6dsx_ext_dev_settings *settings; 3608c2ecf20Sopenharmony_ci u32 slv_odr; 3618c2ecf20Sopenharmony_ci u8 addr; 3628c2ecf20Sopenharmony_ci } ext_info; 3638c2ecf20Sopenharmony_ci}; 3648c2ecf20Sopenharmony_ci 3658c2ecf20Sopenharmony_ci/** 3668c2ecf20Sopenharmony_ci * struct st_lsm6dsx_hw - ST IMU MEMS hw instance 3678c2ecf20Sopenharmony_ci * @dev: Pointer to instance of struct device (I2C or SPI). 3688c2ecf20Sopenharmony_ci * @regmap: Register map of the device. 3698c2ecf20Sopenharmony_ci * @irq: Device interrupt line (I2C or SPI). 3708c2ecf20Sopenharmony_ci * @fifo_lock: Mutex to prevent concurrent access to the hw FIFO. 3718c2ecf20Sopenharmony_ci * @conf_lock: Mutex to prevent concurrent FIFO configuration update. 3728c2ecf20Sopenharmony_ci * @page_lock: Mutex to prevent concurrent memory page configuration. 3738c2ecf20Sopenharmony_ci * @suspend_mask: Suspended sensor bitmask. 3748c2ecf20Sopenharmony_ci * @enable_mask: Enabled sensor bitmask. 3758c2ecf20Sopenharmony_ci * @fifo_mask: Enabled hw FIFO bitmask. 3768c2ecf20Sopenharmony_ci * @ts_gain: Hw timestamp rate after internal calibration. 3778c2ecf20Sopenharmony_ci * @ts_sip: Total number of timestamp samples in a given pattern. 3788c2ecf20Sopenharmony_ci * @sip: Total number of samples (acc/gyro/ts) in a given pattern. 3798c2ecf20Sopenharmony_ci * @buff: Device read buffer. 3808c2ecf20Sopenharmony_ci * @irq_routing: pointer to interrupt routing configuration. 3818c2ecf20Sopenharmony_ci * @event_threshold: wakeup event threshold. 3828c2ecf20Sopenharmony_ci * @enable_event: enabled event bitmask. 3838c2ecf20Sopenharmony_ci * @iio_devs: Pointers to acc/gyro iio_dev instances. 3848c2ecf20Sopenharmony_ci * @settings: Pointer to the specific sensor settings in use. 3858c2ecf20Sopenharmony_ci * @orientation: sensor chip orientation relative to main hardware. 3868c2ecf20Sopenharmony_ci * @scan: Temporary buffers used to align data before iio_push_to_buffers() 3878c2ecf20Sopenharmony_ci */ 3888c2ecf20Sopenharmony_cistruct st_lsm6dsx_hw { 3898c2ecf20Sopenharmony_ci struct device *dev; 3908c2ecf20Sopenharmony_ci struct regmap *regmap; 3918c2ecf20Sopenharmony_ci int irq; 3928c2ecf20Sopenharmony_ci 3938c2ecf20Sopenharmony_ci struct mutex fifo_lock; 3948c2ecf20Sopenharmony_ci struct mutex conf_lock; 3958c2ecf20Sopenharmony_ci struct mutex page_lock; 3968c2ecf20Sopenharmony_ci 3978c2ecf20Sopenharmony_ci u8 suspend_mask; 3988c2ecf20Sopenharmony_ci u8 enable_mask; 3998c2ecf20Sopenharmony_ci u8 fifo_mask; 4008c2ecf20Sopenharmony_ci s64 ts_gain; 4018c2ecf20Sopenharmony_ci u8 ts_sip; 4028c2ecf20Sopenharmony_ci u8 sip; 4038c2ecf20Sopenharmony_ci 4048c2ecf20Sopenharmony_ci const struct st_lsm6dsx_reg *irq_routing; 4058c2ecf20Sopenharmony_ci u8 event_threshold; 4068c2ecf20Sopenharmony_ci u8 enable_event; 4078c2ecf20Sopenharmony_ci 4088c2ecf20Sopenharmony_ci u8 *buff; 4098c2ecf20Sopenharmony_ci 4108c2ecf20Sopenharmony_ci struct iio_dev *iio_devs[ST_LSM6DSX_ID_MAX]; 4118c2ecf20Sopenharmony_ci 4128c2ecf20Sopenharmony_ci const struct st_lsm6dsx_settings *settings; 4138c2ecf20Sopenharmony_ci 4148c2ecf20Sopenharmony_ci struct iio_mount_matrix orientation; 4158c2ecf20Sopenharmony_ci /* Ensure natural alignment of buffer elements */ 4168c2ecf20Sopenharmony_ci struct { 4178c2ecf20Sopenharmony_ci __le16 channels[3]; 4188c2ecf20Sopenharmony_ci s64 ts __aligned(8); 4198c2ecf20Sopenharmony_ci } scan[3]; 4208c2ecf20Sopenharmony_ci}; 4218c2ecf20Sopenharmony_ci 4228c2ecf20Sopenharmony_cistatic __maybe_unused const struct iio_event_spec st_lsm6dsx_event = { 4238c2ecf20Sopenharmony_ci .type = IIO_EV_TYPE_THRESH, 4248c2ecf20Sopenharmony_ci .dir = IIO_EV_DIR_EITHER, 4258c2ecf20Sopenharmony_ci .mask_separate = BIT(IIO_EV_INFO_VALUE) | 4268c2ecf20Sopenharmony_ci BIT(IIO_EV_INFO_ENABLE) 4278c2ecf20Sopenharmony_ci}; 4288c2ecf20Sopenharmony_ci 4298c2ecf20Sopenharmony_cistatic __maybe_unused const unsigned long st_lsm6dsx_available_scan_masks[] = { 4308c2ecf20Sopenharmony_ci 0x7, 0x0, 4318c2ecf20Sopenharmony_ci}; 4328c2ecf20Sopenharmony_ci 4338c2ecf20Sopenharmony_ciextern const struct dev_pm_ops st_lsm6dsx_pm_ops; 4348c2ecf20Sopenharmony_ci 4358c2ecf20Sopenharmony_ciint st_lsm6dsx_probe(struct device *dev, int irq, int hw_id, 4368c2ecf20Sopenharmony_ci struct regmap *regmap); 4378c2ecf20Sopenharmony_ciint st_lsm6dsx_sensor_set_enable(struct st_lsm6dsx_sensor *sensor, 4388c2ecf20Sopenharmony_ci bool enable); 4398c2ecf20Sopenharmony_ciint st_lsm6dsx_fifo_setup(struct st_lsm6dsx_hw *hw); 4408c2ecf20Sopenharmony_ciint st_lsm6dsx_set_watermark(struct iio_dev *iio_dev, unsigned int val); 4418c2ecf20Sopenharmony_ciint st_lsm6dsx_update_watermark(struct st_lsm6dsx_sensor *sensor, 4428c2ecf20Sopenharmony_ci u16 watermark); 4438c2ecf20Sopenharmony_ciint st_lsm6dsx_update_fifo(struct st_lsm6dsx_sensor *sensor, bool enable); 4448c2ecf20Sopenharmony_ciint st_lsm6dsx_flush_fifo(struct st_lsm6dsx_hw *hw); 4458c2ecf20Sopenharmony_ciint st_lsm6dsx_resume_fifo(struct st_lsm6dsx_hw *hw); 4468c2ecf20Sopenharmony_ciint st_lsm6dsx_read_fifo(struct st_lsm6dsx_hw *hw); 4478c2ecf20Sopenharmony_ciint st_lsm6dsx_read_tagged_fifo(struct st_lsm6dsx_hw *hw); 4488c2ecf20Sopenharmony_ciint st_lsm6dsx_check_odr(struct st_lsm6dsx_sensor *sensor, u32 odr, u8 *val); 4498c2ecf20Sopenharmony_ciint st_lsm6dsx_shub_probe(struct st_lsm6dsx_hw *hw, const char *name); 4508c2ecf20Sopenharmony_ciint st_lsm6dsx_shub_set_enable(struct st_lsm6dsx_sensor *sensor, bool enable); 4518c2ecf20Sopenharmony_ciint st_lsm6dsx_set_page(struct st_lsm6dsx_hw *hw, bool enable); 4528c2ecf20Sopenharmony_ci 4538c2ecf20Sopenharmony_cistatic inline int 4548c2ecf20Sopenharmony_cist_lsm6dsx_update_bits_locked(struct st_lsm6dsx_hw *hw, unsigned int addr, 4558c2ecf20Sopenharmony_ci unsigned int mask, unsigned int val) 4568c2ecf20Sopenharmony_ci{ 4578c2ecf20Sopenharmony_ci int err; 4588c2ecf20Sopenharmony_ci 4598c2ecf20Sopenharmony_ci mutex_lock(&hw->page_lock); 4608c2ecf20Sopenharmony_ci err = regmap_update_bits(hw->regmap, addr, mask, val); 4618c2ecf20Sopenharmony_ci mutex_unlock(&hw->page_lock); 4628c2ecf20Sopenharmony_ci 4638c2ecf20Sopenharmony_ci return err; 4648c2ecf20Sopenharmony_ci} 4658c2ecf20Sopenharmony_ci 4668c2ecf20Sopenharmony_cistatic inline int 4678c2ecf20Sopenharmony_cist_lsm6dsx_read_locked(struct st_lsm6dsx_hw *hw, unsigned int addr, 4688c2ecf20Sopenharmony_ci void *val, unsigned int len) 4698c2ecf20Sopenharmony_ci{ 4708c2ecf20Sopenharmony_ci int err; 4718c2ecf20Sopenharmony_ci 4728c2ecf20Sopenharmony_ci mutex_lock(&hw->page_lock); 4738c2ecf20Sopenharmony_ci err = regmap_bulk_read(hw->regmap, addr, val, len); 4748c2ecf20Sopenharmony_ci mutex_unlock(&hw->page_lock); 4758c2ecf20Sopenharmony_ci 4768c2ecf20Sopenharmony_ci return err; 4778c2ecf20Sopenharmony_ci} 4788c2ecf20Sopenharmony_ci 4798c2ecf20Sopenharmony_cistatic inline int 4808c2ecf20Sopenharmony_cist_lsm6dsx_write_locked(struct st_lsm6dsx_hw *hw, unsigned int addr, 4818c2ecf20Sopenharmony_ci unsigned int val) 4828c2ecf20Sopenharmony_ci{ 4838c2ecf20Sopenharmony_ci int err; 4848c2ecf20Sopenharmony_ci 4858c2ecf20Sopenharmony_ci mutex_lock(&hw->page_lock); 4868c2ecf20Sopenharmony_ci err = regmap_write(hw->regmap, addr, val); 4878c2ecf20Sopenharmony_ci mutex_unlock(&hw->page_lock); 4888c2ecf20Sopenharmony_ci 4898c2ecf20Sopenharmony_ci return err; 4908c2ecf20Sopenharmony_ci} 4918c2ecf20Sopenharmony_ci 4928c2ecf20Sopenharmony_cistatic inline const struct iio_mount_matrix * 4938c2ecf20Sopenharmony_cist_lsm6dsx_get_mount_matrix(const struct iio_dev *iio_dev, 4948c2ecf20Sopenharmony_ci const struct iio_chan_spec *chan) 4958c2ecf20Sopenharmony_ci{ 4968c2ecf20Sopenharmony_ci struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev); 4978c2ecf20Sopenharmony_ci struct st_lsm6dsx_hw *hw = sensor->hw; 4988c2ecf20Sopenharmony_ci 4998c2ecf20Sopenharmony_ci return &hw->orientation; 5008c2ecf20Sopenharmony_ci} 5018c2ecf20Sopenharmony_ci 5028c2ecf20Sopenharmony_cistatic const 5038c2ecf20Sopenharmony_cistruct iio_chan_spec_ext_info __maybe_unused st_lsm6dsx_accel_ext_info[] = { 5048c2ecf20Sopenharmony_ci IIO_MOUNT_MATRIX(IIO_SHARED_BY_ALL, st_lsm6dsx_get_mount_matrix), 5058c2ecf20Sopenharmony_ci { } 5068c2ecf20Sopenharmony_ci}; 5078c2ecf20Sopenharmony_ci 5088c2ecf20Sopenharmony_ci#endif /* ST_LSM6DSX_H */ 509