fxos8700_core.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * FXOS8700 - NXP IMU (accelerometer plus magnetometer)
  4. *
  5. * IIO core driver for FXOS8700, with support for I2C/SPI busses
  6. *
  7. * TODO: Buffer, trigger, and IRQ support
  8. */
  9. #include <linux/module.h>
  10. #include <linux/regmap.h>
  11. #include <linux/acpi.h>
  12. #include <linux/bitops.h>
  13. #include <linux/iio/iio.h>
  14. #include <linux/iio/sysfs.h>
  15. #include "fxos8700.h"
  16. /* Register Definitions */
  17. #define FXOS8700_STATUS 0x00
  18. #define FXOS8700_OUT_X_MSB 0x01
  19. #define FXOS8700_OUT_X_LSB 0x02
  20. #define FXOS8700_OUT_Y_MSB 0x03
  21. #define FXOS8700_OUT_Y_LSB 0x04
  22. #define FXOS8700_OUT_Z_MSB 0x05
  23. #define FXOS8700_OUT_Z_LSB 0x06
  24. #define FXOS8700_F_SETUP 0x09
  25. #define FXOS8700_TRIG_CFG 0x0a
  26. #define FXOS8700_SYSMOD 0x0b
  27. #define FXOS8700_INT_SOURCE 0x0c
  28. #define FXOS8700_WHO_AM_I 0x0d
  29. #define FXOS8700_XYZ_DATA_CFG 0x0e
  30. #define FXOS8700_HP_FILTER_CUTOFF 0x0f
  31. #define FXOS8700_PL_STATUS 0x10
  32. #define FXOS8700_PL_CFG 0x11
  33. #define FXOS8700_PL_COUNT 0x12
  34. #define FXOS8700_PL_BF_ZCOMP 0x13
  35. #define FXOS8700_PL_THS_REG 0x14
  36. #define FXOS8700_A_FFMT_CFG 0x15
  37. #define FXOS8700_A_FFMT_SRC 0x16
  38. #define FXOS8700_A_FFMT_THS 0x17
  39. #define FXOS8700_A_FFMT_COUNT 0x18
  40. #define FXOS8700_TRANSIENT_CFG 0x1d
  41. #define FXOS8700_TRANSIENT_SRC 0x1e
  42. #define FXOS8700_TRANSIENT_THS 0x1f
  43. #define FXOS8700_TRANSIENT_COUNT 0x20
  44. #define FXOS8700_PULSE_CFG 0x21
  45. #define FXOS8700_PULSE_SRC 0x22
  46. #define FXOS8700_PULSE_THSX 0x23
  47. #define FXOS8700_PULSE_THSY 0x24
  48. #define FXOS8700_PULSE_THSZ 0x25
  49. #define FXOS8700_PULSE_TMLT 0x26
  50. #define FXOS8700_PULSE_LTCY 0x27
  51. #define FXOS8700_PULSE_WIND 0x28
  52. #define FXOS8700_ASLP_COUNT 0x29
  53. #define FXOS8700_CTRL_REG1 0x2a
  54. #define FXOS8700_CTRL_REG2 0x2b
  55. #define FXOS8700_CTRL_REG3 0x2c
  56. #define FXOS8700_CTRL_REG4 0x2d
  57. #define FXOS8700_CTRL_REG5 0x2e
  58. #define FXOS8700_OFF_X 0x2f
  59. #define FXOS8700_OFF_Y 0x30
  60. #define FXOS8700_OFF_Z 0x31
  61. #define FXOS8700_M_DR_STATUS 0x32
  62. #define FXOS8700_M_OUT_X_MSB 0x33
  63. #define FXOS8700_M_OUT_X_LSB 0x34
  64. #define FXOS8700_M_OUT_Y_MSB 0x35
  65. #define FXOS8700_M_OUT_Y_LSB 0x36
  66. #define FXOS8700_M_OUT_Z_MSB 0x37
  67. #define FXOS8700_M_OUT_Z_LSB 0x38
  68. #define FXOS8700_CMP_X_MSB 0x39
  69. #define FXOS8700_CMP_X_LSB 0x3a
  70. #define FXOS8700_CMP_Y_MSB 0x3b
  71. #define FXOS8700_CMP_Y_LSB 0x3c
  72. #define FXOS8700_CMP_Z_MSB 0x3d
  73. #define FXOS8700_CMP_Z_LSB 0x3e
  74. #define FXOS8700_M_OFF_X_MSB 0x3f
  75. #define FXOS8700_M_OFF_X_LSB 0x40
  76. #define FXOS8700_M_OFF_Y_MSB 0x41
  77. #define FXOS8700_M_OFF_Y_LSB 0x42
  78. #define FXOS8700_M_OFF_Z_MSB 0x43
  79. #define FXOS8700_M_OFF_Z_LSB 0x44
  80. #define FXOS8700_MAX_X_MSB 0x45
  81. #define FXOS8700_MAX_X_LSB 0x46
  82. #define FXOS8700_MAX_Y_MSB 0x47
  83. #define FXOS8700_MAX_Y_LSB 0x48
  84. #define FXOS8700_MAX_Z_MSB 0x49
  85. #define FXOS8700_MAX_Z_LSB 0x4a
  86. #define FXOS8700_MIN_X_MSB 0x4b
  87. #define FXOS8700_MIN_X_LSB 0x4c
  88. #define FXOS8700_MIN_Y_MSB 0x4d
  89. #define FXOS8700_MIN_Y_LSB 0x4e
  90. #define FXOS8700_MIN_Z_MSB 0x4f
  91. #define FXOS8700_MIN_Z_LSB 0x50
  92. #define FXOS8700_TEMP 0x51
  93. #define FXOS8700_M_THS_CFG 0x52
  94. #define FXOS8700_M_THS_SRC 0x53
  95. #define FXOS8700_M_THS_X_MSB 0x54
  96. #define FXOS8700_M_THS_X_LSB 0x55
  97. #define FXOS8700_M_THS_Y_MSB 0x56
  98. #define FXOS8700_M_THS_Y_LSB 0x57
  99. #define FXOS8700_M_THS_Z_MSB 0x58
  100. #define FXOS8700_M_THS_Z_LSB 0x59
  101. #define FXOS8700_M_THS_COUNT 0x5a
  102. #define FXOS8700_M_CTRL_REG1 0x5b
  103. #define FXOS8700_M_CTRL_REG2 0x5c
  104. #define FXOS8700_M_CTRL_REG3 0x5d
  105. #define FXOS8700_M_INT_SRC 0x5e
  106. #define FXOS8700_A_VECM_CFG 0x5f
  107. #define FXOS8700_A_VECM_THS_MSB 0x60
  108. #define FXOS8700_A_VECM_THS_LSB 0x61
  109. #define FXOS8700_A_VECM_CNT 0x62
  110. #define FXOS8700_A_VECM_INITX_MSB 0x63
  111. #define FXOS8700_A_VECM_INITX_LSB 0x64
  112. #define FXOS8700_A_VECM_INITY_MSB 0x65
  113. #define FXOS8700_A_VECM_INITY_LSB 0x66
  114. #define FXOS8700_A_VECM_INITZ_MSB 0x67
  115. #define FXOS8700_A_VECM_INITZ_LSB 0x68
  116. #define FXOS8700_M_VECM_CFG 0x69
  117. #define FXOS8700_M_VECM_THS_MSB 0x6a
  118. #define FXOS8700_M_VECM_THS_LSB 0x6b
  119. #define FXOS8700_M_VECM_CNT 0x6c
  120. #define FXOS8700_M_VECM_INITX_MSB 0x6d
  121. #define FXOS8700_M_VECM_INITX_LSB 0x6e
  122. #define FXOS8700_M_VECM_INITY_MSB 0x6f
  123. #define FXOS8700_M_VECM_INITY_LSB 0x70
  124. #define FXOS8700_M_VECM_INITZ_MSB 0x71
  125. #define FXOS8700_M_VECM_INITZ_LSB 0x72
  126. #define FXOS8700_A_FFMT_THS_X_MSB 0x73
  127. #define FXOS8700_A_FFMT_THS_X_LSB 0x74
  128. #define FXOS8700_A_FFMT_THS_Y_MSB 0x75
  129. #define FXOS8700_A_FFMT_THS_Y_LSB 0x76
  130. #define FXOS8700_A_FFMT_THS_Z_MSB 0x77
  131. #define FXOS8700_A_FFMT_THS_Z_LSB 0x78
  132. #define FXOS8700_A_TRAN_INIT_MSB 0x79
  133. #define FXOS8700_A_TRAN_INIT_LSB_X 0x7a
  134. #define FXOS8700_A_TRAN_INIT_LSB_Y 0x7b
  135. #define FXOS8700_A_TRAN_INIT_LSB_Z 0x7d
  136. #define FXOS8700_TM_NVM_LOCK 0x7e
  137. #define FXOS8700_NVM_DATA0_35 0x80
  138. #define FXOS8700_NVM_DATA_BNK3 0xa4
  139. #define FXOS8700_NVM_DATA_BNK2 0xa5
  140. #define FXOS8700_NVM_DATA_BNK1 0xa6
  141. #define FXOS8700_NVM_DATA_BNK0 0xa7
  142. /* Bit definitions for FXOS8700_CTRL_REG1 */
  143. #define FXOS8700_CTRL_ODR_MSK 0x38
  144. #define FXOS8700_CTRL_ODR_MAX 0x00
  145. #define FXOS8700_CTRL_ODR_MIN GENMASK(4, 3)
  146. /* Bit definitions for FXOS8700_M_CTRL_REG1 */
  147. #define FXOS8700_HMS_MASK GENMASK(1, 0)
  148. #define FXOS8700_OS_MASK GENMASK(4, 2)
  149. /* Bit definitions for FXOS8700_M_CTRL_REG2 */
  150. #define FXOS8700_MAXMIN_RST BIT(2)
  151. #define FXOS8700_MAXMIN_DIS_THS BIT(3)
  152. #define FXOS8700_MAXMIN_DIS BIT(4)
  153. #define FXOS8700_ACTIVE 0x01
  154. #define FXOS8700_ACTIVE_MIN_USLEEP 4000 /* from table 6 in datasheet */
  155. #define FXOS8700_DEVICE_ID 0xC7
  156. #define FXOS8700_PRE_DEVICE_ID 0xC4
  157. #define FXOS8700_DATA_BUF_SIZE 3
  158. struct fxos8700_data {
  159. struct regmap *regmap;
  160. struct iio_trigger *trig;
  161. __be16 buf[FXOS8700_DATA_BUF_SIZE] ____cacheline_aligned;
  162. };
  163. /* Regmap info */
  164. static const struct regmap_range read_range[] = {
  165. {
  166. .range_min = FXOS8700_STATUS,
  167. .range_max = FXOS8700_A_FFMT_COUNT,
  168. }, {
  169. .range_min = FXOS8700_TRANSIENT_CFG,
  170. .range_max = FXOS8700_A_FFMT_THS_Z_LSB,
  171. },
  172. };
  173. static const struct regmap_range write_range[] = {
  174. {
  175. .range_min = FXOS8700_F_SETUP,
  176. .range_max = FXOS8700_TRIG_CFG,
  177. }, {
  178. .range_min = FXOS8700_XYZ_DATA_CFG,
  179. .range_max = FXOS8700_HP_FILTER_CUTOFF,
  180. }, {
  181. .range_min = FXOS8700_PL_CFG,
  182. .range_max = FXOS8700_A_FFMT_CFG,
  183. }, {
  184. .range_min = FXOS8700_A_FFMT_THS,
  185. .range_max = FXOS8700_TRANSIENT_CFG,
  186. }, {
  187. .range_min = FXOS8700_TRANSIENT_THS,
  188. .range_max = FXOS8700_PULSE_CFG,
  189. }, {
  190. .range_min = FXOS8700_PULSE_THSX,
  191. .range_max = FXOS8700_OFF_Z,
  192. }, {
  193. .range_min = FXOS8700_M_OFF_X_MSB,
  194. .range_max = FXOS8700_M_OFF_Z_LSB,
  195. }, {
  196. .range_min = FXOS8700_M_THS_CFG,
  197. .range_max = FXOS8700_M_THS_CFG,
  198. }, {
  199. .range_min = FXOS8700_M_THS_X_MSB,
  200. .range_max = FXOS8700_M_CTRL_REG3,
  201. }, {
  202. .range_min = FXOS8700_A_VECM_CFG,
  203. .range_max = FXOS8700_A_FFMT_THS_Z_LSB,
  204. },
  205. };
  206. static const struct regmap_access_table driver_read_table = {
  207. .yes_ranges = read_range,
  208. .n_yes_ranges = ARRAY_SIZE(read_range),
  209. };
  210. static const struct regmap_access_table driver_write_table = {
  211. .yes_ranges = write_range,
  212. .n_yes_ranges = ARRAY_SIZE(write_range),
  213. };
  214. const struct regmap_config fxos8700_regmap_config = {
  215. .reg_bits = 8,
  216. .val_bits = 8,
  217. .max_register = FXOS8700_NVM_DATA_BNK0,
  218. .rd_table = &driver_read_table,
  219. .wr_table = &driver_write_table,
  220. };
  221. EXPORT_SYMBOL(fxos8700_regmap_config);
  222. #define FXOS8700_CHANNEL(_type, _axis) { \
  223. .type = _type, \
  224. .modified = 1, \
  225. .channel2 = IIO_MOD_##_axis, \
  226. .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
  227. .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \
  228. BIT(IIO_CHAN_INFO_SAMP_FREQ), \
  229. }
  230. enum fxos8700_accel_scale_bits {
  231. MODE_2G = 0,
  232. MODE_4G,
  233. MODE_8G,
  234. };
  235. /* scan indexes follow DATA register order */
  236. enum fxos8700_scan_axis {
  237. FXOS8700_SCAN_ACCEL_X = 0,
  238. FXOS8700_SCAN_ACCEL_Y,
  239. FXOS8700_SCAN_ACCEL_Z,
  240. FXOS8700_SCAN_MAGN_X,
  241. FXOS8700_SCAN_MAGN_Y,
  242. FXOS8700_SCAN_MAGN_Z,
  243. FXOS8700_SCAN_RHALL,
  244. FXOS8700_SCAN_TIMESTAMP,
  245. };
  246. enum fxos8700_sensor {
  247. FXOS8700_ACCEL = 0,
  248. FXOS8700_MAGN,
  249. FXOS8700_NUM_SENSORS /* must be last */
  250. };
  251. enum fxos8700_int_pin {
  252. FXOS8700_PIN_INT1,
  253. FXOS8700_PIN_INT2
  254. };
  255. struct fxos8700_scale {
  256. u8 bits;
  257. int uscale;
  258. };
  259. struct fxos8700_odr {
  260. u8 bits;
  261. int odr;
  262. int uodr;
  263. };
  264. static const struct fxos8700_scale fxos8700_accel_scale[] = {
  265. { MODE_2G, 244},
  266. { MODE_4G, 488},
  267. { MODE_8G, 976},
  268. };
  269. /*
  270. * Accellerometer and magnetometer have the same ODR options, set in the
  271. * CTRL_REG1 register. ODR is halved when using both sensors at once in
  272. * hybrid mode.
  273. */
  274. static const struct fxos8700_odr fxos8700_odr[] = {
  275. {0x00, 800, 0},
  276. {0x01, 400, 0},
  277. {0x02, 200, 0},
  278. {0x03, 100, 0},
  279. {0x04, 50, 0},
  280. {0x05, 12, 500000},
  281. {0x06, 6, 250000},
  282. {0x07, 1, 562500},
  283. };
  284. static const struct iio_chan_spec fxos8700_channels[] = {
  285. FXOS8700_CHANNEL(IIO_ACCEL, X),
  286. FXOS8700_CHANNEL(IIO_ACCEL, Y),
  287. FXOS8700_CHANNEL(IIO_ACCEL, Z),
  288. FXOS8700_CHANNEL(IIO_MAGN, X),
  289. FXOS8700_CHANNEL(IIO_MAGN, Y),
  290. FXOS8700_CHANNEL(IIO_MAGN, Z),
  291. IIO_CHAN_SOFT_TIMESTAMP(FXOS8700_SCAN_TIMESTAMP),
  292. };
  293. static enum fxos8700_sensor fxos8700_to_sensor(enum iio_chan_type iio_type)
  294. {
  295. switch (iio_type) {
  296. case IIO_ACCEL:
  297. return FXOS8700_ACCEL;
  298. case IIO_ANGL_VEL:
  299. return FXOS8700_MAGN;
  300. default:
  301. return -EINVAL;
  302. }
  303. }
  304. static int fxos8700_set_active_mode(struct fxos8700_data *data,
  305. enum fxos8700_sensor t, bool mode)
  306. {
  307. int ret;
  308. ret = regmap_write(data->regmap, FXOS8700_CTRL_REG1, mode);
  309. if (ret)
  310. return ret;
  311. usleep_range(FXOS8700_ACTIVE_MIN_USLEEP,
  312. FXOS8700_ACTIVE_MIN_USLEEP + 1000);
  313. return 0;
  314. }
  315. static int fxos8700_set_scale(struct fxos8700_data *data,
  316. enum fxos8700_sensor t, int uscale)
  317. {
  318. int i;
  319. static const int scale_num = ARRAY_SIZE(fxos8700_accel_scale);
  320. struct device *dev = regmap_get_device(data->regmap);
  321. if (t == FXOS8700_MAGN) {
  322. dev_err(dev, "Magnetometer scale is locked at 1200uT\n");
  323. return -EINVAL;
  324. }
  325. for (i = 0; i < scale_num; i++)
  326. if (fxos8700_accel_scale[i].uscale == uscale)
  327. break;
  328. if (i == scale_num)
  329. return -EINVAL;
  330. return regmap_write(data->regmap, FXOS8700_XYZ_DATA_CFG,
  331. fxos8700_accel_scale[i].bits);
  332. }
  333. static int fxos8700_get_scale(struct fxos8700_data *data,
  334. enum fxos8700_sensor t, int *uscale)
  335. {
  336. int i, ret, val;
  337. static const int scale_num = ARRAY_SIZE(fxos8700_accel_scale);
  338. if (t == FXOS8700_MAGN) {
  339. *uscale = 1200; /* Magnetometer is locked at 1200uT */
  340. return 0;
  341. }
  342. ret = regmap_read(data->regmap, FXOS8700_XYZ_DATA_CFG, &val);
  343. if (ret)
  344. return ret;
  345. for (i = 0; i < scale_num; i++) {
  346. if (fxos8700_accel_scale[i].bits == (val & 0x3)) {
  347. *uscale = fxos8700_accel_scale[i].uscale;
  348. return 0;
  349. }
  350. }
  351. return -EINVAL;
  352. }
  353. static int fxos8700_get_data(struct fxos8700_data *data, int chan_type,
  354. int axis, int *val)
  355. {
  356. u8 base, reg;
  357. int ret;
  358. enum fxos8700_sensor type = fxos8700_to_sensor(chan_type);
  359. base = type ? FXOS8700_OUT_X_MSB : FXOS8700_M_OUT_X_MSB;
  360. /* Block read 6 bytes of device output registers to avoid data loss */
  361. ret = regmap_bulk_read(data->regmap, base, data->buf,
  362. FXOS8700_DATA_BUF_SIZE);
  363. if (ret)
  364. return ret;
  365. /* Convert axis to buffer index */
  366. reg = axis - IIO_MOD_X;
  367. /* Convert to native endianness */
  368. *val = sign_extend32(be16_to_cpu(data->buf[reg]), 15);
  369. return 0;
  370. }
  371. static int fxos8700_set_odr(struct fxos8700_data *data, enum fxos8700_sensor t,
  372. int odr, int uodr)
  373. {
  374. int i, ret, val;
  375. bool active_mode;
  376. static const int odr_num = ARRAY_SIZE(fxos8700_odr);
  377. ret = regmap_read(data->regmap, FXOS8700_CTRL_REG1, &val);
  378. if (ret)
  379. return ret;
  380. active_mode = val & FXOS8700_ACTIVE;
  381. if (active_mode) {
  382. /*
  383. * The device must be in standby mode to change any of the
  384. * other fields within CTRL_REG1
  385. */
  386. ret = regmap_write(data->regmap, FXOS8700_CTRL_REG1,
  387. val & ~FXOS8700_ACTIVE);
  388. if (ret)
  389. return ret;
  390. }
  391. for (i = 0; i < odr_num; i++)
  392. if (fxos8700_odr[i].odr == odr && fxos8700_odr[i].uodr == uodr)
  393. break;
  394. if (i >= odr_num)
  395. return -EINVAL;
  396. return regmap_update_bits(data->regmap,
  397. FXOS8700_CTRL_REG1,
  398. FXOS8700_CTRL_ODR_MSK + FXOS8700_ACTIVE,
  399. fxos8700_odr[i].bits << 3 | active_mode);
  400. }
  401. static int fxos8700_get_odr(struct fxos8700_data *data, enum fxos8700_sensor t,
  402. int *odr, int *uodr)
  403. {
  404. int i, val, ret;
  405. static const int odr_num = ARRAY_SIZE(fxos8700_odr);
  406. ret = regmap_read(data->regmap, FXOS8700_CTRL_REG1, &val);
  407. if (ret)
  408. return ret;
  409. val &= FXOS8700_CTRL_ODR_MSK;
  410. for (i = 0; i < odr_num; i++)
  411. if (val == fxos8700_odr[i].bits)
  412. break;
  413. if (i >= odr_num)
  414. return -EINVAL;
  415. *odr = fxos8700_odr[i].odr;
  416. *uodr = fxos8700_odr[i].uodr;
  417. return 0;
  418. }
  419. static int fxos8700_read_raw(struct iio_dev *indio_dev,
  420. struct iio_chan_spec const *chan,
  421. int *val, int *val2, long mask)
  422. {
  423. int ret;
  424. struct fxos8700_data *data = iio_priv(indio_dev);
  425. switch (mask) {
  426. case IIO_CHAN_INFO_RAW:
  427. ret = fxos8700_get_data(data, chan->type, chan->channel2, val);
  428. if (ret)
  429. return ret;
  430. return IIO_VAL_INT;
  431. case IIO_CHAN_INFO_SCALE:
  432. *val = 0;
  433. ret = fxos8700_get_scale(data, fxos8700_to_sensor(chan->type),
  434. val2);
  435. return ret ? ret : IIO_VAL_INT_PLUS_MICRO;
  436. case IIO_CHAN_INFO_SAMP_FREQ:
  437. ret = fxos8700_get_odr(data, fxos8700_to_sensor(chan->type),
  438. val, val2);
  439. return ret ? ret : IIO_VAL_INT_PLUS_MICRO;
  440. default:
  441. return -EINVAL;
  442. }
  443. }
  444. static int fxos8700_write_raw(struct iio_dev *indio_dev,
  445. struct iio_chan_spec const *chan,
  446. int val, int val2, long mask)
  447. {
  448. struct fxos8700_data *data = iio_priv(indio_dev);
  449. switch (mask) {
  450. case IIO_CHAN_INFO_SCALE:
  451. return fxos8700_set_scale(data, fxos8700_to_sensor(chan->type),
  452. val2);
  453. case IIO_CHAN_INFO_SAMP_FREQ:
  454. return fxos8700_set_odr(data, fxos8700_to_sensor(chan->type),
  455. val, val2);
  456. default:
  457. return -EINVAL;
  458. }
  459. }
  460. static IIO_CONST_ATTR(in_accel_sampling_frequency_available,
  461. "1.5625 6.25 12.5 50 100 200 400 800");
  462. static IIO_CONST_ATTR(in_magn_sampling_frequency_available,
  463. "1.5625 6.25 12.5 50 100 200 400 800");
  464. static IIO_CONST_ATTR(in_accel_scale_available, "0.000244 0.000488 0.000976");
  465. static IIO_CONST_ATTR(in_magn_scale_available, "0.000001200");
  466. static struct attribute *fxos8700_attrs[] = {
  467. &iio_const_attr_in_accel_sampling_frequency_available.dev_attr.attr,
  468. &iio_const_attr_in_magn_sampling_frequency_available.dev_attr.attr,
  469. &iio_const_attr_in_accel_scale_available.dev_attr.attr,
  470. &iio_const_attr_in_magn_scale_available.dev_attr.attr,
  471. NULL,
  472. };
  473. static const struct attribute_group fxos8700_attrs_group = {
  474. .attrs = fxos8700_attrs,
  475. };
  476. static const struct iio_info fxos8700_info = {
  477. .read_raw = fxos8700_read_raw,
  478. .write_raw = fxos8700_write_raw,
  479. .attrs = &fxos8700_attrs_group,
  480. };
  481. static int fxos8700_chip_init(struct fxos8700_data *data, bool use_spi)
  482. {
  483. int ret;
  484. unsigned int val;
  485. struct device *dev = regmap_get_device(data->regmap);
  486. ret = regmap_read(data->regmap, FXOS8700_WHO_AM_I, &val);
  487. if (ret) {
  488. dev_err(dev, "Error reading chip id\n");
  489. return ret;
  490. }
  491. if (val != FXOS8700_DEVICE_ID && val != FXOS8700_PRE_DEVICE_ID) {
  492. dev_err(dev, "Wrong chip id, got %x expected %x or %x\n",
  493. val, FXOS8700_DEVICE_ID, FXOS8700_PRE_DEVICE_ID);
  494. return -ENODEV;
  495. }
  496. ret = fxos8700_set_active_mode(data, FXOS8700_ACCEL, true);
  497. if (ret)
  498. return ret;
  499. ret = fxos8700_set_active_mode(data, FXOS8700_MAGN, true);
  500. if (ret)
  501. return ret;
  502. /*
  503. * The device must be in standby mode to change any of the other fields
  504. * within CTRL_REG1
  505. */
  506. ret = regmap_write(data->regmap, FXOS8700_CTRL_REG1, 0x00);
  507. if (ret)
  508. return ret;
  509. /* Set max oversample ratio (OSR) and both devices active */
  510. ret = regmap_write(data->regmap, FXOS8700_M_CTRL_REG1,
  511. FXOS8700_HMS_MASK | FXOS8700_OS_MASK);
  512. if (ret)
  513. return ret;
  514. /* Disable and rst min/max measurements & threshold */
  515. ret = regmap_write(data->regmap, FXOS8700_M_CTRL_REG2,
  516. FXOS8700_MAXMIN_RST | FXOS8700_MAXMIN_DIS_THS |
  517. FXOS8700_MAXMIN_DIS);
  518. if (ret)
  519. return ret;
  520. /* Max ODR (800Hz individual or 400Hz hybrid), active mode */
  521. ret = regmap_write(data->regmap, FXOS8700_CTRL_REG1,
  522. FXOS8700_CTRL_ODR_MAX | FXOS8700_ACTIVE);
  523. if (ret)
  524. return ret;
  525. /* Set for max full-scale range (+/-8G) */
  526. return regmap_write(data->regmap, FXOS8700_XYZ_DATA_CFG, MODE_8G);
  527. }
  528. static void fxos8700_chip_uninit(void *data)
  529. {
  530. struct fxos8700_data *fxos8700_data = data;
  531. fxos8700_set_active_mode(fxos8700_data, FXOS8700_ACCEL, false);
  532. fxos8700_set_active_mode(fxos8700_data, FXOS8700_MAGN, false);
  533. }
  534. int fxos8700_core_probe(struct device *dev, struct regmap *regmap,
  535. const char *name, bool use_spi)
  536. {
  537. struct iio_dev *indio_dev;
  538. struct fxos8700_data *data;
  539. int ret;
  540. indio_dev = devm_iio_device_alloc(dev, sizeof(*data));
  541. if (!indio_dev)
  542. return -ENOMEM;
  543. data = iio_priv(indio_dev);
  544. dev_set_drvdata(dev, indio_dev);
  545. data->regmap = regmap;
  546. ret = fxos8700_chip_init(data, use_spi);
  547. if (ret)
  548. return ret;
  549. ret = devm_add_action_or_reset(dev, fxos8700_chip_uninit, data);
  550. if (ret)
  551. return ret;
  552. indio_dev->channels = fxos8700_channels;
  553. indio_dev->num_channels = ARRAY_SIZE(fxos8700_channels);
  554. indio_dev->name = name ? name : "fxos8700";
  555. indio_dev->modes = INDIO_DIRECT_MODE;
  556. indio_dev->info = &fxos8700_info;
  557. return devm_iio_device_register(dev, indio_dev);
  558. }
  559. EXPORT_SYMBOL_GPL(fxos8700_core_probe);
  560. MODULE_AUTHOR("Robert Jones <rjones@gateworks.com>");
  561. MODULE_DESCRIPTION("FXOS8700 6-Axis Acc and Mag Combo Sensor driver");
  562. MODULE_LICENSE("GPL v2");