blob: 42bcd07731cdba176258895a56d9ee81b750213b [file] [log] [blame]
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001/* 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
13#include <linux/kernel.h>
14#include <linux/init.h>
15#include <linux/mutex.h>
16#include <linux/platform_device.h>
17#include <linux/err.h>
18#include <linux/hwmon.h>
19#include <linux/hwmon-sysfs.h>
20#include <linux/miscdevice.h>
21#include <linux/fs.h>
22#include <linux/sched.h>
23#include <linux/wait.h>
24#include <linux/uaccess.h>
25#include <linux/msm_adc.h>
26#include <linux/pmic8058-xoadc.h>
27#include <linux/slab.h>
28#include <linux/semaphore.h>
29
30#include <mach/dal.h>
31
32#define MSM_ADC_DRIVER_NAME "msm_adc"
33#define MSM_ADC_MAX_FNAME 15
34
35#define MSM_ADC_DALRPC_DEVICEID 0x02000067
36#define MSM_ADC_DALRPC_PORT_NAME "DAL00"
37#define MSM_ADC_DALRPC_CPU SMD_APPS_MODEM
38
39#define MSM_ADC_DALRPC_CMD_REQ_CONV 9
40#define MSM_ADC_DALRPC_CMD_INPUT_PROP 11
41
42#define MSM_ADC_DALRC_CONV_TIMEOUT (5 * HZ) /* 5 seconds */
43
44enum dal_error {
45 DAL_ERROR_INVALID_DEVICE_IDX = 1,
46 DAL_ERROR_INVALID_CHANNEL_IDX,
47 DAL_ERROR_NULL_POINTER,
48 DAL_ERROR_DEVICE_QUEUE_FULL,
49 DAL_ERROR_INVALID_PROPERTY_LENGTH,
50 DAL_ERROR_REMOTE_EVENT_POOL_FULL
51};
52
53enum dal_result_status {
54 DAL_RESULT_STATUS_INVALID,
55 DAL_RESULT_STATUS_VALID
56};
57
58struct dal_conv_state {
59 struct dal_conv_slot context[MSM_ADC_DEV_MAX_INFLIGHT];
60 struct list_head slots;
61 struct mutex list_lock;
62 struct semaphore slot_count;
63};
64
65struct adc_dev {
66 char *name;
67 uint32_t nchans;
68 struct dal_conv_state conv;
69 struct dal_translation transl;
70 struct sensor_device_attribute *sens_attr;
71 char **fnames;
72};
73
74struct msm_adc_drv {
75 /* Common to both XOADC and EPM */
76 struct platform_device *pdev;
77 struct device *hwmon;
78 struct miscdevice misc;
79 /* XOADC variables */
80 struct sensor_device_attribute *sens_attr;
81 struct workqueue_struct *wq;
82 atomic_t online;
83 atomic_t total_outst;
84 wait_queue_head_t total_outst_wait;
85
86 /* EPM variables */
87 void *dev_h;
88 struct adc_dev *devs[MSM_ADC_MAX_NUM_DEVS];
89 struct mutex prop_lock;
90 atomic_t rpc_online;
91 atomic_t rpc_total_outst;
92 wait_queue_head_t rpc_total_outst_wait;
93};
94
95static bool epm_init;
96static bool epm_fluid_enabled;
97
98/* Needed to support file_op interfaces */
99static struct msm_adc_drv *msm_adc_drv;
100
101static ssize_t msm_adc_show_curr(struct device *dev,
102 struct device_attribute *devattr, char *buf);
103
104static int msm_rpc_adc_blocking_conversion(struct msm_adc_drv *msm_adc,
105 uint32_t chan, struct adc_chan_result *result);
106
107static int msm_adc_blocking_conversion(struct msm_adc_drv *msm_adc,
108 uint32_t chan, struct adc_chan_result *result);
109
110static int msm_adc_open(struct inode *inode, struct file *file)
111{
112 struct msm_client_data *client;
113 struct msm_adc_drv *msm_adc = msm_adc_drv;
114 struct platform_device *pdev = msm_adc->pdev;
115
116 client = kzalloc(sizeof(struct msm_client_data), GFP_KERNEL);
117 if (!client) {
118 dev_err(&pdev->dev, "Unable to allocate memory\n");
119 return -ENOMEM;
120 }
121
122 if (!try_module_get(THIS_MODULE)) {
123 kfree(client);
124 return -EACCES;
125 }
126
127 mutex_init(&client->lock);
128 INIT_LIST_HEAD(&client->complete_list);
129 init_waitqueue_head(&client->data_wait);
130 init_waitqueue_head(&client->outst_wait);
131
132 client->online = 1;
133
134 file->private_data = client;
135
136 return nonseekable_open(inode, file);
137}
138
139static inline void msm_adc_restore_slot(struct dal_conv_state *conv_s,
140 struct dal_conv_slot *slot)
141{
142 mutex_lock(&conv_s->list_lock);
143 list_add(&slot->list, &conv_s->slots);
144 mutex_unlock(&conv_s->list_lock);
145
146 up(&conv_s->slot_count);
147}
148
149static int no_pending_client_requests(struct msm_client_data *client)
150{
151 mutex_lock(&client->lock);
152
153 if (client->num_outstanding == 0) {
154 mutex_unlock(&client->lock);
155 return 1;
156 }
157
158 mutex_unlock(&client->lock);
159
160 return 0;
161}
162
163static int data_avail(struct msm_client_data *client, uint32_t *pending)
164{
165 uint32_t completed;
166
167 mutex_lock(&client->lock);
168 completed = client->num_complete;
169 mutex_unlock(&client->lock);
170
171 if (completed > 0) {
172 if (pending != NULL)
173 *pending = completed;
174 return 1;
175 }
176
177 return 0;
178}
179
180static int msm_adc_release(struct inode *inode, struct file *file)
181{
182 struct msm_client_data *client = file->private_data;
183 struct adc_conv_slot *slot, *tmp;
184 int rc;
185 struct msm_adc_platform_data *pdata =
186 msm_adc_drv->pdev->dev.platform_data;
187 struct msm_adc_channels *channel = pdata->channel;
188
189 module_put(THIS_MODULE);
190
191 mutex_lock(&client->lock);
192
193 /* prevent any further requests while we teardown the client */
194 client->online = 0;
195
196 mutex_unlock(&client->lock);
197
198 /*
199 * We may still have outstanding transactions in flight from this
200 * client that have not completed. Make sure they're completed
201 * before removing the client.
202 */
203 rc = wait_event_interruptible(client->outst_wait,
204 no_pending_client_requests(client));
205 if (rc) {
206 pr_err("%s: wait_event_interruptible failed rc = %d\n",
207 __func__, rc);
208 return rc;
209 }
210
211 /*
212 * All transactions have completed. Add slot resources back to the
213 * appropriate devices.
214 */
215 list_for_each_entry_safe(slot, tmp, &client->complete_list, list) {
216 slot->client = NULL;
217 list_del(&slot->list);
218 channel[slot->conv.result.chan].adc_access_fn->adc_restore_slot(
219 channel[slot->conv.result.chan].adc_dev_instance, slot);
220 }
221
222 kfree(client);
223
224 return 0;
225}
226
227static int msm_adc_translate_dal_to_hwmon(struct msm_adc_drv *msm_adc,
228 uint32_t chan,
229 struct adc_dev_spec *dest)
230{
231 struct dal_translation *transl;
232 struct msm_adc_platform_data *pdata = msm_adc->pdev->dev.platform_data;
233 int i;
234
235 for (i = 0; i < pdata->num_adc; i++) {
236 transl = &msm_adc->devs[i]->transl;
237 if (chan >= transl->hwmon_start &&
238 chan <= transl->hwmon_end) {
239 dest->dal.dev_idx = transl->dal_dev_idx;
240 dest->hwmon_dev_idx = transl->hwmon_dev_idx;
241 dest->dal.chan_idx = chan - transl->hwmon_start;
242 return 0;
243 }
244 }
245 return -EINVAL;
246}
247
248static int msm_adc_translate_hwmon_to_dal(struct msm_adc_drv *msm_adc,
249 struct adc_dev_spec *source,
250 uint32_t *chan)
251{
252 struct msm_adc_platform_data *pdata = msm_adc->pdev->dev.platform_data;
253 struct dal_translation *transl;
254 int i;
255
256 for (i = 0; i < pdata->num_adc; i++) {
257 transl = &msm_adc->devs[i]->transl;
258 if (source->dal.dev_idx != transl->dal_dev_idx)
259 continue;
260 *chan = transl->hwmon_start + source->dal.chan_idx;
261 return 0;
262 }
263 return -EINVAL;
264}
265
266static int msm_adc_getinputproperties(struct msm_adc_drv *msm_adc,
267 const char *lookup_name,
268 struct adc_dev_spec *result)
269{
270 struct device *dev = &msm_adc->pdev->dev;
271 int rc;
272
273 mutex_lock(&msm_adc->prop_lock);
274
275 rc = dalrpc_fcn_8(MSM_ADC_DALRPC_CMD_INPUT_PROP, msm_adc->dev_h,
276 lookup_name, strlen(lookup_name) + 1,
277 &result->dal, sizeof(struct dal_dev_spec));
278 if (rc) {
279 dev_err(dev, "DAL getprop request failed: rc = %d\n", rc);
280 mutex_unlock(&msm_adc->prop_lock);
281 return -EIO;
282 }
283
284 mutex_unlock(&msm_adc->prop_lock);
285 return rc;
286}
287
288static int msm_adc_lookup(struct msm_adc_drv *msm_adc,
289 struct msm_adc_lookup *lookup)
290{
291 struct msm_adc_platform_data *pdata = msm_adc->pdev->dev.platform_data;
292 struct adc_dev_spec target;
293 int rc = 0, i = 0;
294 uint32_t len = 0;
295
296 len = strnlen(lookup->name, MSM_ADC_MAX_CHAN_STR);
297 while (i < pdata->num_chan_supported) {
298 if (strncmp(lookup->name, pdata->channel[i].name, len))
299 i++;
300 else
301 break;
302 }
303
304 if (pdata->num_chan_supported > 0 && i < pdata->num_chan_supported) {
305 lookup->chan_idx = i;
306 } else if (msm_adc->dev_h) {
307 rc = msm_adc_getinputproperties(msm_adc, lookup->name, &target);
308 if (rc) {
309 pr_err("%s: Lookup failed for %s\n", __func__,
310 lookup->name);
311 return rc;
312 }
313 rc = msm_adc_translate_hwmon_to_dal(msm_adc, &target,
314 &lookup->chan_idx);
315 if (rc)
316 pr_err("%s: Translation failed for %s\n", __func__,
317 lookup->name);
318 } else {
319 pr_err("%s: Lookup failed for %s\n", __func__, lookup->name);
320 rc = -EINVAL;
321 }
322 return rc;
323}
324
325static int msm_adc_aio_conversion(struct msm_adc_drv *msm_adc,
326 struct adc_chan_result *request,
327 struct msm_client_data *client)
328{
329 struct msm_adc_platform_data *pdata =
330 msm_adc_drv->pdev->dev.platform_data;
331 struct msm_adc_channels *channel = &pdata->channel[request->chan];
332 struct adc_conv_slot *slot;
333
334 /* we could block here, but only for a bounded time */
335 channel->adc_access_fn->adc_slot_request(channel->adc_dev_instance,
336 &slot);
337
338 if (slot) {
339 atomic_inc(&msm_adc->total_outst);
340 mutex_lock(&client->lock);
341 client->num_outstanding++;
342 mutex_unlock(&client->lock);
343
344 /* indicates non blocking request to callback handler */
345 slot->blocking = 0;
346 slot->compk = NULL;/*For kernel space usage; n/a for usr space*/
347 slot->conv.result.chan = client->adc_chan = request->chan;
348 slot->client = client;
349 slot->adc_request = START_OF_CONV;
350 slot->chan_path = channel->chan_path_type;
351 slot->chan_adc_config = channel->adc_config_type;
352 slot->chan_adc_calib = channel->adc_calib_type;
353 queue_work(msm_adc->wq, &slot->work);
354 return 0;
355 }
356 return -EBUSY;
357}
358
359static int msm_adc_fluid_hw_deinit(struct msm_adc_drv *msm_adc)
360{
361 struct msm_adc_platform_data *pdata = msm_adc->pdev->dev.platform_data;
362
363 if (!epm_init)
364 return -EINVAL;
365
366 if (pdata->gpio_config == APROC_CONFIG &&
367 epm_fluid_enabled && pdata->adc_fluid_disable != NULL) {
368 pdata->adc_fluid_disable();
369 epm_fluid_enabled = false;
370 }
371
372 return 0;
373}
374
375static int msm_adc_fluid_hw_init(struct msm_adc_drv *msm_adc)
376{
377 struct msm_adc_platform_data *pdata = msm_adc->pdev->dev.platform_data;
378
379 if (!epm_init)
380 return -EINVAL;
381
382 if (!pdata->adc_fluid_enable)
383 return -ENODEV;
384
385 printk(KERN_DEBUG "msm_adc_fluid_hw_init: Calling adc_fluid_enable.\n");
386
387 if (pdata->gpio_config == APROC_CONFIG && !epm_fluid_enabled) {
388 pdata->adc_fluid_enable();
389 epm_fluid_enabled = true;
390 }
391
392 /* return success for now but check for errors from hw init configuration */
393 return 0;
394}
395
396static int msm_adc_poll_complete(struct msm_adc_drv *msm_adc,
397 struct msm_client_data *client, uint32_t *pending)
398{
399 int rc;
400
401 /*
402 * Don't proceed if there there's nothing queued on this client.
403 * We could deadlock otherwise in a single threaded scenario.
404 */
405 if (no_pending_client_requests(client) && !data_avail(client, pending))
406 return -EDEADLK;
407
408 rc = wait_event_interruptible(client->data_wait,
409 data_avail(client, pending));
410 if (rc)
411 return rc;
412
413 return 0;
414}
415
416static int msm_adc_read_result(struct msm_adc_drv *msm_adc,
417 struct msm_client_data *client,
418 struct adc_chan_result *result)
419{
420 struct msm_adc_platform_data *pdata = msm_adc->pdev->dev.platform_data;
421 struct msm_adc_channels *channel = pdata->channel;
422 struct adc_conv_slot *slot;
423 int rc = 0;
424
425 mutex_lock(&client->lock);
426
427 slot = list_first_entry(&client->complete_list,
428 struct adc_conv_slot, list);
429 if (!slot) {
430 mutex_unlock(&client->lock);
431 return -ENOMSG;
432 }
433
434 slot->client = NULL;
435 list_del(&slot->list);
436
437 client->num_complete--;
438
439 mutex_unlock(&client->lock);
440
441 *result = slot->conv.result;
442
443 /* restore this slot to reserve */
444 channel[slot->conv.result.chan].adc_access_fn->adc_restore_slot(
445 channel[slot->conv.result.chan].adc_dev_instance, slot);
446
447 return rc;
448}
449
450static long msm_adc_ioctl(struct file *file, unsigned int cmd,
451 unsigned long arg)
452{
453 struct msm_client_data *client = file->private_data;
454 struct msm_adc_drv *msm_adc = msm_adc_drv;
455 struct platform_device *pdev = msm_adc->pdev;
456 struct msm_adc_platform_data *pdata = pdev->dev.platform_data;
457 uint32_t block_res = 0;
458
459 int rc;
460
461 switch (cmd) {
462 case MSM_ADC_REQUEST:
463 {
464 struct adc_chan_result conv;
465
466 if (copy_from_user(&conv, (void __user *)arg,
467 sizeof(struct adc_chan_result)))
468 return -EFAULT;
469
470 if (conv.chan < pdata->num_chan_supported) {
471 rc = msm_adc_blocking_conversion(msm_adc,
472 conv.chan, &conv);
473 } else {
474 if (!msm_adc->dev_h)
475 return -EAGAIN;
476
477 rc = msm_rpc_adc_blocking_conversion(msm_adc,
478 conv.chan, &conv);
479 }
480 if (rc) {
481 dev_dbg(&pdev->dev, "BLK conversion failed\n");
482 return rc;
483 }
484
485 if (copy_to_user((void __user *)arg, &conv,
486 sizeof(struct adc_chan_result)))
487 return -EFAULT;
488 break;
489 }
490 case MSM_ADC_AIO_REQUEST_BLOCK_RES:
491 block_res = 1;
492 case MSM_ADC_AIO_REQUEST:
493 {
494 struct adc_chan_result conv;
495
496 if (copy_from_user(&conv, (void __user *)arg,
497 sizeof(struct adc_chan_result)))
498 return -EFAULT;
499
500 if (conv.chan >= pdata->num_chan_supported)
501 return -EINVAL;
502
503 rc = msm_adc_aio_conversion(msm_adc, &conv, client);
504 if (rc) {
505 dev_dbg(&pdev->dev, "AIO conversion failed\n");
506 return rc;
507 }
508 if (copy_to_user((void __user *)arg, &conv,
509 sizeof(struct adc_chan_result)))
510 return -EFAULT;
511 break;
512 }
513 case MSM_ADC_AIO_POLL:
514 {
515 uint32_t completed;
516
517 rc = msm_adc_poll_complete(msm_adc, client, &completed);
518 if (rc) {
519 dev_dbg(&pdev->dev, "poll request failed\n");
520 return rc;
521 }
522
523 if (copy_to_user((void __user *)arg, &completed,
524 sizeof(uint32_t)))
525 return -EFAULT;
526
527 break;
528 }
529 case MSM_ADC_AIO_READ:
530 {
531 struct adc_chan_result result;
532
533 rc = msm_adc_read_result(msm_adc, client, &result);
534 if (rc) {
535 dev_dbg(&pdev->dev, "read result failed\n");
536 return rc;
537 }
538
539 if (copy_to_user((void __user *)arg, &result,
540 sizeof(struct adc_chan_result)))
541 return -EFAULT;
542 break;
543 }
544 case MSM_ADC_LOOKUP:
545 {
546 struct msm_adc_lookup lookup;
547
548 if (copy_from_user(&lookup, (void __user *)arg,
549 sizeof(struct msm_adc_lookup)))
550 return -EFAULT;
551
552 rc = msm_adc_lookup(msm_adc, &lookup);
553 if (rc) {
554 dev_dbg(&pdev->dev, "No such channel: %s\n",
555 lookup.name);
556 return rc;
557 }
558
559 if (copy_to_user((void __user *)arg, &lookup,
560 sizeof(struct msm_adc_lookup)))
561 return -EFAULT;
562 break;
563 }
564 case MSM_ADC_FLUID_INIT:
565 {
566 uint32_t result;
567
568 result = msm_adc_fluid_hw_init(msm_adc);
569
570 if (copy_to_user((void __user *)arg, &result,
571 sizeof(uint32_t))) {
572 printk(KERN_ERR "MSM_ADC_FLUID_INIT: "
573 "copy_to_user returned an error.\n");
574 return -EFAULT;
575 }
576 printk(KERN_DEBUG "MSM_ADC_FLUID_INIT: Success.\n");
577 break;
578 }
579 case MSM_ADC_FLUID_DEINIT:
580 {
581 uint32_t result;
582
583 result = msm_adc_fluid_hw_deinit(msm_adc);
584
585 if (copy_to_user((void __user *)arg, &result,
586 sizeof(uint32_t)))
587 return -EFAULT;
588 break;
589 }
590 default:
591 return -EINVAL;
592 }
593
594 return 0;
595}
596
597const struct file_operations msm_adc_fops = {
598 .open = msm_adc_open,
599 .release = msm_adc_release,
600 .unlocked_ioctl = msm_adc_ioctl,
601};
602
603static ssize_t msm_adc_show_curr(struct device *dev,
604 struct device_attribute *devattr, char *buf)
605{
606 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
607 struct msm_adc_drv *msm_adc = dev_get_drvdata(dev);
608 struct msm_adc_platform_data *pdata = msm_adc->pdev->dev.platform_data;
609 struct adc_chan_result result;
610 int rc;
611
612#ifdef CONFIG_PMIC8058_XOADC
613 rc = pm8058_xoadc_registered();
614 if (rc <= 0)
615 return -ENODEV;
616#endif
617 if (attr->index < pdata->num_chan_supported) {
618 rc = msm_adc_blocking_conversion(msm_adc,
619 attr->index, &result);
620 } else {
621 if (pdata->gpio_config == APROC_CONFIG && !epm_fluid_enabled
622 && pdata->adc_fluid_enable != NULL) {
623 printk(KERN_DEBUG "This is to read ADC value for "
624 "Fluid EPM and init. Do it only once.\n");
625 pdata->adc_fluid_enable();
626 epm_fluid_enabled = true;
627 }
628 rc = msm_rpc_adc_blocking_conversion(msm_adc,
629 attr->index, &result);
630 }
631 if (rc)
632 return 0;
633
634 return sprintf(buf, "Result: %lld Raw: %d\n", result.physical,
635 result.adc_code);
636}
637
638static int msm_rpc_adc_blocking_conversion(struct msm_adc_drv *msm_adc,
639 uint32_t hwmon_chan, struct adc_chan_result *result)
640{
641 struct msm_adc_platform_data *pdata = msm_adc->pdev->dev.platform_data;
642 struct dal_conv_request params;
643 struct device *dev = &msm_adc->pdev->dev;
644 struct adc_dev *adc_dev;
645 struct dal_conv_state *conv_s;
646 struct dal_conv_slot *slot;
647 struct adc_dev_spec dest;
648 int timeout, rc = 0;
649
650 if (pdata->gpio_config == APROC_CONFIG &&
651 pdata->adc_gpio_enable != NULL)
652 pdata->adc_gpio_enable(hwmon_chan-pdata->num_chan_supported);
653
654 rc = msm_adc_translate_dal_to_hwmon(msm_adc, hwmon_chan, &dest);
655 if (rc) {
656 dev_err(dev, "%s: translation from chan %u failed\n",
657 __func__, hwmon_chan);
658 if (pdata->gpio_config == APROC_CONFIG &&
659 pdata->adc_gpio_disable != NULL)
660 pdata->adc_gpio_disable(hwmon_chan
661 -pdata->num_chan_supported);
662 return -EINVAL;
663 }
664
665 adc_dev = msm_adc->devs[dest.hwmon_dev_idx];
666 conv_s = &adc_dev->conv;
667
668 down(&conv_s->slot_count);
669
670 mutex_lock(&conv_s->list_lock);
671
672 slot = list_first_entry(&conv_s->slots, struct dal_conv_slot, list);
673 list_del(&slot->list);
674 BUG_ON(!slot);
675
676 mutex_unlock(&conv_s->list_lock);
677
678 /* indicates blocking request to callback handler */
679 slot->blocking = 1;
680
681 params.target.dev_idx = dest.dal.dev_idx;
682 params.target.chan_idx = dest.dal.chan_idx;
683 params.cb_h = slot->cb_h;
684
685 rc = dalrpc_fcn_8(MSM_ADC_DALRPC_CMD_REQ_CONV, msm_adc->dev_h,
686 &params, sizeof(params), NULL, 0);
687 if (rc) {
688 dev_err(dev, "%s: Conversion for device = %u channel = %u"
689 " failed\n", __func__, params.target.dev_idx,
690 params.target.chan_idx);
691
692 rc = -EIO;
693 goto blk_conv_err;
694 }
695
696 timeout = wait_for_completion_interruptible_timeout(&slot->comp,
697 MSM_ADC_DALRC_CONV_TIMEOUT);
698 if (timeout == 0) {
699 dev_err(dev, "read for device = %u channel = %u timed out\n",
700 params.target.dev_idx, params.target.chan_idx);
701 rc = -ETIMEDOUT;
702 goto blk_conv_err;
703 } else if (timeout < 0) {
704 rc = -EINTR;
705 goto blk_conv_err;
706 }
707
708 result->physical = (int64_t)slot->result.physical;
709
710 if (slot->result.status == DAL_RESULT_STATUS_INVALID)
711 rc = -ENODATA;
712
713blk_conv_err:
714 if (pdata->gpio_config == APROC_CONFIG &&
715 pdata->adc_gpio_disable != NULL)
716 pdata->adc_gpio_disable(hwmon_chan-pdata->num_chan_supported);
717 msm_adc_restore_slot(conv_s, slot);
718
719 return rc;
720}
721
722static int msm_adc_blocking_conversion(struct msm_adc_drv *msm_adc,
723 uint32_t hwmon_chan, struct adc_chan_result *result)
724{
725 struct adc_conv_slot *slot;
726 struct msm_adc_platform_data *pdata =
727 msm_adc_drv->pdev->dev.platform_data;
728 struct msm_adc_channels *channel = &pdata->channel[hwmon_chan];
729
730 channel->adc_access_fn->adc_slot_request(channel->adc_dev_instance,
731 &slot);
732 if (slot) {
733 slot->conv.result.chan = hwmon_chan;
734 /* indicates blocking request to callback handler */
735 slot->blocking = 1;
736 slot->adc_request = START_OF_CONV;
737 slot->chan_path = channel->chan_path_type;
738 slot->chan_adc_config = channel->adc_config_type;
739 slot->chan_adc_calib = channel->adc_calib_type;
740 queue_work(msm_adc_drv->wq, &slot->work);
741
742 wait_for_completion_interruptible(&slot->comp);
743 *result = slot->conv.result;
744 channel->adc_access_fn->adc_restore_slot(
745 channel->adc_dev_instance, slot);
746 return 0;
747 }
748 return -EBUSY;
749}
750
751int32_t adc_channel_open(uint32_t channel, void **h)
752{
753 struct msm_client_data *client;
754 struct msm_adc_drv *msm_adc = msm_adc_drv;
755 struct msm_adc_platform_data *pdata;
756 struct platform_device *pdev;
757 int i = 0;
758
759 if (!msm_adc_drv)
760 return -EFAULT;
761
762#ifdef CONFIG_PMIC8058_XOADC
763 if (pm8058_xoadc_registered() <= 0)
764 return -ENODEV;
765#endif
766 pdata = msm_adc->pdev->dev.platform_data;
767 pdev = msm_adc->pdev;
768
769 while (i < pdata->num_chan_supported) {
770 if (channel == pdata->channel[i].channel_name)
771 break;
772 else
773 i++;
774 }
775
776 if (i == pdata->num_chan_supported)
777 return -EBADF; /* unknown channel */
778
779 client = kzalloc(sizeof(struct msm_client_data), GFP_KERNEL);
780 if (!client) {
781 dev_err(&pdev->dev, "Unable to allocate memory\n");
782 return -ENOMEM;
783 }
784
785 if (!try_module_get(THIS_MODULE)) {
786 kfree(client);
787 return -EACCES;
788 }
789
790 mutex_init(&client->lock);
791 INIT_LIST_HEAD(&client->complete_list);
792 init_waitqueue_head(&client->data_wait);
793 init_waitqueue_head(&client->outst_wait);
794
795 client->online = 1;
796 client->adc_chan = i;
797 *h = (void *)client;
798 return 0;
799}
800
801int32_t adc_channel_close(void *h)
802{
803 struct msm_client_data *client = (struct msm_client_data *)h;
804
805 kfree(client);
806 return 0;
807}
808
809int32_t adc_channel_request_conv(void *h, struct completion *conv_complete_evt)
810{
811 struct msm_client_data *client = (struct msm_client_data *)h;
812 struct msm_adc_platform_data *pdata =
813 msm_adc_drv->pdev->dev.platform_data;
814 struct msm_adc_channels *channel = &pdata->channel[client->adc_chan];
815 struct adc_conv_slot *slot;
816
817 channel->adc_access_fn->adc_slot_request(channel->adc_dev_instance,
818 &slot);
819
820 if (slot) {
821 atomic_inc(&msm_adc_drv->total_outst);
822 mutex_lock(&client->lock);
823 client->num_outstanding++;
824 mutex_unlock(&client->lock);
825
826 slot->conv.result.chan = client->adc_chan;
827 slot->blocking = 0;
828 slot->compk = conv_complete_evt;
829 slot->client = client;
830 slot->adc_request = START_OF_CONV;
831 slot->chan_path = channel->chan_path_type;
832 slot->chan_adc_config = channel->adc_config_type;
833 slot->chan_adc_calib = channel->adc_calib_type;
834 queue_work(msm_adc_drv->wq, &slot->work);
835 return 0;
836 }
837 return -EBUSY;
838}
839
840int32_t adc_channel_read_result(void *h, struct adc_chan_result *chan_result)
841{
842 struct msm_client_data *client = (struct msm_client_data *)h;
843 struct msm_adc_platform_data *pdata =
844 msm_adc_drv->pdev->dev.platform_data;
845 struct msm_adc_channels *channel = pdata->channel;
846 struct adc_conv_slot *slot;
847 int rc = 0;
848
849 mutex_lock(&client->lock);
850
851 slot = list_first_entry(&client->complete_list,
852 struct adc_conv_slot, list);
853 if (!slot) {
854 mutex_unlock(&client->lock);
855 return -ENOMSG;
856 }
857
858 slot->client = NULL;
859 list_del(&slot->list);
860
861 client->num_complete--;
862
863 mutex_unlock(&client->lock);
864
865 *chan_result = slot->conv.result;
866
867 /* restore this slot to reserve */
868 channel[slot->conv.result.chan].adc_access_fn->adc_restore_slot(
869 channel[slot->conv.result.chan].adc_dev_instance, slot);
870
871 return rc;
872}
873
874int32_t adc_calib_request(void *h, struct completion *calib_complete_evt)
875{
876 struct msm_client_data *client = (struct msm_client_data *)h;
877 struct msm_adc_platform_data *pdata =
878 msm_adc_drv->pdev->dev.platform_data;
879 struct msm_adc_channels *channel = &pdata->channel[client->adc_chan];
880 struct adc_conv_slot *slot;
881 int rc, calib_status;
882
883 channel->adc_access_fn->adc_slot_request(channel->adc_dev_instance,
884 &slot);
885 if (slot) {
886 slot->conv.result.chan = client->adc_chan;
887 slot->blocking = 0;
888 slot->compk = calib_complete_evt;
889 slot->adc_request = START_OF_CALIBRATION;
890 slot->chan_path = channel->chan_path_type;
891 slot->chan_adc_config = channel->adc_config_type;
892 slot->chan_adc_calib = channel->adc_calib_type;
893 rc = channel->adc_access_fn->adc_calibrate(
894 channel->adc_dev_instance, slot, &calib_status);
895
896 if (calib_status == CALIB_NOT_REQUIRED) {
897 channel->adc_access_fn->adc_restore_slot(
898 channel->adc_dev_instance, slot);
899 /* client will always wait in case when
900 calibration is not required */
901 complete(calib_complete_evt);
902 } else {
903 atomic_inc(&msm_adc_drv->total_outst);
904 mutex_lock(&client->lock);
905 client->num_outstanding++;
906 mutex_unlock(&client->lock);
907 }
908
909 return rc;
910 }
911 return -EBUSY;
912}
913
914static void msm_rpc_adc_conv_cb(void *context, u32 param,
915 void *evt_buf, u32 len)
916{
917 struct dal_adc_result *result = evt_buf;
918 struct dal_conv_slot *slot = context;
919 struct msm_adc_drv *msm_adc = msm_adc_drv;
920
921 memcpy(&slot->result, result, sizeof(slot->result));
922
923 /* for blocking requests, signal complete */
924 if (slot->blocking)
925 complete(&slot->comp);
926
927 /* for non-blocking requests, add slot to the client completed list */
928 else {
929 struct msm_client_data *client = slot->client;
930
931 mutex_lock(&client->lock);
932
933 list_add(&slot->list, &client->complete_list);
934 client->num_complete++;
935 client->num_outstanding--;
936
937 /*
938 * if the client release has been invoked and this is call
939 * corresponds to the last request, then signal release
940 * to complete.
941 */
942 if (slot->client->online == 0 && client->num_outstanding == 0)
943 wake_up_interruptible_all(&client->outst_wait);
944
945 mutex_unlock(&client->lock);
946
947 wake_up_interruptible_all(&client->data_wait);
948
949 atomic_dec(&msm_adc->total_outst);
950
951 /* verify driver remove has not been invoked */
952 if (atomic_read(&msm_adc->online) == 0 &&
953 atomic_read(&msm_adc->total_outst) == 0)
954 wake_up_interruptible_all(&msm_adc->total_outst_wait);
955 }
956}
957
958void msm_adc_conv_cb(void *context, u32 param,
959 void *evt_buf, u32 len)
960{
961 struct adc_conv_slot *slot = context;
962 struct msm_adc_drv *msm_adc = msm_adc_drv;
963
964 switch (slot->adc_request) {
965 case START_OF_CONV:
966 slot->adc_request = END_OF_CONV;
967 break;
968 case START_OF_CALIBRATION:
969 slot->adc_request = END_OF_CALIBRATION;
970 break;
971 case END_OF_CALIBRATION:
972 case END_OF_CONV:
973 break;
974 }
975 queue_work(msm_adc->wq, &slot->work);
976}
977
978static void msm_adc_teardown_device_conv(struct platform_device *pdev,
979 struct adc_dev *adc_dev)
980{
981 struct dal_conv_state *conv_s = &adc_dev->conv;
982 struct msm_adc_drv *msm_adc = platform_get_drvdata(pdev);
983 struct dal_conv_slot *slot;
984 int i;
985
986 for (i = 0; i < MSM_ADC_DEV_MAX_INFLIGHT; i++) {
987 slot = &conv_s->context[i];
988 if (slot->cb_h) {
989 dalrpc_dealloc_cb(msm_adc->dev_h, slot->cb_h);
990 slot->cb_h = NULL;
991 }
992 }
993}
994
995static void msm_rpc_adc_teardown_device(struct platform_device *pdev,
996 struct adc_dev *adc_dev)
997{
998 struct dal_translation *transl = &adc_dev->transl;
999 int i, num_chans = transl->hwmon_end - transl->hwmon_start + 1;
1000
1001 if (adc_dev->sens_attr)
1002 for (i = 0; i < num_chans; i++)
1003 device_remove_file(&pdev->dev,
1004 &adc_dev->sens_attr[i].dev_attr);
1005
1006 msm_adc_teardown_device_conv(pdev, adc_dev);
1007
1008 kfree(adc_dev->fnames);
1009 kfree(adc_dev->sens_attr);
1010 kfree(adc_dev);
1011}
1012
1013static void msm_rpc_adc_teardown_devices(struct platform_device *pdev)
1014{
1015 struct msm_adc_platform_data *pdata = pdev->dev.platform_data;
1016 struct msm_adc_drv *msm_adc = platform_get_drvdata(pdev);
1017 int i, rc = 0;
1018
1019 for (i = 0; i < pdata->num_adc; i++) {
1020 if (msm_adc->devs[i]) {
1021 msm_rpc_adc_teardown_device(pdev, msm_adc->devs[i]);
1022 msm_adc->devs[i] = NULL;
1023 } else
1024 break;
1025 }
1026
1027 if (msm_adc->dev_h) {
1028 rc = daldevice_detach(msm_adc->dev_h);
1029 if (rc)
1030 dev_err(&pdev->dev, "Cannot detach from dal device\n");
1031 msm_adc->dev_h = NULL;
1032 }
1033
1034}
1035
1036static void msm_adc_teardown_device(struct platform_device *pdev,
1037 struct msm_adc_drv *msm_adc)
1038{
1039 struct msm_adc_platform_data *pdata = pdev->dev.platform_data;
1040 int i, num_chans = pdata->num_chan_supported;
1041
1042 if (pdata->num_chan_supported > 0) {
1043 if (msm_adc->sens_attr)
1044 for (i = 0; i < num_chans; i++)
1045 device_remove_file(&pdev->dev,
1046 &msm_adc->sens_attr[i].dev_attr);
1047 kfree(msm_adc->sens_attr);
1048 }
1049}
1050
1051static void msm_adc_teardown(struct platform_device *pdev)
1052{
1053 struct msm_adc_drv *msm_adc = platform_get_drvdata(pdev);
1054
1055 if (!msm_adc)
1056 return;
1057
1058 misc_deregister(&msm_adc->misc);
1059
1060 if (msm_adc->hwmon)
1061 hwmon_device_unregister(msm_adc->hwmon);
1062
1063 msm_rpc_adc_teardown_devices(pdev);
1064 msm_adc_teardown_device(pdev, msm_adc);
1065
1066 kfree(msm_adc);
1067 platform_set_drvdata(pdev, NULL);
1068}
1069
1070static int __devinit msm_adc_device_conv_init(struct msm_adc_drv *msm_adc,
1071 struct adc_dev *adc_dev)
1072{
1073 struct platform_device *pdev = msm_adc->pdev;
1074 struct dal_conv_state *conv_s = &adc_dev->conv;
1075 struct dal_conv_slot *slot = conv_s->context;
1076 int rc, i;
1077
1078 sema_init(&conv_s->slot_count, MSM_ADC_DEV_MAX_INFLIGHT);
1079 mutex_init(&conv_s->list_lock);
1080 INIT_LIST_HEAD(&conv_s->slots);
1081
1082 for (i = 0; i < MSM_ADC_DEV_MAX_INFLIGHT; i++) {
1083 list_add(&slot->list, &conv_s->slots);
1084 slot->cb_h = dalrpc_alloc_cb(msm_adc->dev_h,
1085 msm_rpc_adc_conv_cb, slot);
1086 if (!slot->cb_h) {
1087 dev_err(&pdev->dev, "Unable to allocate DAL callback"
1088 " for slot %d\n", i);
1089 rc = -ENOMEM;
1090 goto dal_err_cb;
1091 }
1092 init_completion(&slot->comp);
1093 slot->idx = i;
1094 slot++;
1095 }
1096
1097 return 0;
1098
1099dal_err_cb:
1100 msm_adc_teardown_device_conv(pdev, adc_dev);
1101
1102 return rc;
1103}
1104
1105static struct sensor_device_attribute msm_rpc_adc_curr_in_attr =
1106 SENSOR_ATTR(NULL, S_IRUGO, msm_adc_show_curr, NULL, 0);
1107
1108static int __devinit msm_rpc_adc_device_init_hwmon(struct platform_device *pdev,
1109 struct adc_dev *adc_dev)
1110{
1111 struct dal_translation *transl = &adc_dev->transl;
1112 int i, rc, num_chans = transl->hwmon_end - transl->hwmon_start + 1;
1113 const char prefix[] = "curr", postfix[] = "_input";
1114 char tmpbuf[5];
1115
1116 adc_dev->fnames = kzalloc(num_chans * MSM_ADC_MAX_FNAME +
1117 num_chans * sizeof(char *), GFP_KERNEL);
1118 if (!adc_dev->fnames) {
1119 dev_err(&pdev->dev, "Unable to allocate memory\n");
1120 return -ENOMEM;
1121 }
1122
1123 adc_dev->sens_attr = kzalloc(num_chans *
1124 sizeof(struct sensor_device_attribute), GFP_KERNEL);
1125 if (!adc_dev->sens_attr) {
1126 dev_err(&pdev->dev, "Unable to allocate memory\n");
1127 rc = -ENOMEM;
1128 goto hwmon_err_fnames;
1129 }
1130
1131 for (i = 0; i < num_chans; i++) {
1132 adc_dev->fnames[i] = (char *)adc_dev->fnames +
1133 i * MSM_ADC_MAX_FNAME + num_chans * sizeof(char *);
1134 strcpy(adc_dev->fnames[i], prefix);
1135 sprintf(tmpbuf, "%d", transl->hwmon_start + i);
1136 strcat(adc_dev->fnames[i], tmpbuf);
1137 strcat(adc_dev->fnames[i], postfix);
1138
1139 msm_rpc_adc_curr_in_attr.index = transl->hwmon_start + i;
1140 msm_rpc_adc_curr_in_attr.dev_attr.attr.name =
1141 adc_dev->fnames[i];
1142 memcpy(&adc_dev->sens_attr[i], &msm_rpc_adc_curr_in_attr,
1143 sizeof(msm_rpc_adc_curr_in_attr));
1144
1145 rc = device_create_file(&pdev->dev,
1146 &adc_dev->sens_attr[i].dev_attr);
1147 if (rc) {
1148 dev_err(&pdev->dev, "device_create_file failed for "
1149 "dal dev %u chan %d\n",
1150 adc_dev->transl.dal_dev_idx, i);
1151 goto hwmon_err_sens;
1152 }
1153 }
1154
1155 return 0;
1156
1157hwmon_err_sens:
1158 kfree(adc_dev->sens_attr);
1159hwmon_err_fnames:
1160 kfree(adc_dev->fnames);
1161
1162 return rc;
1163}
1164
1165static int __devinit msm_rpc_adc_device_init(struct platform_device *pdev)
1166{
1167 struct msm_adc_platform_data *pdata = pdev->dev.platform_data;
1168 struct msm_adc_drv *msm_adc = platform_get_drvdata(pdev);
1169 struct adc_dev *adc_dev;
1170 struct adc_dev_spec target;
1171 int i, rc;
1172 int hwmon_cntr = pdata->num_chan_supported;
1173
1174 for (i = 0; i < pdata->num_adc; i++) {
1175 adc_dev = kzalloc(sizeof(struct adc_dev), GFP_KERNEL);
1176 if (!adc_dev) {
1177 dev_err(&pdev->dev, "Unable to allocate memory\n");
1178 rc = -ENOMEM;
1179 goto dev_init_err;
1180 }
1181
1182 msm_adc->devs[i] = adc_dev;
1183 adc_dev->name = pdata->dev_names[i];
1184
1185 rc = msm_adc_device_conv_init(msm_adc, adc_dev);
1186 if (rc) {
1187 dev_err(&pdev->dev, "DAL device[%s] failed conv init\n",
1188 adc_dev->name);
1189 goto dev_init_err;
1190 }
1191
1192 /* DAL device lookup */
1193 rc = msm_adc_getinputproperties(msm_adc, adc_dev->name,
1194 &target);
1195 if (rc) {
1196 dev_err(&pdev->dev, "No such DAL device[%s]\n",
1197 adc_dev->name);
1198 goto dev_init_err;
1199 }
1200
1201 adc_dev->transl.dal_dev_idx = target.dal.dev_idx;
1202 adc_dev->transl.hwmon_dev_idx = i;
1203 adc_dev->nchans = target.dal.chan_idx;
1204 adc_dev->transl.hwmon_start = hwmon_cntr;
1205 adc_dev->transl.hwmon_end = hwmon_cntr + adc_dev->nchans - 1;
1206 hwmon_cntr += adc_dev->nchans;
1207
1208 rc = msm_rpc_adc_device_init_hwmon(pdev, adc_dev);
1209 if (rc)
1210 goto dev_init_err;
1211 }
1212
1213 return 0;
1214
1215dev_init_err:
1216 msm_rpc_adc_teardown_devices(pdev);
1217 return rc;
1218}
1219
1220static int __devinit msm_rpc_adc_init(struct platform_device *pdev1)
1221{
1222 struct msm_adc_drv *msm_adc = msm_adc_drv;
1223 struct platform_device *pdev = msm_adc->pdev;
1224 struct msm_adc_platform_data *pdata = pdev->dev.platform_data;
1225 int rc = 0;
1226
1227 dev_dbg(&pdev->dev, "msm_rpc_adc_init called\n");
1228
1229 if (!pdata) {
1230 dev_err(&pdev->dev, "no platform data?\n");
1231 return -EINVAL;
1232 }
1233
1234 mutex_init(&msm_adc->prop_lock);
1235
1236 rc = daldevice_attach(MSM_ADC_DALRPC_DEVICEID,
1237 MSM_ADC_DALRPC_PORT_NAME,
1238 MSM_ADC_DALRPC_CPU,
1239 &msm_adc->dev_h);
1240 if (rc) {
1241 dev_err(&pdev->dev, "Cannot attach to dal device\n");
1242 return rc;
1243 }
1244
1245 dev_dbg(&pdev->dev, "Attach to dal device Succeeded\n");
1246
1247 rc = msm_rpc_adc_device_init(pdev);
1248 if (rc) {
1249 dev_err(&pdev->dev, "msm_adc_dev_init failed\n");
1250 goto err_cleanup;
1251 }
1252
1253 init_waitqueue_head(&msm_adc->rpc_total_outst_wait);
1254 atomic_set(&msm_adc->rpc_online, 1);
1255 atomic_set(&msm_adc->rpc_total_outst, 0);
1256 epm_init = true;
1257 pr_info("msm_adc successfully registered\n");
1258
1259 return 0;
1260
1261err_cleanup:
1262 msm_rpc_adc_teardown_devices(pdev);
1263
1264 return rc;
1265}
1266
1267/*
1268 * Process the deferred job
1269 */
1270void msm_adc_wq_work(struct work_struct *work)
1271{
1272 struct adc_properties *adc_properties;
1273 struct adc_conv_slot *slot = container_of(work,
1274 struct adc_conv_slot, work);
1275 uint32_t idx = slot->conv.result.chan;
1276 struct msm_adc_platform_data *pdata =
1277 msm_adc_drv->pdev->dev.platform_data;
1278 struct msm_adc_channels *channel = &pdata->channel[idx];
1279 int32_t adc_code;
1280
1281 switch (slot->adc_request) {
1282 case START_OF_CONV:
1283 channel->adc_access_fn->adc_select_chan_and_start_conv(
1284 channel->adc_dev_instance, slot);
1285 break;
1286 case END_OF_CONV:
1287 adc_properties = channel->adc_access_fn->adc_get_properties(
1288 channel->adc_dev_instance);
1289 if (channel->adc_access_fn->adc_read_adc_code)
1290 channel->adc_access_fn->adc_read_adc_code(
1291 channel->adc_dev_instance, &adc_code);
1292 if (channel->chan_processor)
1293 channel->chan_processor(adc_code, adc_properties,
1294 &slot->chan_properties, &slot->conv.result);
1295 /* Intentionally a fall thru here. Calibraton does not need
1296 to perform channel processing, etc. However, both
1297 end of conversion and end of calibration requires the below
1298 fall thru code to be executed. */
1299 case END_OF_CALIBRATION:
1300 /* for blocking requests, signal complete */
1301 if (slot->blocking)
1302 complete(&slot->comp);
1303 else {
1304 struct msm_client_data *client = slot->client;
1305
1306 mutex_lock(&client->lock);
1307
1308 if (slot->adc_request == END_OF_CONV) {
1309 list_add(&slot->list, &client->complete_list);
1310 client->num_complete++;
1311 }
1312 client->num_outstanding--;
1313
1314 /*
1315 * if the client release has been invoked and this is call
1316 * corresponds to the last request, then signal release
1317 * to complete.
1318 */
1319 if (slot->client->online == 0 &&
1320 client->num_outstanding == 0)
1321 wake_up_interruptible_all(&client->outst_wait);
1322
1323 mutex_unlock(&client->lock);
1324
1325 wake_up_interruptible_all(&client->data_wait);
1326
1327 atomic_dec(&msm_adc_drv->total_outst);
1328
1329 /* verify driver remove has not been invoked */
1330 if (atomic_read(&msm_adc_drv->online) == 0 &&
1331 atomic_read(&msm_adc_drv->total_outst) == 0)
1332 wake_up_interruptible_all(
1333 &msm_adc_drv->total_outst_wait);
1334
1335 if (slot->compk) /* Kernel space request */
1336 complete(slot->compk);
1337 if (slot->adc_request == END_OF_CALIBRATION)
1338 channel->adc_access_fn->adc_restore_slot(
1339 channel->adc_dev_instance, slot);
1340 }
1341 break;
1342 case START_OF_CALIBRATION: /* code here to please code reviewers
1343 to satisfy silly compiler warnings */
1344 break;
1345 }
1346}
1347
1348static struct sensor_device_attribute msm_adc_curr_in_attr =
1349 SENSOR_ATTR(NULL, S_IRUGO, msm_adc_show_curr, NULL, 0);
1350
1351static int __devinit msm_adc_init_hwmon(struct platform_device *pdev,
1352 struct msm_adc_drv *msm_adc)
1353{
1354 struct msm_adc_platform_data *pdata = pdev->dev.platform_data;
1355 struct msm_adc_channels *channel = pdata->channel;
1356 int i, rc, num_chans = pdata->num_chan_supported;
1357
1358 if (!channel)
1359 return -EINVAL;
1360
1361 msm_adc->sens_attr = kzalloc(num_chans *
1362 sizeof(struct sensor_device_attribute), GFP_KERNEL);
1363 if (!msm_adc->sens_attr) {
1364 dev_err(&pdev->dev, "Unable to allocate memory\n");
1365 rc = -ENOMEM;
1366 goto hwmon_err_sens;
1367 }
1368
1369 for (i = 0; i < num_chans; i++) {
1370 msm_adc_curr_in_attr.index = i;
1371 msm_adc_curr_in_attr.dev_attr.attr.name = channel[i].name;
1372 memcpy(&msm_adc->sens_attr[i], &msm_adc_curr_in_attr,
1373 sizeof(msm_adc_curr_in_attr));
1374
1375 rc = device_create_file(&pdev->dev,
1376 &msm_adc->sens_attr[i].dev_attr);
1377 if (rc) {
1378 dev_err(&pdev->dev, "device_create_file failed for "
1379 "dal dev %s\n",
1380 channel[i].name);
1381 goto hwmon_err_sens;
1382 }
1383 }
1384
1385 return 0;
1386
1387hwmon_err_sens:
1388 kfree(msm_adc->sens_attr);
1389
1390 return rc;
1391}
1392
1393static struct platform_driver msm_adc_rpcrouter_remote_driver = {
1394 .probe = msm_rpc_adc_init,
1395 .driver = {
1396 .name = MSM_ADC_DALRPC_PORT_NAME,
1397 .owner = THIS_MODULE,
1398 },
1399};
1400
1401static int msm_adc_probe(struct platform_device *pdev)
1402{
1403 struct msm_adc_platform_data *pdata = pdev->dev.platform_data;
1404 struct msm_adc_drv *msm_adc;
1405 int rc = 0;
1406
1407 if (!pdata) {
1408 dev_err(&pdev->dev, "no platform data?\n");
1409 return -EINVAL;
1410 }
1411
1412 msm_adc = kzalloc(sizeof(struct msm_adc_drv), GFP_KERNEL);
1413 if (!msm_adc) {
1414 dev_err(&pdev->dev, "Unable to allocate memory\n");
1415 return -ENOMEM;
1416 }
1417
1418 platform_set_drvdata(pdev, msm_adc);
1419 msm_adc_drv = msm_adc;
1420 msm_adc->pdev = pdev;
1421
1422 if (pdata->target_hw == MSM_8x60 || pdata->target_hw == FSM_9xxx) {
1423 rc = msm_adc_init_hwmon(pdev, msm_adc);
1424 if (rc) {
1425 dev_err(&pdev->dev, "msm_adc_dev_init failed\n");
1426 goto err_cleanup;
1427 }
1428 }
1429
1430 msm_adc->hwmon = hwmon_device_register(&pdev->dev);
1431 if (IS_ERR(msm_adc->hwmon)) {
1432 dev_err(&pdev->dev, "hwmon_device_register failed\n");
1433 rc = PTR_ERR(msm_adc->hwmon);
1434 goto err_cleanup;
1435 }
1436
1437 msm_adc->misc.name = MSM_ADC_DRIVER_NAME;
1438 msm_adc->misc.minor = MISC_DYNAMIC_MINOR;
1439 msm_adc->misc.fops = &msm_adc_fops;
1440
1441 if (misc_register(&msm_adc->misc)) {
1442 dev_err(&pdev->dev, "Unable to register misc device!\n");
1443 goto err_cleanup;
1444 }
1445
1446 init_waitqueue_head(&msm_adc->total_outst_wait);
1447 atomic_set(&msm_adc->online, 1);
1448 atomic_set(&msm_adc->total_outst, 0);
1449
1450 msm_adc->wq = create_singlethread_workqueue("msm_adc");
1451 if (!msm_adc->wq)
1452 goto err_cleanup;
1453
1454 if (pdata->num_adc > 0) {
1455 if (pdata->target_hw == MSM_8x60)
1456 platform_driver_register(
1457 &msm_adc_rpcrouter_remote_driver);
1458 else
1459 msm_rpc_adc_init(pdev);
1460 }
1461
1462 pr_info("msm_adc successfully registered\n");
1463
1464 return 0;
1465
1466err_cleanup:
1467 msm_adc_teardown(pdev);
1468
1469 return rc;
1470}
1471
1472static int __devexit msm_adc_remove(struct platform_device *pdev)
1473{
1474 int rc;
1475
1476 struct msm_adc_drv *msm_adc = platform_get_drvdata(pdev);
1477
1478 atomic_set(&msm_adc->online, 0);
1479
1480 atomic_set(&msm_adc->rpc_online, 0);
1481
1482 misc_deregister(&msm_adc->misc);
1483
1484 hwmon_device_unregister(msm_adc->hwmon);
1485 msm_adc->hwmon = NULL;
1486
1487 /*
1488 * We may still have outstanding transactions in flight that have not
1489 * completed. Make sure they're completed before tearing down.
1490 */
1491 rc = wait_event_interruptible(msm_adc->total_outst_wait,
1492 atomic_read(&msm_adc->total_outst) == 0);
1493 if (rc) {
1494 pr_err("%s: wait_event_interruptible failed rc = %d\n",
1495 __func__, rc);
1496 return rc;
1497 }
1498
1499 rc = wait_event_interruptible(msm_adc->rpc_total_outst_wait,
1500 atomic_read(&msm_adc->rpc_total_outst) == 0);
1501 if (rc) {
1502 pr_err("%s: wait_event_interruptible failed rc = %d\n",
1503 __func__, rc);
1504 return rc;
1505 }
1506
1507 msm_adc_teardown(pdev);
1508
1509 pr_info("msm_adc unregistered\n");
1510
1511 return 0;
1512}
1513
1514static struct platform_driver msm_adc_driver = {
1515 .probe = msm_adc_probe,
1516 .remove = __devexit_p(msm_adc_remove),
1517 .driver = {
1518 .name = MSM_ADC_DRIVER_NAME,
1519 .owner = THIS_MODULE,
1520 },
1521};
1522
1523static int __init msm_adc_init(void)
1524{
1525 return platform_driver_register(&msm_adc_driver);
1526}
1527module_init(msm_adc_init);
1528
1529static void __exit msm_adc_exit(void)
1530{
1531 platform_driver_unregister(&msm_adc_driver);
1532}
1533module_exit(msm_adc_exit);
1534
1535MODULE_DESCRIPTION("MSM ADC Driver");
1536MODULE_ALIAS("platform:msm_adc");
1537MODULE_LICENSE("GPL v2");
1538MODULE_VERSION("0.1");