lis2dw12.c 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410
  1. /* ST Microelectronics LIS2DW12 3-axis accelerometer driver
  2. *
  3. * Copyright (c) 2019 STMicroelectronics
  4. *
  5. * SPDX-License-Identifier: Apache-2.0
  6. *
  7. * Datasheet:
  8. * https://www.st.com/resource/en/datasheet/lis2dw12.pdf
  9. */
  10. #define DT_DRV_COMPAT st_lis2dw12
  11. #include <init.h>
  12. #include <sys/__assert.h>
  13. #include <sys/byteorder.h>
  14. #include <logging/log.h>
  15. #include <drivers/sensor.h>
  16. #if DT_ANY_INST_ON_BUS_STATUS_OKAY(spi)
  17. #include <drivers/spi.h>
  18. #elif DT_ANY_INST_ON_BUS_STATUS_OKAY(i2c)
  19. #include <drivers/i2c.h>
  20. #endif
  21. #include "lis2dw12.h"
  22. LOG_MODULE_REGISTER(LIS2DW12, CONFIG_SENSOR_LOG_LEVEL);
  23. /**
  24. * lis2dw12_set_range - set full scale range for acc
  25. * @dev: Pointer to instance of struct device (I2C or SPI)
  26. * @range: Full scale range (2, 4, 8 and 16 G)
  27. */
  28. static int lis2dw12_set_range(const struct device *dev, uint8_t fs)
  29. {
  30. int err;
  31. struct lis2dw12_data *lis2dw12 = dev->data;
  32. const struct lis2dw12_device_config *cfg = dev->config;
  33. stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx;
  34. uint8_t shift_gain = 0U;
  35. err = lis2dw12_full_scale_set(ctx, fs);
  36. if (cfg->pm == LIS2DW12_CONT_LOW_PWR_12bit) {
  37. shift_gain = LIS2DW12_SHFT_GAIN_NOLP1;
  38. }
  39. if (!err) {
  40. /* save internally gain for optimization */
  41. lis2dw12->gain =
  42. LIS2DW12_FS_TO_GAIN(fs, shift_gain);
  43. }
  44. return err;
  45. }
  46. /**
  47. * lis2dw12_set_odr - set new sampling frequency
  48. * @dev: Pointer to instance of struct device (I2C or SPI)
  49. * @odr: Output data rate
  50. */
  51. static int lis2dw12_set_odr(const struct device *dev, uint16_t odr)
  52. {
  53. const struct lis2dw12_device_config *cfg = dev->config;
  54. stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx;
  55. uint8_t val;
  56. /* check if power off */
  57. if (odr == 0U) {
  58. return lis2dw12_data_rate_set(ctx, LIS2DW12_XL_ODR_OFF);
  59. }
  60. val = LIS2DW12_ODR_TO_REG(odr);
  61. if (val > LIS2DW12_XL_ODR_1k6Hz) {
  62. LOG_ERR("ODR too high");
  63. return -ENOTSUP;
  64. }
  65. return lis2dw12_data_rate_set(ctx, val);
  66. }
  67. static inline void lis2dw12_convert(struct sensor_value *val, int raw_val,
  68. float gain)
  69. {
  70. int64_t dval;
  71. /* Gain is in ug/LSB */
  72. /* Convert to m/s^2 */
  73. dval = ((int64_t)raw_val * gain * SENSOR_G) / 1000000LL;
  74. val->val1 = dval / 1000000LL;
  75. val->val2 = dval % 1000000LL;
  76. }
  77. static inline void lis2dw12_channel_get_acc(const struct device *dev,
  78. enum sensor_channel chan,
  79. struct sensor_value *val)
  80. {
  81. int i;
  82. uint8_t ofs_start, ofs_stop;
  83. struct lis2dw12_data *lis2dw12 = dev->data;
  84. struct sensor_value *pval = val;
  85. switch (chan) {
  86. case SENSOR_CHAN_ACCEL_X:
  87. ofs_start = ofs_stop = 0U;
  88. break;
  89. case SENSOR_CHAN_ACCEL_Y:
  90. ofs_start = ofs_stop = 1U;
  91. break;
  92. case SENSOR_CHAN_ACCEL_Z:
  93. ofs_start = ofs_stop = 2U;
  94. break;
  95. default:
  96. ofs_start = 0U; ofs_stop = 2U;
  97. break;
  98. }
  99. for (i = ofs_start; i <= ofs_stop ; i++) {
  100. lis2dw12_convert(pval++, lis2dw12->acc[i], lis2dw12->gain);
  101. }
  102. }
  103. static int lis2dw12_channel_get(const struct device *dev,
  104. enum sensor_channel chan,
  105. struct sensor_value *val)
  106. {
  107. switch (chan) {
  108. case SENSOR_CHAN_ACCEL_X:
  109. case SENSOR_CHAN_ACCEL_Y:
  110. case SENSOR_CHAN_ACCEL_Z:
  111. case SENSOR_CHAN_ACCEL_XYZ:
  112. lis2dw12_channel_get_acc(dev, chan, val);
  113. return 0;
  114. default:
  115. LOG_DBG("Channel not supported");
  116. break;
  117. }
  118. return -ENOTSUP;
  119. }
  120. static int lis2dw12_config(const struct device *dev, enum sensor_channel chan,
  121. enum sensor_attribute attr,
  122. const struct sensor_value *val)
  123. {
  124. switch (attr) {
  125. case SENSOR_ATTR_FULL_SCALE:
  126. return lis2dw12_set_range(dev,
  127. LIS2DW12_FS_TO_REG(sensor_ms2_to_g(val)));
  128. case SENSOR_ATTR_SAMPLING_FREQUENCY:
  129. return lis2dw12_set_odr(dev, val->val1);
  130. default:
  131. LOG_DBG("Acc attribute not supported");
  132. break;
  133. }
  134. return -ENOTSUP;
  135. }
  136. static int lis2dw12_attr_set(const struct device *dev,
  137. enum sensor_channel chan,
  138. enum sensor_attribute attr,
  139. const struct sensor_value *val)
  140. {
  141. switch (chan) {
  142. case SENSOR_CHAN_ACCEL_X:
  143. case SENSOR_CHAN_ACCEL_Y:
  144. case SENSOR_CHAN_ACCEL_Z:
  145. case SENSOR_CHAN_ACCEL_XYZ:
  146. return lis2dw12_config(dev, chan, attr, val);
  147. default:
  148. LOG_DBG("Attr not supported on %d channel", chan);
  149. break;
  150. }
  151. return -ENOTSUP;
  152. }
  153. static int lis2dw12_sample_fetch(const struct device *dev,
  154. enum sensor_channel chan)
  155. {
  156. struct lis2dw12_data *lis2dw12 = dev->data;
  157. const struct lis2dw12_device_config *cfg = dev->config;
  158. stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx;
  159. uint8_t shift;
  160. int16_t buf[3];
  161. /* fetch raw data sample */
  162. if (lis2dw12_acceleration_raw_get(ctx, buf) < 0) {
  163. LOG_DBG("Failed to fetch raw data sample");
  164. return -EIO;
  165. }
  166. /* adjust to resolution */
  167. if (cfg->pm == LIS2DW12_CONT_LOW_PWR_12bit) {
  168. shift = LIS2DW12_SHIFT_PM1;
  169. } else {
  170. shift = LIS2DW12_SHIFT_PMOTHER;
  171. }
  172. lis2dw12->acc[0] = sys_le16_to_cpu(buf[0]) >> shift;
  173. lis2dw12->acc[1] = sys_le16_to_cpu(buf[1]) >> shift;
  174. lis2dw12->acc[2] = sys_le16_to_cpu(buf[2]) >> shift;
  175. return 0;
  176. }
  177. static const struct sensor_driver_api lis2dw12_driver_api = {
  178. .attr_set = lis2dw12_attr_set,
  179. #if CONFIG_LIS2DW12_TRIGGER
  180. .trigger_set = lis2dw12_trigger_set,
  181. #endif /* CONFIG_LIS2DW12_TRIGGER */
  182. .sample_fetch = lis2dw12_sample_fetch,
  183. .channel_get = lis2dw12_channel_get,
  184. };
  185. static int lis2dw12_set_power_mode(const struct device *dev,
  186. lis2dw12_mode_t pm)
  187. {
  188. const struct lis2dw12_device_config *cfg = dev->config;
  189. stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx;
  190. uint8_t regval = LIS2DW12_CONT_LOW_PWR_12bit;
  191. switch (pm) {
  192. case LIS2DW12_CONT_LOW_PWR_2:
  193. case LIS2DW12_CONT_LOW_PWR_3:
  194. case LIS2DW12_CONT_LOW_PWR_4:
  195. case LIS2DW12_HIGH_PERFORMANCE:
  196. regval = pm;
  197. break;
  198. default:
  199. LOG_DBG("Apply default Power Mode");
  200. break;
  201. }
  202. return lis2dw12_write_reg(ctx, LIS2DW12_CTRL1, &regval, 1);
  203. }
  204. static int lis2dw12_init(const struct device *dev)
  205. {
  206. const struct lis2dw12_device_config *cfg = dev->config;
  207. stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx;
  208. uint8_t wai;
  209. int ret;
  210. /* check chip ID */
  211. ret = lis2dw12_device_id_get(ctx, &wai);
  212. if (ret < 0) {
  213. LOG_ERR("Not able to read dev id");
  214. return ret;
  215. }
  216. if (wai != LIS2DW12_ID) {
  217. LOG_ERR("Invalid chip ID");
  218. return -EINVAL;
  219. }
  220. /* reset device */
  221. ret = lis2dw12_reset_set(ctx, PROPERTY_ENABLE);
  222. if (ret < 0) {
  223. return ret;
  224. }
  225. k_busy_wait(100);
  226. ret = lis2dw12_block_data_update_set(ctx, PROPERTY_ENABLE);
  227. if (ret < 0) {
  228. LOG_ERR("Not able to set BDU");
  229. return ret;
  230. }
  231. /* set power mode */
  232. LOG_DBG("power-mode is %d", cfg->pm);
  233. if (lis2dw12_set_power_mode(dev, cfg->pm)) {
  234. return -EIO;
  235. }
  236. /* set default odr to 12.5Hz acc */
  237. ret = lis2dw12_set_odr(dev, 12);
  238. if (ret < 0) {
  239. LOG_ERR("odr init error (12.5 Hz)");
  240. return ret;
  241. }
  242. LOG_DBG("range is %d", cfg->range);
  243. ret = lis2dw12_set_range(dev, LIS2DW12_FS_TO_REG(cfg->range));
  244. if (ret < 0) {
  245. LOG_ERR("range init error %d", cfg->range);
  246. return ret;
  247. }
  248. #ifdef CONFIG_LIS2DW12_TRIGGER
  249. if (lis2dw12_init_interrupt(dev) < 0) {
  250. LOG_ERR("Failed to initialize interrupts");
  251. return -EIO;
  252. }
  253. #endif /* CONFIG_LIS2DW12_TRIGGER */
  254. return 0;
  255. }
  256. #if DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT) == 0
  257. #warning "LIS2DW12 driver enabled without any devices"
  258. #endif
  259. /*
  260. * Device creation macro, shared by LIS2DW12_DEFINE_SPI() and
  261. * LIS2DW12_DEFINE_I2C().
  262. */
  263. #define LIS2DW12_DEVICE_INIT(inst) \
  264. DEVICE_DT_INST_DEFINE(inst, \
  265. lis2dw12_init, \
  266. NULL, \
  267. &lis2dw12_data_##inst, \
  268. &lis2dw12_config_##inst, \
  269. POST_KERNEL, \
  270. CONFIG_SENSOR_INIT_PRIORITY, \
  271. &lis2dw12_driver_api);
  272. /*
  273. * Instantiation macros used when a device is on a SPI bus.
  274. */
  275. #ifdef CONFIG_LIS2DW12_TAP
  276. #define LIS2DW12_CONFIG_TAP(inst) \
  277. .tap_mode = DT_INST_PROP(inst, tap_mode), \
  278. .tap_threshold = DT_INST_PROP(inst, tap_threshold), \
  279. .tap_shock = DT_INST_PROP(inst, tap_shock), \
  280. .tap_latency = DT_INST_PROP(inst, tap_latency), \
  281. .tap_quiet = DT_INST_PROP(inst, tap_quiet),
  282. #else
  283. #define LIS2DW12_CONFIG_TAP(inst)
  284. #endif /* CONFIG_LIS2DW12_TAP */
  285. #ifdef CONFIG_LIS2DW12_TRIGGER
  286. #define LIS2DW12_CFG_IRQ(inst) \
  287. .gpio_int = GPIO_DT_SPEC_INST_GET(inst, irq_gpios), \
  288. .int_pin = DT_INST_PROP(inst, int_pin),
  289. #else
  290. #define LIS2DW12_CFG_IRQ(inst)
  291. #endif /* CONFIG_LIS2DW12_TRIGGER */
  292. #define LIS2DW12_SPI_OPERATION (SPI_WORD_SET(8) | \
  293. SPI_OP_MODE_MASTER | \
  294. SPI_MODE_CPOL | \
  295. SPI_MODE_CPHA) \
  296. #define LIS2DW12_CONFIG_SPI(inst) \
  297. { \
  298. .ctx = { \
  299. .read_reg = \
  300. (stmdev_read_ptr) stmemsc_spi_read, \
  301. .write_reg = \
  302. (stmdev_write_ptr) stmemsc_spi_write, \
  303. .handle = \
  304. (void *)&lis2dw12_config_##inst.stmemsc_cfg, \
  305. }, \
  306. .stmemsc_cfg.spi = { \
  307. .bus = DEVICE_DT_GET(DT_INST_BUS(inst)), \
  308. .spi_cfg = SPI_CONFIG_DT_INST(inst, \
  309. LIS2DW12_SPI_OPERATION, \
  310. 0), \
  311. }, \
  312. .pm = DT_INST_PROP(inst, power_mode), \
  313. .range = DT_INST_PROP(inst, range), \
  314. LIS2DW12_CONFIG_TAP(inst) \
  315. COND_CODE_1(DT_INST_NODE_HAS_PROP(inst, irq_gpios), \
  316. (LIS2DW12_CFG_IRQ(inst)), ()) \
  317. }
  318. /*
  319. * Instantiation macros used when a device is on an I2C bus.
  320. */
  321. #define LIS2DW12_CONFIG_I2C(inst) \
  322. { \
  323. .ctx = { \
  324. .read_reg = \
  325. (stmdev_read_ptr) stmemsc_i2c_read, \
  326. .write_reg = \
  327. (stmdev_write_ptr) stmemsc_i2c_write, \
  328. .handle = \
  329. (void *)&lis2dw12_config_##inst.stmemsc_cfg, \
  330. }, \
  331. .stmemsc_cfg.i2c = { \
  332. .bus = DEVICE_DT_GET(DT_INST_BUS(inst)), \
  333. .i2c_slv_addr = DT_INST_REG_ADDR(inst), \
  334. }, \
  335. .pm = DT_INST_PROP(inst, power_mode), \
  336. .range = DT_INST_PROP(inst, range), \
  337. LIS2DW12_CONFIG_TAP(inst) \
  338. COND_CODE_1(DT_INST_NODE_HAS_PROP(inst, irq_gpios), \
  339. (LIS2DW12_CFG_IRQ(inst)), ()) \
  340. }
  341. /*
  342. * Main instantiation macro. Use of COND_CODE_1() selects the right
  343. * bus-specific macro at preprocessor time.
  344. */
  345. #define LIS2DW12_DEFINE(inst) \
  346. static struct lis2dw12_data lis2dw12_data_##inst; \
  347. static const struct lis2dw12_device_config lis2dw12_config_##inst = \
  348. COND_CODE_1(DT_INST_ON_BUS(inst, spi), \
  349. (LIS2DW12_CONFIG_SPI(inst)), \
  350. (LIS2DW12_CONFIG_I2C(inst))); \
  351. LIS2DW12_DEVICE_INIT(inst)
  352. DT_INST_FOREACH_STATUS_OKAY(LIS2DW12_DEFINE)