3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License.
10 struct list_head adc_host_head;
12 static void adc_host_work(struct work_struct *work);
13 struct adc_host *adc_alloc_host(struct device *dev, int extra, enum host_chn_mask mask)
17 adc = kzalloc(sizeof(struct adc_host) + extra, GFP_KERNEL);
23 spin_lock_init(&adc->lock);
24 INIT_LIST_HEAD(&adc->req_head);
25 INIT_WORK(&adc->work, adc_host_work);
27 list_add_tail(&adc->entry, &adc_host_head);
32 void adc_free_host(struct adc_host *adc)
34 list_del(&adc->entry);
40 struct adc_client *adc_register(int chn,
41 void (*callback)(struct adc_client *, void *, int),
45 struct adc_client *client = NULL;
46 struct adc_host *adc = NULL;
48 list_for_each_entry(adc, &adc_host_head, entry) {
49 if((chn == 0 && adc->mask == SARADC_CHN_MASK) ||
51 client = kzalloc(sizeof(struct adc_client), GFP_KERNEL);
54 client->callback = callback;
55 client->callback_param = callback_param;
58 client->index = adc->client_count;
59 init_waitqueue_head(&client->wait);
65 dev_err(adc->dev, "chn(%d) is not support\n", chn);
69 void adc_unregister(struct adc_client *client)
71 struct adc_host *adc = client->adc;
79 static inline void trigger_next_adc_job_if_any(struct adc_host *adc)
81 struct adc_request *req = NULL;
85 req = list_first_entry(&adc->req_head, struct adc_request, entry);
87 adc->chn = req->client->chn;
93 static void adc_host_work(struct work_struct *work)
96 struct adc_host *adc =
97 container_of(work, struct adc_host, work);
99 spin_lock_irqsave(&adc->lock, flags);
100 trigger_next_adc_job_if_any(adc);
101 spin_unlock_irqrestore(&adc->lock, flags);
103 static int adc_request_add(struct adc_host *adc, struct adc_client *client)
105 struct adc_request *req = NULL;
107 req = kzalloc(sizeof(struct adc_request), GFP_ATOMIC);
111 INIT_LIST_HEAD(&req->entry);
112 req->client = client;
113 list_add_tail(&req->entry, &adc->req_head);
114 trigger_next_adc_job_if_any(adc);
118 adc_sync_read_callback(struct adc_client *client, void *param, int result)
120 client->result = result;
122 static void adc_finished(struct adc_host *adc, int result)
124 struct adc_request *req = NULL, *n = NULL;
126 adc_dbg(adc->dev, "chn[%d] read value: %d\n", adc->chn, result);
128 list_for_each_entry_safe(req, n, &adc->req_head, entry) {
129 if(req->client->chn == adc->chn){
130 if(req->client->flags & (1<<ADC_ASYNC_READ)){
131 req->client->callback(req->client, req->client->callback_param, result);
133 if(req->client->flags & (1<<ADC_SYNC_READ)){
134 adc_sync_read_callback(req->client, NULL, result);
135 req->client->is_finished = 1;
136 wake_up(&req->client->wait);
138 req->client->result = result;
139 req->client->flags = 0;
140 list_del_init(&req->entry);
146 void adc_core_irq_handle(struct adc_host *adc)
150 spin_lock(&adc->lock);
151 result = adc->ops->read(adc);
153 adc_finished(adc, result);
155 if(!list_empty(&adc->req_head))
156 schedule_work(&adc->work);
157 spin_unlock(&adc->lock);
160 int adc_host_read(struct adc_client *client, enum read_type type)
164 struct adc_host *adc = NULL;
167 printk(KERN_ERR "client is NULL");
171 if(adc->is_suspended == 1) {
172 dev_err(adc->dev, "adc is in suspend state\n");
176 spin_lock_irqsave(&adc->lock, flags);
177 if(client->flags & (1<<type)){
178 spin_unlock_irqrestore(&adc->lock, flags);
179 adc_dbg(adc->dev, "req is exist: %s, client->index: %d\n",
180 (type == ADC_ASYNC_READ)?"async_read":"sync_read", client->index);
182 }else if(client->flags != 0){
183 client->flags |= 1<<type;
185 client->flags = 1<<type;
186 ret = adc_request_add(adc, client);
188 spin_unlock_irqrestore(&adc->lock, flags);
189 dev_err(adc->dev, "fail to add request\n");
193 if(type == ADC_ASYNC_READ){
194 spin_unlock_irqrestore(&adc->lock, flags);
197 client->is_finished = 0;
198 spin_unlock_irqrestore(&adc->lock, flags);
200 tmo = wait_event_timeout(client->wait, ( client->is_finished == 1 ), msecs_to_jiffies(ADC_READ_TMO));
201 spin_lock_irqsave(&adc->lock, flags);
202 if(unlikely((tmo <= 0) && (client->is_finished == 0))) {
205 dev_err(adc->dev, "get adc value timeout.................................\n");
206 adc_finished(adc, -1);
207 spin_unlock_irqrestore(&adc->lock, flags);
210 spin_unlock_irqrestore(&adc->lock, flags);
212 return client->result;
215 int adc_sync_read(struct adc_client *client)
217 return adc_host_read(client, ADC_SYNC_READ);
220 int adc_async_read(struct adc_client *client)
222 return adc_host_read(client, ADC_ASYNC_READ);
226 static int __init adc_core_init(void)
228 INIT_LIST_HEAD(&adc_host_head);
231 subsys_initcall(adc_core_init);
233 static void __exit adc_core_exit(void)
237 module_exit(adc_core_exit);