misc: bluedroid_pm: Convert to proc_create_data
[linux-3.10.git] / drivers / misc / a2220.c
1 /* drivers/i2c/chips/a2220.c - a2220 voice processor driver
2  *
3  * Copyright (C) 2009 HTC Corporation.
4  *
5  * This software is licensed under the terms of the GNU General Public
6  * License version 2, as published by the Free Software Foundation, and
7  * may be copied, distributed, and modified under those terms.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  */
15
16 #include <linux/kernel.h>
17 #include <linux/init.h>
18 #include <linux/err.h>
19 #include <linux/module.h>
20 #include <linux/interrupt.h>
21 #include <linux/i2c.h>
22 #include <linux/slab.h>
23 #include <linux/irq.h>
24 #include <linux/miscdevice.h>
25 #include <linux/gpio.h>
26 #include <linux/uaccess.h>
27 #include <linux/delay.h>
28 #include <linux/input.h>
29 #include <linux/workqueue.h>
30 #include <linux/freezer.h>
31 #include <linux/a2220.h>
32 #include <linux/a2220_fw.h>
33 #include <linux/kthread.h>
34 #include <linux/clk.h>
35
36 #include <mach/iomap.h>
37 #include <linux/io.h>
38
39
40 #define PMC_CLK_OUT                     0x1a8
41 #define CLK3_SRC_SEL    (0x3 << 22)
42 #define CLK3_FORCE_EN   (0x1 << 18)
43
44 #define MODULE_NAME "audience_a2220"
45 #define DEBUG                   (0)
46 #define ENABLE_DIAG_IOCTLS      (0)
47 #define WAKEUP_GPIO_NUM_HERCULES_REV01 33
48 #define WAKEUP_GPIO_NUM_CELOX_ATT_REV05 33
49
50 /* MAGIC NUMBERS! Fixme */
51 #define VP_RESET 118
52 #define AUDIO_LD0_EN  60
53 #define AMP_SHUTDOWN_N  139
54
55 static struct i2c_client *this_client;
56 static struct a2220_platform_data *pdata;
57 static struct task_struct *task;
58 static int execute_cmdmsg(unsigned int);
59
60 static struct mutex a2220_lock;
61 static int a2220_opened;
62 static int a2220_suspended;
63 static int control_a2220_clk = 0;
64 struct clk *extern3_clk;
65 static unsigned int a2220_NS_state = A2220_NS_STATE_AUTO;
66 static int a2220_current_config = A2220_PATH_SUSPEND;
67 static int a2220_param_ID;
68
69 struct vp_ctxt {
70         unsigned char *data;
71         unsigned int img_size;
72 };
73
74 struct vp_ctxt the_vp;
75
76 unsigned int get_hw_rev(void)
77 {
78         return 0x05;
79 }
80
81 static int a2220_i2c_read(char *rxData, int length)
82 {
83         int rc;
84         struct i2c_msg msgs[] = {
85                 {
86                  .addr = this_client->addr,
87                  .flags = I2C_M_RD,
88                  .len = length,
89                  .buf = rxData,
90                  },
91         };
92
93         rc = i2c_transfer(this_client->adapter, msgs, 1);
94         if (rc < 0) {
95                 printk(KERN_ERR "%s: transfer error %d\n", __func__, rc);
96                 return rc;
97         }
98 #if DEBUG
99         {
100                 int i = 0;
101                 for (i = 0; i < length; i++)
102                         pr_info("%s: rx[%d] = %2x\n", __func__, i, rxData[i]);
103         }
104 #endif
105
106         return 0;
107 }
108
109 static int a2220_i2c_write(char *txData, int length)
110 {
111         int rc;
112         struct i2c_msg msg[] = {
113                 {
114                  .addr = this_client->addr,
115                  .flags = 0,
116                  .len = length,
117                  .buf = txData,
118                  },
119         };
120
121         rc = i2c_transfer(this_client->adapter, msg, 1);
122         if (rc < 0) {
123                 printk(KERN_ERR "%s: transfer error %d\n", __func__, rc);
124                 return rc;
125         }
126 #if DEBUG
127         {
128                 int i = 0;
129                 for (i = 0; i < length; i++)
130                         pr_info("%s: tx[%d] = %2x\n", __func__, i, txData[i]);
131         }
132 #endif
133
134         return 0;
135 }
136
137 static int a2220_open(struct inode *inode, struct file *file)
138 {
139         int rc = 0;
140         struct vp_ctxt *vp = &the_vp;
141
142         mutex_lock(&a2220_lock);
143
144         if (a2220_opened) {
145                 printk(KERN_ERR "%s: busy\n", __func__);
146                 rc = -EBUSY;
147                 goto done;
148         }
149
150         file->private_data = vp;
151         vp->img_size = 0;
152         a2220_opened = 1;
153  done:
154         mutex_unlock(&a2220_lock);
155         return rc;
156 }
157
158 static int a2220_release(struct inode *inode, struct file *file)
159 {
160         mutex_lock(&a2220_lock);
161         a2220_opened = 0;
162         mutex_unlock(&a2220_lock);
163
164         return 0;
165 }
166
167 #ifdef AUDIENCE_BYPASS                    /*(+)dragonball Multimedia mode */
168 #define A100_msg_mutimedia1   0x801C0000  /*VoiceProcessingOn, 0x0000:off */
169 #define A100_msg_mutimedia2   0x8026001F  /*SelectRouting, 0x001A:(26) */
170 #define A100_msg_mutimedia3   0x800C0B03  /* ; PCM B Din delay 1bit */
171 #define A100_msg_mutimedia4   0x800D0001
172 #define A100_msg_mutimedia5   0x800C0A03  /* ; PCM A Din delay 1bit */
173 #define A100_msg_mutimedia6   0x800D0001
174 #endif
175
176 static void a2220_i2c_sw_reset(unsigned int reset_cmd)
177 {
178         int rc = 0;
179         unsigned char msgbuf[4];
180
181         msgbuf[0] = (reset_cmd >> 24) & 0xFF;
182         msgbuf[1] = (reset_cmd >> 16) & 0xFF;
183         msgbuf[2] = (reset_cmd >> 8) & 0xFF;
184         msgbuf[3] = reset_cmd & 0xFF;
185
186         pr_info("%s: %08x\n", __func__, reset_cmd);
187
188         rc = a2220_i2c_write(msgbuf, 4);
189         if (!rc)
190                 msleep(20);
191 }
192
193 static ssize_t a2220_hw_reset(struct a2220img *img)
194 {
195         struct a2220img *vp = img;
196         int rc, i, pass = 0;
197         int remaining;
198         int retry = RETRY_CNT;
199         unsigned char *index;
200         char buf[2];
201
202         while (retry--) {
203                 /* Reset A2220 chip */
204                 if (pdata->gpio_a2220_reset)
205                         gpio_set_value(pdata->gpio_a2220_reset, 0);
206                 else
207                         gpio_set_value(VP_RESET, 1);
208
209                 /* Enable A2220 clock */
210                 if (control_a2220_clk)
211                         gpio_set_value(pdata->gpio_a2220_clk, 1);
212                 mdelay(1);
213
214                 /* Take out of reset */
215                 if (pdata->gpio_a2220_reset)
216                         gpio_set_value(pdata->gpio_a2220_reset, 1);
217                 else
218                         gpio_set_value(VP_RESET, 0);
219
220                 msleep(50);     /* Delay before send I2C command */
221
222                 /* Boot Cmd to A2220 */
223                 buf[0] = A2220_msg_BOOT >> 8;
224                 buf[1] = A2220_msg_BOOT & 0xff;
225
226                 rc = a2220_i2c_write(buf, 2);
227                 if (rc < 0) {
228                         printk(KERN_ERR "%s: set boot mode error (%d retries left)\n",
229                                __func__, retry);
230                         continue;
231                 }
232
233                 mdelay(1);
234                 rc = a2220_i2c_read(buf, 1);
235
236                 if (rc < 0) {
237                         printk(KERN_ERR "%s: boot mode ack error (%d retries left)\n",
238                                __func__, retry);
239                         continue;
240                 }
241
242                 remaining = vp->img_size / 32;
243                 index = vp->buf;
244
245                 for (; remaining; remaining--, index += 32) {
246                         rc = a2220_i2c_write(index, 32);
247                         if (rc < 0)
248                                 break;
249                 }
250
251                 if (rc >= 0 && vp->img_size % 32)
252                         rc = a2220_i2c_write(index, vp->img_size % 32);
253
254                 if (rc < 0) {
255                         printk(KERN_ERR "%s: fw load error %d (%d retries left)\n",
256                                __func__, rc, retry);
257                         continue;
258                 }
259
260                 msleep(20);     /* Delay time before issue a Sync Cmd */
261
262                 for (i = 0; i < 10; i++)
263                         msleep(20);
264
265                 rc = execute_cmdmsg(A100_msg_Sync);
266                 if (rc < 0) {
267                         printk(KERN_ERR "%s: sync command error %d (%d retries left)\n",
268                                __func__, rc, retry);
269                         continue;
270                 }
271
272                 pass = 1;
273                 break;
274         }
275         return rc;
276 }
277
278 /* eS305B HPT  */
279 #ifdef CONFIG_USA_MODEL_SGH_I717
280 static int hpt_longCmd_execute(unsigned char *i2c_cmds, int size)
281 {
282
283         int i = 0, rc = 0;
284         int retry = 4;
285 /*      unsigned int sw_reset = 0; */
286         unsigned int msg;
287         unsigned char *pMsg;
288
289         pMsg = (unsigned char *)&msg;
290
291         for (i = 0; i < size; i += 4) {
292                 pMsg[3] = i2c_cmds[i];
293                 pMsg[2] = i2c_cmds[i + 1];
294                 pMsg[1] = i2c_cmds[i + 2];
295                 pMsg[0] = i2c_cmds[i + 3];
296
297                 do {
298                         rc = execute_cmdmsg(msg);
299                 } while ((rc < 0) && --retry);
300
301         }
302         return 0;
303 }
304 #endif
305
306 static int a2220_set_boot_mode()
307 {
308         int rc;
309         int retry = RETRY_CNT;
310         char buf[2];
311
312         mdelay(100);
313
314         while (retry--) {
315                 /* Reset A2220 chip */
316                 gpio_set_value(VP_RESET, 1);
317
318                 /* Enable A2220 clock */
319                 if (control_a2220_clk)
320                         gpio_set_value(pdata->gpio_a2220_clk, 1);
321                 mdelay(1);
322
323                 /* Take out of reset */
324                 gpio_set_value(VP_RESET, 0);
325
326                 msleep(150); /* Delay before send I2C command */
327
328                 /* Boot Cmd to A2220 */
329                 buf[0] = A2220_msg_BOOT >> 8;
330                 buf[1] = A2220_msg_BOOT & 0xff;
331                 rc = a2220_i2c_write(buf, 2);
332                 if (rc < 0) {
333                         printk(KERN_ERR "%s: write error (%d retries left)\n",
334                                __func__, retry);
335                         if (retry > 0)
336                                 continue;
337                         else
338                                 return rc;
339                 }
340
341                 mdelay(1);
342                 rc = a2220_i2c_read(buf, 1);
343
344                 if (rc < 0) {
345                         printk(KERN_ERR "%s: ack error (%d retries left)\n",
346                                __func__, retry);
347                         continue;
348                 }
349         }
350
351         return rc;
352 }
353
354 static ssize_t a2220_bootup_init(struct a2220img *pImg)
355 {
356         struct a2220img *vp = pImg;
357         int rc, pass = 0;
358         int remaining;
359         int retry = RETRY_CNT;
360         unsigned char *index;
361         char buf[2];
362
363         mdelay(10);
364
365         while (retry--) {
366                 remaining = vp->img_size / 32;
367                 index = vp->buf;
368                 pr_info("%s: starting to load image (%d passes)...\n",
369                         __func__, remaining + !!(vp->img_size % 32));
370
371                 for (; remaining; remaining--, index += 32) {
372                         rc = a2220_i2c_write(index, 32);
373                         if (rc < 0)
374                                 break;
375                 }
376
377                 if (rc >= 0 && vp->img_size % 32)
378                         rc = a2220_i2c_write(index, vp->img_size % 32);
379
380                 if (rc < 0) {
381                         printk(KERN_ERR "%s: fw load error %d (%d retries left)\n",
382                                __func__, rc, retry);
383                         continue;
384                 }
385
386                 msleep(150);    /* Delay time before issue a Sync Cmd */
387
388                 rc = execute_cmdmsg(A100_msg_Sync);
389                 if (rc < 0) {
390                         printk(KERN_ERR "%s: sync command error %d (%d retries left)\n",
391                                __func__, rc, retry);
392                         continue;
393                 }
394
395                 pass = 1;
396                 break;
397         }
398
399         rc = execute_cmdmsg(A100_msg_ReadPortA);
400         if (rc < 0)
401                 printk(KERN_ERR "%s: suspend error\n", __func__);
402
403         rc = execute_cmdmsg(A100_msg_PortD_C_PASS);
404         if (rc < 0)
405                 printk(KERN_ERR "%s: suspend error\n", __func__);
406
407         rc = execute_cmdmsg(A100_msg_PortB_A_PASS);
408         if (rc < 0)
409                 printk(KERN_ERR "%s: suspend error\n", __func__);
410
411         a2220_suspended = 0;
412         rc = execute_cmdmsg(A100_msg_Sleep);
413         if (rc < 0)
414                 printk(KERN_ERR "%s: suspend error\n", __func__);
415
416         msleep(30);
417
418         if (control_a2220_clk)
419                 clk_disable(extern3_clk);
420
421         return rc;
422 }
423
424
425 static ssize_t chk_wakeup_a2220(void)
426 {
427         int i, rc = 0, retry = 4;
428
429         if (a2220_suspended == 1) {
430                 /* Enable A2220 clock */
431                 if (control_a2220_clk) {
432                         gpio_set_value(pdata->gpio_a2220_clk, 1);
433                         mdelay(1);
434                 }
435
436                 if (pdata->gpio_a2220_wakeup) {
437                         printk(MODULE_NAME
438                                "%s : chk_wakeup_a2220  --> get_hw_rev of Target = %d\n",
439                                __func__, get_hw_rev());
440 #ifdef CONFIG_USA_MODEL_SGH_T989
441                         if (get_hw_rev() >= 0x05)
442                                 gpio_set_value(WAKEUP_GPIO_NUM_HERCULES_REV01,
443                                                0);
444                         else
445                                 gpio_set_value(pdata->gpio_a2220_wakeup, 0);
446 #elif CONFIG_USA_MODEL_SGH_I727
447                         qweqwewq if (get_hw_rev() >= 0x05)
448                                 gpio_set_value(WAKEUP_GPIO_NUM_CELOX_ATT_REV05,
449                                                0);
450                         else
451                                 gpio_set_value(pdata->gpio_a2220_wakeup, 0);
452 #elif CONFIG_USA_MODEL_SGH_I717
453                         gpio_set_value(WAKEUP_GPIO_NUM_CELOX_ATT_REV05, 0);
454 #else
455                         gpio_set_value(pdata->gpio_a2220_wakeup, 0);
456 #endif
457                 }
458 #ifdef CONFIG_USA_MODEL_SGH_I717
459                 for (i = 0; i < 5; i++)
460                         msleep(20);
461 #else
462                 msleep(30);
463 #endif
464
465                 do {
466                         rc = execute_cmdmsg(A100_msg_Sync);
467                 } while ((rc < 0) && --retry);
468
469                 /* Audience not responding to execute_cmdmsg ,
470                 * doing HW reset of the chipset */
471                 if ((retry == 0) && (rc < 0)) {
472                         struct a2220img img;
473                         img.buf = a2220_firmware_buf;
474                         img.img_size = sizeof(a2220_firmware_buf);
475                         rc = a2220_hw_reset(&img);      /* Call if the Audience
476                         chipset is not responding after retrying 12 times */
477                 }
478                 if (rc < 0)
479                         printk(MODULE_NAME "%s ::  Audience HW Reset Failed\n",
480                                __func__);
481
482 #ifdef CONFIG_USA_MODEL_SGH_I717
483                 rc = hpt_longCmd_execute(hpt_init_macro,
484                                          sizeof(hpt_init_macro));
485                 if (rc < 0)
486                         printk(MODULE_NAME "%s: htp init error\n", __func__);
487 #endif
488
489                 if (pdata->gpio_a2220_wakeup) {
490 #ifdef CONFIG_USA_MODEL_SGH_T989
491                         if (get_hw_rev() >= 0x05)
492                                 gpio_set_value(WAKEUP_GPIO_NUM_HERCULES_REV01,
493                                                1);
494                         else
495                                 gpio_set_value(pdata->gpio_a2220_wakeup, 1);
496 #elif CONFIG_USA_MODEL_SGH_I727
497                         if (get_hw_rev() >= 0x05)
498                                 gpio_set_value(WAKEUP_GPIO_NUM_CELOX_ATT_REV05,
499                                                1);
500                         else
501                                 gpio_set_value(pdata->gpio_a2220_wakeup, 1);
502 #elif CONFIG_USA_MODEL_SGH_I717
503                         gpio_set_value(WAKEUP_GPIO_NUM_CELOX_ATT_REV05, 1);
504 #else
505                         gpio_set_value(pdata->gpio_a2220_wakeup, 1);
506 #endif
507                 }
508
509                 if (rc < 0) {
510                         printk(KERN_ERR "%s: failed (%d)\n", __func__, rc);
511                         goto wakeup_sync_err;
512                 }
513
514                 a2220_suspended = 0;
515         }
516  wakeup_sync_err:
517         return rc;
518 }
519
520 /* Filter commands according to noise suppression state forced by
521  * A2220_SET_NS_STATE ioctl.
522  *
523  * For this function to operate properly, all configurations must include
524  * both A100_msg_Bypass and Mic_Config commands even if default values
525  * are selected or if Mic_Config is useless because VP is off
526  */
527 int a2220_filter_vp_cmd(int cmd, int mode)
528 {
529         int msg = (cmd >> 16) & 0xFFFF;
530         int filtered_cmd = cmd;
531
532         if (a2220_NS_state == A2220_NS_STATE_AUTO)
533                 return cmd;
534
535         switch (msg) {
536         case A100_msg_Bypass:
537                 if (a2220_NS_state == A2220_NS_STATE_OFF)
538                         filtered_cmd = A2220_msg_VP_OFF;
539                 else
540                         filtered_cmd = A2220_msg_VP_ON;
541                 break;
542         case A100_msg_SetAlgorithmParmID:
543                 a2220_param_ID = cmd & 0xFFFF;
544                 break;
545         case A100_msg_SetAlgorithmParm:
546                 if (a2220_param_ID == Mic_Config) {
547                         if (a2220_NS_state == A2220_NS_STATE_CT)
548                                 filtered_cmd = (msg << 16);
549                         else if (a2220_NS_state == A2220_NS_STATE_FT)
550                                 filtered_cmd = (msg << 16) | 0x0002;
551                 }
552                 break;
553         default:
554                 if (mode == A2220_CONFIG_VP)
555                         filtered_cmd = -1;
556                 break;
557         }
558
559         pr_info("%s: %x filtered = %x, a2220_NS_state %d, mode %d\n", __func__,
560                 cmd, filtered_cmd, a2220_NS_state, mode);
561
562         return filtered_cmd;
563 }
564
565 int a2220_set_config(char newid, int mode)
566 {
567         int i = 0, rc = 0, size = 0;
568         int retry = 4;
569         unsigned int sw_reset = 0;
570         unsigned char *i2c_cmds;
571         unsigned int msg;
572         unsigned char *pMsg;
573
574         if ((a2220_suspended) && (newid == A2220_PATH_SUSPEND))
575                 return rc;
576
577 #if defined(CONFIG_USA_MODEL_SGH_T989) || defined(CONFIG_USA_MODEL_SGH_I727)\
578                 || defined(CONFIG_USA_MODEL_SGH_I717)
579         if (a2220_current_config == newid) {
580                 printk(KERN_DEBUG "already configured this path!!!\n");
581                 return rc;
582         }
583 #endif
584
585         rc = chk_wakeup_a2220();
586         if (rc < 0)
587                 return rc;
588
589         sw_reset = ((A100_msg_Reset << 16) | RESET_IMMEDIATE);
590
591         switch (newid) {
592         case A2220_PATH_INCALL_RECEIVER_NSON:
593                 i2c_cmds = phonecall_receiver_nson;
594                 size = sizeof(phonecall_receiver_nson);
595                 break;
596
597         case A2220_PATH_INCALL_RECEIVER_NSOFF:
598                 i2c_cmds = phonecall_receiver_nsoff;
599                 size = sizeof(phonecall_receiver_nsoff);
600                 break;
601
602                 /* (+) ysseo 20110420 : to use a2220 bypass mode */
603 #ifdef AUDIENCE_BYPASS          /*(+)dragonball Multimedia bypass mode */
604         case A2220_PATH_BYPASS_MULTIMEDIA:
605                 printk(KERN_DEBUG "%s : setting A2220_PATH_BYPASS_MULTIMEDIA\n",
606                          __func__);
607                 i2c_cmds = bypass_multimedia;
608                 size = sizeof(bypass_multimedia);
609                 break;
610 #endif
611         case A2220_PATH_INCALL_HEADSET:
612                 i2c_cmds = phonecall_headset;
613                 size = sizeof(phonecall_headset);
614                 break;
615         case A2220_PATH_INCALL_SPEAKER:
616                 i2c_cmds = phonecall_speaker;
617                 size = sizeof(phonecall_speaker);
618                 break;
619         case A2220_PATH_INCALL_BT:
620                 i2c_cmds = phonecall_bt;
621                 size = sizeof(phonecall_bt);
622                 break;
623         case A2220_PATH_INCALL_TTY:
624                 i2c_cmds = phonecall_tty;
625                 size = sizeof(phonecall_tty);
626                 break;
627         case A2220_PATH_VR_NO_NS_RECEIVER:
628                 i2c_cmds = vr_no_ns_receiver;
629                 size = sizeof(vr_no_ns_receiver);
630                 break;
631         case A2220_PATH_VR_NO_NS_HEADSET:
632                 i2c_cmds = vr_no_ns_headset;
633                 size = sizeof(vr_no_ns_headset);
634                 break;
635         case A2220_PATH_VR_NO_NS_SPEAKER:
636                 i2c_cmds = vr_no_ns_speaker;
637                 size = sizeof(vr_no_ns_speaker);
638                 break;
639         case A2220_PATH_VR_NO_NS_BT:
640                 i2c_cmds = vr_no_ns_bt;
641                 size = sizeof(vr_no_ns_bt);
642                 break;
643         case A2220_PATH_VR_NS_RECEIVER:
644                 i2c_cmds = vr_ns_receiver;
645                 size = sizeof(vr_ns_receiver);
646                 break;
647         case A2220_PATH_VR_NS_HEADSET:
648                 i2c_cmds = vr_ns_headset;
649                 size = sizeof(vr_ns_headset);
650                 break;
651         case A2220_PATH_VR_NS_SPEAKER:
652                 i2c_cmds = vr_ns_speaker;
653                 size = sizeof(vr_ns_speaker);
654                 break;
655         case A2220_PATH_VR_NS_BT:
656                 i2c_cmds = vr_ns_bt;
657                 size = sizeof(vr_ns_bt);
658                 break;
659         case A2220_PATH_RECORD_RECEIVER:
660                 i2c_cmds = INT_MIC_recording_receiver;
661                 size = sizeof(INT_MIC_recording_receiver);
662                 break;
663         case A2220_PATH_RECORD_HEADSET:
664                 i2c_cmds = EXT_MIC_recording;
665                 size = sizeof(EXT_MIC_recording);
666                 break;
667         case A2220_PATH_RECORD_SPEAKER:
668                 i2c_cmds = INT_MIC_recording_speaker;
669                 size = sizeof(INT_MIC_recording_speaker);
670                 break;
671         case A2220_PATH_RECORD_BT:
672                 i2c_cmds = phonecall_bt;
673                 size = sizeof(phonecall_bt);
674                 break;
675         case A2220_PATH_SUSPEND:
676                 i2c_cmds = (unsigned char *)suspend_mode;
677                 size = sizeof(suspend_mode);
678                 break;
679         case A2220_PATH_CAMCORDER:
680                 i2c_cmds = BACK_MIC_recording;
681                 size = sizeof(BACK_MIC_recording);
682                 break;
683         default:
684                 printk(KERN_ERR "%s: invalid cmd %d\n", __func__, newid);
685                 rc = -1;
686                 goto input_err;
687                 break;
688         }
689
690         a2220_current_config = newid;
691
692 #if DEBUG
693         pr_info("%s: change to mode %d\n", __func__, newid);
694         pr_info("%s: block write start (size = %d)\n", __func__, size);
695         for (i = 1; i <= size; i++) {
696                 pr_info("%x ", *(i2c_cmds + i - 1));
697                 if (!(i % 4))
698                         pr_info("\n");
699         }
700 #endif
701
702 #if 1
703
704         pMsg = (unsigned char *)&msg;
705
706         for (i = 0; i < size; i += 4) {
707                 pMsg[3] = i2c_cmds[i];
708                 pMsg[2] = i2c_cmds[i + 1];
709                 pMsg[1] = i2c_cmds[i + 2];
710                 pMsg[0] = i2c_cmds[i + 3];
711
712                 do {
713                         rc = execute_cmdmsg(msg);
714                 } while ((rc < 0) && --retry);
715
716                 /* Audience not responding to execute_cmdmsg ,
717                 * doing HW reset of the chipset */
718                 if ((retry == 0) && (rc < 0)) {
719                         struct a2220img img;
720                         img.buf = a2220_firmware_buf;
721                         img.img_size = sizeof(a2220_firmware_buf);
722                         rc = a2220_hw_reset(&img); /* Call if the Audience
723                         chipset is not responding after retrying 12 times */
724                         if (rc < 0) {
725                                 printk(MODULE_NAME
726                                        "%s ::  Audience HW Reset Failed\n",
727                                        __func__);
728                                 return rc;
729                         }
730                 }
731
732         }
733
734 #else
735         rc = a2220_i2c_write(i2c_cmds, size);
736         if (rc < 0) {
737                 printk(KERN_ERR "A2220 CMD block write error!\n");
738                 a2220_i2c_sw_reset(sw_reset);
739                 return rc;
740         }
741         pr_info("%s: block write end\n", __func__);
742
743         /* Don't need to get Ack after sending out a suspend command */
744         if (*i2c_cmds == 0x80 && *(i2c_cmds + 1) == 0x10
745             && *(i2c_cmds + 2) == 0x00 && *(i2c_cmds + 3) == 0x01) {
746                 a2220_suspended = 1;
747                 /* Disable A2220 clock */
748                 msleep(120);
749                 if (control_a2220_clk)
750                         gpio_set_value(pdata->gpio_a2220_clk, 0);
751                 return rc;
752         }
753
754         memset(ack_buf, 0, sizeof(ack_buf));
755         msleep(20);
756         pr_info("%s: CMD ACK block read start\n", __func__);
757         rc = a2220_i2c_read(ack_buf, size);
758         if (rc < 0) {
759                 printk(KERN_ERR "%s: CMD ACK block read error\n", __func__);
760                 a2220_i2c_sw_reset(sw_reset);
761                 return rc;
762         } else {
763                 pr_info("%s: CMD ACK block read end\n", __func__);
764 #if DEBUG
765                 for (i = 1; i <= size; i++) {
766                         pr_info("%x ", ack_buf[i - 1]);
767                         if (!(i % 4))
768                                 pr_info("\n");
769                 }
770 #endif
771                 index = ack_buf;
772                 number_of_cmd_sets = size / 4;
773                 do {
774                         if (*index == 0x00) {
775                                 rd_retry_cnt = POLLING_RETRY_CNT;
776  rd_retry:
777                                 if (rd_retry_cnt--) {
778                                         memset(rdbuf, 0, sizeof(rdbuf));
779                                         rc = a2220_i2c_read(rdbuf, 4);
780                                         if (rc < 0)
781                                                 return rc;
782 #if DEBUG
783                                         for (i = 0; i < sizeof(rdbuf); i++)
784                                                 pr_info("0x%x\n", rdbuf[i]);
785                                         pr_info("-----------------\n");
786 #endif
787                                         if (rdbuf[0] == 0x00) {
788                                                 msleep(20);
789                                                 goto rd_retry;
790                                         }
791                                 } else {
792                                         printk(KERN_ERR "%s: CMD ACK Not Ready\n",
793                                                __func__);
794                                         return -EBUSY;
795                                 }
796                         } else if (*index == 0xff) {    /* illegal cmd */
797                                 return -ENOEXEC;
798                         } else if (*index == 0x80) {
799                                 index += 4;
800                         }
801                 } while (--number_of_cmd_sets);
802         }
803 #endif
804
805  input_err:
806         return rc;
807 }
808
809 int execute_cmdmsg(unsigned int msg)
810 {
811         int rc = 0;
812         int retries, pass = 0;
813         unsigned char msgbuf[4];
814         unsigned char chkbuf[4];
815         unsigned int sw_reset = 0;
816
817         sw_reset = ((A100_msg_Reset << 16) | RESET_IMMEDIATE);
818
819         msgbuf[0] = (msg >> 24) & 0xFF;
820         msgbuf[1] = (msg >> 16) & 0xFF;
821         msgbuf[2] = (msg >> 8) & 0xFF;
822         msgbuf[3] = msg & 0xFF;
823
824 #if DEBUG
825         printk(KERN_DEBUG "%s : execute_cmdmsg :: %x %x %x %x\n",
826                 __func__, msgbuf[0], msgbuf[1], msgbuf[2], msgbuf[3]);
827 #endif
828         memcpy(chkbuf, msgbuf, 4);
829
830         rc = a2220_i2c_write(msgbuf, 4);
831         if (rc < 0) {
832                 a2220_i2c_sw_reset(sw_reset);
833
834                 if (msg == A100_msg_Sleep) {
835                         printk(MODULE_NAME
836                                "%s : execute_cmdmsg ...go to suspend first\n",
837                                __func__);
838                         a2220_suspended = 1;/*(+)dragonball test for audience */
839                         msleep(120);
840
841                 }
842                 return rc;
843         }
844
845         /* We don't need to get Ack after sending out a suspend command */
846         if (msg == A100_msg_Sleep) {
847                 printk(MODULE_NAME "%s : ...go to suspend first\n", __func__);
848                 a2220_suspended = 1;    /*(+)dragonball test for audience */
849
850                 return rc;
851         }
852
853         retries = POLLING_RETRY_CNT;
854         while (retries--) {
855                 rc = 0;
856                 memset(msgbuf, 0, sizeof(msgbuf));
857                 rc = a2220_i2c_read(msgbuf, 4);
858                 if (rc < 0) {
859                         printk(KERN_ERR "%s: ...........ack-read error %d (%d retries)\n",
860                              __func__, rc, retries);
861                         continue;
862                 }
863
864                 if (msgbuf[0] == 0x80 && msgbuf[1] == chkbuf[1]) {
865                         pass = 1;
866                         break;
867                 } else if (msgbuf[0] == 0xff && msgbuf[1] == 0xff) {
868                         printk(KERN_ERR "%s: illegal cmd %08x\n",
869                                 __func__, msg);
870                         rc = -EINVAL;
871                         /*break; */
872                 } else if (msgbuf[0] == 0x00 && msgbuf[1] == 0x00) {
873                         pr_info("%s: not ready (%d retries)\n", __func__,
874                                 retries);
875                         rc = -EBUSY;
876                 } else {
877                         pr_info("%s: cmd/ack mismatch: (%d retries left)\n",
878                                 __func__, retries);
879 #if DEBUG
880                         pr_info("%s: msgbuf[0] = %x\n", __func__, msgbuf[0]);
881                         pr_info("%s: msgbuf[1] = %x\n", __func__, msgbuf[1]);
882                         pr_info("%s: msgbuf[2] = %x\n", __func__, msgbuf[2]);
883                         pr_info("%s: msgbuf[3] = %x\n", __func__, msgbuf[3]);
884 #endif
885                         rc = -EBUSY;
886                 }
887                 msleep(20);     /* use polling */
888         }
889
890         if (!pass) {
891                 printk(KERN_ERR "%s: failed execute cmd %08x (%d)\n",
892                         __func__, msg, rc);
893                 a2220_i2c_sw_reset(sw_reset);
894         }
895
896         return rc;
897 }
898
899 #if ENABLE_DIAG_IOCTLS
900 static int a2220_set_mic_state(char miccase)
901 {
902         int rc = 0;
903         unsigned int cmd_msg = 0;
904
905         switch (miccase) {
906         case 1:         /* Mic-1 ON / Mic-2 OFF */
907                 cmd_msg = 0x80260007;
908                 break;
909         case 2:         /* Mic-1 OFF / Mic-2 ON */
910                 cmd_msg = 0x80260015;
911                 break;
912         case 3:         /* both ON */
913                 cmd_msg = 0x80260001;
914                 break;
915         case 4:         /* both OFF */
916                 cmd_msg = 0x80260006;
917                 break;
918         default:
919                 pr_info("%s: invalid input %d\n", __func__, miccase);
920                 rc = -EINVAL;
921                 break;
922         }
923         rc = execute_cmdmsg(cmd_msg);
924         return rc;
925 }
926
927 static int exe_cmd_in_file(unsigned char *incmd)
928 {
929         int rc = 0;
930         int i = 0;
931         unsigned int cmd_msg = 0;
932         unsigned char tmp = 0;
933
934         for (i = 0; i < 4; i++) {
935                 tmp = *(incmd + i);
936                 cmd_msg |= (unsigned int)tmp;
937                 if (i != 3)
938                         cmd_msg = cmd_msg << 8;
939         }
940         rc = execute_cmdmsg(cmd_msg);
941         if (rc < 0)
942                 printk(KERN_ERR "%s: cmd %08x error %d\n",
943                         __func__, cmd_msg, rc);
944         return rc;
945 }
946 #endif  /* ENABLE_DIAG_IOCTLS */
947
948 /* Thread does the init process of Audience Chip */
949 static int a2220_init_thread(void *data)
950 {
951         int rc = 0;
952         struct a2220img img;
953         img.buf = a2220_firmware_buf;
954         img.img_size = sizeof(a2220_firmware_buf);
955         rc = a2220_bootup_init(&img);
956         return rc;
957 }
958
959 static int
960 a2220_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
961             unsigned long arg)
962 {
963         void __user *argp = (void __user *)arg;
964         struct a2220img img;
965         int rc = 0;
966 #if ENABLE_DIAG_IOCTLS
967         char msg[4];
968         int mic_cases = 0;
969         int mic_sel = 0;
970 #endif
971         unsigned int ns_state;
972
973         switch (cmd) {
974         case A2220_BOOTUP_INIT:
975                 img.buf = a2220_firmware_buf;
976                 img.img_size = sizeof(a2220_firmware_buf);
977                 printk(MODULE_NAME "%s : a2220_firmware_buf = %d\n", __func__,
978                        sizeof(a2220_firmware_buf));
979                 task =
980                     kthread_run(a2220_init_thread, NULL, "a2220_init_thread");
981                 if (IS_ERR(task)) {
982                         rc = PTR_ERR(task);
983                         task = NULL;
984                 }
985                 break;
986         case A2220_SET_CONFIG:
987                 rc = a2220_set_config(arg, A2220_CONFIG_FULL);
988                 if (rc < 0)
989                         printk(KERN_ERR "%s: A2220_SET_CONFIG (%lu) error %d!\n",
990                                __func__, arg, rc);
991                 break;
992         case A2220_SET_NS_STATE:
993                 if (copy_from_user(&ns_state, argp, sizeof(ns_state)))
994                         return -EFAULT;
995                 pr_info("%s: set noise suppression %d\n", __func__, ns_state);
996                 if (ns_state < 0 || ns_state >= A2220_NS_NUM_STATES)
997                         return -EINVAL;
998                 a2220_NS_state = ns_state;
999                 if (!a2220_suspended)
1000                         a2220_set_config(a2220_current_config, A2220_CONFIG_VP);
1001                 break;
1002 #if ENABLE_DIAG_IOCTLS
1003         case A2220_SET_MIC_ONOFF:
1004                 rc = chk_wakeup_a2220();
1005                 if (rc < 0)
1006                         return rc;
1007                 if (copy_from_user(&mic_cases, argp, sizeof(mic_cases)))
1008                         return -EFAULT;
1009                 rc = a2220_set_mic_state(mic_cases);
1010                 if (rc < 0)
1011                         printk(KERN_ERR "%s: A2220_SET_MIC_ONOFF %d error %d!\n",
1012                                __func__, mic_cases, rc);
1013                 break;
1014         case A2220_SET_MICSEL_ONOFF:
1015                 rc = chk_wakeup_a2220();
1016                 if (rc < 0)
1017                         return rc;
1018                 if (copy_from_user(&mic_sel, argp, sizeof(mic_sel)))
1019                         return -EFAULT;
1020                 rc = 0;
1021                 break;
1022         case A2220_READ_DATA:
1023                 rc = chk_wakeup_a2220();
1024                 if (rc < 0)
1025                         return rc;
1026                 rc = a2220_i2c_read(msg, 4);
1027                 if (copy_to_user(argp, &msg, 4))
1028                         return -EFAULT;
1029                 break;
1030         case A2220_WRITE_MSG:
1031                 rc = chk_wakeup_a2220();
1032                 if (rc < 0)
1033                         return rc;
1034                 if (copy_from_user(msg, argp, sizeof(msg)))
1035                         return -EFAULT;
1036                 rc = a2220_i2c_write(msg, 4);
1037                 break;
1038         case A2220_SYNC_CMD:
1039                 rc = chk_wakeup_a2220();
1040                 if (rc < 0)
1041                         return rc;
1042                 msg[0] = 0x80;
1043                 msg[1] = 0x00;
1044                 msg[2] = 0x00;
1045                 msg[3] = 0x00;
1046                 rc = a2220_i2c_write(msg, 4);
1047                 break;
1048         case A2220_SET_CMD_FILE:
1049                 rc = chk_wakeup_a2220();
1050                 if (rc < 0)
1051                         return rc;
1052                 if (copy_from_user(msg, argp, sizeof(msg)))
1053                         return -EFAULT;
1054                 rc = exe_cmd_in_file(msg);
1055                 break;
1056 #endif                          /* ENABLE_DIAG_IOCTLS */
1057         default:
1058                 printk(KERN_ERR "%s: invalid command %d\n",
1059                         __func__, _IOC_NR(cmd));
1060                 rc = -EINVAL;
1061                 break;
1062         }
1063
1064         return rc;
1065 }
1066
1067 int a2220_ioctl2(unsigned int cmd, unsigned long arg)
1068 {
1069         a2220_ioctl(NULL, NULL, cmd, arg);
1070         return 0;
1071 }
1072 EXPORT_SYMBOL(a2220_ioctl2);
1073
1074 int a2220_port_path_change(unsigned int msg)
1075 {
1076         switch (msg) {
1077         case A100_msg_PortC_D_PASS:
1078         case A100_msg_PortD_C_PASS:
1079         case A100_msg_PortB_A_PASS:
1080         case A100_msg_PortA_B_PASS:
1081         case A100_msg_PortC_A_PASS:
1082         case A100_msg_PortA_C_PASS:
1083                 break;
1084         default:
1085                 printk(KERN_ERR "Not support [0x%X] for port change\n", msg);
1086                 return -EINVAL;
1087         }
1088         /* Default set to PORTD -> PORTC and
1089            PORTB -> PORTA in pass through) */
1090         /* return execute_cmdmsg(msg); */
1091         return 0;
1092 }
1093 EXPORT_SYMBOL(a2220_port_path_change);
1094
1095 static const struct file_operations a2220_fops = {
1096         .owner = THIS_MODULE,
1097         .open = a2220_open,
1098         .release = a2220_release,
1099 /*      .ioctl = a2220_ioctl, */
1100 };
1101
1102 static struct miscdevice a2220_device = {
1103         .minor = MISC_DYNAMIC_MINOR,
1104         .name = "audience_a2220",
1105         .fops = &a2220_fops,
1106 };
1107
1108 static int a2220_probe(struct i2c_client *client,
1109                        const struct i2c_device_id *id)
1110 {
1111         int rc = 0, ret;
1112         unsigned long val;
1113         void __iomem *pmc_base = IO_ADDRESS(TEGRA_PMC_BASE);
1114
1115         extern3_clk = clk_get_sys("extern3", NULL);
1116         if (IS_ERR(extern3_clk)) {
1117                 printk(KERN_ERR "%s: Can't retrieve extern3\n", __func__);
1118                 goto err_clk_get_failed;
1119         }
1120
1121         ret = clk_enable(extern3_clk);
1122         if (ret) {
1123                 printk(KERN_ERR "Can't enable clk extern3");
1124                 goto err_clk_enable_failed;
1125         }
1126
1127         control_a2220_clk = 1;
1128         /* disable master enable in PMC */
1129         val = readl(pmc_base + PMC_CLK_OUT);
1130         val |= CLK3_SRC_SEL;
1131
1132         writel(val, pmc_base + PMC_CLK_OUT);
1133
1134         val = readl(pmc_base + PMC_CLK_OUT);
1135         val |= CLK3_FORCE_EN;
1136         writel(val, pmc_base + PMC_CLK_OUT);
1137
1138         pdata = client->dev.platform_data;
1139
1140         if (pdata == NULL) {
1141                 pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
1142                 printk(KERN_ERR "%s : a2220_probe - pdata NULL so allocating ...\n",
1143                        __func__);
1144                 if (pdata == NULL) {
1145                         rc = -ENOMEM;
1146                         printk(KERN_ERR "%s: platform data is NULL\n",
1147                                 __func__);
1148
1149                         goto err_alloc_data_failed;
1150                 }
1151         }
1152
1153 #ifdef CONFIG_USA_MODEL_SGH_T989
1154         if (get_hw_rev() >= 0x05)
1155                 gpio_tlmm_config(GPIO_CFG(33, 0, GPIO_CFG_OUTPUT,
1156                                 GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
1157                                 GPIO_CFG_ENABLE);/* 2MIC_PWDN */
1158         else
1159                 gpio_tlmm_config(GPIO_CFG(34, 0, GPIO_CFG_OUTPUT,
1160                                 GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
1161                                 GPIO_CFG_ENABLE);/* 2MIC_PWDN */
1162 #elif CONFIG_USA_MODEL_SGH_I727
1163         if (get_hw_rev() >= 0x05) {
1164                 printk(KERN_DEBUG " %s : GPIO 33\n", __func__);
1165                 gpio_tlmm_config(GPIO_CFG(33, 0, GPIO_CFG_OUTPUT,
1166                                 GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
1167                                 GPIO_CFG_ENABLE);/* 2MIC_PWDN */
1168         } else {
1169                 printk(KERN_DEBUG "%s : get_hw_rev() == %d\n",
1170                         __func__, get_hw_rev());
1171
1172                 gpio_tlmm_config(GPIO_CFG(34, 0, GPIO_CFG_OUTPUT,
1173                                 GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
1174                                 GPIO_CFG_ENABLE);/* 2MIC_PWDN */
1175         }
1176 #elif CONFIG_USA_MODEL_SGH_I717
1177
1178 #else
1179         gpio_tlmm_config(GPIO_CFG(34, 0, GPIO_CFG_OUTPUT,
1180                         GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
1181                         GPIO_CFG_ENABLE);       /* 2MIC_PWDN */
1182 #endif
1183
1184 #if !defined(CONFIG_USA_MODEL_SGH_I727) && !defined(CONFIG_USA_MODEL_SGH_T989)\
1185         &&  !defined(CONFIG_USA_MODEL_SGH_I717) /*qup_a2220 */
1186         gpio_tlmm_config(GPIO_CFG(35, 0, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL,
1187                         GPIO_CFG_2MA), GPIO_CFG_ENABLE);/* 2MIC_SDA_1.8V */
1188         gpio_tlmm_config(GPIO_CFG(36, 0, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL,
1189                         GPIO_CFG_2MA), GPIO_CFG_ENABLE);/* 2MIC_SCL_1.8V */
1190 #endif
1191
1192         /*VP  reset  */
1193         gpio_set_value(VP_RESET, 1);
1194         gpio_set_value(AUDIO_LD0_EN, 0);
1195
1196         this_client = client;
1197
1198         gpio_set_value(VP_RESET, 0);
1199
1200         if (pdata->gpio_a2220_clk) {
1201                 rc = gpio_request(pdata->gpio_a2220_clk, "a2220");
1202                 if (rc < 0) {
1203                         control_a2220_clk = 0;
1204                         goto chk_gpio_micsel;
1205                 }
1206                 control_a2220_clk = 1;
1207
1208                 rc = gpio_direction_output(pdata->gpio_a2220_clk, 1);
1209                 if (rc < 0) {
1210                         printk(KERN_ERR "%s: request clk gpio direction failed\n",
1211                                __func__);
1212                         goto err_free_gpio_clk;
1213                 }
1214         }
1215  chk_gpio_micsel:
1216         if (pdata->gpio_a2220_micsel) {
1217                 rc = gpio_request(pdata->gpio_a2220_micsel, "a2220");
1218                 if (rc < 0) {
1219                         printk(KERN_ERR "%s: gpio request mic_sel pin failed\n",
1220                                __func__);
1221                         goto err_free_gpio_micsel;
1222                 }
1223
1224                 rc = gpio_direction_output(pdata->gpio_a2220_micsel, 1);
1225                 if (rc < 0) {
1226                         printk(KERN_ERR "%s: request mic_sel gpio direction failed\n",
1227                                __func__);
1228                         goto err_free_gpio_micsel;
1229                 }
1230         }
1231
1232         if (pdata->gpio_a2220_wakeup) {
1233 #ifdef CONFIG_USA_MODEL_SGH_T989
1234                 if (get_hw_rev() >= 0x05)
1235                         rc = gpio_request(WAKEUP_GPIO_NUM_HERCULES_REV01,
1236                                           "a2220");
1237                 else
1238                         rc = gpio_request(pdata->gpio_a2220_wakeup, "a2220");
1239 #elif CONFIG_USA_MODEL_SGH_I727
1240                 if (get_hw_rev() >= 0x05)
1241                         rc = gpio_request(WAKEUP_GPIO_NUM_CELOX_ATT_REV05,
1242                                           "a2220");
1243                 else
1244                         rc = gpio_request(pdata->gpio_a2220_wakeup, "a2220");
1245 #elif CONFIG_USA_MODEL_SGH_I717
1246                 rc = gpio_request(WAKEUP_GPIO_NUM_CELOX_ATT_REV05, "a2220");
1247 #else
1248                 rc = gpio_request(pdata->gpio_a2220_wakeup, "a2220");
1249 #endif
1250                 if (rc < 0) {
1251                         printk(KERN_ERR "%s: gpio request wakeup pin failed\n",
1252                                __func__);
1253                         goto err_free_gpio;
1254                 }
1255 #ifdef CONFIG_USA_MODEL_SGH_T989
1256                 if (get_hw_rev() >= 0x05)
1257                         rc = gpio_direction_output
1258                             (WAKEUP_GPIO_NUM_HERCULES_REV01, 1);
1259                 else
1260                         rc = gpio_direction_output(pdata->gpio_a2220_wakeup, 1);
1261 #elif CONFIG_USA_MODEL_SGH_I727
1262                 if (get_hw_rev() >= 0x05)
1263                         rc = gpio_direction_output
1264                             (WAKEUP_GPIO_NUM_CELOX_ATT_REV05, 1);
1265                 else
1266                         rc = gpio_direction_output(pdata->gpio_a2220_wakeup, 1);
1267 #elif CONFIG_USA_MODEL_SGH_I717
1268                 rc = gpio_direction_output(WAKEUP_GPIO_NUM_CELOX_ATT_REV05, 1);
1269 #else
1270                 rc = gpio_direction_output(pdata->gpio_a2220_wakeup, 1);
1271 #endif
1272
1273
1274                 if (rc < 0) {
1275                         printk(KERN_ERR "%s: request wakeup gpio direction failed\n",
1276                                __func__);
1277                         goto err_free_gpio;
1278                 }
1279         }
1280
1281         if (pdata->gpio_a2220_reset) {
1282                 rc = gpio_request(pdata->gpio_a2220_reset, "a2220");
1283                 if (rc < 0) {
1284                         printk(KERN_ERR "%s: gpio request reset pin failed\n",
1285                         __func__);
1286                         goto err_free_gpio;
1287                 }
1288
1289                 rc = gpio_direction_output(pdata->gpio_a2220_reset, 1);
1290                 if (rc < 0) {
1291                         printk(KERN_ERR "%s: request reset gpio direction failed\n",
1292                         __func__);
1293                         goto err_free_gpio_all;
1294                 }
1295         }
1296
1297         if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
1298                 printk(KERN_ERR "%s: i2c check functionality error\n",
1299                 __func__);
1300                 rc = -ENODEV;
1301                 goto err_free_gpio_all;
1302         }
1303
1304         if (control_a2220_clk)
1305                 gpio_set_value(pdata->gpio_a2220_clk, 1);
1306         if (pdata->gpio_a2220_micsel)
1307                 gpio_set_value(pdata->gpio_a2220_micsel, 0);
1308
1309         if (pdata->gpio_a2220_wakeup) {
1310 #ifdef CONFIG_USA_MODEL_SGH_T989
1311                 if (get_hw_rev() >= 0x05)
1312                         gpio_set_value(WAKEUP_GPIO_NUM_HERCULES_REV01, 1);
1313                 else
1314                         gpio_set_value(pdata->gpio_a2220_wakeup, 1);
1315 #elif CONFIG_USA_MODEL_SGH_I727
1316                 if (get_hw_rev() >= 0x05)
1317                         gpio_set_value(WAKEUP_GPIO_NUM_CELOX_ATT_REV05, 1);
1318                 else
1319                         gpio_set_value(pdata->gpio_a2220_wakeup, 1);
1320 #elif CONFIG_USA_MODEL_SGH_I717
1321                 gpio_set_value(WAKEUP_GPIO_NUM_CELOX_ATT_REV05, 1);
1322 #else
1323                 gpio_set_value(pdata->gpio_a2220_wakeup, 1);
1324 #endif
1325         }
1326
1327         if (pdata->gpio_a2220_reset)
1328                 gpio_set_value(pdata->gpio_a2220_reset, 1);
1329
1330         if (pdata->gpio_a2220_audience_chip_sel)
1331                 gpio_set_value(pdata->gpio_a2220_audience_chip_sel, 1);
1332
1333         rc = misc_register(&a2220_device);
1334         if (rc) {
1335                 printk(KERN_ERR "%s: a2220_device register failed\n", __func__);
1336                 goto err_free_gpio_all;
1337         }
1338
1339         /* send boot msg */
1340         rc = a2220_set_boot_mode();
1341         if (rc < 0) {
1342                 printk(KERN_ERR "%s: failed %d\n", __func__, rc);
1343                 goto err_free_gpio_all;
1344         }
1345
1346         /* A2220 firmware download start .. */
1347         a2220_ioctl2(A2220_BOOTUP_INIT, 0);
1348
1349         return 0;
1350
1351  err_free_gpio_all:
1352         if (pdata->gpio_a2220_reset)
1353                 gpio_free(pdata->gpio_a2220_reset);
1354  err_free_gpio:
1355         if (pdata->gpio_a2220_wakeup) {
1356 #ifdef CONFIG_USA_MODEL_SGH_T989
1357                 if (get_hw_rev() >= 0x05)
1358                         gpio_free(WAKEUP_GPIO_NUM_HERCULES_REV01);
1359                 else
1360                         gpio_free(pdata->gpio_a2220_wakeup);
1361 #elif CONFIG_USA_MODEL_SGH_I727
1362                 if (get_hw_rev() >= 0x05)
1363                         gpio_free(WAKEUP_GPIO_NUM_CELOX_ATT_REV05);
1364                 else
1365                         gpio_free(pdata->gpio_a2220_wakeup);
1366 #elif CONFIG_USA_MODEL_SGH_I717
1367                 gpio_free(WAKEUP_GPIO_NUM_CELOX_ATT_REV05);
1368 #else
1369                 gpio_free(pdata->gpio_a2220_wakeup);
1370 #endif
1371         }
1372  err_free_gpio_micsel:
1373         if (pdata->gpio_a2220_micsel)
1374                 gpio_free(pdata->gpio_a2220_micsel);
1375  err_free_gpio_clk:
1376         if (pdata->gpio_a2220_clk)
1377                 gpio_free(pdata->gpio_a2220_clk);
1378  err_alloc_data_failed:
1379         clk_disable(extern3_clk);
1380  err_clk_enable_failed:
1381         clk_put(extern3_clk);
1382  err_clk_get_failed:
1383
1384         return rc;
1385 }
1386
1387 static int a2220_remove(struct i2c_client *client)
1388 {
1389         struct a2220_platform_data *p1026data = i2c_get_clientdata(client);
1390         kfree(p1026data);
1391
1392         return 0;
1393 }
1394
1395 static int a2220_suspend(struct i2c_client *client, pm_message_t mesg)
1396 {
1397         return 0;
1398 }
1399
1400 static int a2220_resume(struct i2c_client *client)
1401 {
1402         return 0;
1403 }
1404
1405 static const struct i2c_device_id a2220_id[] = {
1406         {"audience_a2220", 0},
1407         {}
1408 };
1409
1410 MODULE_DEVICE_TABLE(i2c, a2220_id);
1411
1412 static struct i2c_driver a2220_driver = {
1413         .probe = a2220_probe,
1414         .remove = a2220_remove,
1415         .suspend = a2220_suspend,
1416         .resume = a2220_resume,
1417         .id_table = a2220_id,
1418         .driver = {
1419                    .name = "audience_a2220",
1420                    },
1421 };
1422
1423
1424 static int __init a2220_init(void)
1425 {
1426 #ifdef CONFIG_BATTERY_SEC
1427         if (is_lpcharging_state()) {
1428                 pr_info("%s : LPM Charging Mode! return 0\n", __func__);
1429                 return 0;
1430         }
1431 #endif
1432         mutex_init(&a2220_lock);
1433
1434         return i2c_add_driver(&a2220_driver);
1435 }
1436
1437 static void __exit a2220_exit(void)
1438 {
1439         i2c_del_driver(&a2220_driver);
1440 }
1441
1442 module_init(a2220_init);
1443 module_exit(a2220_exit);
1444
1445 MODULE_DESCRIPTION("A2220 voice processor driver");
1446 MODULE_LICENSE("GPL");