mmc35240.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * MMC35240 - MEMSIC 3-axis Magnetic Sensor
  4. *
  5. * Copyright (c) 2015, Intel Corporation.
  6. *
  7. * IIO driver for MMC35240 (7-bit I2C slave address 0x30).
  8. *
  9. * TODO: offset, ACPI, continuous measurement mode, PM
  10. */
  11. #include <linux/module.h>
  12. #include <linux/mod_devicetable.h>
  13. #include <linux/init.h>
  14. #include <linux/i2c.h>
  15. #include <linux/delay.h>
  16. #include <linux/regmap.h>
  17. #include <linux/pm.h>
  18. #include <linux/iio/iio.h>
  19. #include <linux/iio/sysfs.h>
  20. #define MMC35240_DRV_NAME "mmc35240"
  21. #define MMC35240_REGMAP_NAME "mmc35240_regmap"
  22. #define MMC35240_REG_XOUT_L 0x00
  23. #define MMC35240_REG_XOUT_H 0x01
  24. #define MMC35240_REG_YOUT_L 0x02
  25. #define MMC35240_REG_YOUT_H 0x03
  26. #define MMC35240_REG_ZOUT_L 0x04
  27. #define MMC35240_REG_ZOUT_H 0x05
  28. #define MMC35240_REG_STATUS 0x06
  29. #define MMC35240_REG_CTRL0 0x07
  30. #define MMC35240_REG_CTRL1 0x08
  31. #define MMC35240_REG_ID 0x20
  32. #define MMC35240_STATUS_MEAS_DONE_BIT BIT(0)
  33. #define MMC35240_CTRL0_REFILL_BIT BIT(7)
  34. #define MMC35240_CTRL0_RESET_BIT BIT(6)
  35. #define MMC35240_CTRL0_SET_BIT BIT(5)
  36. #define MMC35240_CTRL0_CMM_BIT BIT(1)
  37. #define MMC35240_CTRL0_TM_BIT BIT(0)
  38. /* output resolution bits */
  39. #define MMC35240_CTRL1_BW0_BIT BIT(0)
  40. #define MMC35240_CTRL1_BW1_BIT BIT(1)
  41. #define MMC35240_CTRL1_BW_MASK (MMC35240_CTRL1_BW0_BIT | \
  42. MMC35240_CTRL1_BW1_BIT)
  43. #define MMC35240_CTRL1_BW_SHIFT 0
  44. #define MMC35240_WAIT_CHARGE_PUMP 50000 /* us */
  45. #define MMC35240_WAIT_SET_RESET 1000 /* us */
  46. /*
  47. * Memsic OTP process code piece is put here for reference:
  48. *
  49. * #define OTP_CONVERT(REG) ((float)((REG) >=32 ? (32 - (REG)) : (REG)) * 0.006
  50. * 1) For X axis, the COEFFICIENT is always 1.
  51. * 2) For Y axis, the COEFFICIENT is as below:
  52. * f_OTP_matrix[4] = OTP_CONVERT(((reg_data[1] & 0x03) << 4) |
  53. * (reg_data[2] >> 4)) + 1.0;
  54. * 3) For Z axis, the COEFFICIENT is as below:
  55. * f_OTP_matrix[8] = (OTP_CONVERT(reg_data[3] & 0x3f) + 1) * 1.35;
  56. * We implemented the OTP logic into driver.
  57. */
  58. /* scale = 1000 here for Y otp */
  59. #define MMC35240_OTP_CONVERT_Y(REG) (((REG) >= 32 ? (32 - (REG)) : (REG)) * 6)
  60. /* 0.6 * 1.35 = 0.81, scale 10000 for Z otp */
  61. #define MMC35240_OTP_CONVERT_Z(REG) (((REG) >= 32 ? (32 - (REG)) : (REG)) * 81)
  62. #define MMC35240_X_COEFF(x) (x)
  63. #define MMC35240_Y_COEFF(y) (y + 1000)
  64. #define MMC35240_Z_COEFF(z) (z + 13500)
  65. #define MMC35240_OTP_START_ADDR 0x1B
  66. enum mmc35240_resolution {
  67. MMC35240_16_BITS_SLOW = 0, /* 7.92 ms */
  68. MMC35240_16_BITS_FAST, /* 4.08 ms */
  69. MMC35240_14_BITS, /* 2.16 ms */
  70. MMC35240_12_BITS, /* 1.20 ms */
  71. };
  72. enum mmc35240_axis {
  73. AXIS_X = 0,
  74. AXIS_Y,
  75. AXIS_Z,
  76. };
  77. static const struct {
  78. int sens[3]; /* sensitivity per X, Y, Z axis */
  79. int nfo; /* null field output */
  80. } mmc35240_props_table[] = {
  81. /* 16 bits, 125Hz ODR */
  82. {
  83. {1024, 1024, 1024},
  84. 32768,
  85. },
  86. /* 16 bits, 250Hz ODR */
  87. {
  88. {1024, 1024, 770},
  89. 32768,
  90. },
  91. /* 14 bits, 450Hz ODR */
  92. {
  93. {256, 256, 193},
  94. 8192,
  95. },
  96. /* 12 bits, 800Hz ODR */
  97. {
  98. {64, 64, 48},
  99. 2048,
  100. },
  101. };
  102. struct mmc35240_data {
  103. struct i2c_client *client;
  104. struct mutex mutex;
  105. struct regmap *regmap;
  106. enum mmc35240_resolution res;
  107. /* OTP compensation */
  108. int axis_coef[3];
  109. int axis_scale[3];
  110. };
  111. static const struct {
  112. int val;
  113. int val2;
  114. } mmc35240_samp_freq[] = { {1, 500000},
  115. {13, 0},
  116. {25, 0},
  117. {50, 0} };
  118. static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("1.5 13 25 50");
  119. #define MMC35240_CHANNEL(_axis) { \
  120. .type = IIO_MAGN, \
  121. .modified = 1, \
  122. .channel2 = IIO_MOD_ ## _axis, \
  123. .address = AXIS_ ## _axis, \
  124. .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
  125. .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SAMP_FREQ) | \
  126. BIT(IIO_CHAN_INFO_SCALE), \
  127. }
  128. static const struct iio_chan_spec mmc35240_channels[] = {
  129. MMC35240_CHANNEL(X),
  130. MMC35240_CHANNEL(Y),
  131. MMC35240_CHANNEL(Z),
  132. };
  133. static struct attribute *mmc35240_attributes[] = {
  134. &iio_const_attr_sampling_frequency_available.dev_attr.attr,
  135. NULL
  136. };
  137. static const struct attribute_group mmc35240_attribute_group = {
  138. .attrs = mmc35240_attributes,
  139. };
  140. static int mmc35240_get_samp_freq_index(struct mmc35240_data *data,
  141. int val, int val2)
  142. {
  143. int i;
  144. for (i = 0; i < ARRAY_SIZE(mmc35240_samp_freq); i++)
  145. if (mmc35240_samp_freq[i].val == val &&
  146. mmc35240_samp_freq[i].val2 == val2)
  147. return i;
  148. return -EINVAL;
  149. }
  150. static int mmc35240_hw_set(struct mmc35240_data *data, bool set)
  151. {
  152. int ret;
  153. u8 coil_bit;
  154. /*
  155. * Recharge the capacitor at VCAP pin, requested to be issued
  156. * before a SET/RESET command.
  157. */
  158. ret = regmap_set_bits(data->regmap, MMC35240_REG_CTRL0,
  159. MMC35240_CTRL0_REFILL_BIT);
  160. if (ret < 0)
  161. return ret;
  162. usleep_range(MMC35240_WAIT_CHARGE_PUMP, MMC35240_WAIT_CHARGE_PUMP + 1);
  163. if (set)
  164. coil_bit = MMC35240_CTRL0_SET_BIT;
  165. else
  166. coil_bit = MMC35240_CTRL0_RESET_BIT;
  167. return regmap_set_bits(data->regmap, MMC35240_REG_CTRL0, coil_bit);
  168. }
  169. static int mmc35240_init(struct mmc35240_data *data)
  170. {
  171. int ret, y_convert, z_convert;
  172. unsigned int reg_id;
  173. u8 otp_data[6];
  174. ret = regmap_read(data->regmap, MMC35240_REG_ID, &reg_id);
  175. if (ret < 0) {
  176. dev_err(&data->client->dev, "Error reading product id\n");
  177. return ret;
  178. }
  179. dev_dbg(&data->client->dev, "MMC35240 chip id %x\n", reg_id);
  180. /*
  181. * make sure we restore sensor characteristics, by doing
  182. * a SET/RESET sequence, the axis polarity being naturally
  183. * aligned after RESET
  184. */
  185. ret = mmc35240_hw_set(data, true);
  186. if (ret < 0)
  187. return ret;
  188. usleep_range(MMC35240_WAIT_SET_RESET, MMC35240_WAIT_SET_RESET + 1);
  189. ret = mmc35240_hw_set(data, false);
  190. if (ret < 0)
  191. return ret;
  192. /* set default sampling frequency */
  193. ret = regmap_update_bits(data->regmap, MMC35240_REG_CTRL1,
  194. MMC35240_CTRL1_BW_MASK,
  195. data->res << MMC35240_CTRL1_BW_SHIFT);
  196. if (ret < 0)
  197. return ret;
  198. ret = regmap_bulk_read(data->regmap, MMC35240_OTP_START_ADDR,
  199. otp_data, sizeof(otp_data));
  200. if (ret < 0)
  201. return ret;
  202. y_convert = MMC35240_OTP_CONVERT_Y(((otp_data[1] & 0x03) << 4) |
  203. (otp_data[2] >> 4));
  204. z_convert = MMC35240_OTP_CONVERT_Z(otp_data[3] & 0x3f);
  205. data->axis_coef[0] = MMC35240_X_COEFF(1);
  206. data->axis_coef[1] = MMC35240_Y_COEFF(y_convert);
  207. data->axis_coef[2] = MMC35240_Z_COEFF(z_convert);
  208. data->axis_scale[0] = 1;
  209. data->axis_scale[1] = 1000;
  210. data->axis_scale[2] = 10000;
  211. return 0;
  212. }
  213. static int mmc35240_take_measurement(struct mmc35240_data *data)
  214. {
  215. int ret, tries = 100;
  216. unsigned int reg_status;
  217. ret = regmap_write(data->regmap, MMC35240_REG_CTRL0,
  218. MMC35240_CTRL0_TM_BIT);
  219. if (ret < 0)
  220. return ret;
  221. while (tries-- > 0) {
  222. ret = regmap_read(data->regmap, MMC35240_REG_STATUS,
  223. &reg_status);
  224. if (ret < 0)
  225. return ret;
  226. if (reg_status & MMC35240_STATUS_MEAS_DONE_BIT)
  227. break;
  228. /* minimum wait time to complete measurement is 10 ms */
  229. usleep_range(10000, 11000);
  230. }
  231. if (tries < 0) {
  232. dev_err(&data->client->dev, "data not ready\n");
  233. return -EIO;
  234. }
  235. return 0;
  236. }
  237. static int mmc35240_read_measurement(struct mmc35240_data *data, __le16 buf[3])
  238. {
  239. int ret;
  240. ret = mmc35240_take_measurement(data);
  241. if (ret < 0)
  242. return ret;
  243. return regmap_bulk_read(data->regmap, MMC35240_REG_XOUT_L, buf,
  244. 3 * sizeof(__le16));
  245. }
  246. /**
  247. * mmc35240_raw_to_mgauss - convert raw readings to milli gauss. Also apply
  248. * compensation for output value.
  249. *
  250. * @data: device private data
  251. * @index: axis index for which we want the conversion
  252. * @buf: raw data to be converted, 2 bytes in little endian format
  253. * @val: compensated output reading (unit is milli gauss)
  254. *
  255. * Returns: 0 in case of success, -EINVAL when @index is not valid
  256. */
  257. static int mmc35240_raw_to_mgauss(struct mmc35240_data *data, int index,
  258. __le16 buf[], int *val)
  259. {
  260. int raw[3];
  261. int sens[3];
  262. int nfo;
  263. raw[AXIS_X] = le16_to_cpu(buf[AXIS_X]);
  264. raw[AXIS_Y] = le16_to_cpu(buf[AXIS_Y]);
  265. raw[AXIS_Z] = le16_to_cpu(buf[AXIS_Z]);
  266. sens[AXIS_X] = mmc35240_props_table[data->res].sens[AXIS_X];
  267. sens[AXIS_Y] = mmc35240_props_table[data->res].sens[AXIS_Y];
  268. sens[AXIS_Z] = mmc35240_props_table[data->res].sens[AXIS_Z];
  269. nfo = mmc35240_props_table[data->res].nfo;
  270. switch (index) {
  271. case AXIS_X:
  272. *val = (raw[AXIS_X] - nfo) * 1000 / sens[AXIS_X];
  273. break;
  274. case AXIS_Y:
  275. *val = (raw[AXIS_Y] - nfo) * 1000 / sens[AXIS_Y] -
  276. (raw[AXIS_Z] - nfo) * 1000 / sens[AXIS_Z];
  277. break;
  278. case AXIS_Z:
  279. *val = (raw[AXIS_Y] - nfo) * 1000 / sens[AXIS_Y] +
  280. (raw[AXIS_Z] - nfo) * 1000 / sens[AXIS_Z];
  281. break;
  282. default:
  283. return -EINVAL;
  284. }
  285. /* apply OTP compensation */
  286. *val = (*val) * data->axis_coef[index] / data->axis_scale[index];
  287. return 0;
  288. }
  289. static int mmc35240_read_raw(struct iio_dev *indio_dev,
  290. struct iio_chan_spec const *chan, int *val,
  291. int *val2, long mask)
  292. {
  293. struct mmc35240_data *data = iio_priv(indio_dev);
  294. int ret, i;
  295. unsigned int reg;
  296. __le16 buf[3];
  297. switch (mask) {
  298. case IIO_CHAN_INFO_RAW:
  299. mutex_lock(&data->mutex);
  300. ret = mmc35240_read_measurement(data, buf);
  301. mutex_unlock(&data->mutex);
  302. if (ret < 0)
  303. return ret;
  304. ret = mmc35240_raw_to_mgauss(data, chan->address, buf, val);
  305. if (ret < 0)
  306. return ret;
  307. return IIO_VAL_INT;
  308. case IIO_CHAN_INFO_SCALE:
  309. *val = 0;
  310. *val2 = 1000;
  311. return IIO_VAL_INT_PLUS_MICRO;
  312. case IIO_CHAN_INFO_SAMP_FREQ:
  313. mutex_lock(&data->mutex);
  314. ret = regmap_read(data->regmap, MMC35240_REG_CTRL1, &reg);
  315. mutex_unlock(&data->mutex);
  316. if (ret < 0)
  317. return ret;
  318. i = (reg & MMC35240_CTRL1_BW_MASK) >> MMC35240_CTRL1_BW_SHIFT;
  319. if (i < 0 || i >= ARRAY_SIZE(mmc35240_samp_freq))
  320. return -EINVAL;
  321. *val = mmc35240_samp_freq[i].val;
  322. *val2 = mmc35240_samp_freq[i].val2;
  323. return IIO_VAL_INT_PLUS_MICRO;
  324. default:
  325. return -EINVAL;
  326. }
  327. }
  328. static int mmc35240_write_raw(struct iio_dev *indio_dev,
  329. struct iio_chan_spec const *chan, int val,
  330. int val2, long mask)
  331. {
  332. struct mmc35240_data *data = iio_priv(indio_dev);
  333. int i, ret;
  334. switch (mask) {
  335. case IIO_CHAN_INFO_SAMP_FREQ:
  336. i = mmc35240_get_samp_freq_index(data, val, val2);
  337. if (i < 0)
  338. return -EINVAL;
  339. mutex_lock(&data->mutex);
  340. ret = regmap_update_bits(data->regmap, MMC35240_REG_CTRL1,
  341. MMC35240_CTRL1_BW_MASK,
  342. i << MMC35240_CTRL1_BW_SHIFT);
  343. mutex_unlock(&data->mutex);
  344. return ret;
  345. default:
  346. return -EINVAL;
  347. }
  348. }
  349. static const struct iio_info mmc35240_info = {
  350. .read_raw = mmc35240_read_raw,
  351. .write_raw = mmc35240_write_raw,
  352. .attrs = &mmc35240_attribute_group,
  353. };
  354. static bool mmc35240_is_writeable_reg(struct device *dev, unsigned int reg)
  355. {
  356. switch (reg) {
  357. case MMC35240_REG_CTRL0:
  358. case MMC35240_REG_CTRL1:
  359. return true;
  360. default:
  361. return false;
  362. }
  363. }
  364. static bool mmc35240_is_readable_reg(struct device *dev, unsigned int reg)
  365. {
  366. switch (reg) {
  367. case MMC35240_REG_XOUT_L:
  368. case MMC35240_REG_XOUT_H:
  369. case MMC35240_REG_YOUT_L:
  370. case MMC35240_REG_YOUT_H:
  371. case MMC35240_REG_ZOUT_L:
  372. case MMC35240_REG_ZOUT_H:
  373. case MMC35240_REG_STATUS:
  374. case MMC35240_REG_ID:
  375. return true;
  376. default:
  377. return false;
  378. }
  379. }
  380. static bool mmc35240_is_volatile_reg(struct device *dev, unsigned int reg)
  381. {
  382. switch (reg) {
  383. case MMC35240_REG_CTRL0:
  384. case MMC35240_REG_CTRL1:
  385. return false;
  386. default:
  387. return true;
  388. }
  389. }
  390. static const struct reg_default mmc35240_reg_defaults[] = {
  391. { MMC35240_REG_CTRL0, 0x00 },
  392. { MMC35240_REG_CTRL1, 0x00 },
  393. };
  394. static const struct regmap_config mmc35240_regmap_config = {
  395. .name = MMC35240_REGMAP_NAME,
  396. .reg_bits = 8,
  397. .val_bits = 8,
  398. .max_register = MMC35240_REG_ID,
  399. .cache_type = REGCACHE_FLAT,
  400. .writeable_reg = mmc35240_is_writeable_reg,
  401. .readable_reg = mmc35240_is_readable_reg,
  402. .volatile_reg = mmc35240_is_volatile_reg,
  403. .reg_defaults = mmc35240_reg_defaults,
  404. .num_reg_defaults = ARRAY_SIZE(mmc35240_reg_defaults),
  405. };
  406. static int mmc35240_probe(struct i2c_client *client)
  407. {
  408. struct mmc35240_data *data;
  409. struct iio_dev *indio_dev;
  410. struct regmap *regmap;
  411. int ret;
  412. indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
  413. if (!indio_dev)
  414. return -ENOMEM;
  415. regmap = devm_regmap_init_i2c(client, &mmc35240_regmap_config);
  416. if (IS_ERR(regmap)) {
  417. dev_err(&client->dev, "regmap initialization failed\n");
  418. return PTR_ERR(regmap);
  419. }
  420. data = iio_priv(indio_dev);
  421. i2c_set_clientdata(client, indio_dev);
  422. data->client = client;
  423. data->regmap = regmap;
  424. data->res = MMC35240_16_BITS_SLOW;
  425. mutex_init(&data->mutex);
  426. indio_dev->info = &mmc35240_info;
  427. indio_dev->name = MMC35240_DRV_NAME;
  428. indio_dev->channels = mmc35240_channels;
  429. indio_dev->num_channels = ARRAY_SIZE(mmc35240_channels);
  430. indio_dev->modes = INDIO_DIRECT_MODE;
  431. ret = mmc35240_init(data);
  432. if (ret < 0) {
  433. dev_err(&client->dev, "mmc35240 chip init failed\n");
  434. return ret;
  435. }
  436. return devm_iio_device_register(&client->dev, indio_dev);
  437. }
  438. static int mmc35240_suspend(struct device *dev)
  439. {
  440. struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
  441. struct mmc35240_data *data = iio_priv(indio_dev);
  442. regcache_cache_only(data->regmap, true);
  443. return 0;
  444. }
  445. static int mmc35240_resume(struct device *dev)
  446. {
  447. struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
  448. struct mmc35240_data *data = iio_priv(indio_dev);
  449. int ret;
  450. regcache_mark_dirty(data->regmap);
  451. ret = regcache_sync_region(data->regmap, MMC35240_REG_CTRL0,
  452. MMC35240_REG_CTRL1);
  453. if (ret < 0)
  454. dev_err(dev, "Failed to restore control registers\n");
  455. regcache_cache_only(data->regmap, false);
  456. return 0;
  457. }
  458. static DEFINE_SIMPLE_DEV_PM_OPS(mmc35240_pm_ops, mmc35240_suspend,
  459. mmc35240_resume);
  460. static const struct of_device_id mmc35240_of_match[] = {
  461. { .compatible = "memsic,mmc35240", },
  462. { }
  463. };
  464. MODULE_DEVICE_TABLE(of, mmc35240_of_match);
  465. static const struct acpi_device_id mmc35240_acpi_match[] = {
  466. {"MMC35240", 0},
  467. { },
  468. };
  469. MODULE_DEVICE_TABLE(acpi, mmc35240_acpi_match);
  470. static const struct i2c_device_id mmc35240_id[] = {
  471. { "mmc35240" },
  472. {}
  473. };
  474. MODULE_DEVICE_TABLE(i2c, mmc35240_id);
  475. static struct i2c_driver mmc35240_driver = {
  476. .driver = {
  477. .name = MMC35240_DRV_NAME,
  478. .of_match_table = mmc35240_of_match,
  479. .pm = pm_sleep_ptr(&mmc35240_pm_ops),
  480. .acpi_match_table = mmc35240_acpi_match,
  481. },
  482. .probe = mmc35240_probe,
  483. .id_table = mmc35240_id,
  484. };
  485. module_i2c_driver(mmc35240_driver);
  486. MODULE_AUTHOR("Daniel Baluta <daniel.baluta@intel.com>");
  487. MODULE_DESCRIPTION("MEMSIC MMC35240 magnetic sensor driver");
  488. MODULE_LICENSE("GPL v2");