/drivers/hwmon/m_adc.c

https://bitbucket.org/cresqo/cm7-p500-kernel · C · 922 lines · 697 code · 168 blank · 57 comment · 86 complexity · 3aba6bbc092d018c612aff2d1daa9706 MD5 · raw file

  1. /* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
  2. *
  3. * This program is free software; you can redistribute it and/or modify
  4. * it under the terms of the GNU General Public License version 2 and
  5. * only version 2 as published by the Free Software Foundation.
  6. *
  7. * This program is distributed in the hope that it will be useful,
  8. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. * GNU General Public License for more details.
  11. *
  12. * You should have received a copy of the GNU General Public License
  13. * along with this program; if not, write to the Free Software
  14. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  15. * 02110-1301, USA.
  16. */
  17. #include <linux/kernel.h>
  18. #include <linux/init.h>
  19. #include <linux/mutex.h>
  20. #include <linux/platform_device.h>
  21. #include <linux/err.h>
  22. #include <linux/hwmon.h>
  23. #include <linux/hwmon-sysfs.h>
  24. #include <linux/miscdevice.h>
  25. #include <linux/fs.h>
  26. #include <linux/sched.h>
  27. #include <linux/wait.h>
  28. #include <linux/uaccess.h>
  29. #include <linux/m_adc.h>
  30. #include <linux/pmic8058-xoadc.h>
  31. #include <linux/slab.h>
  32. #define MSM_ADC_DRIVER_NAME "msm_adc"
  33. struct msm_adc_drv {
  34. void *dev_h;
  35. struct platform_device *pdev;
  36. struct sensor_device_attribute *sens_attr;
  37. struct workqueue_struct *wq;
  38. struct device *hwmon;
  39. struct miscdevice misc;
  40. atomic_t online;
  41. atomic_t total_outst;
  42. wait_queue_head_t total_outst_wait;
  43. };
  44. /* Needed to support file_op interfaces */
  45. static struct msm_adc_drv *msm_adc_drv;
  46. static int conv_first_request;
  47. static ssize_t msm_adc_show_curr(struct device *dev,
  48. struct device_attribute *devattr, char *buf);
  49. static int msm_adc_blocking_conversion(struct msm_adc_drv *msm_adc,
  50. uint32_t chan, struct adc_chan_result *result);
  51. static int msm_adc_open(struct inode *inode, struct file *file)
  52. {
  53. struct msm_client_data *client;
  54. struct msm_adc_drv *msm_adc = msm_adc_drv;
  55. struct platform_device *pdev = msm_adc->pdev;
  56. client = kzalloc(sizeof(struct msm_client_data), GFP_KERNEL);
  57. if (!client) {
  58. dev_err(&pdev->dev, "Unable to allocate memory\n");
  59. return -ENOMEM;
  60. }
  61. if (!try_module_get(THIS_MODULE)) {
  62. kfree(client);
  63. return -EACCES;
  64. }
  65. mutex_init(&client->lock);
  66. INIT_LIST_HEAD(&client->complete_list);
  67. init_waitqueue_head(&client->data_wait);
  68. init_waitqueue_head(&client->outst_wait);
  69. client->online = 1;
  70. file->private_data = client;
  71. return nonseekable_open(inode, file);
  72. }
  73. static int no_pending_client_requests(struct msm_client_data *client)
  74. {
  75. mutex_lock(&client->lock);
  76. if (client->num_outstanding == 0) {
  77. mutex_unlock(&client->lock);
  78. return 1;
  79. }
  80. mutex_unlock(&client->lock);
  81. return 0;
  82. }
  83. static int data_avail(struct msm_client_data *client, uint32_t *pending)
  84. {
  85. uint32_t completed;
  86. mutex_lock(&client->lock);
  87. completed = client->num_complete;
  88. mutex_unlock(&client->lock);
  89. if (completed > 0) {
  90. if (pending != NULL)
  91. *pending = completed;
  92. return 1;
  93. }
  94. return 0;
  95. }
  96. static int msm_adc_release(struct inode *inode, struct file *file)
  97. {
  98. struct msm_client_data *client = file->private_data;
  99. struct adc_conv_slot *slot, *tmp;
  100. int rc;
  101. struct msm_adc_platform_data *pdata =
  102. msm_adc_drv->pdev->dev.platform_data;
  103. struct msm_adc_channels *channel = pdata->channel;
  104. module_put(THIS_MODULE);
  105. mutex_lock(&client->lock);
  106. /* prevent any further requests while we teardown the client */
  107. client->online = 0;
  108. mutex_unlock(&client->lock);
  109. /*
  110. * We may still have outstanding transactions in flight from this
  111. * client that have not completed. Make sure they're completed
  112. * before removing the client.
  113. */
  114. rc = wait_event_interruptible(client->outst_wait,
  115. no_pending_client_requests(client));
  116. if (rc) {
  117. pr_err("%s: wait_event_interruptible failed rc = %d\n",
  118. __func__, rc);
  119. return rc;
  120. }
  121. /*
  122. * All transactions have completed. Add slot resources back to the
  123. * appropriate devices.
  124. */
  125. list_for_each_entry_safe(slot, tmp, &client->complete_list, list) {
  126. slot->client = NULL;
  127. list_del(&slot->list);
  128. channel[slot->conv.result.chan].adc_access_fn->adc_restore_slot(
  129. channel[slot->conv.result.chan].adc_dev_instance, slot);
  130. }
  131. kfree(client);
  132. return 0;
  133. }
  134. static int msm_adc_lookup(struct msm_adc_drv *msm_adc,
  135. struct msm_adc_lookup *lookup)
  136. {
  137. struct platform_device *pdev = msm_adc->pdev;
  138. struct msm_adc_platform_data *pdata = msm_adc->pdev->dev.platform_data;
  139. int rc = 0, i = 0;
  140. do {
  141. if (strcmp(lookup->name, pdata->channel[i].name))
  142. i++;
  143. else
  144. break;
  145. } while (i < pdata->num_chan_supported);
  146. if (i == pdata->num_chan_supported)
  147. rc = -EINVAL;
  148. if (rc) {
  149. dev_err(&pdev->dev, "Lookup failed for %s\n", lookup->name);
  150. return rc;
  151. }
  152. lookup->chan_idx = i;
  153. return rc;
  154. }
  155. static int msm_adc_aio_conversion(struct msm_adc_drv *msm_adc,
  156. struct adc_chan_result *request,
  157. struct msm_client_data *client)
  158. {
  159. struct msm_adc_platform_data *pdata =
  160. msm_adc_drv->pdev->dev.platform_data;
  161. struct msm_adc_channels *channel = &pdata->channel[request->chan];
  162. struct adc_conv_slot *slot;
  163. /* we could block here, but only for a bounded time */
  164. channel->adc_access_fn->adc_slot_request(channel->adc_dev_instance,
  165. &slot);
  166. if (slot) {
  167. atomic_inc(&msm_adc->total_outst);
  168. mutex_lock(&client->lock);
  169. client->num_outstanding++;
  170. mutex_unlock(&client->lock);
  171. /* indicates non blocking request to callback handler */
  172. slot->blocking = 0;
  173. slot->compk = NULL;/*For kernel space usage; n/a for usr space*/
  174. slot->conv.result.chan = client->adc_chan = request->chan;
  175. slot->client = client;
  176. slot->adc_request = START_OF_CONV;
  177. slot->chan_path = channel->chan_path_type;
  178. slot->chan_adc_config = channel->adc_config_type;
  179. slot->chan_adc_calib = channel->adc_calib_type;
  180. queue_work(msm_adc->wq, &slot->work);
  181. return 0;
  182. }
  183. return -EBUSY;
  184. }
  185. static int msm_adc_poll_complete(struct msm_adc_drv *msm_adc,
  186. struct msm_client_data *client, uint32_t *pending)
  187. {
  188. int rc;
  189. /*
  190. * Don't proceed if there there's nothing queued on this client.
  191. * We could deadlock otherwise in a single threaded scenario.
  192. */
  193. if (no_pending_client_requests(client))
  194. return -EDEADLK;
  195. rc = wait_event_interruptible(client->data_wait,
  196. data_avail(client, pending));
  197. if (rc)
  198. return rc;
  199. return 0;
  200. }
  201. static int msm_adc_read_result(struct msm_adc_drv *msm_adc,
  202. struct msm_client_data *client,
  203. struct adc_chan_result *result)
  204. {
  205. struct msm_adc_platform_data *pdata = msm_adc->pdev->dev.platform_data;
  206. struct msm_adc_channels *channel = pdata->channel;
  207. struct adc_conv_slot *slot;
  208. int rc = 0;
  209. mutex_lock(&client->lock);
  210. slot = list_first_entry(&client->complete_list,
  211. struct adc_conv_slot, list);
  212. if (!slot) {
  213. mutex_unlock(&client->lock);
  214. return -ENOMSG;
  215. }
  216. slot->client = NULL;
  217. list_del(&slot->list);
  218. client->num_complete--;
  219. mutex_unlock(&client->lock);
  220. *result = slot->conv.result;
  221. /* restore this slot to reserve */
  222. channel[slot->conv.result.chan].adc_access_fn->adc_restore_slot(
  223. channel[slot->conv.result.chan].adc_dev_instance, slot);
  224. return rc;
  225. }
  226. static long msm_adc_ioctl(struct file *file, unsigned int cmd,
  227. unsigned long arg)
  228. {
  229. struct msm_client_data *client = file->private_data;
  230. struct msm_adc_drv *msm_adc = msm_adc_drv;
  231. struct platform_device *pdev = msm_adc->pdev;
  232. int rc;
  233. switch (cmd) {
  234. case MSM_ADC_REQUEST:
  235. {
  236. struct adc_chan_result conv;
  237. if (copy_from_user(&conv, (void __user *)arg,
  238. sizeof(struct adc_chan_result)))
  239. return -EFAULT;
  240. rc = msm_adc_blocking_conversion(msm_adc, conv.chan,
  241. &conv);
  242. if (rc) {
  243. dev_dbg(&pdev->dev, "BLK conversion failed\n");
  244. return rc;
  245. }
  246. if (copy_to_user((void __user *)arg, &conv,
  247. sizeof(struct adc_chan_result)))
  248. return -EFAULT;
  249. break;
  250. }
  251. case MSM_ADC_AIO_REQUEST:
  252. {
  253. struct adc_chan_result conv;
  254. if (copy_from_user(&conv, (void __user *)arg,
  255. sizeof(struct adc_chan_result)))
  256. return -EFAULT;
  257. rc = msm_adc_aio_conversion(msm_adc, &conv, client);
  258. if (rc) {
  259. dev_dbg(&pdev->dev, "AIO conversion failed\n");
  260. return rc;
  261. }
  262. break;
  263. }
  264. case MSM_ADC_AIO_POLL:
  265. {
  266. uint32_t completed;
  267. rc = msm_adc_poll_complete(msm_adc, client, &completed);
  268. if (rc) {
  269. dev_dbg(&pdev->dev, "poll request failed\n");
  270. return rc;
  271. }
  272. if (copy_to_user((void __user *)arg, &completed,
  273. sizeof(uint32_t)))
  274. return -EFAULT;
  275. break;
  276. }
  277. case MSM_ADC_AIO_READ:
  278. {
  279. struct adc_chan_result result;
  280. rc = msm_adc_read_result(msm_adc, client, &result);
  281. if (rc) {
  282. dev_dbg(&pdev->dev, "read result failed\n");
  283. return rc;
  284. }
  285. if (copy_to_user((void __user *)arg, &result,
  286. sizeof(struct adc_chan_result)))
  287. return -EFAULT;
  288. break;
  289. }
  290. case MSM_ADC_LOOKUP:
  291. {
  292. struct msm_adc_lookup lookup;
  293. if (copy_from_user(&lookup, (void __user *)arg,
  294. sizeof(struct msm_adc_lookup)))
  295. return -EFAULT;
  296. rc = msm_adc_lookup(msm_adc, &lookup);
  297. if (rc) {
  298. dev_dbg(&pdev->dev, "No such channel: %s\n",
  299. lookup.name);
  300. return rc;
  301. }
  302. if (copy_to_user((void __user *)arg, &lookup,
  303. sizeof(struct msm_adc_lookup)))
  304. return -EFAULT;
  305. break;
  306. }
  307. default:
  308. return -EINVAL;
  309. }
  310. return 0;
  311. }
  312. const struct file_operations msm_adc_fops = {
  313. .open = msm_adc_open,
  314. .release = msm_adc_release,
  315. .unlocked_ioctl = msm_adc_ioctl,
  316. };
  317. static ssize_t msm_adc_show_curr(struct device *dev,
  318. struct device_attribute *devattr, char *buf)
  319. {
  320. struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
  321. struct msm_adc_drv *msm_adc = dev_get_drvdata(dev);
  322. int rc;
  323. struct adc_chan_result result;
  324. rc = pm8058_xoadc_registered();
  325. if (rc <= 0)
  326. return -ENODEV;
  327. rc = msm_adc_blocking_conversion(msm_adc, attr->index, &result);
  328. if (rc)
  329. return 0;
  330. return sprintf(buf, "Result: %lld Raw: %d\n", result.physical,
  331. result.adc_code);
  332. }
  333. static int msm_adc_blocking_conversion(struct msm_adc_drv *msm_adc,
  334. uint32_t hwmon_chan, struct adc_chan_result *result)
  335. {
  336. struct adc_conv_slot *slot;
  337. struct msm_adc_platform_data *pdata =
  338. msm_adc_drv->pdev->dev.platform_data;
  339. struct msm_adc_channels *channel = &pdata->channel[hwmon_chan];
  340. int ret;
  341. if (!conv_first_request) {
  342. ret = pm8058_xoadc_calib_device(channel->adc_dev_instance);
  343. if (ret) {
  344. pr_err("pmic8058 xoadc calibration failed, retry\n");
  345. return ret;
  346. }
  347. conv_first_request = 1;
  348. }
  349. channel->adc_access_fn->adc_slot_request(channel->adc_dev_instance,
  350. &slot);
  351. if (slot) {
  352. slot->conv.result.chan = hwmon_chan;
  353. /* indicates blocking request to callback handler */
  354. slot->blocking = 1;
  355. slot->adc_request = START_OF_CONV;
  356. slot->chan_path = channel->chan_path_type;
  357. slot->chan_adc_config = channel->adc_config_type;
  358. slot->chan_adc_calib = channel->adc_calib_type;
  359. queue_work(msm_adc_drv->wq, &slot->work);
  360. wait_for_completion_interruptible(&slot->comp);
  361. *result = slot->conv.result;
  362. channel->adc_access_fn->adc_restore_slot(
  363. channel->adc_dev_instance, slot);
  364. return 0;
  365. }
  366. return -EBUSY;
  367. }
  368. void msm_adc_conv_cb(void *context, u32 param,
  369. void *evt_buf, u32 len)
  370. {
  371. struct adc_conv_slot *slot = context;
  372. struct msm_adc_drv *msm_adc = msm_adc_drv;
  373. switch (slot->adc_request) {
  374. case START_OF_CONV:
  375. slot->adc_request = END_OF_CONV;
  376. break;
  377. case START_OF_CALIBRATION:
  378. slot->adc_request = END_OF_CALIBRATION;
  379. break;
  380. case END_OF_CALIBRATION:
  381. case END_OF_CONV:
  382. break;
  383. }
  384. queue_work(msm_adc->wq, &slot->work);
  385. }
  386. EXPORT_SYMBOL(msm_adc_conv_cb);
  387. static void msm_adc_teardown_device(struct platform_device *pdev,
  388. struct msm_adc_drv *msm_adc)
  389. {
  390. struct msm_adc_platform_data *pdata = pdev->dev.platform_data;
  391. int i, num_chans = pdata->num_chan_supported;
  392. if (msm_adc->sens_attr)
  393. for (i = 0; i < num_chans; i++)
  394. device_remove_file(&pdev->dev,
  395. &msm_adc->sens_attr[i].dev_attr);
  396. kfree(msm_adc->sens_attr);
  397. }
  398. static void msm_adc_teardown(struct platform_device *pdev)
  399. {
  400. struct msm_adc_drv *msm_adc = platform_get_drvdata(pdev);
  401. if (!msm_adc)
  402. return;
  403. misc_deregister(&msm_adc->misc);
  404. if (msm_adc->hwmon)
  405. hwmon_device_unregister(msm_adc->hwmon);
  406. msm_adc_teardown_device(pdev, msm_adc);
  407. if (msm_adc->dev_h)
  408. msm_adc->dev_h = NULL;
  409. kfree(msm_adc);
  410. platform_set_drvdata(pdev, NULL);
  411. }
  412. /*
  413. * Process the deferred job
  414. */
  415. void msm_adc_wq_work(struct work_struct *work)
  416. {
  417. struct adc_properties *adc_properties;
  418. struct adc_conv_slot *slot = container_of(work,
  419. struct adc_conv_slot, work);
  420. uint32_t idx = slot->conv.result.chan;
  421. struct msm_adc_platform_data *pdata =
  422. msm_adc_drv->pdev->dev.platform_data;
  423. struct msm_adc_channels *channel = &pdata->channel[idx];
  424. int32_t adc_code;
  425. switch (slot->adc_request) {
  426. case START_OF_CONV:
  427. channel->adc_access_fn->adc_select_chan_and_start_conv(
  428. channel->adc_dev_instance, slot);
  429. break;
  430. case END_OF_CONV:
  431. adc_properties = channel->adc_access_fn->adc_get_properties(
  432. channel->adc_dev_instance);
  433. if (channel->adc_access_fn->adc_read_adc_code)
  434. channel->adc_access_fn->adc_read_adc_code(
  435. channel->adc_dev_instance, &adc_code);
  436. if (channel->chan_processor)
  437. channel->chan_processor(adc_code, adc_properties,
  438. &slot->chan_properties, &slot->conv.result);
  439. /* Intentionally a fall thru here. Calibraton does not need
  440. to perform channel processing, etc. However, both
  441. end of conversion and end of calibration requires the below
  442. fall thru code to be executed. */
  443. case END_OF_CALIBRATION:
  444. /* for blocking requests, signal complete */
  445. if (slot->blocking)
  446. complete(&slot->comp);
  447. else {
  448. struct msm_client_data *client = slot->client;
  449. mutex_lock(&client->lock);
  450. if (slot->adc_request == END_OF_CONV) {
  451. list_add(&slot->list, &client->complete_list);
  452. client->num_complete++;
  453. }
  454. client->num_outstanding--;
  455. /*
  456. * if the client release has been invoked and this is call
  457. * corresponds to the last request, then signal release
  458. * to complete.
  459. */
  460. if (slot->client->online == 0 &&
  461. client->num_outstanding == 0)
  462. wake_up_interruptible_all(&client->outst_wait);
  463. mutex_unlock(&client->lock);
  464. wake_up_interruptible_all(&client->data_wait);
  465. atomic_dec(&msm_adc_drv->total_outst);
  466. /* verify driver remove has not been invoked */
  467. if (atomic_read(&msm_adc_drv->online) == 0 &&
  468. atomic_read(&msm_adc_drv->total_outst) == 0)
  469. wake_up_interruptible_all(
  470. &msm_adc_drv->total_outst_wait);
  471. if (slot->compk) /* Kernel space request */
  472. complete(slot->compk);
  473. if (slot->adc_request == END_OF_CALIBRATION)
  474. channel->adc_access_fn->adc_restore_slot(
  475. channel->adc_dev_instance, slot);
  476. }
  477. break;
  478. case START_OF_CALIBRATION: /* code here to please code reviewers
  479. to satisfy silly compiler warnings */
  480. break;
  481. }
  482. }
  483. EXPORT_SYMBOL(msm_adc_wq_work);
  484. static struct sensor_device_attribute msm_adc_curr_in_attr =
  485. SENSOR_ATTR(NULL, S_IRUGO, msm_adc_show_curr, NULL, 0);
  486. static int __devinit msm_adc_init_hwmon(struct platform_device *pdev,
  487. struct msm_adc_drv *msm_adc)
  488. {
  489. struct msm_adc_platform_data *pdata = pdev->dev.platform_data;
  490. struct msm_adc_channels *channel = pdata->channel;
  491. int i, rc, num_chans = pdata->num_chan_supported;
  492. if (!channel)
  493. return -EINVAL;
  494. msm_adc->sens_attr = kzalloc(num_chans *
  495. sizeof(struct sensor_device_attribute), GFP_KERNEL);
  496. if (!msm_adc->sens_attr) {
  497. dev_err(&pdev->dev, "Unable to allocate memory\n");
  498. rc = -ENOMEM;
  499. goto hwmon_err_sens;
  500. }
  501. for (i = 0; i < num_chans; i++) {
  502. msm_adc_curr_in_attr.index = i;
  503. msm_adc_curr_in_attr.dev_attr.attr.name = channel[i].name;
  504. memcpy(&msm_adc->sens_attr[i], &msm_adc_curr_in_attr,
  505. sizeof(msm_adc_curr_in_attr));
  506. rc = device_create_file(&pdev->dev,
  507. &msm_adc->sens_attr[i].dev_attr);
  508. if (rc) {
  509. dev_err(&pdev->dev, "device_create_file failed for "
  510. "dal dev %s\n",
  511. channel[i].name);
  512. goto hwmon_err_sens;
  513. }
  514. }
  515. return 0;
  516. hwmon_err_sens:
  517. kfree(msm_adc->sens_attr);
  518. return rc;
  519. }
  520. static int __devinit msm_adc_probe(struct platform_device *pdev)
  521. {
  522. struct msm_adc_platform_data *pdata = pdev->dev.platform_data;
  523. struct msm_adc_drv *msm_adc;
  524. int rc = 0;
  525. if (!pdata) {
  526. dev_err(&pdev->dev, "no platform data?\n");
  527. return -EINVAL;
  528. }
  529. msm_adc = kzalloc(sizeof(struct msm_adc_drv), GFP_KERNEL);
  530. if (!msm_adc) {
  531. dev_err(&pdev->dev, "Unable to allocate memory\n");
  532. return -ENOMEM;
  533. }
  534. platform_set_drvdata(pdev, msm_adc);
  535. msm_adc_drv = msm_adc;
  536. msm_adc->pdev = pdev;
  537. rc = msm_adc_init_hwmon(pdev, msm_adc);
  538. if (rc) {
  539. dev_err(&pdev->dev, "msm_adc_dev_init failed\n");
  540. goto err_cleanup;
  541. }
  542. msm_adc->hwmon = hwmon_device_register(&pdev->dev);
  543. if (IS_ERR(msm_adc->hwmon)) {
  544. dev_err(&pdev->dev, "hwmon_device_register failed.\n");
  545. rc = PTR_ERR(msm_adc->hwmon);
  546. goto err_cleanup;
  547. }
  548. msm_adc->misc.name = MSM_ADC_DRIVER_NAME;
  549. msm_adc->misc.minor = MISC_DYNAMIC_MINOR;
  550. msm_adc->misc.fops = &msm_adc_fops;
  551. if (misc_register(&msm_adc->misc)) {
  552. dev_err(&pdev->dev, "Unable to register misc device!\n");
  553. goto err_cleanup;
  554. }
  555. init_waitqueue_head(&msm_adc->total_outst_wait);
  556. atomic_set(&msm_adc->online, 1);
  557. atomic_set(&msm_adc->total_outst, 0);
  558. msm_adc->wq = create_singlethread_workqueue("msm_adc");
  559. if (!msm_adc->wq)
  560. goto err_cleanup;
  561. pr_info("msm_adc successfully registered\n");
  562. return 0;
  563. err_cleanup:
  564. msm_adc_teardown(pdev);
  565. return rc;
  566. }
  567. static int __devexit msm_adc_remove(struct platform_device *pdev)
  568. {
  569. int rc;
  570. struct msm_adc_drv *msm_adc = platform_get_drvdata(pdev);
  571. atomic_set(&msm_adc->online, 0);
  572. misc_deregister(&msm_adc->misc);
  573. hwmon_device_unregister(msm_adc->hwmon);
  574. msm_adc->hwmon = NULL;
  575. /*
  576. * We may still have outstanding transactions in flight that have not
  577. * completed. Make sure they're completed before tearing down.
  578. */
  579. rc = wait_event_interruptible(msm_adc->total_outst_wait,
  580. atomic_read(&msm_adc->total_outst) == 0);
  581. if (rc) {
  582. pr_err("%s: wait_event_interruptible failed rc = %d\n",
  583. __func__, rc);
  584. return rc;
  585. }
  586. msm_adc_teardown(pdev);
  587. pr_info("msm_adc unregistered\n");
  588. return 0;
  589. }
  590. static struct platform_driver msm_adc_driver = {
  591. .probe = msm_adc_probe,
  592. .remove = __devexit_p(msm_adc_remove),
  593. .driver = {
  594. .name = MSM_ADC_DRIVER_NAME,
  595. .owner = THIS_MODULE,
  596. },
  597. };
  598. static int __init msm_adc_init(void)
  599. {
  600. return platform_driver_register(&msm_adc_driver);
  601. }
  602. module_init(msm_adc_init);
  603. static void __exit msm_adc_exit(void)
  604. {
  605. platform_driver_unregister(&msm_adc_driver);
  606. }
  607. module_exit(msm_adc_exit);
  608. MODULE_DESCRIPTION("MSM ADC Driver");
  609. MODULE_ALIAS("platform:msm_adc");
  610. MODULE_LICENSE("GPL v2");
  611. MODULE_VERSION("0.1");
  612. int32_t adc_channel_open(uint32_t channel, void **h)
  613. {
  614. struct msm_client_data *client;
  615. struct msm_adc_drv *msm_adc = msm_adc_drv;
  616. struct msm_adc_platform_data *pdata;
  617. struct platform_device *pdev;
  618. int i = 0, rc;
  619. if (!msm_adc_drv)
  620. return -EFAULT;
  621. rc = pm8058_xoadc_registered();
  622. if (rc <= 0)
  623. return -ENODEV;
  624. pdata = msm_adc->pdev->dev.platform_data;
  625. pdev = msm_adc->pdev;
  626. while (i < pdata->num_chan_supported) {
  627. if (channel == pdata->channel[i].channel_name)
  628. break;
  629. else
  630. i++;
  631. }
  632. if (i == pdata->num_chan_supported)
  633. return -EBADF; /* unknown channel */
  634. client = kzalloc(sizeof(struct msm_client_data), GFP_KERNEL);
  635. if (!client) {
  636. dev_err(&pdev->dev, "Unable to allocate memory\n");
  637. return -ENOMEM;
  638. }
  639. if (!try_module_get(THIS_MODULE)) {
  640. kfree(client);
  641. return -EACCES;
  642. }
  643. mutex_init(&client->lock);
  644. INIT_LIST_HEAD(&client->complete_list);
  645. init_waitqueue_head(&client->data_wait);
  646. init_waitqueue_head(&client->outst_wait);
  647. client->online = 1;
  648. client->adc_chan = i;
  649. *h = (void *)client;
  650. return 0;
  651. }
  652. int32_t adc_channel_close(void *h)
  653. {
  654. struct msm_client_data *client = (struct msm_client_data *)h;
  655. kfree(client);
  656. return 0;
  657. }
  658. int32_t adc_channel_request_conv(void *h, struct completion *conv_complete_evt)
  659. {
  660. struct msm_client_data *client = (struct msm_client_data *)h;
  661. struct msm_adc_platform_data *pdata =
  662. msm_adc_drv->pdev->dev.platform_data;
  663. struct msm_adc_channels *channel = &pdata->channel[client->adc_chan];
  664. struct adc_conv_slot *slot;
  665. int ret;
  666. if (!conv_first_request) {
  667. ret = pm8058_xoadc_calib_device(channel->adc_dev_instance);
  668. if (ret) {
  669. pr_err("pm8058 xoadc calibration failed, retry\n");
  670. return ret;
  671. }
  672. conv_first_request = 1;
  673. }
  674. channel->adc_access_fn->adc_slot_request(channel->adc_dev_instance,
  675. &slot);
  676. if (slot) {
  677. atomic_inc(&msm_adc_drv->total_outst);
  678. mutex_lock(&client->lock);
  679. client->num_outstanding++;
  680. mutex_unlock(&client->lock);
  681. slot->conv.result.chan = client->adc_chan;
  682. slot->blocking = 0;
  683. slot->compk = conv_complete_evt;
  684. slot->client = client;
  685. slot->adc_request = START_OF_CONV;
  686. slot->chan_path = channel->chan_path_type;
  687. slot->chan_adc_config = channel->adc_config_type;
  688. slot->chan_adc_calib = channel->adc_calib_type;
  689. queue_work(msm_adc_drv->wq, &slot->work);
  690. return 0;
  691. }
  692. return -EBUSY;
  693. }
  694. int32_t adc_channel_read_result(void *h, struct adc_chan_result *chan_result)
  695. {
  696. struct msm_client_data *client = (struct msm_client_data *)h;
  697. struct msm_adc_platform_data *pdata =
  698. msm_adc_drv->pdev->dev.platform_data;
  699. struct msm_adc_channels *channel = pdata->channel;
  700. struct adc_conv_slot *slot;
  701. int rc = 0;
  702. mutex_lock(&client->lock);
  703. slot = list_first_entry(&client->complete_list,
  704. struct adc_conv_slot, list);
  705. if (!slot) {
  706. mutex_unlock(&client->lock);
  707. return -ENOMSG;
  708. }
  709. slot->client = NULL;
  710. list_del(&slot->list);
  711. client->num_complete--;
  712. mutex_unlock(&client->lock);
  713. *chan_result = slot->conv.result;
  714. /* restore this slot to reserve */
  715. channel[slot->conv.result.chan].adc_access_fn->adc_restore_slot(
  716. channel[slot->conv.result.chan].adc_dev_instance, slot);
  717. return rc;
  718. }
  719. int32_t adc_calib_request(void *h, struct completion *calib_complete_evt)
  720. {
  721. struct msm_client_data *client = (struct msm_client_data *)h;
  722. struct msm_adc_platform_data *pdata =
  723. msm_adc_drv->pdev->dev.platform_data;
  724. struct msm_adc_channels *channel = &pdata->channel[client->adc_chan];
  725. struct adc_conv_slot *slot;
  726. int rc, calib_status;
  727. channel->adc_access_fn->adc_slot_request(channel->adc_dev_instance,
  728. &slot);
  729. if (slot) {
  730. slot->conv.result.chan = client->adc_chan;
  731. slot->blocking = 0;
  732. slot->compk = calib_complete_evt;
  733. slot->adc_request = START_OF_CALIBRATION;
  734. slot->chan_path = channel->chan_path_type;
  735. slot->chan_adc_config = channel->adc_config_type;
  736. slot->chan_adc_calib = channel->adc_calib_type;
  737. rc = channel->adc_access_fn->adc_calibrate(
  738. channel->adc_dev_instance, slot, &calib_status);
  739. if (calib_status == CALIB_NOT_REQUIRED) {
  740. channel->adc_access_fn->adc_restore_slot(
  741. channel->adc_dev_instance, slot);
  742. /* client will always wait in case when
  743. calibration is not required */
  744. complete(calib_complete_evt);
  745. } else {
  746. atomic_inc(&msm_adc_drv->total_outst);
  747. mutex_lock(&client->lock);
  748. client->num_outstanding++;
  749. mutex_unlock(&client->lock);
  750. }
  751. return rc;
  752. }
  753. return -EBUSY;
  754. }