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 adc_host *g_adc = NULL;
11 static LIST_HEAD(adc_host_head);
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 mutex_init(&adc->m_lock);
25 INIT_LIST_HEAD(&adc->req_head);
26 INIT_LIST_HEAD(&adc->callback_head);
28 list_add_tail(&adc->entry, &adc_host_head);
33 void adc_free_host(struct adc_host *adc)
35 list_del(&adc->entry);
41 struct adc_client *adc_register(int chn,
42 void (*callback)(struct adc_client *, void *, int),
46 struct adc_client *client = NULL;
47 struct adc_host *adc = NULL;
51 list_for_each_entry(adc, &adc_host_head, entry) {
52 if((chn == 0 && adc->mask == SARADC_CHN_MASK) ||
54 client = kzalloc(sizeof(struct adc_client), GFP_KERNEL);
57 client->callback = callback;
58 client->callback_param = callback_param;
61 client->index = adc->client_count;
62 init_waitqueue_head(&client->wait);
68 dev_err(adc->dev, "chn(%d) is not support\n", chn);
71 EXPORT_SYMBOL(adc_register);
73 void adc_unregister(struct adc_client *client)
75 struct adc_host *adc = client->adc;
82 EXPORT_SYMBOL(adc_unregister);
84 static inline void trigger_next_adc_job_if_any(struct adc_host *adc)
86 struct adc_request *req = NULL;
88 req = list_first_entry(&adc->req_head, struct adc_request, entry);
90 if(req->client == NULL){
91 dev_err(adc->dev, "Abnormal: client piont is NULL...............\n");
94 adc->chn = req->client->chn;
101 static int adc_request_add(struct adc_host *adc, struct adc_client *client)
103 struct adc_request *req = NULL;
105 req = kzalloc(sizeof(struct adc_request), GFP_ATOMIC);
109 INIT_LIST_HEAD(&req->entry);
110 req->client = client;
111 list_add_tail(&req->entry, &adc->req_head);
113 trigger_next_adc_job_if_any(adc);
117 adc_sync_read_callback(struct adc_client *client, void *param, int result)
119 client->result = result;
122 static void adc_callback(struct adc_host *adc)
124 struct adc_request *req = NULL, *n = NULL;
126 list_for_each_entry_safe(req, n, &adc->callback_head, entry) {
127 if(req->client->flags & (1<<ADC_ASYNC_READ)){
128 req->client->callback(req->client, req->client->callback_param, req->client->result);
130 if(req->client->flags & (1<<ADC_SYNC_READ)){
131 adc_sync_read_callback(req->client, NULL, req->client->result);
132 req->client->is_finished = 1;
133 wake_up(&req->client->wait);
135 req->client->flags = 0;
136 list_del_init(&req->entry);
141 void adc_finished(struct adc_host *adc, int result)
144 struct adc_request *req = NULL, *n = NULL;
148 spin_lock_irqsave(&adc->lock, flags);
149 list_for_each_entry_safe(req, n, &adc->req_head, entry) {
150 if(req->client->chn == adc->chn){
151 req->client->result = result;
152 list_move_tail(&req->entry, &adc->callback_head);
156 if(!list_empty(&adc->req_head))
157 trigger_next_adc_job_if_any(adc);
158 spin_unlock_irqrestore(&adc->lock, flags);
163 void adc_core_irq_handle(struct adc_host *adc)
167 WARN_ON(adc->chn == -1);
169 mutex_lock(&adc->m_lock);
171 result = adc->ops->read(adc);
172 adc_dbg(adc->dev, "chn[%d] read value: %d\n", adc->chn, result);
174 adc_finished(adc, result);
176 mutex_unlock(&adc->m_lock);
179 int adc_host_read(struct adc_client *client, enum read_type type)
183 struct adc_host *adc = NULL;
186 printk(KERN_ERR "client is NULL");
190 if(adc->is_suspended == 1) {
191 dev_err(adc->dev, "adc is in suspend state\n");
195 spin_lock_irqsave(&adc->lock, flags);
196 if(client->flags & (1<<type)){
197 spin_unlock_irqrestore(&adc->lock, flags);
198 adc_dbg(adc->dev, "req is exist: %s, client->index: %d\n",
199 (type == ADC_ASYNC_READ)?"async_read":"sync_read", client->index);
201 }else if(client->flags != 0){
202 client->flags |= 1<<type;
204 client->flags = 1<<type;
205 ret = adc_request_add(adc, client);
207 spin_unlock_irqrestore(&adc->lock, flags);
208 dev_err(adc->dev, "fail to add request\n");
212 if(type == ADC_ASYNC_READ){
213 spin_unlock_irqrestore(&adc->lock, flags);
216 client->is_finished = 0;
217 spin_unlock_irqrestore(&adc->lock, flags);
219 tmo = wait_event_timeout(client->wait, ( client->is_finished == 1 ), msecs_to_jiffies(ADC_READ_TMO));
220 mutex_lock(&adc->m_lock);
221 if(unlikely((tmo <= 0) && (client->is_finished == 0))) {
222 dev_err(adc->dev, "get adc value timeout.................................\n");
225 adc_finished(adc, -1);
226 mutex_unlock(&adc->m_lock);
229 mutex_unlock(&adc->m_lock);
231 return client->result;
234 int adc_sync_read(struct adc_client *client)
236 return adc_host_read(client, ADC_SYNC_READ);
238 EXPORT_SYMBOL(adc_sync_read);
240 int adc_async_read(struct adc_client *client)
242 return adc_host_read(client, ADC_ASYNC_READ);
245 EXPORT_SYMBOL(adc_async_read);
247 int adc_get_def_ref_volt(void)
249 return g_adc->pdata->ref_volt;
251 EXPORT_SYMBOL(adc_get_def_ref_volt);
253 int adc_get_curr_ref_volt(void)
259 if(!g_adc->base_client)
260 return g_adc->pdata->ref_volt;
262 volt = g_adc->pdata->get_base_volt();
264 return g_adc->pdata->ref_volt;
266 v = adc_sync_read(g_adc->base_client);
270 return volt * 1024 / v;
272 EXPORT_SYMBOL(adc_get_curr_ref_volt);