hmc425a.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * HMC425A and similar Gain Amplifiers
  4. *
  5. * Copyright 2020, 2024 Analog Devices Inc.
  6. */
  7. #include <linux/bits.h>
  8. #include <linux/bitops.h>
  9. #include <linux/device.h>
  10. #include <linux/err.h>
  11. #include <linux/gpio/consumer.h>
  12. #include <linux/iio/iio.h>
  13. #include <linux/iio/sysfs.h>
  14. #include <linux/kernel.h>
  15. #include <linux/math.h>
  16. #include <linux/mod_devicetable.h>
  17. #include <linux/module.h>
  18. #include <linux/platform_device.h>
  19. #include <linux/property.h>
  20. #include <linux/slab.h>
  21. #include <linux/regulator/consumer.h>
  22. #include <linux/sysfs.h>
  23. /*
  24. * The LTC6373 amplifier supports configuring gain using GPIO's with the following
  25. * values (OUTPUT_V / INPUT_V): 0(shutdown), 0.25, 0.5, 1, 2, 4, 8, 16
  26. *
  27. * Except for the shutdown value, all can be converted to dB using 20 * log10(x)
  28. * From here, it is observed that all values are multiples of the '2' gain setting,
  29. * with the correspondent of 6.020dB.
  30. */
  31. #define LTC6373_CONVERSION_CONSTANT 6020
  32. #define LTC6373_MIN_GAIN_CODE 0x6
  33. #define LTC6373_CONVERSION_MASK GENMASK(2, 0)
  34. #define LTC6373_SHUTDOWN GENMASK(2, 0)
  35. enum hmc425a_type {
  36. ID_HMC425A,
  37. ID_HMC540S,
  38. ID_ADRF5740,
  39. ID_LTC6373,
  40. };
  41. struct hmc425a_chip_info {
  42. const char *name;
  43. const struct iio_chan_spec *channels;
  44. unsigned int num_channels;
  45. unsigned int num_gpios;
  46. int gain_min;
  47. int gain_max;
  48. int default_gain;
  49. int powerdown_val;
  50. bool has_powerdown;
  51. int (*gain_dB_to_code)(int gain, int *code);
  52. int (*code_to_gain_dB)(int code, int *val, int *val2);
  53. };
  54. struct hmc425a_state {
  55. struct mutex lock; /* protect sensor state */
  56. const struct hmc425a_chip_info *chip_info;
  57. struct gpio_descs *gpios;
  58. u32 gain;
  59. bool powerdown;
  60. };
  61. static int gain_dB_to_code(struct hmc425a_state *st, int val, int val2, int *code)
  62. {
  63. const struct hmc425a_chip_info *inf = st->chip_info;
  64. int gain;
  65. if (val < 0)
  66. gain = (val * 1000) - (val2 / 1000);
  67. else
  68. gain = (val * 1000) + (val2 / 1000);
  69. if (gain > inf->gain_max || gain < inf->gain_min)
  70. return -EINVAL;
  71. if (st->powerdown)
  72. return -EPERM;
  73. return st->chip_info->gain_dB_to_code(gain, code);
  74. }
  75. static int hmc425a_gain_dB_to_code(int gain, int *code)
  76. {
  77. *code = ~((abs(gain) / 500) & 0x3F);
  78. return 0;
  79. }
  80. static int hmc540s_gain_dB_to_code(int gain, int *code)
  81. {
  82. *code = ~((abs(gain) / 1000) & 0xF);
  83. return 0;
  84. }
  85. static int adrf5740_gain_dB_to_code(int gain, int *code)
  86. {
  87. int temp = (abs(gain) / 2000) & 0xF;
  88. /* Bit [0-3]: 2dB 4dB 8dB 8dB */
  89. *code = temp & BIT(3) ? temp | BIT(2) : temp;
  90. return 0;
  91. }
  92. static int ltc6373_gain_dB_to_code(int gain, int *code)
  93. {
  94. *code = ~(DIV_ROUND_CLOSEST(gain, LTC6373_CONVERSION_CONSTANT) + 3)
  95. & LTC6373_CONVERSION_MASK;
  96. return 0;
  97. }
  98. static int code_to_gain_dB(struct hmc425a_state *st, int *val, int *val2)
  99. {
  100. if (st->powerdown)
  101. return -EPERM;
  102. return st->chip_info->code_to_gain_dB(st->gain, val, val2);
  103. }
  104. static int hmc425a_code_to_gain_dB(int code, int *val, int *val2)
  105. {
  106. *val = (~code * -500) / 1000;
  107. *val2 = ((~code * -500) % 1000) * 1000;
  108. return 0;
  109. }
  110. static int hmc540s_code_to_gain_dB(int code, int *val, int *val2)
  111. {
  112. *val = (~code * -1000) / 1000;
  113. *val2 = ((~code * -1000) % 1000) * 1000;
  114. return 0;
  115. }
  116. static int adrf5740_code_to_gain_dB(int code, int *val, int *val2)
  117. {
  118. /*
  119. * Bit [0-3]: 2dB 4dB 8dB 8dB
  120. * When BIT(3) is set, unset BIT(2) and use 3 as double the place value
  121. */
  122. code = code & BIT(3) ? code & ~BIT(2) : code;
  123. *val = (code * -2000) / 1000;
  124. *val2 = ((code * -2000) % 1000) * 1000;
  125. return 0;
  126. }
  127. static int ltc6373_code_to_gain_dB(int code, int *val, int *val2)
  128. {
  129. int gain = ((~code & LTC6373_CONVERSION_MASK) - 3) *
  130. LTC6373_CONVERSION_CONSTANT;
  131. *val = gain / 1000;
  132. *val2 = (gain % 1000) * 1000;
  133. return 0;
  134. }
  135. static int hmc425a_write(struct iio_dev *indio_dev, u32 value)
  136. {
  137. struct hmc425a_state *st = iio_priv(indio_dev);
  138. DECLARE_BITMAP(values, BITS_PER_TYPE(value));
  139. values[0] = value;
  140. gpiod_set_array_value_cansleep(st->gpios->ndescs, st->gpios->desc,
  141. NULL, values);
  142. return 0;
  143. }
  144. static int hmc425a_read_raw(struct iio_dev *indio_dev,
  145. struct iio_chan_spec const *chan, int *val,
  146. int *val2, long m)
  147. {
  148. struct hmc425a_state *st = iio_priv(indio_dev);
  149. int ret;
  150. mutex_lock(&st->lock);
  151. switch (m) {
  152. case IIO_CHAN_INFO_HARDWAREGAIN:
  153. ret = code_to_gain_dB(st, val, val2);
  154. if (ret)
  155. break;
  156. ret = IIO_VAL_INT_PLUS_MICRO_DB;
  157. break;
  158. default:
  159. ret = -EINVAL;
  160. }
  161. mutex_unlock(&st->lock);
  162. return ret;
  163. };
  164. static int hmc425a_write_raw(struct iio_dev *indio_dev,
  165. struct iio_chan_spec const *chan, int val,
  166. int val2, long mask)
  167. {
  168. struct hmc425a_state *st = iio_priv(indio_dev);
  169. int code = 0, ret;
  170. mutex_lock(&st->lock);
  171. switch (mask) {
  172. case IIO_CHAN_INFO_HARDWAREGAIN:
  173. ret = gain_dB_to_code(st, val, val2, &code);
  174. if (ret)
  175. break;
  176. st->gain = code;
  177. ret = hmc425a_write(indio_dev, st->gain);
  178. break;
  179. default:
  180. ret = -EINVAL;
  181. }
  182. mutex_unlock(&st->lock);
  183. return ret;
  184. }
  185. static int hmc425a_write_raw_get_fmt(struct iio_dev *indio_dev,
  186. struct iio_chan_spec const *chan,
  187. long mask)
  188. {
  189. switch (mask) {
  190. case IIO_CHAN_INFO_HARDWAREGAIN:
  191. return IIO_VAL_INT_PLUS_MICRO_DB;
  192. default:
  193. return -EINVAL;
  194. }
  195. }
  196. static const struct iio_info hmc425a_info = {
  197. .read_raw = &hmc425a_read_raw,
  198. .write_raw = &hmc425a_write_raw,
  199. .write_raw_get_fmt = &hmc425a_write_raw_get_fmt,
  200. };
  201. static ssize_t ltc6373_read_powerdown(struct iio_dev *indio_dev,
  202. uintptr_t private,
  203. const struct iio_chan_spec *chan,
  204. char *buf)
  205. {
  206. struct hmc425a_state *st = iio_priv(indio_dev);
  207. return sysfs_emit(buf, "%d\n", st->powerdown);
  208. }
  209. static ssize_t ltc6373_write_powerdown(struct iio_dev *indio_dev,
  210. uintptr_t private,
  211. const struct iio_chan_spec *chan,
  212. const char *buf,
  213. size_t len)
  214. {
  215. struct hmc425a_state *st = iio_priv(indio_dev);
  216. bool powerdown;
  217. int code, ret;
  218. ret = kstrtobool(buf, &powerdown);
  219. if (ret)
  220. return ret;
  221. mutex_lock(&st->lock);
  222. st->powerdown = powerdown;
  223. code = (powerdown) ? LTC6373_SHUTDOWN : st->gain;
  224. hmc425a_write(indio_dev, code);
  225. mutex_unlock(&st->lock);
  226. return len;
  227. }
  228. static const struct iio_chan_spec_ext_info ltc6373_ext_info[] = {
  229. {
  230. .name = "powerdown",
  231. .read = ltc6373_read_powerdown,
  232. .write = ltc6373_write_powerdown,
  233. .shared = IIO_SEPARATE,
  234. },
  235. {}
  236. };
  237. #define HMC425A_CHAN(_channel) \
  238. { \
  239. .type = IIO_VOLTAGE, \
  240. .output = 1, \
  241. .indexed = 1, \
  242. .channel = _channel, \
  243. .info_mask_separate = BIT(IIO_CHAN_INFO_HARDWAREGAIN), \
  244. }
  245. #define LTC6373_CHAN(_channel) \
  246. { \
  247. .type = IIO_VOLTAGE, \
  248. .output = 1, \
  249. .indexed = 1, \
  250. .channel = _channel, \
  251. .info_mask_separate = BIT(IIO_CHAN_INFO_HARDWAREGAIN), \
  252. .ext_info = ltc6373_ext_info, \
  253. }
  254. static const struct iio_chan_spec hmc425a_channels[] = {
  255. HMC425A_CHAN(0),
  256. };
  257. static const struct iio_chan_spec ltc6373_channels[] = {
  258. LTC6373_CHAN(0),
  259. };
  260. static const struct hmc425a_chip_info hmc425a_chip_info_tbl[] = {
  261. [ID_HMC425A] = {
  262. .name = "hmc425a",
  263. .channels = hmc425a_channels,
  264. .num_channels = ARRAY_SIZE(hmc425a_channels),
  265. .num_gpios = 6,
  266. .gain_min = -31500,
  267. .gain_max = 0,
  268. .default_gain = -0x40, /* set default gain -31.5db*/
  269. .gain_dB_to_code = hmc425a_gain_dB_to_code,
  270. .code_to_gain_dB = hmc425a_code_to_gain_dB,
  271. },
  272. [ID_HMC540S] = {
  273. .name = "hmc540s",
  274. .channels = hmc425a_channels,
  275. .num_channels = ARRAY_SIZE(hmc425a_channels),
  276. .num_gpios = 4,
  277. .gain_min = -15000,
  278. .gain_max = 0,
  279. .default_gain = -0x10, /* set default gain -15.0db*/
  280. .gain_dB_to_code = hmc540s_gain_dB_to_code,
  281. .code_to_gain_dB = hmc540s_code_to_gain_dB,
  282. },
  283. [ID_ADRF5740] = {
  284. .name = "adrf5740",
  285. .channels = hmc425a_channels,
  286. .num_channels = ARRAY_SIZE(hmc425a_channels),
  287. .num_gpios = 4,
  288. .gain_min = -22000,
  289. .gain_max = 0,
  290. .default_gain = 0xF, /* set default gain -22.0db*/
  291. .gain_dB_to_code = adrf5740_gain_dB_to_code,
  292. .code_to_gain_dB = adrf5740_code_to_gain_dB,
  293. },
  294. [ID_LTC6373] = {
  295. .name = "ltc6373",
  296. .channels = ltc6373_channels,
  297. .num_channels = ARRAY_SIZE(ltc6373_channels),
  298. .num_gpios = 3,
  299. .gain_min = -12041, /* gain setting x0.25*/
  300. .gain_max = 24082, /* gain setting x16 */
  301. .default_gain = LTC6373_MIN_GAIN_CODE,
  302. .powerdown_val = LTC6373_SHUTDOWN,
  303. .has_powerdown = true,
  304. .gain_dB_to_code = ltc6373_gain_dB_to_code,
  305. .code_to_gain_dB = ltc6373_code_to_gain_dB,
  306. },
  307. };
  308. static int hmc425a_probe(struct platform_device *pdev)
  309. {
  310. struct iio_dev *indio_dev;
  311. struct hmc425a_state *st;
  312. int ret;
  313. indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*st));
  314. if (!indio_dev)
  315. return -ENOMEM;
  316. st = iio_priv(indio_dev);
  317. st->chip_info = device_get_match_data(&pdev->dev);
  318. indio_dev->num_channels = st->chip_info->num_channels;
  319. indio_dev->channels = st->chip_info->channels;
  320. indio_dev->name = st->chip_info->name;
  321. st->gain = st->chip_info->default_gain;
  322. st->gpios = devm_gpiod_get_array(&pdev->dev, "ctrl", GPIOD_OUT_LOW);
  323. if (IS_ERR(st->gpios))
  324. return dev_err_probe(&pdev->dev, PTR_ERR(st->gpios),
  325. "failed to get gpios\n");
  326. if (st->gpios->ndescs != st->chip_info->num_gpios) {
  327. dev_err(&pdev->dev, "%d GPIOs needed to operate\n",
  328. st->chip_info->num_gpios);
  329. return -ENODEV;
  330. }
  331. ret = devm_regulator_get_enable(&pdev->dev, "vcc-supply");
  332. if (ret)
  333. return ret;
  334. mutex_init(&st->lock);
  335. indio_dev->info = &hmc425a_info;
  336. indio_dev->modes = INDIO_DIRECT_MODE;
  337. if (st->chip_info->has_powerdown) {
  338. st->powerdown = true;
  339. hmc425a_write(indio_dev, st->chip_info->powerdown_val);
  340. } else {
  341. /* Set default gain */
  342. hmc425a_write(indio_dev, st->gain);
  343. }
  344. return devm_iio_device_register(&pdev->dev, indio_dev);
  345. }
  346. /* Match table for of_platform binding */
  347. static const struct of_device_id hmc425a_of_match[] = {
  348. { .compatible = "adi,hmc425a",
  349. .data = &hmc425a_chip_info_tbl[ID_HMC425A]},
  350. { .compatible = "adi,hmc540s",
  351. .data = &hmc425a_chip_info_tbl[ID_HMC540S]},
  352. { .compatible = "adi,adrf5740",
  353. .data = &hmc425a_chip_info_tbl[ID_ADRF5740]},
  354. { .compatible = "adi,ltc6373",
  355. .data = &hmc425a_chip_info_tbl[ID_LTC6373]},
  356. {}
  357. };
  358. MODULE_DEVICE_TABLE(of, hmc425a_of_match);
  359. static struct platform_driver hmc425a_driver = {
  360. .driver = {
  361. .name = KBUILD_MODNAME,
  362. .of_match_table = hmc425a_of_match,
  363. },
  364. .probe = hmc425a_probe,
  365. };
  366. module_platform_driver(hmc425a_driver);
  367. MODULE_AUTHOR("Michael Hennerich <michael.hennerich@analog.com>");
  368. MODULE_DESCRIPTION("Analog Devices HMC425A and similar GPIO control Gain Amplifiers");
  369. MODULE_LICENSE("GPL v2");