ds4424.c 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341
  1. /*
  2. * Maxim Integrated
  3. * 7-bit, Multi-Channel Sink/Source Current DAC Driver
  4. * Copyright (C) 2017 Maxim Integrated
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License version 2 as
  8. * published by the Free Software Foundation.
  9. */
  10. #include <linux/kernel.h>
  11. #include <linux/module.h>
  12. #include <linux/i2c.h>
  13. #include <linux/regulator/consumer.h>
  14. #include <linux/err.h>
  15. #include <linux/delay.h>
  16. #include <linux/iio/iio.h>
  17. #include <linux/iio/driver.h>
  18. #include <linux/iio/machine.h>
  19. #include <linux/iio/consumer.h>
  20. #define DS4422_MAX_DAC_CHANNELS 2
  21. #define DS4424_MAX_DAC_CHANNELS 4
  22. #define DS4424_DAC_ADDR(chan) ((chan) + 0xf8)
  23. #define DS4424_SOURCE_I 1
  24. #define DS4424_SINK_I 0
  25. #define DS4424_CHANNEL(chan) { \
  26. .type = IIO_CURRENT, \
  27. .indexed = 1, \
  28. .output = 1, \
  29. .channel = chan, \
  30. .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
  31. }
  32. /*
  33. * DS4424 DAC control register 8 bits
  34. * [7] 0: to sink; 1: to source
  35. * [6:0] steps to sink/source
  36. * bit[7] looks like a sign bit, but the value of the register is
  37. * not a two's complement code considering the bit[6:0] is a absolute
  38. * distance from the zero point.
  39. */
  40. union ds4424_raw_data {
  41. struct {
  42. u8 dx:7;
  43. u8 source_bit:1;
  44. };
  45. u8 bits;
  46. };
  47. enum ds4424_device_ids {
  48. ID_DS4422,
  49. ID_DS4424,
  50. };
  51. struct ds4424_data {
  52. struct i2c_client *client;
  53. struct mutex lock;
  54. uint8_t save[DS4424_MAX_DAC_CHANNELS];
  55. struct regulator *vcc_reg;
  56. uint8_t raw[DS4424_MAX_DAC_CHANNELS];
  57. };
  58. static const struct iio_chan_spec ds4424_channels[] = {
  59. DS4424_CHANNEL(0),
  60. DS4424_CHANNEL(1),
  61. DS4424_CHANNEL(2),
  62. DS4424_CHANNEL(3),
  63. };
  64. static int ds4424_get_value(struct iio_dev *indio_dev,
  65. int *val, int channel)
  66. {
  67. struct ds4424_data *data = iio_priv(indio_dev);
  68. int ret;
  69. mutex_lock(&data->lock);
  70. ret = i2c_smbus_read_byte_data(data->client, DS4424_DAC_ADDR(channel));
  71. if (ret < 0)
  72. goto fail;
  73. *val = ret;
  74. fail:
  75. mutex_unlock(&data->lock);
  76. return ret;
  77. }
  78. static int ds4424_set_value(struct iio_dev *indio_dev,
  79. int val, struct iio_chan_spec const *chan)
  80. {
  81. struct ds4424_data *data = iio_priv(indio_dev);
  82. int ret;
  83. mutex_lock(&data->lock);
  84. ret = i2c_smbus_write_byte_data(data->client,
  85. DS4424_DAC_ADDR(chan->channel), val);
  86. if (ret < 0)
  87. goto fail;
  88. data->raw[chan->channel] = val;
  89. fail:
  90. mutex_unlock(&data->lock);
  91. return ret;
  92. }
  93. static int ds4424_read_raw(struct iio_dev *indio_dev,
  94. struct iio_chan_spec const *chan,
  95. int *val, int *val2, long mask)
  96. {
  97. union ds4424_raw_data raw;
  98. int ret;
  99. switch (mask) {
  100. case IIO_CHAN_INFO_RAW:
  101. ret = ds4424_get_value(indio_dev, val, chan->channel);
  102. if (ret < 0) {
  103. pr_err("%s : ds4424_get_value returned %d\n",
  104. __func__, ret);
  105. return ret;
  106. }
  107. raw.bits = *val;
  108. *val = raw.dx;
  109. if (raw.source_bit == DS4424_SINK_I)
  110. *val = -*val;
  111. return IIO_VAL_INT;
  112. default:
  113. return -EINVAL;
  114. }
  115. }
  116. static int ds4424_write_raw(struct iio_dev *indio_dev,
  117. struct iio_chan_spec const *chan,
  118. int val, int val2, long mask)
  119. {
  120. union ds4424_raw_data raw;
  121. if (val2 != 0)
  122. return -EINVAL;
  123. switch (mask) {
  124. case IIO_CHAN_INFO_RAW:
  125. if (val < S8_MIN || val > S8_MAX)
  126. return -EINVAL;
  127. if (val > 0) {
  128. raw.source_bit = DS4424_SOURCE_I;
  129. raw.dx = val;
  130. } else {
  131. raw.source_bit = DS4424_SINK_I;
  132. raw.dx = -val;
  133. }
  134. return ds4424_set_value(indio_dev, raw.bits, chan);
  135. default:
  136. return -EINVAL;
  137. }
  138. }
  139. static int ds4424_verify_chip(struct iio_dev *indio_dev)
  140. {
  141. int ret, val;
  142. ret = ds4424_get_value(indio_dev, &val, DS4424_DAC_ADDR(0));
  143. if (ret < 0)
  144. dev_err(&indio_dev->dev,
  145. "%s failed. ret: %d\n", __func__, ret);
  146. return ret;
  147. }
  148. static int __maybe_unused ds4424_suspend(struct device *dev)
  149. {
  150. struct i2c_client *client = to_i2c_client(dev);
  151. struct iio_dev *indio_dev = i2c_get_clientdata(client);
  152. struct ds4424_data *data = iio_priv(indio_dev);
  153. int ret = 0;
  154. int i;
  155. for (i = 0; i < indio_dev->num_channels; i++) {
  156. data->save[i] = data->raw[i];
  157. ret = ds4424_set_value(indio_dev, 0,
  158. &indio_dev->channels[i]);
  159. if (ret < 0)
  160. return ret;
  161. }
  162. return ret;
  163. }
  164. static int __maybe_unused ds4424_resume(struct device *dev)
  165. {
  166. struct i2c_client *client = to_i2c_client(dev);
  167. struct iio_dev *indio_dev = i2c_get_clientdata(client);
  168. struct ds4424_data *data = iio_priv(indio_dev);
  169. int ret = 0;
  170. int i;
  171. for (i = 0; i < indio_dev->num_channels; i++) {
  172. ret = ds4424_set_value(indio_dev, data->save[i],
  173. &indio_dev->channels[i]);
  174. if (ret < 0)
  175. return ret;
  176. }
  177. return ret;
  178. }
  179. static SIMPLE_DEV_PM_OPS(ds4424_pm_ops, ds4424_suspend, ds4424_resume);
  180. static const struct iio_info ds4424_info = {
  181. .read_raw = ds4424_read_raw,
  182. .write_raw = ds4424_write_raw,
  183. };
  184. static int ds4424_probe(struct i2c_client *client,
  185. const struct i2c_device_id *id)
  186. {
  187. struct ds4424_data *data;
  188. struct iio_dev *indio_dev;
  189. int ret;
  190. indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
  191. if (!indio_dev) {
  192. dev_err(&client->dev, "iio dev alloc failed.\n");
  193. return -ENOMEM;
  194. }
  195. data = iio_priv(indio_dev);
  196. i2c_set_clientdata(client, indio_dev);
  197. data->client = client;
  198. indio_dev->name = id->name;
  199. indio_dev->dev.of_node = client->dev.of_node;
  200. indio_dev->dev.parent = &client->dev;
  201. if (!client->dev.of_node) {
  202. dev_err(&client->dev,
  203. "Not found DT.\n");
  204. return -ENODEV;
  205. }
  206. data->vcc_reg = devm_regulator_get(&client->dev, "vcc");
  207. if (IS_ERR(data->vcc_reg)) {
  208. dev_err(&client->dev,
  209. "Failed to get vcc-supply regulator. err: %ld\n",
  210. PTR_ERR(data->vcc_reg));
  211. return PTR_ERR(data->vcc_reg);
  212. }
  213. mutex_init(&data->lock);
  214. ret = regulator_enable(data->vcc_reg);
  215. if (ret < 0) {
  216. dev_err(&client->dev,
  217. "Unable to enable the regulator.\n");
  218. return ret;
  219. }
  220. usleep_range(1000, 1200);
  221. ret = ds4424_verify_chip(indio_dev);
  222. if (ret < 0)
  223. goto fail;
  224. switch (id->driver_data) {
  225. case ID_DS4422:
  226. indio_dev->num_channels = DS4422_MAX_DAC_CHANNELS;
  227. break;
  228. case ID_DS4424:
  229. indio_dev->num_channels = DS4424_MAX_DAC_CHANNELS;
  230. break;
  231. default:
  232. dev_err(&client->dev,
  233. "ds4424: Invalid chip id.\n");
  234. ret = -ENXIO;
  235. goto fail;
  236. }
  237. indio_dev->channels = ds4424_channels;
  238. indio_dev->modes = INDIO_DIRECT_MODE;
  239. indio_dev->info = &ds4424_info;
  240. ret = iio_device_register(indio_dev);
  241. if (ret < 0) {
  242. dev_err(&client->dev,
  243. "iio_device_register failed. ret: %d\n", ret);
  244. goto fail;
  245. }
  246. return ret;
  247. fail:
  248. regulator_disable(data->vcc_reg);
  249. return ret;
  250. }
  251. static int ds4424_remove(struct i2c_client *client)
  252. {
  253. struct iio_dev *indio_dev = i2c_get_clientdata(client);
  254. struct ds4424_data *data = iio_priv(indio_dev);
  255. iio_device_unregister(indio_dev);
  256. regulator_disable(data->vcc_reg);
  257. return 0;
  258. }
  259. static const struct i2c_device_id ds4424_id[] = {
  260. { "ds4422", ID_DS4422 },
  261. { "ds4424", ID_DS4424 },
  262. { }
  263. };
  264. MODULE_DEVICE_TABLE(i2c, ds4424_id);
  265. static const struct of_device_id ds4424_of_match[] = {
  266. { .compatible = "maxim,ds4422" },
  267. { .compatible = "maxim,ds4424" },
  268. { },
  269. };
  270. MODULE_DEVICE_TABLE(of, ds4424_of_match);
  271. static struct i2c_driver ds4424_driver = {
  272. .driver = {
  273. .name = "ds4424",
  274. .of_match_table = ds4424_of_match,
  275. .pm = &ds4424_pm_ops,
  276. },
  277. .probe = ds4424_probe,
  278. .remove = ds4424_remove,
  279. .id_table = ds4424_id,
  280. };
  281. module_i2c_driver(ds4424_driver);
  282. MODULE_DESCRIPTION("Maxim DS4424 DAC Driver");
  283. MODULE_AUTHOR("Ismail H. Kose <ismail.kose@maximintegrated.com>");
  284. MODULE_AUTHOR("Vishal Sood <vishal.sood@maximintegrated.com>");
  285. MODULE_AUTHOR("David Jung <david.jung@maximintegrated.com>");
  286. MODULE_LICENSE("GPL v2");