blob: 1ac79d463e428e65872f33efeb45d625bd656146 [file] [log] [blame]
Duy Truonge833aca2013-02-12 13:35:08 -08001/* Copyright (c) 2009-2011, The Linux Foundation. All rights reserved.
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002 *
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
14#include <linux/kernel.h>
15#include <linux/module.h>
16#include <linux/miscdevice.h>
17#include <linux/uaccess.h>
18#include <linux/fs.h>
19#include <linux/mutex.h>
20#include <linux/sched.h>
21#include <linux/msm_audio.h>
22#include <mach/qdsp5v2/audio_dev_ctl.h>
23#include <mach/dal.h>
24#include <linux/kthread.h>
25#include <linux/completion.h>
26#include <linux/wait.h>
27#include <mach/qdsp5v2/voice.h>
28#include <mach/debug_mm.h>
29
30struct voice_data {
31 void *handle; /* DALRPC handle */
32 void *cb_handle; /* DALRPC callback handle */
33 int network; /* Network information */
34 int dev_state;/*READY, CHANGE, REL_DONE,INIT*/
35 int voc_state;/*INIT, CHANGE, RELEASE, ACQUIRE */
36 struct mutex voc_lock;
37 struct mutex vol_lock;
38 int voc_event;
39 int dev_event;
40 atomic_t rel_start_flag;
41 atomic_t acq_start_flag;
42 atomic_t chg_start_flag;
43 struct task_struct *task;
44 struct completion complete;
45 wait_queue_head_t dev_wait;
46 wait_queue_head_t voc_wait;
47 uint32_t device_events;
48 /* cache the values related to Rx and Tx */
49 struct device_data dev_rx;
50 struct device_data dev_tx;
51 /* these default values are for all devices */
52 uint32_t default_mute_val;
53 uint32_t default_vol_val;
54 uint32_t default_sample_val;
55 /* call status */
56 int v_call_status; /* Start or End */
57 s32 max_rx_vol[VOC_RX_VOL_ARRAY_NUM]; /* [0] is for NB, [1] for WB */
58 s32 min_rx_vol[VOC_RX_VOL_ARRAY_NUM];
59};
60
61static struct voice_data voice;
62
63static int voice_cmd_device_info(struct voice_data *);
64static int voice_cmd_acquire_done(struct voice_data *);
65static void voice_auddev_cb_function(u32 evt_id,
66 union auddev_evt_data *evt_payload,
67 void *private_data);
68
69static int voice_cmd_change(void)
70{
71
72 struct voice_header hdr;
73 struct voice_data *v = &voice;
74 int err;
75
76 hdr.id = CMD_DEVICE_CHANGE;
77 hdr.data_len = 0;
78
79 MM_DBG("\n"); /* Macro prints the file name and function */
80
81 err = dalrpc_fcn_5(VOICE_DALRPC_CMD, v->handle, &hdr,
82 sizeof(struct voice_header));
83
84 if (err)
85 MM_ERR("Voice change command failed\n");
86 return err;
87}
88
89static void voice_auddev_cb_function(u32 evt_id,
90 union auddev_evt_data *evt_payload,
91 void *private_data)
92{
93 struct voice_data *v = &voice;
94 int rc = 0, i;
95
96 MM_INFO("auddev_cb_function, evt_id=%d, dev_state=%d, voc_state=%d\n",
97 evt_id, v->dev_state, v->voc_state);
98 if ((evt_id != AUDDEV_EVT_START_VOICE) ||
99 (evt_id != AUDDEV_EVT_END_VOICE)) {
100 if (evt_payload == NULL) {
101 MM_ERR(" evt_payload is NULL pointer\n");
102 return;
103 }
104 }
105 switch (evt_id) {
106 case AUDDEV_EVT_START_VOICE:
107 if ((v->dev_state == DEV_INIT) ||
108 (v->dev_state == DEV_REL_DONE)) {
109 v->v_call_status = VOICE_CALL_START;
110 if ((v->dev_rx.enabled == VOICE_DEV_ENABLED)
111 && (v->dev_tx.enabled == VOICE_DEV_ENABLED)) {
112 v->dev_state = DEV_READY;
113 MM_DBG("dev_state into ready\n");
114 wake_up(&v->dev_wait);
115 }
Santosh Mardid828aea2011-07-19 18:09:49 +0530116 if (v->voc_state == VOICE_CHANGE) {
117 MM_DBG("voc_state is in VOICE_CHANGE\n");
118 v->voc_state = VOICE_ACQUIRE;
119 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700120 }
121 break;
122 case AUDDEV_EVT_DEV_CHG_VOICE:
123 if (v->dev_state == DEV_READY) {
124 v->dev_rx.enabled = VOICE_DEV_DISABLED;
125 v->dev_tx.enabled = VOICE_DEV_DISABLED;
126 v->dev_state = DEV_CHANGE;
127 mutex_lock(&voice.voc_lock);
128 if (v->voc_state == VOICE_ACQUIRE) {
129 /* send device change to modem */
130 voice_cmd_change();
131 mutex_unlock(&voice.voc_lock);
132 msm_snddev_enable_sidetone(v->dev_rx.dev_id,
133 0);
134 /* block to wait for CHANGE_START */
135 rc = wait_event_interruptible(
136 v->voc_wait, (v->voc_state == VOICE_CHANGE)
137 || (atomic_read(&v->chg_start_flag) == 1)
138 || (atomic_read(&v->rel_start_flag) == 1));
139 } else {
140 mutex_unlock(&voice.voc_lock);
141 MM_ERR(" Voice is not at ACQUIRE state\n");
142 }
143 } else if ((v->dev_state == DEV_INIT) ||
144 (v->dev_state == DEV_REL_DONE)) {
145 v->dev_rx.enabled = VOICE_DEV_DISABLED;
146 v->dev_tx.enabled = VOICE_DEV_DISABLED;
147 } else
148 MM_ERR(" device is not at proper state\n");
149 break;
150 case AUDDEV_EVT_DEV_RDY:
151 /* update the dev info */
152 if (evt_payload->voc_devinfo.dev_type == DIR_RX) {
153 for (i = 0; i < VOC_RX_VOL_ARRAY_NUM; i++) {
154 v->max_rx_vol[i] =
155 evt_payload->voc_devinfo.max_rx_vol[i];
156 v->min_rx_vol[i] =
157 evt_payload->voc_devinfo.min_rx_vol[i];
158 }
159 }
160 if (v->dev_state == DEV_CHANGE) {
161 if (evt_payload->voc_devinfo.dev_type == DIR_RX) {
162 v->dev_rx.dev_acdb_id =
163 evt_payload->voc_devinfo.acdb_dev_id;
164 v->dev_rx.sample =
165 evt_payload->voc_devinfo.dev_sample;
166 v->dev_rx.dev_id =
167 evt_payload->voc_devinfo.dev_id;
168 v->dev_rx.enabled = VOICE_DEV_ENABLED;
169 } else {
170 v->dev_tx.dev_acdb_id =
171 evt_payload->voc_devinfo.acdb_dev_id;
172 v->dev_tx.sample =
173 evt_payload->voc_devinfo.dev_sample;
174 v->dev_tx.enabled = VOICE_DEV_ENABLED;
175 v->dev_tx.dev_id =
176 evt_payload->voc_devinfo.dev_id;
177 }
178 if ((v->dev_rx.enabled == VOICE_DEV_ENABLED) &&
179 (v->dev_tx.enabled == VOICE_DEV_ENABLED)) {
180 v->dev_state = DEV_READY;
181 MM_DBG("dev state into ready\n");
182 voice_cmd_device_info(v);
183 wake_up(&v->dev_wait);
184 mutex_lock(&voice.voc_lock);
185 if (v->voc_state == VOICE_CHANGE) {
186 v->dev_event = DEV_CHANGE_READY;
187 complete(&v->complete);
188 }
189 mutex_unlock(&voice.voc_lock);
190 }
191 } else if ((v->dev_state == DEV_INIT) ||
192 (v->dev_state == DEV_REL_DONE)) {
193 if (evt_payload->voc_devinfo.dev_type == DIR_RX) {
194 v->dev_rx.dev_acdb_id =
195 evt_payload->voc_devinfo.acdb_dev_id;
196 v->dev_rx.sample =
197 evt_payload->voc_devinfo.dev_sample;
198 v->dev_rx.dev_id =
199 evt_payload->voc_devinfo.dev_id;
200 v->dev_rx.enabled = VOICE_DEV_ENABLED;
201 } else {
202 v->dev_tx.dev_acdb_id =
203 evt_payload->voc_devinfo.acdb_dev_id;
204 v->dev_tx.sample =
205 evt_payload->voc_devinfo.dev_sample;
206 v->dev_tx.dev_id =
207 evt_payload->voc_devinfo.dev_id;
208 v->dev_tx.enabled = VOICE_DEV_ENABLED;
209 }
210 if ((v->dev_rx.enabled == VOICE_DEV_ENABLED) &&
211 (v->dev_tx.enabled == VOICE_DEV_ENABLED) &&
212 (v->v_call_status == VOICE_CALL_START)) {
213 v->dev_state = DEV_READY;
214 MM_DBG("dev state into ready\n");
215 voice_cmd_device_info(v);
216 wake_up(&v->dev_wait);
217 mutex_lock(&voice.voc_lock);
218 if (v->voc_state == VOICE_CHANGE) {
219 v->dev_event = DEV_CHANGE_READY;
220 complete(&v->complete);
221 }
222 mutex_unlock(&voice.voc_lock);
223 }
224 } else
225 MM_ERR("Receive READY not at the proper state =%d\n",
226 v->dev_state);
227 break;
228 case AUDDEV_EVT_DEVICE_VOL_MUTE_CHG:
229 if (evt_payload->voc_devinfo.dev_type == DIR_TX)
230 v->dev_tx.mute =
231 evt_payload->voc_vm_info.dev_vm_val.mute;
232 else
233 v->dev_rx.volume = evt_payload->
234 voc_vm_info.dev_vm_val.vol;
235 /* send device info */
236 voice_cmd_device_info(v);
237 break;
238 case AUDDEV_EVT_REL_PENDING:
239 /* recover the tx mute and rx volume to the default values */
240 if (v->dev_state == DEV_READY) {
241 if (atomic_read(&v->rel_start_flag)) {
242 atomic_dec(&v->rel_start_flag);
243 if (evt_payload->voc_devinfo.dev_type == DIR_RX)
244 v->dev_rx.enabled = VOICE_DEV_DISABLED;
245 else
246 v->dev_tx.enabled = VOICE_DEV_DISABLED;
247 v->dev_state = DEV_REL_DONE;
248 wake_up(&v->dev_wait);
249 break;
250 }
251 mutex_lock(&voice.voc_lock);
252 if ((v->voc_state == VOICE_RELEASE) ||
253 (v->voc_state == VOICE_INIT)) {
254 if (evt_payload->voc_devinfo.dev_type
255 == DIR_RX) {
256 v->dev_rx.enabled = VOICE_DEV_DISABLED;
257 } else {
258 v->dev_tx.enabled = VOICE_DEV_DISABLED;
259 }
260 v->dev_state = DEV_REL_DONE;
261 mutex_unlock(&voice.voc_lock);
262 wake_up(&v->dev_wait);
263 } else {
264 /* send device change to modem */
265 voice_cmd_change();
266 mutex_unlock(&voice.voc_lock);
267 rc = wait_event_interruptible(
268 v->voc_wait, (v->voc_state == VOICE_CHANGE)
269 || (atomic_read(&v->chg_start_flag) == 1)
270 || (atomic_read(&v->rel_start_flag) == 1));
271 if (atomic_read(&v->rel_start_flag) == 1)
272 atomic_dec(&v->rel_start_flag);
273 /* clear Rx/Tx to Disable */
274 if (evt_payload->voc_devinfo.dev_type == DIR_RX)
275 v->dev_rx.enabled = VOICE_DEV_DISABLED;
276 else
277 v->dev_tx.enabled = VOICE_DEV_DISABLED;
278 v->dev_state = DEV_REL_DONE;
279 wake_up(&v->dev_wait);
280 }
281 } else if ((v->dev_state == DEV_INIT) ||
282 (v->dev_state == DEV_REL_DONE)) {
283 if (evt_payload->voc_devinfo.dev_type == DIR_RX)
284 v->dev_rx.enabled = VOICE_DEV_DISABLED;
285 else
286 v->dev_tx.enabled = VOICE_DEV_DISABLED;
287 }
288 break;
289 case AUDDEV_EVT_END_VOICE:
290 /* recover the tx mute and rx volume to the default values */
291 v->dev_tx.mute = v->default_mute_val;
292 v->dev_rx.volume = v->default_vol_val;
293
294 if (v->dev_rx.enabled == VOICE_DEV_ENABLED)
295 msm_snddev_enable_sidetone(v->dev_rx.dev_id, 0);
296
297 if ((v->dev_state == DEV_READY) ||
298 (v->dev_state == DEV_CHANGE)) {
299 if (atomic_read(&v->rel_start_flag)) {
300 atomic_dec(&v->rel_start_flag);
301 v->v_call_status = VOICE_CALL_END;
302 v->dev_state = DEV_REL_DONE;
303 wake_up(&v->dev_wait);
304 break;
305 }
306 mutex_lock(&voice.voc_lock);
307 if ((v->voc_state == VOICE_RELEASE) ||
308 (v->voc_state == VOICE_INIT)) {
309 v->v_call_status = VOICE_CALL_END;
310 v->dev_state = DEV_REL_DONE;
311 mutex_unlock(&voice.voc_lock);
312 wake_up(&v->dev_wait);
313 } else {
314 /* send mute and default volume value to MCAD */
315 voice_cmd_device_info(v);
316 /* send device change to modem */
317 voice_cmd_change();
318 mutex_unlock(&voice.voc_lock);
319 /* block to wait for RELEASE_START
320 or CHANGE_START */
321 rc = wait_event_interruptible(
322 v->voc_wait, (v->voc_state == VOICE_CHANGE)
323 || (atomic_read(&v->chg_start_flag) == 1)
324 || (atomic_read(&v->rel_start_flag) == 1));
325 if (atomic_read(&v->rel_start_flag) == 1)
326 atomic_dec(&v->rel_start_flag);
327 /* set voice call to END state */
328 v->v_call_status = VOICE_CALL_END;
329 v->dev_state = DEV_REL_DONE;
330 wake_up(&v->dev_wait);
331 }
332 } else
333 v->v_call_status = VOICE_CALL_END;
334 break;
335 case AUDDEV_EVT_FREQ_CHG:
336 MM_DBG("Voice Driver got sample rate change Event\n");
337 MM_DBG("sample rate %d\n", evt_payload->freq_info.sample_rate);
338 MM_DBG("dev_type %d\n", evt_payload->freq_info.dev_type);
339 MM_DBG("acdb_dev_id %d\n", evt_payload->freq_info.acdb_dev_id);
340 if (v->dev_state == DEV_READY) {
341 v->dev_tx.enabled = VOICE_DEV_DISABLED;
342 v->dev_state = DEV_CHANGE;
343 mutex_lock(&voice.voc_lock);
344 if (v->voc_state == VOICE_ACQUIRE) {
345 msm_snddev_enable_sidetone(v->dev_rx.dev_id,
346 0);
347 /* send device change to modem */
348 voice_cmd_change();
349 mutex_unlock(&voice.voc_lock);
350 /* block to wait for CHANGE_START */
351 rc = wait_event_interruptible(
352 v->voc_wait, (v->voc_state == VOICE_CHANGE)
353 || (atomic_read(&v->chg_start_flag) == 1)
354 || (atomic_read(&v->rel_start_flag) == 1));
355 } else {
356 mutex_unlock(&voice.voc_lock);
357 MM_ERR(" Voice is not at ACQUIRE state\n");
358 }
359 } else if ((v->dev_state == DEV_INIT) ||
360 (v->dev_state == DEV_REL_DONE)) {
361 v->dev_tx.enabled = VOICE_DEV_DISABLED;
362 } else
363 MM_ERR("Event not at the proper state =%d\n",
364 v->dev_state);
365 break;
366 default:
367 MM_ERR("UNKNOWN EVENT\n");
368 }
369 return;
370}
371EXPORT_SYMBOL(voice_auddev_cb_function);
372
373static void remote_cb_function(void *context, u32 param,
374 void *evt_buf, u32 len)
375{
376 struct voice_header *hdr;
377 struct voice_data *v = context;
378
379 hdr = (struct voice_header *)evt_buf;
380
381 MM_INFO("len=%d id=%d\n", len, hdr->id);
382
383 if (len <= 0) {
384 MM_ERR("unexpected event with length %d \n", len);
385 return;
386 }
387
388 switch (hdr->id) {
389 case EVENT_ACQUIRE_START:
390 atomic_inc(&v->acq_start_flag);
391 wake_up(&v->dev_wait);
392 v->voc_event = VOICE_ACQUIRE_START;
393 v->network = ((struct voice_network *)evt_buf)->network_info;
394 complete(&v->complete);
395 break;
396 case EVENT_RELEASE_START:
397 /* If ACQUIRED come in before the RELEASE,
398 * will only services the RELEASE */
399 atomic_inc(&v->rel_start_flag);
400 wake_up(&v->voc_wait);
401 wake_up(&v->dev_wait);
402 v->voc_event = VOICE_RELEASE_START;
403 complete(&v->complete);
404 break;
405 case EVENT_CHANGE_START:
406 atomic_inc(&v->chg_start_flag);
407 wake_up(&v->voc_wait);
408 v->voc_event = VOICE_CHANGE_START;
409 complete(&v->complete);
410 break;
411 case EVENT_NETWORK_RECONFIG:
412 /* send network change to audio_dev,
413 if sample rate is less than 16k,
414 otherwise, send acquire done */
415 v->voc_event = VOICE_NETWORK_RECONFIG;
416 v->network = ((struct voice_network *)evt_buf)->network_info;
417 complete(&v->complete);
418 break;
419 default:
420 MM_ERR("Undefined event %d \n", hdr->id);
421 }
422
423}
424
425static int voice_cmd_init(struct voice_data *v)
426{
427
428 struct voice_init cmd;
429 int err;
430
431 MM_DBG("\n"); /* Macro prints the file name and function */
432
433 cmd.hdr.id = CMD_VOICE_INIT;
434 cmd.hdr.data_len = sizeof(struct voice_init) -
435 sizeof(struct voice_header);
436 cmd.cb_handle = v->cb_handle;
437
438 err = dalrpc_fcn_5(VOICE_DALRPC_CMD, v->handle, &cmd,
439 sizeof(struct voice_init));
440
441 if (err)
442 MM_ERR("Voice init command failed\n");
443 return err;
444}
445
446static int voice_cmd_acquire_done(struct voice_data *v)
447{
448 struct voice_header hdr;
449 int err;
450
451 hdr.id = CMD_ACQUIRE_DONE;
452 hdr.data_len = 0;
453
454 MM_INFO("\n"); /* Macro prints the file name and function */
455
456 /* Enable HW sidetone if device supports it */
457 msm_snddev_enable_sidetone(v->dev_rx.dev_id, 1);
458
459 err = dalrpc_fcn_5(VOICE_DALRPC_CMD, v->handle, &hdr,
460 sizeof(struct voice_header));
461
462 if (err)
463 MM_ERR("Voice acquire done command failed\n");
464 return err;
465}
466
467static int voice_cmd_device_info(struct voice_data *v)
468{
469 struct voice_device cmd;
470 int err, vol;
471
472 MM_INFO("tx_dev=%d, rx_dev=%d, tx_sample=%d, tx_mute=%d\n",
473 v->dev_tx.dev_acdb_id, v->dev_rx.dev_acdb_id,
474 v->dev_tx.sample, v->dev_tx.mute);
475
476 mutex_lock(&voice.vol_lock);
477
478 cmd.hdr.id = CMD_DEVICE_INFO;
479 cmd.hdr.data_len = sizeof(struct voice_device) -
480 sizeof(struct voice_header);
481 cmd.tx_device = v->dev_tx.dev_acdb_id;
482 cmd.rx_device = v->dev_rx.dev_acdb_id;
483 if (v->network == NETWORK_WCDMA_WB)
484 vol = v->min_rx_vol[VOC_WB_INDEX] +
485 ((v->max_rx_vol[VOC_WB_INDEX] -
486 v->min_rx_vol[VOC_WB_INDEX]) * v->dev_rx.volume)/100;
487 else
488 vol = v->min_rx_vol[VOC_NB_INDEX] +
489 ((v->max_rx_vol[VOC_NB_INDEX] -
490 v->min_rx_vol[VOC_NB_INDEX]) * v->dev_rx.volume)/100;
491 cmd.rx_volume = (u32)vol; /* in mb */
492 cmd.rx_mute = 0;
493 cmd.tx_mute = v->dev_tx.mute;
494 cmd.rx_sample = v->dev_rx.sample/1000;
495 cmd.tx_sample = v->dev_tx.sample/1000;
496
497 MM_DBG("rx_vol=%d, rx_sample=%d\n", cmd.rx_volume, v->dev_rx.sample);
498
499 err = dalrpc_fcn_5(VOICE_DALRPC_CMD, v->handle, &cmd,
500 sizeof(struct voice_device));
501
502 mutex_unlock(&voice.vol_lock);
503
504 if (err)
505 MM_ERR("Voice device command failed\n");
506 return err;
507}
508EXPORT_SYMBOL(voice_cmd_device_info);
509
510void voice_change_sample_rate(struct voice_data *v)
511{
512 int freq = 48000;
513 int rc = 0;
514
515 MM_DBG("network =%d, vote freq=%d\n", v->network, freq);
516 if (freq != v->dev_tx.sample) {
517 rc = msm_snddev_request_freq(&freq, 0,
518 SNDDEV_CAP_TX, AUDDEV_CLNT_VOC);
519 if (rc >= 0) {
520 v->dev_tx.sample = freq;
521 MM_DBG(" vote for freq=%d successfully \n", freq);
522 } else
523 MM_ERR(" voting for freq=%d failed.\n", freq);
524 }
525}
526
527static int voice_thread(void *data)
528{
529 struct voice_data *v = (struct voice_data *)data;
530 int rc = 0;
531
532 MM_INFO("voice_thread() start\n");
533
534 while (!kthread_should_stop()) {
535 wait_for_completion(&v->complete);
536 init_completion(&v->complete);
537
538 MM_DBG(" voc_event=%d, voice state =%d, dev_event=%d\n",
539 v->voc_event, v->voc_state, v->dev_event);
540 switch (v->voc_event) {
541 case VOICE_ACQUIRE_START:
542 /* check if dev_state = READY */
543 /* if ready, send device_info and acquire_done */
544 /* if not ready, block to wait the dev_state = READY */
545 if ((v->voc_state == VOICE_INIT) ||
546 (v->voc_state == VOICE_RELEASE)) {
547 if (v->dev_state == DEV_READY) {
548 mutex_lock(&voice.voc_lock);
549 voice_change_sample_rate(v);
550 rc = voice_cmd_device_info(v);
551 rc = voice_cmd_acquire_done(v);
552 v->voc_state = VOICE_ACQUIRE;
553 mutex_unlock(&voice.voc_lock);
554 broadcast_event(
555 AUDDEV_EVT_VOICE_STATE_CHG,
556 VOICE_STATE_INCALL, SESSION_IGNORE);
557 } else {
558 rc = wait_event_interruptible(
559 v->dev_wait,
560 (v->dev_state == DEV_READY)
561 || (atomic_read(&v->rel_start_flag)
562 == 1));
563 if (atomic_read(&v->rel_start_flag)
564 == 1) {
565 v->voc_state = VOICE_RELEASE;
566 atomic_dec(&v->rel_start_flag);
567 msm_snddev_withdraw_freq(0,
568 SNDDEV_CAP_TX, AUDDEV_CLNT_VOC);
569 broadcast_event(
570 AUDDEV_EVT_VOICE_STATE_CHG,
571 VOICE_STATE_OFFCALL,
572 SESSION_IGNORE);
573 } else {
574 mutex_lock(&voice.voc_lock);
575 voice_change_sample_rate(v);
576 rc = voice_cmd_device_info(v);
577 rc = voice_cmd_acquire_done(v);
578 v->voc_state = VOICE_ACQUIRE;
579 mutex_unlock(&voice.voc_lock);
580 broadcast_event(
581 AUDDEV_EVT_VOICE_STATE_CHG,
582 VOICE_STATE_INCALL,
583 SESSION_IGNORE);
584 }
585 }
586 } else
587 MM_ERR("Get this event at the wrong state\n");
588 if (atomic_read(&v->acq_start_flag))
589 atomic_dec(&v->acq_start_flag);
590 break;
591 case VOICE_RELEASE_START:
592 MM_DBG("broadcast voice call end\n");
593 broadcast_event(AUDDEV_EVT_VOICE_STATE_CHG,
594 VOICE_STATE_OFFCALL, SESSION_IGNORE);
595 if ((v->dev_state == DEV_REL_DONE) ||
596 (v->dev_state == DEV_INIT)) {
597 v->voc_state = VOICE_RELEASE;
598 msm_snddev_withdraw_freq(0, SNDDEV_CAP_TX,
599 AUDDEV_CLNT_VOC);
600 } else {
601 /* wait for the dev_state = RELEASE */
602 rc = wait_event_interruptible(v->dev_wait,
603 (v->dev_state == DEV_REL_DONE)
604 || (atomic_read(&v->acq_start_flag) == 1));
605 if (atomic_read(&v->acq_start_flag) == 1)
606 atomic_dec(&v->acq_start_flag);
607 v->voc_state = VOICE_RELEASE;
608 msm_snddev_withdraw_freq(0, SNDDEV_CAP_TX,
609 AUDDEV_CLNT_VOC);
610 }
611 if (atomic_read(&v->rel_start_flag))
612 atomic_dec(&v->rel_start_flag);
613 break;
614 case VOICE_CHANGE_START:
615 if (v->voc_state == VOICE_ACQUIRE)
616 v->voc_state = VOICE_CHANGE;
617 else
618 MM_ERR("Get this event at the wrong state\n");
619 wake_up(&v->voc_wait);
620 if (atomic_read(&v->chg_start_flag))
621 atomic_dec(&v->chg_start_flag);
622 break;
623 case VOICE_NETWORK_RECONFIG:
624 if ((v->voc_state == VOICE_ACQUIRE)
625 || (v->voc_state == VOICE_CHANGE)) {
626 voice_change_sample_rate(v);
627 rc = voice_cmd_device_info(v);
628 rc = voice_cmd_acquire_done(v);
629 }
630 break;
631 default:
632 break;
633 }
634
635 switch (v->dev_event) {
636 case DEV_CHANGE_READY:
637 if (v->voc_state == VOICE_CHANGE) {
638 mutex_lock(&voice.voc_lock);
639 msm_snddev_enable_sidetone(v->dev_rx.dev_id,
640 1);
641 /* update voice state */
642 v->voc_state = VOICE_ACQUIRE;
643 v->dev_event = 0;
644 mutex_unlock(&voice.voc_lock);
645 broadcast_event(AUDDEV_EVT_VOICE_STATE_CHG,
646 VOICE_STATE_INCALL, SESSION_IGNORE);
647 } else {
648 mutex_lock(&voice.voc_lock);
649 v->dev_event = 0;
650 mutex_unlock(&voice.voc_lock);
651 MM_ERR("Get this event at the wrong state\n");
652 }
653 break;
654 default:
655 mutex_lock(&voice.voc_lock);
656 v->dev_event = 0;
657 mutex_unlock(&voice.voc_lock);
658 break;
659 }
660 }
661 return 0;
662}
663
664static int __init voice_init(void)
665{
666 int rc, i;
667 struct voice_data *v = &voice;
668 MM_INFO("\n"); /* Macro prints the file name and function */
669
670 mutex_init(&voice.voc_lock);
671 mutex_init(&voice.vol_lock);
672 v->handle = NULL;
673 v->cb_handle = NULL;
674
675 /* set default value */
676 v->default_mute_val = 1; /* default is mute */
677 v->default_vol_val = 0;
678 v->default_sample_val = 8000;
679 for (i = 0; i < VOC_RX_VOL_ARRAY_NUM; i++) {
680 v->max_rx_vol[i] = 0;
681 v->min_rx_vol[i] = 0;
682 }
683 v->network = NETWORK_GSM;
684
685 /* initialize dev_rx and dev_tx */
686 memset(&v->dev_tx, 0, sizeof(struct device_data));
687 memset(&v->dev_rx, 0, sizeof(struct device_data));
688 v->dev_rx.volume = v->default_vol_val;
689 v->dev_tx.mute = v->default_mute_val;
690
691 v->dev_state = DEV_INIT;
692 v->voc_state = VOICE_INIT;
693 atomic_set(&v->rel_start_flag, 0);
694 atomic_set(&v->acq_start_flag, 0);
695 v->dev_event = 0;
696 v->voc_event = 0;
697 init_completion(&voice.complete);
698 init_waitqueue_head(&v->dev_wait);
699 init_waitqueue_head(&v->voc_wait);
700
701 /* get device handle */
702 rc = daldevice_attach(VOICE_DALRPC_DEVICEID,
703 VOICE_DALRPC_PORT_NAME,
704 VOICE_DALRPC_CPU,
705 &v->handle);
706 if (rc) {
707 MM_ERR("Voc DALRPC call to Modem attach failed\n");
708 goto done;
709 }
710
711 /* Allocate the callback handle */
712 v->cb_handle = dalrpc_alloc_cb(v->handle, remote_cb_function, v);
713 if (v->cb_handle == NULL) {
714 MM_ERR("Allocate Callback failure\n");
715 goto err;
716 }
717
718 /* setup the callback */
719 rc = voice_cmd_init(v);
720 if (rc)
721 goto err1;
722
723 v->device_events = AUDDEV_EVT_DEV_CHG_VOICE |
724 AUDDEV_EVT_DEV_RDY |
725 AUDDEV_EVT_REL_PENDING |
726 AUDDEV_EVT_START_VOICE |
727 AUDDEV_EVT_END_VOICE |
728 AUDDEV_EVT_DEVICE_VOL_MUTE_CHG |
729 AUDDEV_EVT_FREQ_CHG;
730
731 MM_DBG(" to register call back \n");
732 /* register callback to auddev */
733 auddev_register_evt_listner(v->device_events, AUDDEV_CLNT_VOC,
734 0, voice_auddev_cb_function, v);
735
736 /* create and start thread */
737 v->task = kthread_run(voice_thread, v, "voice");
738 if (IS_ERR(v->task)) {
739 rc = PTR_ERR(v->task);
740 v->task = NULL;
741 } else
742 goto done;
743
744err1: dalrpc_dealloc_cb(v->handle, v->cb_handle);
745err:
746 daldevice_detach(v->handle);
747 v->handle = NULL;
748done:
749 return rc;
750}
751
752late_initcall(voice_init);