[Feature][ZXW-33]merge ZXW 0428 version

Change-Id: I11f167edfea428d9fab198ff00ff1364932d1b0b
diff --git a/ap/os/linux/linux-3.4.x/arch/arm/mach-zx297520v3/include/mach/spinlock.h b/ap/os/linux/linux-3.4.x/arch/arm/mach-zx297520v3/include/mach/spinlock.h
index 15c1875..a96c57c 100644
--- a/ap/os/linux/linux-3.4.x/arch/arm/mach-zx297520v3/include/mach/spinlock.h
+++ b/ap/os/linux/linux-3.4.x/arch/arm/mach-zx297520v3/include/mach/spinlock.h
@@ -244,6 +244,8 @@
  * Others:

  ********************************************************************************/

  void  reg_spin_unlock(void);

- int  soft_spin_lock_printf(emsf_lock_id sfid);

+#ifdef _USE_VEHICLE_DC

+int  soft_spin_lock_printf(emsf_lock_id sfid);

+#endif

 #endif/*_SYS_H*/

 

diff --git a/ap/os/linux/linux-3.4.x/arch/arm/mach-zx297520v3/spinlock.c b/ap/os/linux/linux-3.4.x/arch/arm/mach-zx297520v3/spinlock.c
index e99382e..7f73d01 100644
--- a/ap/os/linux/linux-3.4.x/arch/arm/mach-zx297520v3/spinlock.c
+++ b/ap/os/linux/linux-3.4.x/arch/arm/mach-zx297520v3/spinlock.c
@@ -206,7 +206,7 @@
     //zspinlock_debug("cpu %d releases %d software lock!/n",SELF_CORE_ID,sfid);

 

 }

-#ifdef _USE_CAP_SYS

+#ifdef _USE_VEHICLE_DC

 int  soft_spin_lock_printf(emsf_lock_id sfid)

 {

 	static unsigned long lock_count = 0;

diff --git a/ap/os/linux/linux-3.4.x/arch/arm/mach-zx297520v3/zx297520v3-mdl-devices.c b/ap/os/linux/linux-3.4.x/arch/arm/mach-zx297520v3/zx297520v3-mdl-devices.c
index 9f77257..8729990 100644
--- a/ap/os/linux/linux-3.4.x/arch/arm/mach-zx297520v3/zx297520v3-mdl-devices.c
+++ b/ap/os/linux/linux-3.4.x/arch/arm/mach-zx297520v3/zx297520v3-mdl-devices.c
@@ -1327,6 +1327,7 @@
 #endif
 
 #ifdef CONFIG_TSC_ZX29
+#ifdef RFC_DCXO_EN
 u32 ts_temp_value_table[TS_ADC_TEMP_NUMBER][TS_ADC_TEMP_VOLTAGE_NUMBER]={
 {30,31,32,33,34,35,36,37,38,39,
  40,41,42,43,44,45,46,47,48,49,
@@ -1351,6 +1352,32 @@
 2227,2221,2215,2210,2204,2198,2193,2188,2183,2178,
 2173,2169,2164,2160,2155,2151 }
 };
+#else
+u32 ts_temp_value_table[TS_ADC_TEMP_NUMBER][TS_ADC_TEMP_VOLTAGE_NUMBER]={
+{30,31,32,33,34,35,36,37,38,39,
+ 40,41,42,43,44,45,46,47,48,49,
+ 50,51,52,53,54,55,56,57,58,59,
+ 60,61,62,63,64,65,66,67,68,69,
+ 70,71,72,73,74,75,76,77,78,79,
+ 80,81,82,83,84,85,86,87,88,89,
+ 90,91,92,93,94,95,96,97,98,99,
+ 100,101,102,103,104,105,106,107,108,109,
+ 110,111,112,113,114,115,116,117,118,119,
+ 120,121,122,123,124,125},
+
+{
+3700,3656,3613,3569,3526,3482,3441,3401,3360,3320, 
+3279,3241,3204,3166,3129,3091,3056,3021,2987,2952, 
+2917,2885,2853,2822,2790,2758,2727,2696,2664,2633, 
+2602,2573,2545,2516,2488,2459,2440,2421,2401,2382, 
+2363,2353,2343,2334,2324,2314,2310,2305,2301,2296,
+2292,2290,2288,2285,2283,2281,2279,2278,2276,2275, 
+2273,2272,2270,2269,2267,2266,2265,2264,2263,2262, 
+2261,2260,2259,2258,2257,2256,2255,2254,2253,2252, 
+2251,2250,2249,2248,2247,2246,2245,2244,2243,2242, 
+2241,2240,2239,2238,2237,2236  }
+};
+#endif
 volatile u32 ts_adc_flag=3;// 1:adc1; 2:adc2, other:adc rf;  
 #endif
 
diff --git a/ap/os/linux/linux-3.4.x/arch/arm/mm/fault.c b/ap/os/linux/linux-3.4.x/arch/arm/mm/fault.c
index a85cfce..422ffdc 100755
--- a/ap/os/linux/linux-3.4.x/arch/arm/mm/fault.c
+++ b/ap/os/linux/linux-3.4.x/arch/arm/mm/fault.c
@@ -21,12 +21,12 @@
 #ifdef CONFIG_MMU
 #ifdef CONFIG_KPROBES
 static inline int notify_page_fault(struct pt_regs*regs,unsigned int fsr){int 
-ret=(0x65+1215-0x524);if(!user_mode(regs)){preempt_disable();if(kprobe_running()
-&&kprobe_fault_handler(regs,fsr))ret=(0x29c+3580-0x1097);preempt_enable();}
-return ret;}
+ret=(0x5fb+1574-0xc21);if(!user_mode(regs)){preempt_disable();if(kprobe_running(
+)&&kprobe_fault_handler(regs,fsr))ret=(0x8e0+274-0x9f1);preempt_enable();}return
+ ret;}
 #else
 static inline int notify_page_fault(struct pt_regs*regs,unsigned int fsr){return
-(0x321+7937-0x2222);}
+(0xc2d+4365-0x1d3a);}
 #endif
 void show_pte(struct mm_struct*mm,unsigned long addr){pgd_t*pgd;if(!mm)mm=&
 init_mm;printk(KERN_ALERT"\x70\x67\x64\x20\x3d\x20\x25\x70" "\n",mm->pgd);pgd=
@@ -34,10 +34,10 @@
 "\x5b\x25\x30\x38\x6c\x78\x5d\x20\x2a\x70\x67\x64\x3d\x25\x30\x38\x6c\x6c\x78",
 addr,(long long)pgd_val(*pgd));do{pud_t*pud;pmd_t*pmd;pte_t*pte;if(pgd_none(*pgd
 ))break;if(pgd_bad(*pgd)){printk("\x28\x62\x61\x64\x29");break;}pud=pud_offset(
-pgd,addr);if(PTRS_PER_PUD!=(0x755+4712-0x19bc))printk(
+pgd,addr);if(PTRS_PER_PUD!=(0xe2a+2894-0x1977))printk(
 "\x2c\x20\x2a\x70\x75\x64\x3d\x25\x30\x38\x6c\x6c\x78",(long long)pud_val(*pud))
 ;if(pud_none(*pud))break;if(pud_bad(*pud)){printk("\x28\x62\x61\x64\x29");break;
-}pmd=pmd_offset(pud,addr);if(PTRS_PER_PMD!=(0x77+5179-0x14b1))printk(
+}pmd=pmd_offset(pud,addr);if(PTRS_PER_PMD!=(0x1c82+165-0x1d26))printk(
 "\x2c\x20\x2a\x70\x6d\x64\x3d\x25\x30\x38\x6c\x6c\x78",(long long)pmd_val(*pmd))
 ;if(pmd_none(*pmd))break;if(pmd_bad(*pmd)){printk("\x28\x62\x61\x64\x29");break;
 }if(PageHighMem(pfn_to_page(pmd_val(*pmd)>>PAGE_SHIFT)))break;pte=pte_offset_map
@@ -47,18 +47,18 @@
 printk("\x2c\x20\x2a\x70\x70\x74\x65\x3d\x25\x30\x38\x6c\x6c\x78",(long long)
 pte_val(pte[PTE_HWTABLE_PTRS]));
 #endif
-pte_unmap(pte);}while((0x70c+1472-0xccc));printk("\n");}
+pte_unmap(pte);}while((0x19c5+3009-0x2586));printk("\n");}
 #else					
 void show_pte(struct mm_struct*mm,unsigned long addr){}
 #endif					
 static void __do_kernel_fault(struct mm_struct*mm,unsigned long addr,unsigned 
 int fsr,struct pt_regs*regs){if(fixup_exception(regs))return;bust_spinlocks(
-(0x69d+6021-0x1e21));printk(KERN_ALERT
+(0xca2+3899-0x1bdc));printk(KERN_ALERT
 "\x55\x6e\x61\x62\x6c\x65\x20\x74\x6f\x20\x68\x61\x6e\x64\x6c\x65\x20\x6b\x65\x72\x6e\x65\x6c\x20\x25\x73\x20\x61\x74\x20\x76\x69\x72\x74\x75\x61\x6c\x20\x61\x64\x64\x72\x65\x73\x73\x20\x25\x30\x38\x6c\x78" "\n"
 ,(addr<PAGE_SIZE)?
 "\x4e\x55\x4c\x4c\x20\x70\x6f\x69\x6e\x74\x65\x72\x20\x64\x65\x72\x65\x66\x65\x72\x65\x6e\x63\x65"
 :"\x70\x61\x67\x69\x6e\x67\x20\x72\x65\x71\x75\x65\x73\x74",addr);show_pte(mm,
-addr);die("\x4f\x6f\x70\x73",regs,fsr);bust_spinlocks((0xf24+5951-0x2663));
+addr);die("\x4f\x6f\x70\x73",regs,fsr);bust_spinlocks((0xe23+530-0x1035));
 do_exit(SIGKILL);}static void __do_user_fault(struct task_struct*tsk,unsigned 
 long addr,unsigned int fsr,unsigned int sig,int code,struct pt_regs*regs){struct
  siginfo si;
@@ -69,7 +69,7 @@
 ,tsk->comm,sig,addr,fsr);show_pte(tsk->mm,addr);show_regs(regs);}
 #endif
 tsk->thread.address=addr;tsk->thread.error_code=fsr;tsk->thread.trap_no=
-(0x121a+3718-0x2092);si.si_signo=sig;si.si_errno=(0x6bd+2274-0xf9f);si.si_code=
+(0x18d9+1862-0x2011);si.si_signo=sig;si.si_errno=(0xc1a+1664-0x129a);si.si_code=
 code;si.si_addr=(void __user*)addr;force_sig_info(sig,&si,tsk);}void do_bad_area
 (unsigned long addr,unsigned int fsr,struct pt_regs*regs){struct task_struct*tsk
 =current;struct mm_struct*mm=tsk->active_mm;if(user_mode(regs))__do_user_fault(
@@ -91,9 +91,9 @@
 static int __kprobes do_page_fault(unsigned long addr,unsigned int fsr,struct 
 pt_regs*regs){struct task_struct*tsk;struct mm_struct*mm;int fault,sig,code;int 
 write=fsr&FSR_WRITE;unsigned int flags=FAULT_FLAG_ALLOW_RETRY|
-FAULT_FLAG_KILLABLE|(write?FAULT_FLAG_WRITE:(0x57b+1475-0xb3e));if(
-notify_page_fault(regs,fsr))return(0xca+7075-0x1c6d);tsk=current;mm=tsk->mm;if(
-interrupts_enabled(regs))local_irq_enable();if(!mm||pagefault_disabled())goto 
+FAULT_FLAG_KILLABLE|(write?FAULT_FLAG_WRITE:(0x14b5+1588-0x1ae9));if(
+notify_page_fault(regs,fsr))return(0x107a+1447-0x1621);tsk=current;mm=tsk->mm;if
+(interrupts_enabled(regs))local_irq_enable();if(!mm||pagefault_disabled())goto 
 no_context;if(!down_read_trylock(&mm->mmap_sem)){if(!user_mode(regs)&&!
 search_exception_tables(regs->ARM_pc))goto no_context;retry:down_read(&mm->
 mmap_sem);}else{might_sleep();
@@ -101,22 +101,22 @@
 if(!user_mode(regs)&&!search_exception_tables(regs->ARM_pc))goto no_context;
 #endif
 }fault=__do_page_fault(mm,addr,fsr,flags,tsk);if((fault&VM_FAULT_RETRY)&&
-fatal_signal_pending(current))return(0xb86+5570-0x2148);perf_sw_event(
-PERF_COUNT_SW_PAGE_FAULTS,(0x948+540-0xb63),regs,addr);if(!(fault&VM_FAULT_ERROR
-)&&flags&FAULT_FLAG_ALLOW_RETRY){if(fault&VM_FAULT_MAJOR){tsk->maj_flt++;
-perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ,(0x5aa+7479-0x22e0),regs,addr);}else
-{tsk->min_flt++;perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN,(0x21b2+1124-0x2615)
-,regs,addr);}if(fault&VM_FAULT_RETRY){flags&=~FAULT_FLAG_ALLOW_RETRY;goto retry;
-}}up_read(&mm->mmap_sem);if(likely(!(fault&(VM_FAULT_ERROR|VM_FAULT_BADMAP|
-VM_FAULT_BADACCESS))))return(0x208b+1089-0x24cc);if(fault&VM_FAULT_OOM){
-pagefault_out_of_memory();return(0x164a+2012-0x1e26);}if(!user_mode(regs))goto 
-no_context;if(fault&VM_FAULT_SIGBUS){sig=SIGBUS;code=BUS_ADRERR;}else{sig=
-SIGSEGV;code=fault==VM_FAULT_BADACCESS?SEGV_ACCERR:SEGV_MAPERR;}__do_user_fault(
-tsk,addr,fsr,sig,code,regs);return(0x1acb+564-0x1cff);no_context:
-__do_kernel_fault(mm,addr,fsr,regs);return(0x16cd+2502-0x2093);}
+fatal_signal_pending(current))return(0xf29+3942-0x1e8f);perf_sw_event(
+PERF_COUNT_SW_PAGE_FAULTS,(0x1b1d+937-0x1ec5),regs,addr);if(!(fault&
+VM_FAULT_ERROR)&&flags&FAULT_FLAG_ALLOW_RETRY){if(fault&VM_FAULT_MAJOR){tsk->
+maj_flt++;perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ,(0x2321+522-0x252a),regs,
+addr);}else{tsk->min_flt++;perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN,
+(0x20b+2927-0xd79),regs,addr);}if(fault&VM_FAULT_RETRY){flags&=~
+FAULT_FLAG_ALLOW_RETRY;goto retry;}}up_read(&mm->mmap_sem);if(likely(!(fault&(
+VM_FAULT_ERROR|VM_FAULT_BADMAP|VM_FAULT_BADACCESS))))return(0x1ab7+2658-0x2519);
+if(fault&VM_FAULT_OOM){pagefault_out_of_memory();return(0x491+7010-0x1ff3);}if(!
+user_mode(regs))goto no_context;if(fault&VM_FAULT_SIGBUS){sig=SIGBUS;code=
+BUS_ADRERR;}else{sig=SIGSEGV;code=fault==VM_FAULT_BADACCESS?SEGV_ACCERR:
+SEGV_MAPERR;}__do_user_fault(tsk,addr,fsr,sig,code,regs);return(0xb1+2894-0xbff)
+;no_context:__do_kernel_fault(mm,addr,fsr,regs);return(0xaa3+5725-0x2100);}
 #else					
 static int do_page_fault(unsigned long addr,unsigned int fsr,struct pt_regs*regs
-){return(0x20f1+1447-0x2698);}
+){return(0x10ca+456-0x1292);}
 #endif					
 #ifdef CONFIG_MMU
 static int __kprobes do_translation_fault(unsigned long addr,unsigned int fsr,
@@ -129,21 +129,21 @@
 bad_area;if(!pud_present(*pud))set_pud(pud,*pud_k);pmd=pmd_offset(pud,addr);
 pmd_k=pmd_offset(pud_k,addr);
 #ifdef CONFIG_ARM_LPAE
-index=(0xef5+1992-0x16bd);
+index=(0x1a6c+1601-0x20ad);
 #else
-index=(addr>>SECTION_SHIFT)&(0x1945+202-0x1a0e);
+index=(addr>>SECTION_SHIFT)&(0x999+5880-0x2090);
 #endif
 if(pmd_none(pmd_k[index]))goto bad_area;copy_pmd(pmd,pmd_k);return
-(0xe01+5556-0x23b5);bad_area:do_bad_area(addr,fsr,regs);return
-(0xffa+3467-0x1d85);}
+(0x92f+1968-0x10df);bad_area:do_bad_area(addr,fsr,regs);return(0x358+3012-0xf1c)
+;}
 #else					
 static int do_translation_fault(unsigned long addr,unsigned int fsr,struct 
-pt_regs*regs){return(0x1b0f+2555-0x250a);}
+pt_regs*regs){return(0x19e0+1414-0x1f66);}
 #endif					
 static int do_sect_fault(unsigned long addr,unsigned int fsr,struct pt_regs*regs
 ){if(interrupts_enabled(regs))local_irq_enable();do_bad_area(addr,fsr,regs);
-return(0x50b+7609-0x22c4);}static int do_bad(unsigned long addr,unsigned int fsr
-,struct pt_regs*regs){return(0x2121+1247-0x25ff);}struct fsr_info{int(*fn)(
+return(0xc88+3680-0x1ae8);}static int do_bad(unsigned long addr,unsigned int fsr
+,struct pt_regs*regs){return(0x2054+1263-0x2542);}struct fsr_info{int(*fn)(
 unsigned long addr,unsigned int fsr,struct pt_regs*regs);int sig;int code;const 
 char*name;};
 #ifdef CONFIG_ARM_LPAE
@@ -152,21 +152,21 @@
 #include "fsr-2level.c"
 #endif
 void __init hook_fault_code(int nr,int(*fn)(unsigned long,unsigned int,struct 
-pt_regs*),int sig,int code,const char*name){if(nr<(0x4f3+563-0x726)||nr>=
+pt_regs*),int sig,int code,const char*name){if(nr<(0x1b92+2269-0x246f)||nr>=
 ARRAY_SIZE(fsr_info))BUG();fsr_info[nr].fn=fn;fsr_info[nr].sig=sig;fsr_info[nr].
 code=code;fsr_info[nr].name=name;}
 #ifdef CONFIG_MODEM_CODE_IS_MAPPING
 static DECLARE_RWSEM(shrinker_rwsem);atomic_t _code_page_count=ATOMIC_INIT(
-(0x747+2440-0x10cf));struct addr_info{struct list_head node;unsigned long vaddr;
+(0x609+6953-0x2132));struct addr_info{struct list_head node;unsigned long vaddr;
 unsigned long kaddr;unsigned long page_index;};enum modem_access_technology{GSM=
-(0x14b+4469-0x12c0),UTRAN=(0x599+1153-0xa19),LTE=(0x1092+5434-0x25ca),COM=
-(0x6a4+1883-0xdfc),NR_MODEM_ACCESS=(0x709+3958-0x167b)};struct list_head 
+(0xb3b+406-0xcd1),UTRAN=(0x11a+6077-0x18d6),LTE=(0xaf1+2083-0x1312),COM=
+(0x1cc+4358-0x12cf),NR_MODEM_ACCESS=(0x1499+3867-0x23b0)};struct list_head 
 modem_page_list[NR_MODEM_ACCESS]={LIST_HEAD_INIT(modem_page_list[
-(0x4a3+6466-0x1de5)]),LIST_HEAD_INIT(modem_page_list[(0xe72+4976-0x21e1)]),
-LIST_HEAD_INIT(modem_page_list[(0xe27+2944-0x19a5)]),LIST_HEAD_INIT(
-modem_page_list[(0x139c+4517-0x253e)]),};unsigned int page_used[
-(0x7e6+1147-0xc39)];struct completion page_completion[(0xe61+5716-0x248d)*
-(0xbdc+4096-0x1bbc)];static void unmap_pte_range(pmd_t*pmd,unsigned long addr,
+(0x10df+1475-0x16a2)]),LIST_HEAD_INIT(modem_page_list[(0x362+2472-0xd09)]),
+LIST_HEAD_INIT(modem_page_list[(0x429+3914-0x1371)]),LIST_HEAD_INIT(
+modem_page_list[(0xb55+6407-0x2459)]),};unsigned int page_used[
+(0x1886+1788-0x1f5a)];struct completion page_completion[(0x1123+4555-0x22c6)*
+(0x113a+1671-0x17a1)];static void unmap_pte_range(pmd_t*pmd,unsigned long addr,
 unsigned long end){pte_t*pte;pte=pte_offset_kernel(pmd,addr);do{pte_t ptent=
 ptep_get_and_clear(&init_mm,addr,pte);WARN_ON(!pte_none(ptent)&&!pte_present(
 ptent));}while(pte++,addr+=PAGE_SIZE,addr!=end);}static void unmap_pmd_range(
@@ -180,14 +180,14 @@
 addr,unsigned long end){pgd_t*pgd;unsigned long next;BUG_ON(addr>=end);pgd=
 pgd_offset_k(addr);do{next=pgd_addr_end(addr,end);if(pgd_none_or_clear_bad(pgd))
 continue;unmap_pud_range(pgd,addr,next);}while(pgd++,addr=next,addr!=end);}void 
-shrink_modem_mem(unsigned int access_type){int i=(0x10b4+5007-0x2443);unsigned 
-long vaddr;struct addr_info*addr,*tmp_addr;struct list_head tmp_page_list;for(i=
-(0x3a2+2264-0xc7a);i<NR_MODEM_ACCESS;i++){if(i==access_type)continue;down_write(
-&shrinker_rwsem);list_replace_init(&modem_page_list[i],&tmp_page_list);up_write(
-&shrinker_rwsem);list_for_each_entry_safe(addr,tmp_addr,&tmp_page_list,node){
+shrink_modem_mem(unsigned int access_type){int i=(0x87+3934-0xfe5);unsigned long
+ vaddr;struct addr_info*addr,*tmp_addr;struct list_head tmp_page_list;for(i=
+(0x735+6474-0x207f);i<NR_MODEM_ACCESS;i++){if(i==access_type)continue;down_write
+(&shrinker_rwsem);list_replace_init(&modem_page_list[i],&tmp_page_list);up_write
+(&shrinker_rwsem);list_for_each_entry_safe(addr,tmp_addr,&tmp_page_list,node){
 list_del_init(&addr->node);page_completion[addr->page_index].done=
-(0x5f7+1315-0xb1a);page_used[addr->page_index/BITS_PER_LONG]&=~(
-(0x1237+1463-0x17ed)<<(addr->page_index%BITS_PER_LONG));vaddr=addr->vaddr&
+(0x56d+8088-0x2505);page_used[addr->page_index/BITS_PER_LONG]&=~(
+(0x602+5850-0x1cdb)<<(addr->page_index%BITS_PER_LONG));vaddr=addr->vaddr&
 PAGE_MASK;if(vaddr<cpps_global_var.cpko_text_start||vaddr>cpps_global_var.
 modem_text_end){panic(
 "\x61\x64\x64\x72\x5f\x69\x6e\x66\x6f\x3a\x20\x25\x30\x38\x78\x20\x69\x73\x20\x20\x64\x65\x73\x74\x72\x6f\x79"
@@ -195,14 +195,14 @@
 PAGE_SIZE);flush_tlb_kernel_range(vaddr,vaddr+PAGE_SIZE);
 #ifdef CONFIG_DEBUG_RODATA
 unsigned int flags;local_irq_save(flags);set_memory_rw(addr->kaddr,
-(0x52b+2018-0xd0c));local_irq_restore(flags);
+(0x1882+2136-0x20d9));local_irq_restore(flags);
 #endif
 free_page(addr->kaddr);kfree(addr);atomic_dec(&_code_page_count);};}}
 EXPORT_SYMBOL(shrink_modem_mem);phys_addr_t virt_is_mapping(unsigned long addr){
 pgd_t*pgd;pmd_t*pmd;pte_t*ptep,pte;unsigned long pfn;pgd=pgd_offset_k(addr);if(!
 pgd_none(*pgd)){pmd=pmd_offset(pgd,addr);if(!pmd_none(*pmd)){ptep=pte_offset_map
 (pmd,addr);pte=*ptep;if(pte_present(pte)){pfn=pte_pfn(pte);return __pfn_to_phys(
-pfn);}}}return(0x164b+2351-0x1f7a);}static int sync_pgd(unsigned long addr,
+pfn);}}}return(0x222d+104-0x2295);}static int sync_pgd(unsigned long addr,
 unsigned int fsr,struct pt_regs*regs){unsigned int index;pgd_t*pgd,*pgd_k;pud_t*
 pud,*pud_k;pmd_t*pmd,*pmd_k;index=pgd_index(addr);pgd=cpu_get_pgd()+index;pgd_k=
 init_mm.pgd+index;if(pgd_none(*pgd_k))goto bad_area;if(!pgd_present(*pgd))
@@ -210,13 +210,13 @@
 pud_none(*pud_k))goto bad_area;if(!pud_present(*pud))set_pud(pud,*pud_k);pmd=
 pmd_offset(pud,addr);pmd_k=pmd_offset(pud_k,addr);
 #ifdef CONFIG_ARM_LPAE
-index=(0x13b7+4531-0x256a);
+index=(0x1c7b+37-0x1ca0);
 #else
-index=(addr>>SECTION_SHIFT)&(0x21fb+1059-0x261d);
+index=(addr>>SECTION_SHIFT)&(0x21e6+876-0x2551);
 #endif
 if(pmd_none(pmd_k[index]))goto bad_area;copy_pmd(pmd,pmd_k);return
-(0x44c+7489-0x218d);bad_area:do_bad_area(addr,fsr,regs);return
-(0x15a9+1546-0x1bb3);}unsigned long*read_code_file(unsigned long page_index){
+(0x1da1+1736-0x2469);bad_area:do_bad_area(addr,fsr,regs);return
+(0x4c0+2321-0xdd1);}unsigned long*read_code_file(unsigned long page_index){
 unsigned long*code_buf;ssize_t result;code_buf=get_zeroed_page(GFP_ATOMIC);if(!
 code_buf)panic(
 "\x6d\x65\x6d\x65\x6f\x72\x79\x20\x6e\x6f\x74\x20\x65\x6e\x6f\x75\x67\x68\x21\x21"
@@ -225,23 +225,23 @@
 "\x6f\x70\x65\x6e\x20\x66\x69\x6c\x65\x20\x65\x72\x72\x6f\x72" "\n");}
 mm_segment_t old_fs;old_fs=get_fs();set_fs(KERNEL_DS);loff_t pos;pos=page_index*
 PAGE_SIZE+cpps_global_var.modem_offset;result=vfs_read(cpps_global_var.fp_code,(
-char*)code_buf,PAGE_SIZE,&pos);if(result<(0x666+7290-0x22e0)){panic(
+char*)code_buf,PAGE_SIZE,&pos);if(result<(0x49+6729-0x1a92)){panic(
 "\x72\x65\x61\x64\x20\x63\x6f\x64\x65\x20\x66\x69\x6c\x65\x20\x65\x72\x72\x6f\x72" "\n"
 );}
 #ifdef CONFIG_DEBUG_RODATA
 unsigned int flags;local_irq_save(flags);set_memory_ro((unsigned long)code_buf,
-(0xcbb+5099-0x20a5));local_irq_restore(flags);
+(0x2e5+1761-0x9c5));local_irq_restore(flags);
 #endif
 set_fs(old_fs);return code_buf;}void read_code_mapping(unsigned long addr,
 unsigned int fsr,struct pt_regs*regs){unsigned long offset;unsigned long vaddr;
 const struct mem_type*mtype;unsigned long*vir_codebuf;unsigned long page_index;
-unsigned long page_shift;if(virt_is_mapping(addr&PAGE_MASK)!=(0xf90+2273-0x1871)
-){sync_pgd(addr&PAGE_MASK,fsr,regs);return;}vaddr=addr&PAGE_MASK;offset=vaddr&(~
+unsigned long page_shift;if(virt_is_mapping(addr&PAGE_MASK)!=(0x29+8410-0x2103))
+{sync_pgd(addr&PAGE_MASK,fsr,regs);return;}vaddr=addr&PAGE_MASK;offset=vaddr&(~
 cpps_global_var.cpko_text_start);page_index=offset>>PAGE_SHIFT;page_shift=
 page_index%BITS_PER_LONG;if((page_used[page_index/BITS_PER_LONG]>>page_shift)&
-(0x94c+4338-0x1a3d)){wait_for_completion(&page_completion[page_index]);sync_pgd(
+(0xa1f+1461-0xfd3)){wait_for_completion(&page_completion[page_index]);sync_pgd(
 vaddr,fsr,regs);return;}else page_used[page_index/BITS_PER_LONG]|=(
-(0x1b1+3440-0xf20)<<page_shift);local_irq_enable();vir_codebuf=read_code_file(
+(0x14b1+170-0x155a)<<page_shift);local_irq_enable();vir_codebuf=read_code_file(
 page_index);struct addr_info*addr_info;addr_info=kzalloc(sizeof(struct addr_info
 ),GFP_KERNEL);addr_info->kaddr=vir_codebuf;addr_info->vaddr=addr;addr_info->
 page_index=page_index;down_write(&shrinker_rwsem);if(vaddr<cpps_global_var.
@@ -259,46 +259,46 @@
 struct pt_regs*regs){const struct fsr_info*inf=fsr_info+fsr_fs(fsr);struct 
 siginfo info;
 #ifdef CONFIG_MODEM_CODE_IS_MAPPING
-if(addr!=(0x4e2+1119-0x941)&&addr>=cpps_global_var.cpko_text_start&&addr<=
+if(addr!=(0xf54+4843-0x223f)&&addr>=cpps_global_var.cpko_text_start&&addr<=
 cpps_global_var.modem_text_end){read_code_mapping(addr,fsr&~FSR_LNX_PF,regs);
 return;}
 #endif
 if(!inf->fn(addr,fsr&~FSR_LNX_PF,regs))return;printk(KERN_ALERT
 "\x55\x6e\x68\x61\x6e\x64\x6c\x65\x64\x20\x66\x61\x75\x6c\x74\x3a\x20\x25\x73\x20\x28\x30\x78\x25\x30\x33\x78\x29\x20\x61\x74\x20\x30\x78\x25\x30\x38\x6c\x78" "\n"
-,inf->name,fsr,addr);info.si_signo=inf->sig;info.si_errno=(0x280+4153-0x12b9);
+,inf->name,fsr,addr);info.si_signo=inf->sig;info.si_errno=(0x1ef3+402-0x2085);
 info.si_code=inf->code;info.si_addr=(void __user*)addr;arm_notify_die("",regs,&
-info,fsr,(0x127+1440-0x6c7));}void __init hook_ifault_code(int nr,int(*fn)(
+info,fsr,(0xa68+6882-0x254a));}void __init hook_ifault_code(int nr,int(*fn)(
 unsigned long,unsigned int,struct pt_regs*),int sig,int code,const char*name){if
-(nr<(0xfa+6318-0x19a8)||nr>=ARRAY_SIZE(ifsr_info))BUG();ifsr_info[nr].fn=fn;
+(nr<(0x7a9+6738-0x21fb)||nr>=ARRAY_SIZE(ifsr_info))BUG();ifsr_info[nr].fn=fn;
 ifsr_info[nr].sig=sig;ifsr_info[nr].code=code;ifsr_info[nr].name=name;}
 asmlinkage void __exception do_PrefetchAbort(unsigned long addr,unsigned int 
 ifsr,struct pt_regs*regs){const struct fsr_info*inf=ifsr_info+fsr_fs(ifsr);
 struct siginfo info;
 #ifdef CONFIG_MODEM_CODE_IS_MAPPING
-if(addr!=(0x166f+2778-0x2149)&&addr>=cpps_global_var.cpko_text_start&&addr<=
+if(addr!=(0x14b+8615-0x22f2)&&addr>=cpps_global_var.cpko_text_start&&addr<=
 cpps_global_var.modem_text_end){read_code_mapping(addr,ifsr|FSR_LNX_PF,regs);
 return;}
 #endif
 if(!inf->fn(addr,ifsr|FSR_LNX_PF,regs))return;printk(KERN_ALERT
 "\x55\x6e\x68\x61\x6e\x64\x6c\x65\x64\x20\x70\x72\x65\x66\x65\x74\x63\x68\x20\x61\x62\x6f\x72\x74\x3a\x20\x25\x73\x20\x28\x30\x78\x25\x30\x33\x78\x29\x20\x61\x74\x20\x30\x78\x25\x30\x38\x6c\x78" "\n"
-,inf->name,ifsr,addr);info.si_signo=inf->sig;info.si_errno=(0x1d16+878-0x2084);
+,inf->name,ifsr,addr);info.si_signo=inf->sig;info.si_errno=(0x1c76+118-0x1cec);
 info.si_code=inf->code;info.si_addr=(void __user*)addr;arm_notify_die("",regs,&
-info,ifsr,(0xd27+3858-0x1c39));}
+info,ifsr,(0x161b+3857-0x252c));}
 #ifndef CONFIG_ARM_LPAE
 static int __init exceptions_init(void){if(cpu_architecture()>=CPU_ARCH_ARMv6){
-hook_fault_code((0x101b+1132-0x1483),do_translation_fault,SIGSEGV,SEGV_MAPERR,
+hook_fault_code((0x3e9+7168-0x1fe5),do_translation_fault,SIGSEGV,SEGV_MAPERR,
 "\x49\x2d\x63\x61\x63\x68\x65\x20\x6d\x61\x69\x6e\x74\x65\x6e\x61\x6e\x63\x65\x20\x66\x61\x75\x6c\x74"
-);}if(cpu_architecture()>=CPU_ARCH_ARMv7){hook_fault_code((0x4f0+6325-0x1da2),
+);}if(cpu_architecture()>=CPU_ARCH_ARMv7){hook_fault_code((0x174d+3791-0x2619),
 do_bad,SIGSEGV,SEGV_MAPERR,
 "\x73\x65\x63\x74\x69\x6f\x6e\x20\x61\x63\x63\x65\x73\x73\x20\x66\x6c\x61\x67\x20\x66\x61\x75\x6c\x74"
-);hook_fault_code((0xc3f+5520-0x21c9),do_bad,SIGSEGV,SEGV_MAPERR,
+);hook_fault_code((0x321+7617-0x20dc),do_bad,SIGSEGV,SEGV_MAPERR,
 "\x73\x65\x63\x74\x69\x6f\x6e\x20\x61\x63\x63\x65\x73\x73\x20\x66\x6c\x61\x67\x20\x66\x61\x75\x6c\x74"
 );}
 #ifdef CONFIG_MODEM_CODE_IS_MAPPING
-int index=(0x121d+4114-0x222f);for(index=(0xc29+4294-0x1cef);index<
-(0x1aea+1834-0x21ec)*(0xcc7+5960-0x23ef);index++)init_completion(&
-page_completion[index]);
+int index=(0x16ca+2290-0x1fbc);for(index=(0x19bb+720-0x1c8b);index<
+(0xad9+83-0xb04)*(0x168+2590-0xb66);index++)init_completion(&page_completion[
+index]);
 #endif
-return(0x10c+67-0x14f);}arch_initcall(exceptions_init);
+return(0xa38+837-0xd7d);}arch_initcall(exceptions_init);
 #endif
 
diff --git a/ap/os/linux/linux-3.4.x/drivers/cpko/cpko_main.c b/ap/os/linux/linux-3.4.x/drivers/cpko/cpko_main.c
index 48235f4..fcafeb4 100755
--- a/ap/os/linux/linux-3.4.x/drivers/cpko/cpko_main.c
+++ b/ap/os/linux/linux-3.4.x/drivers/cpko/cpko_main.c
@@ -56,54 +56,55 @@
 int halVoice_Close3G(void);extern int zDrv_Audio_Printf(void*,...);extern void 
 zDrvVp_SetDtmfMute_Wrap(void);extern int zDrvVp_SetTone_Wrap(int);extern int 
 zDrvVp_SetMute_Wrap(int);extern int zDrvVp_GetMute_Wrap(void);extern int 
+zDrvVp_SetRxMute_Wrap(int);extern int zDrvVp_GetRxMute_Wrap(void);extern int 
 zDrvVp_SetVol_Wrap(int);extern int zDrvVp_GetVol_Wrap(void);extern int 
 zDrvVp_GetTxVol_Wrap(void);extern int zDrvVp_SetTxVol_Wrap(int);extern int 
 zDrvVp_GetPath_Wrap(void);extern int zDrvVp_Loop(int);extern int 
 zDrvVp_Soft_Dtmf_Loop(int);extern void zDrvDtmf_Detect_RegCallbacks(
 T_DrvDtmf_Detect_Opt);extern int zDrvVp_SetPath_Wrap(int);extern int 
-zDrvVp_GetSlicFlag(void);extern int zDrvVp_SetEchoDelay_Wrap(int val);extern int
- zDrvVp_GetEchoDelay_Wrap(void);extern int zDrvVp_SetTxNsMode_Wrap(int val);
-extern int zDrvVp_GetTxNsMode_Wrap(void);extern int zDrvVp_SetRxNsMode_Wrap(int 
-val);extern int zDrvVp_GetRxNsMode_Wrap(void);extern int 
-zDrvVp_SetModuleState_Wrap(int*,int);extern int zDrvVp_GetModuleState_Wrap(int*,
-int);extern VOID*mmp_AmrDecOpen(T_zMmp_CodecType codecType);extern VOID*
-mmp_AmrEncOpen(T_zMmp_CodecType codecType,BOOL isDtxEnable);extern UINT16 
-mmp_AmrDecode(VOID*pCodecContext,const UINT8*pAmr,UINT16*pPcm);extern UINT16 
-mmp_AmrEncode(VOID*pCodecContext,T_zMmp_AmrEncMode mode,const UINT16*pPcm,UINT8*
-pAmr);extern VOID mmp_AmrDecClose(VOID*pCodecContext);extern VOID 
-mmp_AmrEncClose(VOID*pCodecContext);extern UINT8 zDrvEdcp_IsBusy(int EdcpNum);
-extern SINT32 zDrvVp_AudioDataWrite(const VOID*pBuf,UINT32 uiLen);extern SINT32 
-zDrvVp_AudioDataOpen(UINT32 audioType,UINT32 sampleRate);extern SINT32 
-zDrvVp_AudioDataClose(void);typedef struct cpko_section{unsigned int 
-cpko_text_start;unsigned int cpko_rodata_start;unsigned int 
-__utran_modem_text_start;unsigned int __lte_modem_text_start;unsigned int 
-__comm_modem_text_start;unsigned int modem_text_end;unsigned int cpko_data_start
-;unsigned int cpko_bss_start;unsigned int cpko_text_offset;}cpko_section_layout;
-cpko_section_layout cpko_ps_section;int raise(int signo){return
-(0x16f4+3666-0x2546);}extern unsigned int SysEntry(void);static int 
+zDrvVp_GetPath_Wrap(void);extern int zDrvVp_GetSlicFlag(void);extern int 
+zDrvVp_SetEchoDelay_Wrap(int val);extern int zDrvVp_GetEchoDelay_Wrap(void);
+extern int zDrvVp_SetTxNsMode_Wrap(int val);extern int zDrvVp_GetTxNsMode_Wrap(
+void);extern int zDrvVp_SetRxNsMode_Wrap(int val);extern int 
+zDrvVp_GetRxNsMode_Wrap(void);extern int zDrvVp_SetModuleState_Wrap(int*,int);
+extern int zDrvVp_GetModuleState_Wrap(int*,int);extern VOID*mmp_AmrDecOpen(
+T_zMmp_CodecType codecType);extern VOID*mmp_AmrEncOpen(T_zMmp_CodecType 
+codecType,BOOL isDtxEnable);extern UINT16 mmp_AmrDecode(VOID*pCodecContext,const
+ UINT8*pAmr,UINT16*pPcm);extern UINT16 mmp_AmrEncode(VOID*pCodecContext,
+T_zMmp_AmrEncMode mode,const UINT16*pPcm,UINT8*pAmr);extern VOID mmp_AmrDecClose
+(VOID*pCodecContext);extern VOID mmp_AmrEncClose(VOID*pCodecContext);extern 
+UINT8 zDrvEdcp_IsBusy(int EdcpNum);extern SINT32 zDrvVp_AudioDataWrite(const 
+VOID*pBuf,UINT32 uiLen);extern SINT32 zDrvVp_AudioDataOpen(UINT32 audioType,
+UINT32 sampleRate);extern SINT32 zDrvVp_AudioDataClose(void);typedef struct 
+cpko_section{unsigned int cpko_text_start;unsigned int cpko_rodata_start;
+unsigned int __utran_modem_text_start;unsigned int __lte_modem_text_start;
+unsigned int __comm_modem_text_start;unsigned int modem_text_end;unsigned int 
+cpko_data_start;unsigned int cpko_bss_start;unsigned int cpko_text_offset;}
+cpko_section_layout;cpko_section_layout cpko_ps_section;int raise(int signo){
+return(0x183+1225-0x64c);}extern unsigned int SysEntry(void);static int 
 ko_Main_Thread(void*data){struct sched_param param={.sched_priority=
-MAX_USER_RT_PRIO/(0x1bfb+2517-0x25ce)-(0x280+9281-0x26be)};int ret=
-(0x1901+2316-0x220d);sched_setscheduler(current,SCHED_FIFO,&param);ret=SysEntry(
-);if(ret!=(0xca3+4238-0x1d31))panic("Main_Thread\n");param.sched_priority=
-MAX_USER_RT_PRIO-(0xdb8+4298-0x1e54);sched_setscheduler(kthreadd_task,SCHED_FIFO
-,&param);return(0x1747+169-0x17f0);}int zte_modem_ko_start(void){kthread_run(
+MAX_USER_RT_PRIO/(0xaf5+6062-0x22a1)-(0x1bab+1765-0x228d)};int ret=
+(0x633+3121-0x1264);sched_setscheduler(current,SCHED_FIFO,&param);ret=SysEntry()
+;if(ret!=(0x509+7685-0x230e))panic("Main_Thread\n");param.sched_priority=
+MAX_USER_RT_PRIO-(0xbb9+1067-0xfb6);sched_setscheduler(kthreadd_task,SCHED_FIFO,
+&param);return(0x10df+2732-0x1b8b);}int zte_modem_ko_start(void){kthread_run(
 ko_Main_Thread,NULL,"\x5a\x54\x45\x4d\x61\x69\x6e\x54\x68\x72\x65\x61\x64");
-return(0xa27+5084-0x1e03);}static void cpko_sectioninfo_set(void){int ret;struct
- file*fp;mm_segment_t old_fs;loff_t cpko_pos=(0x40+104-0xa8);struct 
+return(0x767+1319-0xc8e);}static void cpko_sectioninfo_set(void){int ret;struct 
+file*fp;mm_segment_t old_fs;loff_t cpko_pos=(0xd8c+3134-0x19ca);struct 
 cpps_globalModem globalVar;fp=filp_open(
 "\x2f\x6c\x69\x62\x2f\x63\x70\x6b\x6f\x2f\x63\x70\x6b\x6f\x5f\x73\x65\x63\x69\x6e\x66\x6f\x2e\x62\x69\x6e"
-,(0x36a+6751-0x1dc9),(0x102+1194-0x5ac));if(IS_ERR(fp)||fp==NULL)panic(
+,(0x19aa+718-0x1c78),(0x1099+282-0x11b3));if(IS_ERR(fp)||fp==NULL)panic(
 "\x6f\x70\x65\x6e\x20\x66\x69\x6c\x65\x20\x65\x72\x72\x6f\x72" "\n");old_fs=
 get_fs();set_fs(KERNEL_DS);ret=vfs_read(fp,(char*)&cpko_ps_section,sizeof(
-cpko_section_layout),&cpko_pos);if(ret<=(0x8eb+5166-0x1d19))panic(
+cpko_section_layout),&cpko_pos);if(ret<=(0xc0+7829-0x1f55))panic(
 "\x72\x65\x61\x64\x20\x66\x69\x6c\x65\x20\x65\x72\x72\x6f\x72" "\n");filp_close(
 fp,NULL);
 #ifdef CONFIG_MODEM_CODE_IS_MAPPING
 fp=filp_open(
 "\x2f\x6c\x69\x62\x2f\x63\x70\x6b\x6f\x2f\x63\x70\x6b\x6f\x2e\x6b\x6f",
-(0xf7b+4315-0x2056),(0x9b+404-0x22f));if(IS_ERR(fp)||fp==NULL)panic(
+(0x10f0+205-0x11bd),(0x830+3075-0x1433));if(IS_ERR(fp)||fp==NULL)panic(
 "\x6f\x70\x65\x6e\x20\x66\x69\x6c\x65\x20\x65\x72\x72\x6f\x72" "\n");fp->f_ra.
-ra_pages=(0x16da+1319-0x1c01);
+ra_pages=(0x544+4239-0x15d3);
 #endif
 if(cpko_ps_section.cpko_text_start){globalVar.cpko_text_start=(unsigned long)
 cpko_ps_section.cpko_text_start;globalVar.cpko_rodata_start=(unsigned long)
@@ -123,7 +124,7 @@
 vfree_modem_section(globalVar.cpko_text_start,globalVar.modem_text_end);
 #endif
 }else panic("\x66\x69\x6c\x65\x20\x65\x72\x72\x6f\x72" "\n");}static int 
-cpko_start(void){struct cpps_callbacks callback={(0x1d8b+614-0x1ff1)};callback.
+cpko_start(void){struct cpps_callbacks callback={(0x22b3+1037-0x26c0)};callback.
 zOss_ResetNVFactory=zOss_ResetNVFactory;callback.zOss_NvramFlush=zOss_NvramFlush
 ;callback.zOss_NvItemWrite=zOss_NvItemWrite;callback.zOss_NvItemWriteFactory=
 zOss_NvItemWriteFactory;callback.zOss_NvItemRead=zOss_NvItemRead;callback.
@@ -162,16 +163,19 @@
 halVoice_Close=halVoice_Close;callback.zDrv_Audio_Printf=zDrv_Audio_Printf;
 callback.zDrvVp_SetTone_Wrap=zDrvVp_SetTone_Wrap;callback.zDrvVp_SetMute_Wrap=
 zDrvVp_SetMute_Wrap;callback.zDrvVp_GetMute_Wrap=zDrvVp_GetMute_Wrap;callback.
-zDrvVp_SetVol_Wrap=zDrvVp_SetVol_Wrap;callback.zDrvVp_GetVol_Wrap=
-zDrvVp_GetVol_Wrap;callback.zDrvVp_SetDtmfMute_Wrap=zDrvVp_SetDtmfMute_Wrap;
-callback.zDrvVp_SetTxVol_Wrap=zDrvVp_SetTxVol_Wrap;callback.zDrvVp_GetTxVol_Wrap
-=zDrvVp_GetTxVol_Wrap;callback.zDrvVp_GetPath_Wrap=zDrvVp_GetPath_Wrap;callback.
-zDrvVp_Loop=zDrvVp_Loop;callback.zDrvVp_Soft_Dtmf_Loop=zDrvVp_Soft_Dtmf_Loop;
-callback.zDrvDtmf_Detect_RegCallbacks=zDrvDtmf_Detect_RegCallbacks;callback.
-zDrvVp_SetPath_Wrap=zDrvVp_SetPath_Wrap;callback.halVoice_Open3G=halVoice_Open3G
-;callback.halVoice_Close3G=halVoice_Close3G;callback.zDrvVp_GetSlicFlag=
-zDrvVp_GetSlicFlag;callback.zDrvVp_SetEchoDelay_Wrap=zDrvVp_SetEchoDelay_Wrap;
-callback.zDrvVp_GetEchoDelay_Wrap=zDrvVp_GetEchoDelay_Wrap;callback.
+zDrvVp_SetRxMute_Wrap=zDrvVp_SetRxMute_Wrap;callback.zDrvVp_GetRxMute_Wrap=
+zDrvVp_GetRxMute_Wrap;callback.zDrvVp_SetVol_Wrap=zDrvVp_SetVol_Wrap;callback.
+zDrvVp_GetVol_Wrap=zDrvVp_GetVol_Wrap;callback.zDrvVp_SetDtmfMute_Wrap=
+zDrvVp_SetDtmfMute_Wrap;callback.zDrvVp_SetTxVol_Wrap=zDrvVp_SetTxVol_Wrap;
+callback.zDrvVp_GetTxVol_Wrap=zDrvVp_GetTxVol_Wrap;callback.zDrvVp_GetPath_Wrap=
+zDrvVp_GetPath_Wrap;callback.zDrvVp_Loop=zDrvVp_Loop;callback.
+zDrvVp_Soft_Dtmf_Loop=zDrvVp_Soft_Dtmf_Loop;callback.
+zDrvDtmf_Detect_RegCallbacks=zDrvDtmf_Detect_RegCallbacks;callback.
+zDrvVp_SetPath_Wrap=zDrvVp_SetPath_Wrap;callback.zDrvVp_GetPath_Wrap=
+zDrvVp_GetPath_Wrap;callback.halVoice_Open3G=halVoice_Open3G;callback.
+halVoice_Close3G=halVoice_Close3G;callback.zDrvVp_GetSlicFlag=zDrvVp_GetSlicFlag
+;callback.zDrvVp_SetEchoDelay_Wrap=zDrvVp_SetEchoDelay_Wrap;callback.
+zDrvVp_GetEchoDelay_Wrap=zDrvVp_GetEchoDelay_Wrap;callback.
 zDrvVp_SetTxNsMode_Wrap=zDrvVp_SetTxNsMode_Wrap;callback.zDrvVp_GetTxNsMode_Wrap
 =zDrvVp_GetTxNsMode_Wrap;callback.zDrvVp_SetRxNsMode_Wrap=
 zDrvVp_SetRxNsMode_Wrap;callback.zDrvVp_GetRxNsMode_Wrap=zDrvVp_GetRxNsMode_Wrap
@@ -189,5 +193,5 @@
 psm_GetModemSleepFlagStatus=psm_GetModemSleepFlagStatus;
 #endif
 cpps_callbacks_register(&callback);cpko_sectioninfo_set();zte_modem_ko_start();
-return(0x15fb+4240-0x268b);}static int cpko_stop(void){return(0x15a8+773-0x18ad)
-;}module_init(cpko_start);module_exit(cpko_stop);
+return(0x3a0+2165-0xc15);}static int cpko_stop(void){return(0xc1+7397-0x1da6);}
+module_init(cpko_start);module_exit(cpko_stop);
diff --git a/ap/os/linux/linux-3.4.x/drivers/dma/zte/zx29_dma.c b/ap/os/linux/linux-3.4.x/drivers/dma/zte/zx29_dma.c
index a73b61f..883a819 100644
--- a/ap/os/linux/linux-3.4.x/drivers/dma/zte/zx29_dma.c
+++ b/ap/os/linux/linux-3.4.x/drivers/dma/zte/zx29_dma.c
@@ -485,10 +485,10 @@
     chan_reg_ptr->control  |= DMA_CTRL_FORCE_CLOSE(1);
 
     //memset((void*) chan_reg_ptr,0,sizeof(dma_chan_reg));
-    pReg->raw_int_tc_status 		|=  BIT_SHIFT_L(0x1,peripheral_id);
-    pReg->raw_int_src_err_status 	|=  BIT_SHIFT_L(0x1,peripheral_id);
-    pReg->raw_int_dest_err_status 	|=  BIT_SHIFT_L(0x1,peripheral_id);
-    pReg->raw_int_cfg_err_status 	|=  BIT_SHIFT_L(0x1,peripheral_id);
+    pReg->raw_int_tc_status 		=  BIT_SHIFT_L(0x1,peripheral_id);
+    pReg->raw_int_src_err_status 	=  BIT_SHIFT_L(0x1,peripheral_id);
+    pReg->raw_int_dest_err_status 	=  BIT_SHIFT_L(0x1,peripheral_id);
+    pReg->raw_int_cfg_err_status 	=  BIT_SHIFT_L(0x1,peripheral_id);
 	memset((void*) chan_reg_ptr,0,sizeof(dma_chan_reg));
     //dma_dev[dmac_id].chan_config[channel_id].channelCbk = NULL;
     //dma_dev[dmac_id].chan_config[channel_id].data = NULL;
diff --git a/ap/os/linux/linux-3.4.x/drivers/net/wireless/ssv6x5x/utils/smartlink/qqlink/qqlink.c b/ap/os/linux/linux-3.4.x/drivers/net/wireless/ssv6x5x/utils/smartlink/qqlink/qqlink.c
index 0539f2b..35d8d5f 100755
--- a/ap/os/linux/linux-3.4.x/drivers/net/wireless/ssv6x5x/utils/smartlink/qqlink/qqlink.c
+++ b/ap/os/linux/linux-3.4.x/drivers/net/wireless/ssv6x5x/utils/smartlink/qqlink/qqlink.c
@@ -36,7 +36,6 @@
 void on_wifi_sync_notify(tx_wifi_sync_param *pwifi_sync_param, void *puserdata)
 {
     printf("received said: %s\n", pwifi_sync_param->sz_ssid);
-    printf("received password: %s\n", pwifi_sync_param->sz_password);
     strcpy(_sz_ssid, pwifi_sync_param->sz_ssid);
     strcpy(_sz_password, pwifi_sync_param->sz_password);
 }
diff --git a/ap/os/linux/linux-3.4.x/drivers/net/zvnet/zvnet_dev.c b/ap/os/linux/linux-3.4.x/drivers/net/zvnet/zvnet_dev.c
index 1b9cab9..0209dfe 100644
--- a/ap/os/linux/linux-3.4.x/drivers/net/zvnet/zvnet_dev.c
+++ b/ap/os/linux/linux-3.4.x/drivers/net/zvnet/zvnet_dev.c
@@ -9,25 +9,69 @@
 /*******************************************************************************

  *                             Macro definitions                               *

  ******************************************************************************/

+#define USE_ZVNET_PACKET

+

 #define WATCHDOG_TIMEO (5*HZ)

 #define XMIT_RETRANS_TIMES 3

 #define ZVNET_SKB_PAD 128

 #define ZVNET_TMP_BUFF_LEN 2048

+#define ZVNET_FREE_BUFF_NUM 256

+#define ZVNET_XMIT_BUFF_NUM 64

+#define ZVNET_XMIT_MAX_QUEUE_NUM 2048

 

 /*******************************************************************************

  *							   Type definitions 						*

  ******************************************************************************/

-

+//AP´«µÝ¸øCAPµÄÊý¾Ý°üÐÅÏ¢£¬¸ÃÄÚÈÝдÈë¹²ÏíDDR

+struct	T_zvnet_rpmsg

+{

+	void *buff;//skb_headÖ¸Õ룬ÓÃÓÚÊÍ·Åʱ´«µÝ¸øºË¼ä£¬ÒÔ±ã¿ìËÙÊÍ·Å;

+	void *head;//ºË¼äÄÜʹÓõĵØÖ·±ß½ç£¬²»ÄÜÔ½½ç£¬·ñÔòÄÚ´æÒç³öÒì³£;ÎïÀíµØÖ·

+	unsigned short data_off;//ºË¼ä´«µÝÀ´µÄÊý¾Ý°üÊ×µØÖ·£¬Ö¸ÏòMACÖ¡Í·;ÎïÀíµØÖ·

+	unsigned short len;//Êý¾Ý°üÓÐЧ³¤¶È£¬Ò»°ãΪMACÖ¡³¤¶È

+	unsigned short end_off;//end offset

+	unsigned short dev;//cid 1->8

+};

 /*******************************************************************************

  *						   Local variable definitions					*

  ******************************************************************************/

 struct zvnet_device zvnet_dev[DDR_ZVNET_DEV_MAX];

+int *vir_addr_cap = NULL;

+struct sk_buff_head g_zvnet_skb_queue;

+struct zvnet_channel g_zvnet_chn_info;

+

+#ifdef USE_ZVNET_PACKET

+void *g_zvnet_free_buff[ZVNET_FREE_BUFF_NUM];

+int g_zvnet_free_num;

+spinlock_t g_zvnet_free_lock;

+struct semaphore g_zvnet_free_sem;

+struct semaphore g_zvnet_xmit_sem;

+struct sk_buff_head g_zvnet_skb_xmit_queue;

+

+unsigned int g_wrap_packet_size = 1000;

+module_param(g_wrap_packet_size, int, 0644);

+unsigned int g_wrap_num = 10;

+module_param(g_wrap_num, int, 0644);

+unsigned int g_wrap_timeout = 10;

+module_param(g_wrap_timeout, int, 0644);

+#endif

 

 /*******************************************************************************

  *						  Global variable definitions					*

  ******************************************************************************/

 extern int (*fast_from_driver)(struct sk_buff *skb, struct net_device* dev);

-

+#ifdef CONFIG_SPEED_OPT

+extern void skb_sys_pool_free(void        *ptr);

+extern void *skb_sys_pool_alloc(size_t      size);

+extern size_t skb_sys_pool_size(const void *ptr);

+#endif

+extern void psnet_freepsbuf(void *head);

+extern atomic_t  skb_used;

+extern atomic_t  skb_tops;

+extern atomic_t  skb_fromps;

+extern int skb_num_limit;

+extern struct kmem_cache *skbuff_head_cache;

+extern void dma_cache_maint(const void *vir_addr, const void *phy_addr, size_t size, int direction);

 /*******************************************************************************

  *					   Local function declarations						*

  ******************************************************************************/

@@ -45,10 +89,9 @@
 static int zvnet_channel_read(struct zvnet_channel *chninfo, void *buf, unsigned int len);

 static int zvnet_channel_clear(struct zvnet_channel *chninfo);

 static int zvnet_read_header(struct zvnet_channel *chninfo, struct zvp_header *phzvp);

-static struct sk_buff *zvnet_direct_read_skb(struct zvnet_channel *chninfo, struct zvnet *dev);

+static struct sk_buff *zvnet_direct_read_skb(struct zvnet_channel *chninfo);

 static struct sk_buff *zvnet_read_skb(struct zvnet_channel *chninfo, unsigned int tlen, struct zvnet *dev);

 static int zvnet_receive_thread(void *argv);

-

 static int rpmsgCreateChannel_v2xnet (T_ZDrvRpMsg_ActorID dstCoreID, T_ZDrvRpMsg_ChID chID, unsigned int size);

 static int zvnet_createIcpChannel(T_ZDrvRpMsg_ActorID core_id, T_ZDrvRpMsg_ChID channel_id, unsigned int channel_size);

 static int zvnet_channel_create(struct zvnet_device *zvnetdev);

@@ -56,6 +99,208 @@
 /*******************************************************************************

  * 					 Local function implementations 						*

  ******************************************************************************/

+

+unsigned long virt_to_phys_cap(unsigned long virt)

+{

+	if(virt >= (unsigned long)vir_addr_cap && virt <= ((unsigned long)vir_addr_cap+DDR_BASE_LEN_CAP)) 

+		return DDR_BASE_CAP_ADDR_PA + (virt - (unsigned long)vir_addr_cap);

+	return NULL;

+}

+

+unsigned long phys_to_virt_cap(unsigned long phys)

+{

+	if(phys >= DDR_BASE_CAP_ADDR_PA && phys <= (DDR_BASE_CAP_ADDR_PA + DDR_BASE_LEN_CAP)) 

+		return (unsigned long)vir_addr_cap + (phys - DDR_BASE_CAP_ADDR_PA);

+	return NULL;

+}

+

+void check_skb_test(struct sk_buff *skb)

+{

+	if(skb && vir_addr_cap){

+		struct sk_buff *tmp_skb;

+		if((skb->capHead && (virt_to_phys_cap(skb->head) == NULL))

+		|| ((skb->capHead == NULL) && virt_to_phys_cap(skb->head))){

+			dump_stack();

+			msleep(1000);

+			panic("capHead err");

+		}

+		skb_queue_walk(&g_zvnet_skb_queue, tmp_skb) {

+			if(tmp_skb == skb){

+				dump_stack();

+				msleep(1000);

+				panic("dup free");

+			}

+		}

+	}

+}

+

+int zvnet_get_index_by_netdev(struct net_device *net)

+{

+    int i;

+

+    for (i = 0; i < DDR_ZVNET_DEV_MAX; i++) {

+        if(zvnet_dev[i].net == net)

+            return i;

+    }

+    return -1;

+}

+#ifdef USE_ZVNET_PACKET

+void write_free_apbuf_packet(void)

+{

+	int ret,size;

+	unsigned long flags;

+	void *buf[ZVNET_FREE_BUFF_NUM];

+

+	spin_lock_irqsave(&g_zvnet_free_lock, flags);

+	if(g_zvnet_free_num == 0){

+		spin_unlock_irqrestore(&g_zvnet_free_lock, flags);

+		return;

+	}

+	size = (g_zvnet_free_num << 2);

+	memcpy(buf, g_zvnet_free_buff, size);

+	g_zvnet_free_num = 0;

+	spin_unlock_irqrestore(&g_zvnet_free_lock, flags);

+	{

+		T_ZDrvRpMsg_Msg msg = { .actorID = CAP_ID,

+								.chID = channel_29,

+								.flag = RPMSG_WRITE_INT};

+		if((size >> 2) > ZVNET_FREE_BUFF_NUM)

+			panic("free packet err");

+		msg.buf = &buf;

+		msg.len = size;

+		zv_info("tofree size=%d", size);

+		ret = zvnetWriteLockIrq(&msg);

+		if(ret < 0)

+			panic("err, ret:%d!!!!!!", ret);

+	}

+}

+#endif

+//½«CAP²à´«µÝÀ´µÄcapbufÖ¸ÕëдÈëDDR£¬ÒÔICP·½Ê½Í¨ÖªCAP²à

+void write_free_capbuf(void *head)

+{

+#ifdef USE_ZVNET_PACKET

+	unsigned long flags;

+

+	zv_info("g_zvnet_free_num=%d,skb=0x%x", g_zvnet_free_num, head);

+	spin_lock_irqsave(&g_zvnet_free_lock, flags);

+	g_zvnet_free_buff[g_zvnet_free_num] = head;

+	g_zvnet_free_num++;

+	if(g_zvnet_free_num == ZVNET_FREE_BUFF_NUM){

+		int size;

+		void *buf[ZVNET_FREE_BUFF_NUM];

+		

+		size = (g_zvnet_free_num << 2);

+		memcpy(buf, g_zvnet_free_buff, size);

+		g_zvnet_free_num = 0;

+		spin_unlock_irqrestore(&g_zvnet_free_lock, flags);

+		if((size >> 2) > ZVNET_FREE_BUFF_NUM)

+			panic("free packet err");

+		{

+			int ret;

+			T_ZDrvRpMsg_Msg msg = { .actorID = CAP_ID,

+									.chID = channel_29,

+									.flag = RPMSG_WRITE_INT};

+			msg.buf = &buf;

+			msg.len = size;

+			if(printk_ratelimit())

+				zv_warn("tofree quick size=%d", size);

+			ret = zvnetWriteLockIrq(&msg);

+			if(ret < 0)

+				panic("err, ret:%d!!!!!!", ret);

+		}

+		return;

+	}

+	if(g_zvnet_free_num > g_wrap_num)

+		up(&g_zvnet_free_sem);

+	if(g_zvnet_free_num > ZVNET_FREE_BUFF_NUM)

+		panic("free_buff err");

+	spin_unlock_irqrestore(&g_zvnet_free_lock, flags);

+#else

+	int ret = 0;

+	long buf = (long)head;

+	

+	T_ZDrvRpMsg_Msg msg = { .actorID = CAP_ID,

+							.chID = channel_29,

+							.flag = RPMSG_WRITE_INT,

+							.buf = NULL,

+							.len = 4 };

+	msg.buf = &buf;

+	zv_info("tofree 0x%x", head);

+	ret = zvnetWrite(&msg);

+	if(ret < 0)

+		panic("err, ret:%d!!!!!!", ret);

+#endif	

+}

+

+struct sk_buff *skb_build_capbuf(struct T_zvnet_rpmsg *pbuf_temp)

+{

+	struct skb_shared_info *shinfo;

+	struct sk_buff *skb;

+	unsigned int size;

+	int          len;

+	zv_info("build 0x%x 0x%x %d %d", pbuf_temp->buff, pbuf_temp->head, pbuf_temp->data_off, pbuf_temp->len);

+	if((unsigned long )pbuf_temp->head < DDR_BASE_CAP_ADDR_PA || (unsigned long )pbuf_temp->head > (DDR_BASE_CAP_ADDR_PA + DDR_BASE_LEN_CAP)){

+		zv_err("err 0x%x 0x%x %d %d", pbuf_temp->buff, pbuf_temp->head, pbuf_temp->data_off, pbuf_temp->len);

+		panic("addr is not CAPBUF mem!!!");

+		return NULL;

+	}

+

+	if(skb_num_limit && (atomic_read(&skb_used) > skb_num_limit))

+	{

+		write_free_capbuf(pbuf_temp->buff);

+		if(printk_ratelimit())

+		zv_err("skb=%d capbuff fail tops=%d fromps=%d\n",atomic_read(&skb_used),atomic_read(&skb_tops),atomic_read(&skb_fromps));

+		return NULL;

+	}

+#ifndef CONFIG_SPEED_OPT

+#ifdef CONFIG_SLOB_OPT

+	skb = kmalloc(kmem_cache_size(skbuff_head_cache), GFP_ATOMIC);

+#else

+	skb = kmem_cache_alloc(skbuff_head_cache, GFP_ATOMIC);

+#endif

+#else

+    skb =  skb_sys_pool_alloc(kmem_cache_size(skbuff_head_cache));

+#endif

+	if (!skb)

+	{

+		write_free_capbuf(pbuf_temp->buff);

+		zv_err("skb=%d alloc fail tops=%d fromps=%d\n",atomic_read(&skb_used),atomic_read(&skb_tops),atomic_read(&skb_fromps));

+		return NULL;

+	}

+	skb_alloc_track(skb);

+	memset(skb, 0, offsetof(struct sk_buff, tail));

+

+	//ÅжÏÊÇ·ñÊÇcapbuff

+	

+	if(pbuf_temp->dev < 0 || pbuf_temp->dev >= DDR_ZVNET_DEV_MAX)

+		panic("dev index error!!!");

+	skb->head = phys_to_virt_cap((unsigned long )pbuf_temp->head);

+	skb->data = skb->head + pbuf_temp->data_off;

+	skb->capHead = pbuf_temp->buff;

+	//ÐèÒª¿¼ÂÇcacheÐÐ¶ÔÆë

+	skb->truesize = SKB_TRUESIZE(skb->data - skb->head + pbuf_temp->len);//°´µÀÀíβ²¿»¹ÓпÉÓõÄÄÚ´æ¿Õ¼ä£¬ÔÝʱδ¿¼ÂÇ;SKB_DATA_ALIGN 

+

+	atomic_set(&skb->users, 1);

+	skb_reset_tail_pointer(skb);

+	skb->tail += pbuf_temp->len;

+	skb->len = pbuf_temp->len;

+	skb->end = skb->head + pbuf_temp->end_off;

+	skb->dev = zvnet_dev[pbuf_temp->dev].net;

+	if(IFF_NOARP & skb->dev->flags)

+		memcpy(skb->data, skb->dev->dev_addr, 6);

+	if(skb->len == 0 || skb->len > 2000)

+		panic("len    ERR!!!!!!!!!!\n");

+	/* make sure we initialize shinfo sequentially */

+	dma_cache_maint(skb->head, pbuf_temp->head, pbuf_temp->end_off + sizeof(struct skb_shared_info), DMA_FROM_DEVICE);

+	skb_reset_network_header(skb);

+	//shinfo = skb_shinfo(skb);

+	//memset(shinfo, 0, offsetof(struct skb_shared_info, dataref));

+	//atomic_set(&shinfo->dataref, 1);

+	kmemcheck_annotate_variable(shinfo->destructor_arg);

+	return skb;

+}

+

+

 static void skb_debug_test(struct sk_buff *skb)

 {

     int i;

@@ -107,9 +352,112 @@
 

     return 0;

 }

+#ifdef USE_ZVNET_PACKET

+static void zvnet_xmit_packet(void)

+{

+	int i,j,k,ret,num;

+	unsigned long flags;

+	unsigned long flags1;

+	struct sk_buff *skb;

+	T_ZDrvRpMsg_Msg msg = { .actorID = CAP_ID,

+							.chID = channel_20,

+							.flag = RPMSG_WRITE_INT};

+	static struct T_zvnet_rpmsg buff[ZVNET_XMIT_MAX_QUEUE_NUM];

 

+	spin_lock_irqsave(&g_zvnet_skb_xmit_queue.lock, flags);

+	if (skb_queue_empty(&g_zvnet_skb_xmit_queue)) {

+		spin_unlock_irqrestore(&g_zvnet_skb_xmit_queue.lock, flags);

+		return;

+	}

+	i = 0;

+	skb_queue_walk(&g_zvnet_skb_xmit_queue, skb) {

+		buff[i].buff = skb;

+		buff[i].data_off = skb->data - skb->head;

+		buff[i].head = virt_to_phys(skb->head);

+		buff[i].len = skb->len;

+		buff[i].end_off = skb->end - skb->head;

+		buff[i].dev = zvnet_get_index_by_netdev(skb->dev);

+		i++;

+		zv_info("xmit skb=0x%x i=%d", skb, i);

+		if(i >= ZVNET_XMIT_MAX_QUEUE_NUM){

+			panic("qlen:%d!", i);

+		}

+	}

+	spin_lock_irqsave(&g_zvnet_skb_queue.lock, flags1);

+	skb_queue_splice_tail_init(&g_zvnet_skb_xmit_queue, &g_zvnet_skb_queue);

+	spin_unlock_irqrestore(&g_zvnet_skb_queue.lock, flags1);

+	spin_unlock_irqrestore(&g_zvnet_skb_xmit_queue.lock, flags);

+	zv_info("g_zvnet_skb_queue.qlen=%d i=%d", g_zvnet_skb_queue.qlen, i);

+	for(j = 0; j < i; j = j + ZVNET_XMIT_BUFF_NUM){

+		if(i <= (j + ZVNET_XMIT_BUFF_NUM)){

+			msg.buf = (void *)&buff[j];

+			msg.len = sizeof(struct T_zvnet_rpmsg)*(i-j);/*±¾´ÎÄÜÈ¡¹â*/

+			ret = zvnetWrite(&msg);

+		}else{

+			msg.buf = (void *)&buff[j];

+			msg.len = sizeof(struct T_zvnet_rpmsg)*ZVNET_XMIT_BUFF_NUM;

+			ret = zvnetWrite(&msg);

+		}

+		zv_info("xmit write ret=%d size=%d i=%d j=%d", ret, msg.len, i, j);

+		if(ret < 0) {

+			if(printk_ratelimit())

+				zv_warn("zvnet_channel_write ret=%d fail.",ret);

+			num = msg.len / sizeof(struct T_zvnet_rpmsg);

+			for(k = j; k < j+num; k++){

+				skb = (struct sk_buff *)buff[k].buff;

+				skb_unlink(skb, &g_zvnet_skb_queue);

+				skb->isTocap = 0;

+				kfree_skb(skb);

+			}

+		}

+	}

+}

+#endif

 static netdev_tx_t zvnet_xmit(struct sk_buff *skb, struct net_device *net)

 {

+#ifdef USE_ZVNET_PACKET

+	struct sk_buff *data = NULL;

+

+	//zv_info("g_zvnet_skb_xmit_queue.qlen=%d", g_zvnet_skb_xmit_queue.qlen);

+	if(g_zvnet_skb_xmit_queue.qlen >= ZVNET_XMIT_MAX_QUEUE_NUM){

+		net->stats.tx_errors++;

+		net->stats.tx_dropped++;

+		zv_err("write err, qlen:%d!", g_zvnet_skb_xmit_queue.qlen);

+		kfree_skb(skb);

+		return NET_XMIT_SUCCESS;

+	}

+		

+	if(unlikely(skb->capHead || skb->next || skb->fclone || skb->cloned 

+		|| (skb_shinfo(skb)->nr_frags) || (skb_shinfo(skb)->tx_flags & SKBTX_DEV_ZEROCOPY) 

+		|| (skb_has_frag_list(skb)))){

+		int ret_len = skb->len;

+

+		data = dev_alloc_skb(ret_len + NET_IP_ALIGN);

+		if (unlikely(!data)) {

+			zv_err("dev_alloc_skb fail,len %d",ret_len);

+			net->stats.tx_errors++;

+			net->stats.tx_dropped++;

+			kfree_skb(skb);

+			return NET_XMIT_SUCCESS;

+		}

+		skb_put(data,ret_len);

+		skb_reserve(data, NET_IP_ALIGN);

+		memcpy(data->data, skb->data, ret_len);

+		zv_info("ap=0x%x next=0x%x clone=%d nr_frags=%d tx_flags=%d frag_list=0x%x", skb->capHead, skb->next, skb->cloned, (skb_shinfo(skb)->nr_frags), skb_shinfo(skb)->tx_flags, skb_shinfo(skb)->frag_list);

+		kfree_skb(skb);

+	}else{

+		data = skb;

+	}

+	data->dev = net;

+	data->isTocap = 1;

+	dma_cache_maint(data->head, virt_to_phys(data->head), data->end - data->head + sizeof(struct skb_shared_info), DMA_TO_DEVICE);

+	skb_queue_tail(&g_zvnet_skb_xmit_queue, data);

+	if(data->len < g_wrap_packet_size || g_zvnet_skb_xmit_queue.qlen > g_wrap_num)

+		up(&g_zvnet_xmit_sem);

+	net->trans_start = jiffies;

+	net->stats.tx_packets++;

+	net->stats.tx_bytes += skb->len;

+#else

     struct zvnet *dev = netdev_priv(net);

     struct zvnet_device *zvnetdev = (struct zvnet_device *)dev->dev_priv;

     int ret = 0;

@@ -118,6 +466,7 @@
     if (!skb) {

         zv_err("err: skb == 0!");

     }

+#if 0

     if (skb->len > ZVNET_TMP_BUFF_LEN) {

         zv_err("err: skb->len(%d)>%d!", skb->len, ZVNET_TMP_BUFF_LEN);

     }

@@ -143,7 +492,79 @@
 

 exit:

     kfree_skb(skb);

+#else

+	struct T_zvnet_rpmsg buff = {0};

+	struct sk_buff *data = NULL;

+	if(unlikely(skb->capHead || skb->fclone || skb->cloned || skb->next 

+		|| (skb_shinfo(skb)->nr_frags) || (skb_shinfo(skb)->tx_flags & SKBTX_DEV_ZEROCOPY) 

+		|| (skb_has_frag_list(skb)))){

+		int ret_len = skb->len;

 

+		data = dev_alloc_skb(ret_len + NET_IP_ALIGN);

+		if (unlikely(!data)) {

+			zv_err("dev_alloc_skb fail,len %d",ret_len);

+			net->stats.tx_errors++;

+			net->stats.tx_dropped++;

+			kfree_skb(skb);

+			return NET_XMIT_SUCCESS;

+		}

+		skb_put(data,ret_len);

+		skb_reserve(data, NET_IP_ALIGN);

+		memcpy(data->data, skb->data, ret_len);

+		data->isTocap = 1;

+		buff.buff = data;

+		buff.data_off = data->data - data->head;

+		buff.head = virt_to_phys(data->head);

+		buff.len = ret_len;

+		buff.end_off = data->end - data->head;

+		buff.dev = zvnet_get_index_by_netdev(net);

+		zv_info("alloc 0x%x 0x%x %d %d", buff.buff, buff.head, buff.data_off, buff.len);

+		zv_info("cap=0x%x next=0x%x clone=%d nr_frags=%d tx_flags=%d frag_list=0x%x", skb->capHead, skb->next, skb->cloned, (skb_shinfo(skb)->nr_frags), skb_shinfo(skb)->tx_flags, skb_shinfo(skb)->frag_list);

+		dma_cache_maint(data->head, buff.head, buff.end_off + sizeof(struct skb_shared_info), DMA_TO_DEVICE);

+	}else{

+		skb->isTocap = 1;

+		buff.buff = skb;

+		buff.data_off = skb->data - skb->head;

+		buff.head = virt_to_phys(skb->head);

+		buff.len = skb->len;

+		buff.end_off = skb->end - skb->head;

+		buff.dev = zvnet_get_index_by_netdev(net);

+		zv_info("transfer 0x%x %d 0x%x %d", buff.buff, buff.head, buff.data_off, buff.len);

+		dma_cache_maint(skb->head, buff.head, buff.end_off + sizeof(struct skb_shared_info), DMA_TO_DEVICE);

+	}

+send_header:

+	ret = zvnet_channel_write(&g_zvnet_chn_info, &buff, sizeof(struct T_zvnet_rpmsg));

+

+	if((ret < 0) && (zvnetdev->retran_times < XMIT_RETRANS_TIMES)) {

+		zvnetdev->retran_times ++;

+		zv_warn("The retran_times is %d.",zvnetdev->retran_times);

+		goto send_header;

+	}

+

+	if (ret >= 0) {

+		net->trans_start = jiffies;

+		net->stats.tx_packets++;

+		net->stats.tx_bytes += skb->len;

+		if(data){

+			kfree_skb(skb);

+			skb_queue_tail(&g_zvnet_skb_queue, data);

+		}else

+			skb_queue_tail(&g_zvnet_skb_queue, skb);

+		zvnetdev->retran_times = 0;

+	} else {

+		net->stats.tx_errors++;

+		net->stats.tx_dropped++;

+		zv_err("write err, ret:%d!", ret);

+		if(data){

+			data->isTocap = 0;

+			kfree_skb(data);

+		}

+		else

+			skb->isTocap = 0;

+		kfree_skb(skb);

+	}

+#endif

+#endif

     return NET_XMIT_SUCCESS;

 }

 

@@ -179,7 +600,7 @@
 

     net->netdev_ops = &zvnet_netdev_ops;

     net->watchdog_timeo = WATCHDOG_TIMEO;

-    //net->flags |= IFF_NOARP;

+    net->flags |= IFF_NOARP;

 }

 

 static void zvnet_skb_return (struct zvnet *dev, struct sk_buff *skb)

@@ -254,6 +675,7 @@
 

     return zvnetWrite(&msg);

 }

+

 /*·µ»ØÖµ´óÓÚ0£¬±íʾ¶ÁȡͨµÀ³É¹¦£»Ð¡ÓÚµÈÓÚ0±íʾͨµÀÊý¾ÝΪ¿Õ»òʧ°Ü*/

 static int zvnet_channel_read(struct zvnet_channel *chninfo, void *buf, unsigned int len)

 {

@@ -272,8 +694,8 @@
 

     ret = zvnetRead(&msg);

     if (ret <= 0) {

-        zv_err("No msg or other error!");

-        return -EAGAIN;

+        zv_err("rpm read err=%d!",ret);

+        return ret;

     }

 

     return ret;

@@ -333,9 +755,10 @@
     return skb;

 }

 

-static struct sk_buff *zvnet_direct_read_skb(struct zvnet_channel *chninfo, struct zvnet *dev)

+static struct sk_buff *zvnet_direct_read_skb(struct zvnet_channel *chninfo)

 {

     struct sk_buff *skb;

+#if 0

     char skb_data[ZVNET_TMP_BUFF_LEN];

     int ret_len = 0;

 

@@ -360,43 +783,116 @@
     skb_put(skb,ret_len);

     skb_reserve(skb, ZVNET_SKB_PAD);

     memcpy(skb->data, &skb_data[0], ret_len);

+#else

+	struct T_zvnet_rpmsg buff = {0};

+	int ret_len = 0;

+	ret_len = zvnet_channel_read(chninfo, (void *)&buff, sizeof(struct T_zvnet_rpmsg));

 

-    skb->dev = dev->net;

-

+	if(ret_len <= 0) {

+		zv_err("rpm read err=%d", ret_len);

+		msleep(1000);

+		return NULL;

+	}

+	if(ret_len != sizeof(struct T_zvnet_rpmsg)) {

+		panic("err, ret:%d!!!!!!", ret_len);	

+	}

+    skb = skb_build_capbuf(&buff);

+    if (unlikely(!skb)) {

+        zv_err("netdev_alloc_skb fail,len %d",ret_len);

+        return NULL;

+    }

+#endif

+    //skb->dev = dev->net;

     return skb;

 }

 

 static int zvnet_receive_thread(void *argv)

 {

-    struct zvnet_device *zvnetdev = (struct zvnet_device *)argv;

-    struct zvnet_channel *chninfo = NULL;

+    //struct zvnet_device *zvnetdev = (struct zvnet_device *)argv;

+    //struct zvnet_channel *chninfo = NULL;

     struct zvnet *dev = NULL;

+	int index,ret_len,i,num;

     unsigned long flags;

-    struct zvp_header hzvp;

-

+	struct sk_buff *skb = NULL;

+	T_ZDrvRpMsg_Msg msg = { .actorID = CAP_ID,

+							.chID = channel_20,

+							.flag = 0};

+	struct T_zvnet_rpmsg buff[ZVNET_XMIT_BUFF_NUM];

+    //struct zvp_header hzvp;

+/*

     if(IS_ERR(zvnetdev)) {

         zv_err("The receive thread create fail!");

         return -EINVAL;

     }

     chninfo = &zvnetdev->chn_info;

     dev = zvnetdev->dev;

+*/

     while(1) {

-        struct sk_buff *skb = NULL;

-

+/*

         if(unlikely(!(zvnetdev->net->flags & IFF_UP))) {

             msleep(1000);

             continue;

         }

-

+*/

         //memset(&hzvp, 0, sizeof(hzvp));

-        if(0 != (skb = zvnet_direct_read_skb(chninfo, dev))) {

+#ifdef USE_ZVNET_PACKET

+		//ret_len = zvnet_channel_read(&g_zvnet_chn_info, (void *)buff, sizeof(struct T_zvnet_rpmsg)*ZVNET_XMIT_BUFF_NUM);

+		msg.buf 	= (void *)(buff);  // Êý¾Ý

+		msg.len 	= sizeof(struct T_zvnet_rpmsg)*ZVNET_XMIT_BUFF_NUM;// ¶ÁÈ¡µÄ³¤¶È

+		ret_len = zvnetRead(&msg);	 // ¶ÁÈ¡»·ÐζÓÁÐÖÐÒ»¸ö½Úµã£¬

+		zv_info("zvnetRead ret=%d", ret_len);

+		if(ret_len <= 0) {

+			zv_err("rpm read err=%d", ret_len);

+			msleep(1000);

+			continue;

+		}

+		if((ret_len % sizeof(struct T_zvnet_rpmsg)) != 0) {

+			panic("err, ret:%d!!!!!!", ret_len);	

+		}

+		num = ret_len / sizeof(struct T_zvnet_rpmsg);

+		for(i = 0; i < num; i++){

+			skb = skb_build_capbuf(&buff[i]);

+			if (unlikely(!skb)) {

+				zv_err("skb_build_capbuf fail,len=%d i=%d",ret_len,i);

+				continue;

+			}

+	        if(unlikely(!(skb->dev->flags & IFF_UP))) {

+				dev_kfree_skb (skb);

+				if(printk_ratelimit())

+					zv_err("drop!!!%s is down.", skb->dev->name);

+	            continue;

+	        }

+            if (fast_from_driver && fast_from_driver(skb, skb->dev))

+            {

+                continue;

+            }

+			index = zvnet_get_index_by_netdev(skb->dev);

+			if(index < 0)

+				panic("");

+			dev = zvnet_dev[index].dev;

+            spin_lock_irqsave(&dev->rxq.lock, flags);

+            __skb_queue_tail(&dev->rxq, skb);

+            spin_unlock_irqrestore(&dev->rxq.lock, flags);

+            tasklet_schedule(&dev->bh);

+		}

+#else

+        if(0 != (skb = zvnet_direct_read_skb(&g_zvnet_chn_info))) {

             //skb_debug_test(skb);

+	        if(unlikely(!(skb->dev->flags & IFF_UP))) {

+				dev_kfree_skb (skb);

+				zv_err("drop!!!%s is down.", skb->dev->name);

+	            continue;

+	        }

 #if 1

-            if (fast_from_driver && fast_from_driver(skb, dev->net))

+            if (fast_from_driver && fast_from_driver(skb, skb->dev))

             {

                 continue;

             }

 #endif

+			index = zvnet_get_index_by_netdev(skb->dev);

+			if(index < 0)

+				panic("");

+			dev = zvnet_dev[index].dev;

             spin_lock_irqsave(&dev->rxq.lock, flags);

             __skb_queue_tail(&dev->rxq, skb);

             spin_unlock_irqrestore(&dev->rxq.lock, flags);

@@ -406,6 +902,7 @@
             zv_err("zvnet_read_header fail.");

             msleep(1000);

         }

+#endif

     }

 

     zv_err("The receive thread exit!");

@@ -431,7 +928,7 @@
     zv_err("could not create channel.");

     return retval;

 }

-

+/*

 static int zvnet_channel_create(struct zvnet_device *zvnetdev)

 {

     struct task_struct *th = NULL;

@@ -457,7 +954,98 @@
 

     return 0;

 }

+*/

+static int zvnet_release_thread(void * nouse)

+{

+	T_ZDrvRpMsg_Msg msg = { .actorID = CAP_ID,

+							.chID = channel_29,

+							.flag = 0};

+	void *buff[ZVNET_FREE_BUFF_NUM] = {0};

+	int i,num,retval;

+	struct sk_buff *skb;

+	struct sched_param param = { .sched_priority = 1 };

+	param.sched_priority = 37;

+	sched_setscheduler(current, SCHED_FIFO, &param);

 

+	while(1) {

+		zv_info("g_zvnet_skb_queue.qlen=%d", g_zvnet_skb_queue.qlen);

+#ifdef USE_ZVNET_PACKET

+		msg.buf 	= (unsigned char *)(buff);  // Êý¾Ý

+		msg.len 	= 4*ZVNET_FREE_BUFF_NUM;// ¶ÁÈ¡µÄ³¤¶È

+		retval = zvnetRead(&msg);	 // ¶ÁÈ¡»·ÐζÓÁÐÖÐÒ»¸ö½Úµã£¬

+		zv_info("free read ret=%d", retval);

+		if (retval <= 0) {

+			zv_err("rpm read err=%d", retval);

+			msleep(1000);

+			continue;

+		}

+		if((retval%4) != 0) {

+			panic("err, ret:%d!!!!!!", retval);

+		}

+		num = retval>>2;

+		for(i = 0; i < num; i++){

+			skb = (struct sk_buff *)buff[i];

+			zv_info("free 0x%x i=%d", skb, i);

+			if (skb == NULL || skb->next == NULL || skb->prev == NULL) {

+				panic("rpm read=%d i=%d NULL", retval, i);

+				continue;

+			}

+			skb_unlink(skb, &g_zvnet_skb_queue);

+			if(skb->isTocap != 1)

+				panic("");

+			skb->isTocap = 0;

+			kfree_skb(skb);

+		}

+#else

+		void *buff;

+		msg.actorID = CAP_ID;

+		msg.chID	=  channel_29;

+		msg.buf 	= (unsigned char *)(&buff);  // Êý¾Ý

+		msg.len 	= 4;// ¶ÁÈ¡µÄ³¤¶È

+		//msg.flag |= RPMSG_READ_POLL;

+

+		retval = zvnetRead(&msg);	 // ¶ÁÈ¡»·ÐζÓÁÐÖÐÒ»¸ö½Úµã£¬

+		if (retval <= 0) {

+			zv_err("no msg or threand exited");

+			msleep(1000);

+			continue;

+		}

+		if(retval != 4) {

+			panic("err, ret:%d!!!!!!", retval);

+		}

+		zv_info("free 0x%x", buff);

+		skb = (struct sk_buff *)buff;

+		skb_unlink(skb, &g_zvnet_skb_queue);

+		if(skb->isTocap != 1)

+			panic("");

+		skb->isTocap = 0;

+		kfree_skb(skb);

+#endif

+	}

+    zv_err("The realse thread exit!");

+    return 0;

+}

+#ifdef USE_ZVNET_PACKET

+static int zvnet_xmit_warp_thread(void * nouse)

+{

+	while(1) {

+		down_timeout(&g_zvnet_xmit_sem, msecs_to_jiffies(g_wrap_timeout));

+		zvnet_xmit_packet();

+	}

+	zv_err("The xmit warp thread exit!");

+	return 0;

+}

+

+static int zvnet_free_warp_thread(void * nouse)

+{

+	while(1) {

+		down_timeout(&g_zvnet_free_sem, msecs_to_jiffies(g_wrap_timeout));

+		write_free_apbuf_packet();

+	}

+	zv_err("The free warp thread exit!");

+	return 0;

+}

+#endif

 /*******************************************************************************

  *					 Global function implementations						*

  ******************************************************************************/

@@ -469,6 +1057,16 @@
     struct net_device *net = NULL;

     struct zvnet_device *zvnetdev = NULL;

 

+#ifdef USE_ZVNET_PACKET

+	skb_queue_head_init(&g_zvnet_skb_xmit_queue);

+	spin_lock_init(&g_zvnet_free_lock);

+	sema_init(&g_zvnet_free_sem, 0);

+	sema_init(&g_zvnet_xmit_sem, 0);

+#endif

+    skb_queue_head_init(&g_zvnet_skb_queue);

+	g_zvnet_chn_info.core_id = CAP_ID;

+	g_zvnet_chn_info.channel_id = ICP_CHN_ZVNET1;

+	g_zvnet_chn_info.channel_size = ICP_CHANNEL_SIZE;

     for (i = 0; i < DDR_ZVNET_DEV_MAX; i++) {

         zvnetdev = &zvnet_dev[i];

         memset(zvnetdev, 0, sizeof(struct zvnet_device));

@@ -482,14 +1080,17 @@
         sprintf(net->name, "%s%d", ZVNET_IFNAME_PREFIX, i);

         dev = v2xnet_dev_init(net, zvnetdev);

         v2xnet_init_netdev(net);

+		if(0 == i){

+			net->flags = (net->flags & (~IFF_NOARP));

+		}

         err = register_netdev(net);

         if (err) {

             zv_err("register_netdev error:%d :%d\n",err,i);

-            goto out_free_netdev;

+            return err;

         }

         zvnetdev->dev = dev;

         zvnetdev->net = net;

-

+/*

         zvnetdev->chn_info.core_id = CAP_ID;

         zvnetdev->chn_info.channel_id = ICP_CHN_ZVNET1 + i;//zvnet_collect[i];

         zvnetdev->chn_info.channel_size = ICP_CHANNEL_SIZE;

@@ -498,16 +1099,61 @@
             zv_err("zvnet_channel_create error:%d :%d\n",err,i);

             goto out_unregister_netdev;

         }

+*/

     }

+	{

+	    struct task_struct *th = NULL;

+	    int retval = 0;

+		

+	    retval = zvnet_createIcpChannel(CAP_ID, channel_20, ICP_CHANNEL_SIZE);

+	    if(retval < 0) {

+	        zv_err("Create IcpChannel channel_20 fail.");

+	        return retval;

+	    }

 

+	    th = kthread_run(zvnet_receive_thread, 0, "zvnet-recv%d", channel_20);

+	    if (IS_ERR(th)) {

+	        zv_err("Unable to start receive thread.");

+	        return PTR_ERR(th);

+	    }

+        g_zvnet_chn_info.rcv_thread = th;

+

+	    retval = zvnet_createIcpChannel(CAP_ID, channel_29, ICP_CHANNEL_SIZE);

+	    if(retval < 0) {

+	        zv_err("Create IcpChannel channel_29 fail.");

+	        return retval;

+	    }

+

+	    th = kthread_run(zvnet_release_thread, 0, "zvnet-free%d", channel_29);

+	    if (IS_ERR(th)) {

+	        zv_err("Unable to start release thread.");

+	        return PTR_ERR(th);

+	    }

+#ifdef USE_ZVNET_PACKET

+	    th = kthread_run(zvnet_xmit_warp_thread, 0, "zvnet-xmit-wrap");

+	    if (IS_ERR(th)) {

+	        zv_err("Unable to start xmit_warp thread.");

+	        return PTR_ERR(th);

+	    }

+		

+	    th = kthread_run(zvnet_free_warp_thread, 0, "zvnet-free-wrap");

+	    if (IS_ERR(th)) {

+	        zv_err("Unable to start free_warp thread.");

+	        return PTR_ERR(th);

+	    }

+#endif

+		vir_addr_cap = ioremap_cached(DDR_BASE_CAP_ADDR_PA, DDR_BASE_LEN_CAP);

+		zv_warn("vir_addr_cap vir=0x%x phy=0x%x len=0x%x", vir_addr_cap, DDR_BASE_CAP_ADDR_PA, DDR_BASE_LEN_CAP);

+		if(vir_addr_cap == NULL)

+		{

+			zv_err("CAP mmap failed.\n");

+			return -1;

+		}

+

+	}

     zv_dbg("success.\n");

     return 0;

 

-out_unregister_netdev:

-    unregister_netdev(net);

-out_free_netdev:

-    free_netdev(net);

-    return err;

 }

 

 static void __exit zvnet_exit(void)

diff --git a/ap/os/linux/linux-3.4.x/drivers/net/zvnet/zvnet_dev.h b/ap/os/linux/linux-3.4.x/drivers/net/zvnet/zvnet_dev.h
index dc4cec2..be937d6 100755
--- a/ap/os/linux/linux-3.4.x/drivers/net/zvnet/zvnet_dev.h
+++ b/ap/os/linux/linux-3.4.x/drivers/net/zvnet/zvnet_dev.h
@@ -27,7 +27,7 @@
 	__func__ , ## arg)

 

 //zvnetÉ豸×î´óÊý

-#define DDR_ZVNET_DEV_MAX 4

+#define DDR_ZVNET_DEV_MAX 9

 #define ZVNET_IFNAME_PREFIX "zvnet"

 

 #define ICP_CHN_ZVNET1 channel_20

@@ -41,6 +41,9 @@
 #define zvnetWrite zDrvRpMsg_Write_Cap //zDrvRpMsg_Write

 #define zvnetRead zDrvRpMsg_Read_Cap //zDrvRpMsg_Read

 

+extern int zDrvRpMsg_WriteLockIrq_Cap(const T_ZDrvRpMsg_Msg *pMsg);

+#define zvnetWriteLockIrq zDrvRpMsg_WriteLockIrq_Cap

+

 struct zvnet_channel {

     T_ZDrvRpMsg_ActorID core_id;

     T_ZDrvRpMsg_ChID channel_id;

@@ -58,7 +61,7 @@
 struct zvnet_device {

     struct zvnet *dev;

     struct net_device *net;

-    struct zvnet_channel chn_info;

+    //struct zvnet_channel chn_info;

     unsigned char retran_times;

     //int (*write)(struct sk_buff *,struct v2x_hdr *, unsigned int, struct net_device *);

 };

diff --git a/ap/os/linux/linux-3.4.x/drivers/soc/zte/power/zx-pm.c b/ap/os/linux/linux-3.4.x/drivers/soc/zte/power/zx-pm.c
index a1b90ab..f749f7c 100755
--- a/ap/os/linux/linux-3.4.x/drivers/soc/zte/power/zx-pm.c
+++ b/ap/os/linux/linux-3.4.x/drivers/soc/zte/power/zx-pm.c
@@ -22,6 +22,7 @@
 #include <linux/timer.h>
 #include <linux/kthread.h>	/*For kthread_run()*/
 #include <mach/spinlock.h>
+#include "pub_debug_info.h"
 
 #ifdef CONFIG_ZX_PM_DEBUG
 
@@ -42,6 +43,12 @@
 static u32  pm_sram_point = 0;
 static u32  pm_sram_inited = 0;
 //static char pm_sram_temp_buf[512] = {0};
+/*
+1cnt is 1s
+*/
+unsigned int psm_record_time_cnt=0; 	
+unsigned int psm_record_time= 30; 
+module_param(psm_record_time, uint, 0644);
 
 static void pm_sram_cpy(char *s, unsigned len)
 {
@@ -146,7 +153,6 @@
 		printk(" jiffies:%u; ", cur_jiffies);
 		#ifndef CONFIG_SYSTEM_RECOVERY
 		#ifndef CONFIG_ARCH_ZX297520V3_CAP
-
 			#ifdef USE_CPPS_KO
 			if(cpps_callbacks.psm_GetModemSleepFlagStatus)
 				CPPS_FUNC(cpps_callbacks,psm_GetModemSleepFlagStatus)();
@@ -199,13 +205,54 @@
 /* ------------------for idle print msg-------------------------*/
 
 #endif
-
+extern void pm_debug_wakelocks(void);
 void pm_psm_flag_print(u32 *sleepflag)
 {
+	unsigned int temp_count;
+
 	#ifdef CONFIG_CPU_IDLE
 	#ifndef CONFIG_ARCH_ZX297520V3_CAP
-	printk("L1e w t: 0x%x  0x%x  0x%x; drv:0x%x;  app:0x%x; plat:0x%x; gsm:0x%x ; idle_flag:0x%x;dma_used: 0x%x \n ",  
-		sleepflag[0],  sleepflag[1], sleepflag[2], sleepflag[3], sleepflag[4] , sleepflag[5], sleepflag[6], zx_idle_get_idle_flag(),pm_dma_used());
+	printk("L1e e1 w t: 0x%x  0x%x  0x%x  0x%x; drv:0x%x;  app:0x%x; plat:0x%x; gsm:0x%x; idle_flag:0x%x; dma_used: 0x%x \n ",  
+		sleepflag[0], sleepflag[7],   sleepflag[1], sleepflag[2], sleepflag[3], sleepflag[4] , sleepflag[5], sleepflag[6], zx_idle_get_idle_flag(),pm_dma_used());
+
+	if((psm_record_time_cnt%psm_record_time)==0)
+	{
+		if((sleepflag[0]!=0x7f) ||(sleepflag[7]!=0x7f)||(sleepflag[1]!=0x3f)||(sleepflag[2]!=0x3f)){
+			sc_debug_info_record(MODULE_ID_AP_PSM, "L1e0 e1 w t:%x %x %x %x\n", sleepflag[0], sleepflag[7], sleepflag[1], sleepflag[2] );
+			printk("L1e0 e1 w t: %x %x %x %x\n", sleepflag[0], sleepflag[7], sleepflag[1], sleepflag[2] );
+		}
+		if(sleepflag[3]){
+			sc_debug_info_record(MODULE_ID_AP_PSM, "drv %x\n", sleepflag[3] );
+			printk("drv: %x\n", sleepflag[3] );
+		}
+		if(sleepflag[4]){
+			sc_debug_info_record(MODULE_ID_AP_PSM, "app %x\n", sleepflag[4] );
+			printk("app: %x\n", sleepflag[4] );
+		}
+		if(!sleepflag[5]){
+			sc_debug_info_record(MODULE_ID_AP_PSM, "plat %x\n", sleepflag[5] );
+			printk("plat: %x\n", sleepflag[5] );
+		}
+		if(!sleepflag[6]){
+			sc_debug_info_record(MODULE_ID_AP_PSM, "gsm %x\n", sleepflag[6] );
+			printk("gsm: %x\n", sleepflag[6] );
+		}
+		if(zx_idle_get_idle_flag() ){
+			sc_debug_info_record(MODULE_ID_AP_PSM, "idle_flag %x\n", zx_idle_get_idle_flag() );
+			printk("idle_flag: %x\n", zx_idle_get_idle_flag());
+		}
+		if(pm_dma_used()){
+			sc_debug_info_record(MODULE_ID_AP_PSM, "dma_used %x\n", pm_dma_used());
+			printk("dma_used: %x\n", pm_dma_used() );
+		}
+
+		if(!(pm_get_wakeup_count(&temp_count, false) && pm_save_wakeup_count(temp_count)))
+		{
+			pm_debug_wakelocks();
+		}
+	}
+	psm_record_time_cnt++;		
+		
 	#endif
 	#endif
 }
@@ -444,7 +491,7 @@
  *=============================================================================
  */
 extern void test_wakelock(void);
-extern void pm_debug_wakelocks(void);
+//extern void pm_debug_wakelocks(void);
 static ssize_t wakelock_show(struct kobject *kobj, struct kobj_attribute *attr,
 			  char *buf)
 {
diff --git a/ap/os/linux/linux-3.4.x/drivers/soc/zte/tsc/zx-tsc-strategy.c b/ap/os/linux/linux-3.4.x/drivers/soc/zte/tsc/zx-tsc-strategy.c
index 138bcf8..c259d6b 100644
--- a/ap/os/linux/linux-3.4.x/drivers/soc/zte/tsc/zx-tsc-strategy.c
+++ b/ap/os/linux/linux-3.4.x/drivers/soc/zte/tsc/zx-tsc-strategy.c
@@ -22,7 +22,16 @@
 #include <linux/timer.h>

 #include <linux/cp_types.h>

 #include "NvParam_drv.h"

+#include "pub_debug_info.h"

 

+/****************************************************************************

+*                                           Types

+****************************************************************************/

+typedef struct _T_TscPhy_Strategy

+{

+	char name[32];

+	volatile u32 flag;

+}T_TscP_Strategy;

 

 /*******************************************************************************

 *                                       Global Variables                                      *

@@ -60,6 +69,17 @@
 typedef void (*T_Probe_Strategy)(u32 probe_num,u32 temperature );

 T_Probe_Strategy g_probe_strategy[PROBE_MAX]={0,};

 

+T_TscP_Strategy g_phy_Strategy[STRATEGY_PHY_NUM]={

+	{"lte downrate1",   0},

+	{"lte downrate2",   0},

+	{"w downrate1",    0},

+	{"w downrate2",    0},

+	{"lte up_tansmitepower1",  0},

+	{"lte up_tansmitepower2",  0},

+	{"w up_tansmitepower1",  0},

+	{"w up_tansmitepower2",  0},

+};

+

 /*******************************************************************************

 *                                       ÒýÓÃÍⲿ±äÁ¿                                *

 *******************************************************************************/

@@ -542,12 +562,16 @@
 			if(any_resident_flag){

 				tsctrl_callback_dispatch(PS_STRATEGY_ANYRESIDENT,false); /*È¥ÈÎÒâפÁô,Ò²¾ÍÊÇÕý³£×¤Áô*/

 				tsc_set_reg_bits(TSCTRL_PS,BIT_PS_ANYRESIDENT,BITS_FOR_PSIRAM,false);

+				sc_debug_info_record(MODULE_ID_AP_TSC, "AnyResident stop\n");

+				tsc_print_log("AnyResident  stop!\n");

 				any_resident_flag=0;

 			}

 		}else{		

 			if(!any_resident_flag){

 				tsctrl_callback_dispatch(PS_STRATEGY_ANYRESIDENT,true);/*ÈÎÒâפÁô*/

 				tsc_set_reg_bits(TSCTRL_PS,BIT_PS_ANYRESIDENT,BITS_FOR_PSIRAM,true);

+				sc_debug_info_record(MODULE_ID_AP_TSC, "AnyResident start!\n");

+				tsc_print_log("AnyResident  start!\n");

 				any_resident_flag=1;

 			}

 		}

@@ -586,6 +610,8 @@
 				if(ps_rate_flag!=0){

 					tsctrl_callback_dispatch(PS_STRATEGY_RATE,STRTEGY_STOP);//STOP		

 					tsc_set_reg_bits(TSCTRL_PS,BIT_PS_RATE,BITS_FOR_PSIRAM,STRTEGY_STOP);

+					sc_debug_info_record(MODULE_ID_AP_TSC, "ps modem rate limit  stop!\n");

+					tsc_print_log("ps modem rate limit  stop!\n");

 					ps_rate_flag=0;

 				}

 			}

@@ -594,12 +620,16 @@
 				if(ps_rate_flag!=1){

 					tsctrl_callback_dispatch(PS_STRATEGY_RATE,STRTEGY_START);//START		

 					tsc_set_reg_bits(TSCTRL_PS,BIT_PS_RATE,BITS_FOR_PSIRAM,STRTEGY_START);

+					sc_debug_info_record(MODULE_ID_AP_TSC, "ps modem rate limit  start!\n");

+					tsc_print_log("ps modem rate limit  start!\n");

 					ps_rate_flag=1;

 				}

 			}else{	

 				if(ps_rate_flag!=2){

 					tsctrl_callback_dispatch(PS_STRATEGY_RATE,STRTEGY_HOLD);//HOLD			

 					tsc_set_reg_bits(TSCTRL_PS,BIT_PS_RATE,BITS_FOR_PSIRAM,STRTEGY_HOLD);

+					sc_debug_info_record(MODULE_ID_AP_TSC, "ps modem rate limit  hold!\n");

+					tsc_print_log("ps modem rate limit  hold!\n");

 					ps_rate_flag=2;

 				}

 			}

@@ -607,9 +637,20 @@
 			//ÎïÀí²ã½µËÙÂʲßÂÔ		

 			for(i=0;i<4;i++){

 				if(tsc_read_reg(TSCTRL_LIMIT_LTE_DOWNRATE1+i*0x4)==0){

-					tsc_set_reg_bits(TSCTRL_PHY,(BIT_LIMIT_LTE_DOWNRATE1+i),BITS_FOR_PHYIRAM,STRTEGY_STOP);

+					if(g_phy_Strategy[i].flag !=0) {

+						tsc_set_reg_bits(TSCTRL_PHY,(BIT_LIMIT_LTE_DOWNRATE1+i),BITS_FOR_PHYIRAM,STRTEGY_STOP);

+						sc_debug_info_record(MODULE_ID_AP_TSC, "%s stop\n", g_phy_Strategy[i].name );

+						tsc_print_log("%s stop\n", g_phy_Strategy[i].name);

+						g_phy_Strategy[i].flag=0;

+					}

 				}else{

-					tsc_set_reg_bits(TSCTRL_PHY,(BIT_LIMIT_LTE_DOWNRATE1+i),BITS_FOR_PHYIRAM,STRTEGY_START);

+					if(g_phy_Strategy[i].flag!=1) {

+				

+						tsc_set_reg_bits(TSCTRL_PHY,(BIT_LIMIT_LTE_DOWNRATE1+i),BITS_FOR_PHYIRAM,STRTEGY_START);

+						sc_debug_info_record(MODULE_ID_AP_TSC, "%s start\n", g_phy_Strategy[i].name );

+						tsc_print_log("%s start\n", g_phy_Strategy[i].name);

+						g_phy_Strategy[i].flag=1;

+					}

 				}				

 			}

 		}

@@ -619,9 +660,19 @@
 		if(TsNvData.TansmitPower_En == 0xB2){

 			for(i=4;i<STRATEGY_PHY_NUM;i++){

 				if(tsc_read_reg(TSCTRL_LIMIT_LTE_DOWNRATE1+i*0x4)==0){

-					tsc_set_reg_bits(TSCTRL_PHY,(BIT_LIMIT_LTE_DOWNRATE1+i),BITS_FOR_PHYIRAM,STRTEGY_STOP);

+					if(g_phy_Strategy[i].flag !=0) {

+						tsc_set_reg_bits(TSCTRL_PHY,(BIT_LIMIT_LTE_DOWNRATE1+i),BITS_FOR_PHYIRAM,STRTEGY_STOP);

+						sc_debug_info_record(MODULE_ID_AP_TSC, "%s stop\n", g_phy_Strategy[i].name );

+						tsc_print_log("%s stop\n", g_phy_Strategy[i].name);

+						g_phy_Strategy[i].flag=0;						

+					}

 				}else{

-					tsc_set_reg_bits(TSCTRL_PHY,(BIT_LIMIT_LTE_DOWNRATE1+i),BITS_FOR_PHYIRAM,STRTEGY_START);

+					if(g_phy_Strategy[i].flag !=1) {

+						tsc_set_reg_bits(TSCTRL_PHY,(BIT_LIMIT_LTE_DOWNRATE1+i),BITS_FOR_PHYIRAM,STRTEGY_START);

+						sc_debug_info_record(MODULE_ID_AP_TSC, "%s start\n", g_phy_Strategy[i].name );

+						tsc_print_log("%s start\n", g_phy_Strategy[i].name);

+						g_phy_Strategy[i].flag=1;

+					}

 				}				

 			}

 		}

@@ -638,17 +689,17 @@
 					//tsc_print_log("CPU_FREQ0:zx_getspeed(0)=%d\n",zx_getspeed(0));

 					if(zx_getspeed(0) != 624000 )

 						zx29_set_frequency(1,0); //zDrvPow_SetArmPsCoreFreq(CLK624M);

-

-					//tsc_print_log("CPU_FREQ1:zx_getspeed(0)=%d\n",zx_getspeed(0));	

-

+						

+					sc_debug_info_record(MODULE_ID_AP_TSC, "ps freq 624M start\n" );

+					tsc_print_log("ps freq 624M start\n");

 					ps_freq_flag=0;

 				}	

 			}else{

 				if(!ps_freq_flag){

 					//tsc_print_log("CPU_FREQ1:zx_getspeed(0)=%d\n",zx_getspeed(0));	

 					zx29_set_frequency(0,1); //zDrvPow_SetArmPsCoreFreq(CLK312M);

-					//tsc_print_log("CPU_FREQ1:zx_getspeed(0)=%d\n",zx_getspeed(0));	

-	

+					sc_debug_info_record(MODULE_ID_AP_TSC, "ps freq 312M start\n" );

+					tsc_print_log("ps freq 312M start\n");

 					ps_freq_flag=1;

 				}

 			}	

@@ -656,8 +707,8 @@
 		}	

 

 		if(g_tsc_print_log_debug) {

-			tsc_print_log("0:stop;1:start;2:hold; reg32(TSCTRL_PS)=0x%x,reg32(PS_CORE_SEL_REG)=0x%x,temp_percent=%d\n",tsc_read_reg(TSCTRL_PS),tsc_read_reg(PS_CORE_SEL_REG),temp_percent);		

-			tsc_print_log("bit1:limitLtedownrate2;bit3:limitWdownrate2;bit5:limitLteUptransmitrate2;bit7:limitWUptransmitrate2;reg32(TSCTRL_PHY)=0x%x.\n",tsc_read_reg(TSCTRL_PHY)); 

+			tsc_print_log("0:stop;1:start;2:hold; reg32(TSCTRL_PS)=0x%x,reg32(PS_CORE_SEL_REG)=0x%x\n",tsc_read_reg(TSCTRL_PS),tsc_read_reg(PS_CORE_SEL_REG));		

+			tsc_print_log("bit1:limitLtedownrate2;bit3:limitWdownrate2;bit5:limitLteUptransmitrate2;bit7:limitWUptransmitrate2;reg32(TSCTRL_PHY)=0x%x.\n\n",tsc_read_reg(TSCTRL_PHY)); 

 		}

 	}

 	else

@@ -692,6 +743,9 @@
 			tsc_set_reg_bits(TSCTRL_PHY,(BIT_LIMIT_LTE_DOWNRATE1+i),BITS_FOR_PHYIRAM,STRTEGY_STOP);

 		} 

 

+		//sc_debug_info_record(MODULE_ID_AP_TSC, "close all strategy!\n");

+

+

 		if(g_tsc_print_log_debug)

 			tsc_print_log("g_tsc_ctrlen==0, TSC Closed, close all strategy .\n");

 	}

diff --git a/ap/os/linux/linux-3.4.x/drivers/soc/zte/tsc/zx-tsc.c b/ap/os/linux/linux-3.4.x/drivers/soc/zte/tsc/zx-tsc.c
index c9a5559..144748c 100644
--- a/ap/os/linux/linux-3.4.x/drivers/soc/zte/tsc/zx-tsc.c
+++ b/ap/os/linux/linux-3.4.x/drivers/soc/zte/tsc/zx-tsc.c
@@ -24,6 +24,7 @@
 #include <linux/cpps_init2.h>

 #include <linux/cp_types.h>

 #include "NvParam_drv.h"

+#include "pub_debug_info.h"

 

 #ifdef RFC_DCXO_EN

 #define IRAM_TEMPCOMP_DAC (IRAM_BASE_ADDR_SLAVE_AFC+0x8)  //high16bit: the ADC value of temp	

@@ -31,16 +32,6 @@
 #define IRAM_TEMPCOMP_DAC (IRAM_BASE_ADDR_PUB_RF+64)//the ADC value of temp

 #endif

 

-

-#if 0

-//TsNvData.DetectEn¨º?NV?D¦Ì??????a1?¨º1?¨¹,¨®?¨®¨²????????2?????3¨¬¨º?¡¤????¡¥¡ê?????¡Á¨¹?a1?

-//g_tscCtrlEn¨®??¡ì¨¦¨¨??¦Ì?????2????a1?¨º1?¨¹; TsNvData.DetectEn1?¡À?¡ê??¨°¨®??¡ì¨¦¨¨??g_tscCtrlEn??¨®D¨®¡ã?¨¬

-//TsNvData.DetectEn¡ä¨°?a¡ê?2?????3¨¬?D?¨´?Yg_tscCtrlEn????¨º?¡¤?¡¤?¡¤¡é2???¡ê?g_tscCtrlEn=0¡ê??¨°2?¡¤?¡¤¡é2???¡ê?2¡é?¨°1?¡À??¨´¨®D¨º¦Ì??¦Ì?2???

-//tsc3?¨º?¨º¡ÀD¨¨¨°a¡Á¡é¨°a¡ê??¨¨??g_tscCtrlEn=0xB2¡ê?¨¨?o¨®???¨²¨®??¡ì?¨¢¨¦¨¨??g_tscCtrlEn¦Ì?????ref init?D¨º1g_tscCtrlEn=0(g_tscCtrlEn?¨ª?¡ì??¨¨?¨¦¨¨???a0),

-//¡¤¨¤?1¨®??¡ì¨¦¨¨??g_tscCtrlEn=0?¡ã???¡¥2???¡ê?¨°¨°?a¨¨?MBB?D¡ê?¨º1¨®?¦Ì¨²¨°??????T,??¨°a¦Ì¡Â¨®?2???¦Ì¨²¨°??????T?¨²¦Ì?2???¨°??¡À?eD¡ì

-volatile u8  g_tsc_ctrlen=0;

-#endif

-

 volatile u32 g_adc1_flag = 0;//¨¨?adc1¨®?¨®¨²¨¬?2apa2¨¤???¨¨¡ê??¨°g_adc1_flag=1

 volatile u32 g_adc2_flag = 0;//¨¨?adc2¨®?¨®¨²¨¬?2apa2¨¤???¨¨¡ê??¨°g_adc2_flag=1

 volatile u32 g_adc3_flag = 0; // 1:adcrf work

@@ -51,58 +42,16 @@
 u32 g_test_addr0=0;

 u32 g_test_addr1=0;

 

-#if 0//v3phone

-u32 ts_temp_value_table[TS_ADC_TEMP_NUMBER][TS_ADC_TEMP_VOLTAGE_NUMBER]={

-{30,31,32,33,34,35,36,37,38,39,

- 40,41,42,43,44,45,46,47,48,49,

- 50,51,52,53,54,55,56,57,58,59,

- 60,61,62,63,64,65,66,67,68,69,

- 70,71,72,73,74,75,76,77,78,79,

- 80,81,82,83,84,85,86,87,88,89,

- 90,91,92,93,94,95,96,97,98,99,

- 100,101,102,103,104,105,106,107,108,109,

- 110,111,112,113,114,115,116,117,118,119,

- 120,121,122,123,124,125},

+/*

+1cnt is 20s

+1h=3600s: 180cnt

+*/

+unsigned int tsc_record_time_cnt=0; 	

+unsigned int tsc_record_time= 3600; 

+module_param(tsc_record_time, uint, 0644);

+unsigned int tsc_record_flag= 0; 

+module_param(tsc_record_flag, uint, 0644);

 

-{

-815,799,782,766,750,734,719,703,688,673,

-659,644,630,615,602,588,574,561,548,535,

-523,511,498,487,476,465,454,443,432,422,

-411,401,391,383,374,366,355,347,339,331,

-322,315,306,299,292,285,278,272,265,259, 

-252,246,240,235,229,224,218,213,207,203,

-199,193,189,184,180,175,171,168,164,159, 

-156,153,149,146,143,139,136,133,130,127, 

-124,121,118,116,113,110,108,105,103,102, 

-99,97,95,93,91,89}

-};

-//#else//watch

-

-u32 ts_temp_value_table[TS_ADC_TEMP_NUMBER][TS_ADC_TEMP_VOLTAGE_NUMBER]={

-{30,31,32,33,34,35,36,37,38,39,

- 40,41,42,43,44,45,46,47,48,49,

- 50,51,52,53,54,55,56,57,58,59,

- 60,61,62,63,64,65,66,67,68,69,

- 70,71,72,73,74,75,76,77,78,79,

- 80,81,82,83,84,85,86,87,88,89,

- 90,91,92,93,94,95,96,97,98,99,

- 100,101,102,103,104,105,106,107,108,109,

- 110,111,112,113,114,115,116,117,118,119,

- 120,121,122,123,124,125},

-

-{802,783,764,746,727,709,692,674,657,640,

- 624,607,591,576,561,545,531,516,502,489,

- 475,462,449,437,425,413,402,390,379,369,

- 358,348,338,329,320,311,302,293,285,277,

- 269,262,254,247,240,234,227,221,215,209,

- 203,197,192,187,181,176,172,167,162,158,

- 154,150,146,142,138,134,131,127,124,121,

- 117,114,111,108,106,103,100,98, 95, 93,

- 90, 88, 86, 84, 82, 80, 78, 76, 74, 72,

- 70, 69, 67, 65, 64, 62}

-};

-

-#endif

 extern u32 ts_temp_value_table[TS_ADC_TEMP_NUMBER][TS_ADC_TEMP_VOLTAGE_NUMBER];

 extern volatile u32 ts_adc_flag;

 

@@ -453,8 +402,27 @@
 		if(g_tsc_print_log_debug)

 			tsc_print_log("adc1/adc2 value adc1Value=%d,adc2Value=%d,temp1 = %d.temp2 = %d.temprf = %d.\n",adc1Value,adc2Value,temp1,temp2, g_ts_data_info[PROBE_ADCRF][TS_MEMBER_TEMP]);

 

-		up(&s_tsc_adc_semaphore);		

-		msleep(TS_POLLING_TIME);

+		if((((tsc_record_time_cnt*TS_POLLING_TIME_S)%tsc_record_time)==0) && tsc_record_flag)

+		{

+			if(g_adc1_flag==1){

+				sc_debug_info_record(MODULE_ID_AP_TSC, "temp1:%d\n", zx_read_reg(TSCTRL_TEMPADC1) );

+				printk( "temp1:%d\n", zx_read_reg(TSCTRL_TEMPADC1));

+			}

+			if(g_adc2_flag==1){

+				sc_debug_info_record(MODULE_ID_AP_TSC, "temp2:%d\n", zx_read_reg(TSCTRL_TEMPADC2) );

+				printk( "temp2:%d\n", zx_read_reg(TSCTRL_TEMPADC2));

+			}

+			if(g_adc3_flag==1){

+				sc_debug_info_record(MODULE_ID_AP_TSC, "tempRf:%d\n", zx_read_reg(TSCTRL_TEMPADCRF) );

+				printk( "tempRf:%d\n", zx_read_reg(TSCTRL_TEMPADCRF));

+			}

+			tsc_record_time_cnt++;

+		}

+			

+		 if(TsNvData.DetectEn == 0xB2)

+			up(&s_tsc_adc_semaphore);

+		 

+		msleep(TS_POLLING_TIME_S*1000);

 

 	}

 	

@@ -558,23 +526,16 @@
 	//ret = nand_NvRead(DRV_SYS_NV_ITEM_ADDR(tsc_config),DRV_SYS_NV_ITEM_SIZE(tsc_config),(u8*)&TsNvData);

 	ret = CPPS_FUNC(cpps_callbacks, zOss_NvItemRead)(DRV_SYS_NV_ITEM_ADDR(tsc_config), (u8*)&TsNvData, DRV_SYS_NV_ITEM_SIZE(tsc_config));

 	

-    if(ret != 0){

-    	printk(KERN_ERR"[zx tsc]: zOss_NvItemRead failed [err=%d]!\n", ret);

-        return -1;

-    }

+	if(ret != 0){

+		printk(KERN_ERR"[zx tsc]: zOss_NvItemRead failed [err=%d]!\n", ret);

+	    return -1;

+	}

+	

 	zDrvTsc_SetTscEn(0xB2);//need

 	tsc_refInit();

 

-	

-    if(TsNvData.DetectEn != 0xB2){

-		zDrvTsc_SetTscEn(0);//need		

-		printk("TsNvData.DetectEn != 0xB2.\n");

-        return 0;  /*if dont enable tsc,just return success.*/

-    }

-

 	mutex_init(&tsc_mutexId);

 	sema_init(&s_tsc_adc_semaphore, 0);	

-

 	

 	tsc_createtimer();

 

@@ -594,15 +555,22 @@
 		TsNvData.Threshods[PROBE_ADCRF].THROSHOLD_6,TsNvData.Threshods[PROBE_ADCRF].THROSHOLD_7,\

 		TsNvData.Threshods[PROBE_ADCRF].THROSHOLD_8,TsNvData.Threshods[PROBE_ADCRF].THROSHOLD_9);

 	

+    if(TsNvData.DetectEn != 0xB2){

+		zDrvTsc_SetTscEn(0);//need		

+		printk("TsNvData.DetectEn != 0xB2.\n");

+        return 0;  /*if dont enable tsc,just return success.*/

+    }	

+

+	

 	//????¨º1?¨¹?¨¬2a¦Ì?2????¡¥????2?????3¨¬

-    if(TsNvData.DetectEn == 0xB2){

+  //  if(TsNvData.DetectEn == 0xB2){

 		tsctrl_init(); 

 		power_typ = *(unsigned int *)POWERON_TYPE_BASE;

 		if(POWER_ON_AMT ==power_typ) {

 			zDrvTsc_SetTscEn(0);

 			printk("POWER_ON_AMT set tscen= 0.\n");

 		}

-    }

+ //   }

 

 	printk("zx_tsc_init  end.\n");

  

diff --git a/ap/os/linux/linux-3.4.x/drivers/soc/zte/tsc/zx-tsc.h b/ap/os/linux/linux-3.4.x/drivers/soc/zte/tsc/zx-tsc.h
index fd38957..f9651f6 100644
--- a/ap/os/linux/linux-3.4.x/drivers/soc/zte/tsc/zx-tsc.h
+++ b/ap/os/linux/linux-3.4.x/drivers/soc/zte/tsc/zx-tsc.h
@@ -180,7 +180,8 @@
 // timing parameters
 #define TS_TEMP_DETECT_BEGIN_TIME (60 * 1000)  //60s , the begin time to  detect temp
 #define TS_STRATEGY_SET_BEGIN_TIME (61 * 1000)  //60s , the begin time to  start temp strategy
-#define TS_POLLING_TIME (20 * 1000)  //20s
+#define TS_POLLING_TIME_S	(20)
+#define TS_POLLING_TIME (TS_POLLING_TIME_S * 1000)  //20s
 #define TS_PROBE_OFFSET   2   /*´Óbit2¿ªÊ¼*/
 #define NV_TEMP_VALUE_NUMBERS  7
 
diff --git a/ap/os/linux/linux-3.4.x/drivers/staging/voicedrv/include/voice.h b/ap/os/linux/linux-3.4.x/drivers/staging/voicedrv/include/voice.h
index d853f4b..13a7cb3 100644
--- a/ap/os/linux/linux-3.4.x/drivers/staging/voicedrv/include/voice.h
+++ b/ap/os/linux/linux-3.4.x/drivers/staging/voicedrv/include/voice.h
@@ -55,6 +55,41 @@
     MAX_VOICE_INPUT_VOL_LEVEL
 } T_ZDrvVoice_InputVolLevel;
 
+#ifdef _USE_VEHICLE_DC
+/*  Voice process channel selection. */
+typedef enum
+{
+    VP_PATH_HANDSET    = 0,
+    VP_PATH_SPEAKER,
+    VP_PATH_HEADSET,
+    VP_PATH_BLUETOOTH,
+    VP_PATH_BLUETOOTH_NO_NR,
+    VP_PATH_HSANDSPK,
+
+    VP_PATH_OFF = 255,
+
+    MAX_VP_PATH = VP_PATH_OFF
+} T_ZDrv_VpPath;
+
+typedef enum
+{
+    VP_VOL_0    = 0,
+    VP_VOL_1,
+    VP_VOL_2,
+    VP_VOL_3,
+    VP_VOL_4,
+    VP_VOL_5,
+    VP_VOL_6,
+    VP_VOL_7,
+    VP_VOL_8,
+    VP_VOL_9,
+    VP_VOL_10,
+    VP_VOL_11,
+
+    MAX_VP_VOL
+} T_ZDrv_VpVol;
+#endif
+
 typedef enum {
     VOICE_SAMPLE_8K    = 0, /* voice sample rate 8K. */
     VOICE_SAMPLE_16K     ,  /* voice sample rate 16K. */
diff --git a/ap/os/linux/linux-3.4.x/drivers/staging/voicedrv/voice.c b/ap/os/linux/linux-3.4.x/drivers/staging/voicedrv/voice.c
index 79a5b91..a4e39a0 100644
--- a/ap/os/linux/linux-3.4.x/drivers/staging/voicedrv/voice.c
+++ b/ap/os/linux/linux-3.4.x/drivers/staging/voicedrv/voice.c
@@ -30,10 +30,109 @@
 extern int halVoice_Enable(void);
 extern int halVoice_Disable(void);
 
+#ifdef _USE_VEHICLE_DC
+extern int zDrvVp_GetVol_Wrap(void);
+extern int zDrvVp_SetVol_Wrap(int volume);
+extern int zDrvVp_GetPath_Wrap(void);
+extern int zDrvVp_SetPath_Wrap(int path);
+extern int zDrvVp_SetMute_Wrap(bool enable);
+extern bool zDrvVp_GetMute_Wrap(void);
+#endif
 static int voice_open(struct inode *ip, struct file *fp);
 static int voice_release(struct inode *ip, struct file *fp);
 static long voice_ioctl(struct file *fp, unsigned int cmd, unsigned long arg);
 
+#ifdef _USE_VEHICLE_DC
+
+static int voice_SetMute(bool enable)
+{
+	int ret = 0;
+	ret = CPPS_FUNC(cpps_callbacks, zDrvVp_SetMute_Wrap)(enable);
+	if(ret < 0)
+	{
+		  printk(KERN_ERR "vp_SetMute fail = %d\n",enable);
+		  return ret;
+	}
+	return 0;
+}
+
+static bool voice_GetMute(void)
+{      
+   	bool muteEn; 
+       muteEn = CPPS_FUNC(cpps_callbacks, zDrvVp_GetMute_Wrap)();
+       return muteEn;
+}
+
+static int voice_SetVol(int vol)
+{
+	int ret = 0;
+
+	ret = CPPS_FUNC(cpps_callbacks, zDrvVp_SetVol_Wrap)(vol);
+	if(ret < 0)
+	{
+		  printk(KERN_ERR "vp_SetVol fail = %d\n",vol);
+		  return ret;
+	}
+	return 0;
+}
+
+static int voice_GetVol(void)
+{       
+	T_ZDrv_VpVol vpVol;
+       vpVol = CPPS_FUNC(cpps_callbacks, zDrvVp_GetVol_Wrap)();
+       return vpVol;
+}
+
+static int voice_GetPath(void)
+{	
+	T_ZDrv_VpPath  vpPath;
+	vpPath = CPPS_FUNC(cpps_callbacks, zDrvVp_GetPath_Wrap)();
+	return vpPath;
+}
+
+static int voice_SetPath(int path)
+{
+	int ret = 0;
+	unsigned long  flags;
+
+	ret = CPPS_FUNC(cpps_callbacks, zDrvVp_SetPath_Wrap)(path);
+	if(ret < 0)
+	{
+		  printk(KERN_ERR "vp_SetPath fail = %d\n",path);
+		  return ret;
+	}
+	
+#ifdef _USE_7520V3_PHONE_TYPE_C31F
+	switch (path) {
+	case 0:
+		gpio_set_value(ZX29_GPIO_39, GPIO_LOW);
+		mdelay(1);	
+		gpio_set_value(ZX29_GPIO_40, GPIO_LOW);
+		break;
+	case 1:
+		gpio_set_value(ZX29_GPIO_39, GPIO_LOW);
+		mdelay(1);	
+		raw_spin_lock_irqsave(&codec_pa_lock, flags);
+		gpio_set_value(ZX29_GPIO_39, GPIO_HIGH);
+		udelay(2);	
+		gpio_set_value(ZX29_GPIO_39, GPIO_LOW);
+		udelay(2);
+		gpio_set_value(ZX29_GPIO_39, GPIO_HIGH);
+		raw_spin_unlock_irqrestore(&codec_pa_lock, flags);
+		gpio_set_value(ZX29_GPIO_40, GPIO_HIGH);
+		break;
+	case 2:
+		break;
+	case 3:
+		break;
+	default:
+		break;
+	}
+#endif
+	return 0;
+}
+
+#endif
 
 /* file operations for volte device /dev/volte_device */
 static const struct file_operations voice_fops = {
@@ -246,6 +345,84 @@
 
 		break;
 	}
+	
+#ifdef _USE_VEHICLE_DC
+	case VOICE_IOCTL_SET_VOL: {
+		//	pr_info("voice set vol! \n");
+		int para;
+
+		if (copy_from_user(&para, argp, sizeof(para))) {
+			print_audio("volte_ioctl  set vol copy_to_user err!\n");
+			return -EFAULT;
+		}
+		ret = voice_SetVol(para);
+		break;
+	}
+
+	case VOICE_IOCTL_GET_VOL: {
+		//	pr_info("voice get vol! \n");
+		int vol;
+
+		vol = voice_GetVol();
+
+		if (copy_to_user(argp, &vol, sizeof(vol))) {
+			pr_err("voice_ioctl  get vol copy_to_user err!\n");
+			return -EFAULT;
+		}
+		break;
+	}	
+
+	case VOICE_IOCTL_SET_MUTE: {
+		//	pr_info("voice set mute! \n");
+		bool para;
+
+		if (copy_from_user(&para, argp, sizeof(para))) {
+			print_audio("volte_ioctl  set vol copy_to_user err!\n");
+			return -EFAULT;
+		}
+		ret = voice_SetMute(para);
+		break;
+	}
+
+	case VOICE_IOCTL_GET_MUTE: {
+		//	pr_info("voice get mute! \n");
+		bool muteEn;
+
+		muteEn = voice_GetMute();
+
+		if (copy_to_user(argp, &muteEn, sizeof(muteEn))) {
+			pr_err("voice_ioctl  get mute copy_to_user err!\n");
+			return -EFAULT;
+		}
+		break;
+	}
+
+	case VOICE_IOCTL_SET_PATH: {
+		//	pr_info("voice set path! \n");
+		int para;
+
+		if (copy_from_user(&para, argp, sizeof(para))) {
+			print_audio("volte_ioctl  set path copy_to_user err!\n");
+			return -EFAULT;
+		}
+		ret = voice_SetPath(para);
+		break;
+	}
+
+	case VOICE_IOCTL_GET_PATH: {
+		//	pr_info("voice get path! \n");
+		int path;
+
+		path = voice_GetPath();
+
+		if (copy_to_user(argp, &path, sizeof(path))) {
+			pr_err("voice_ioctl  get path copy_to_user err!\n");
+			return -EFAULT;
+		}
+		break;
+	}
+#endif
+
 	case VOICE_IOCTL_GET_SLIC_USE_FLAG: {
 
 		int flag = 0;
diff --git a/ap/os/linux/linux-3.4.x/drivers/tty/serial/serial_core.c b/ap/os/linux/linux-3.4.x/drivers/tty/serial/serial_core.c
index 3b70883..7e46649 100644
--- a/ap/os/linux/linux-3.4.x/drivers/tty/serial/serial_core.c
+++ b/ap/os/linux/linux-3.4.x/drivers/tty/serial/serial_core.c
@@ -106,11 +106,15 @@
 	    !tty->stopped && !tty->hw_stopped){
 		port->ops->start_tx(port);
 	
+#ifndef _USE_VEHICLE_DC
 		zx_cpuidle_set_busy(IDLE_FLAG_UART);
-
-		if(!uart_console(port))
+#endif
+		if(!uart_console(port)){
+#ifdef _USE_VEHICLE_DC
+			zx_cpuidle_set_busy(IDLE_FLAG_UART);
+#endif
 		wake_lock_timeout(&port->port_wakelock,100);
-
+		}
 	}
 }
 
@@ -582,14 +586,15 @@
 		ret += c;
 	}
 	raw_spin_unlock_irqrestore(&port->lock, flags);
-	#ifdef _USE_VEHICLE_DC
+
+	uart_start(tty);
+#ifdef _USE_VEHICLE_DC
 	if(pdev->id == DEBUG_CONSOLE){
 		if(CIRC_SPACE_TO_END(circ->head, circ->tail, UART_XMIT_SIZE) == 0){
 			ret  = count;
 		}
 	}
 #endif
-	uart_start(tty);
 	return ret;
 }
 
diff --git a/ap/os/linux/linux-3.4.x/drivers/tty/serial/zx29_uart.c b/ap/os/linux/linux-3.4.x/drivers/tty/serial/zx29_uart.c
index d3502e3..c5f8d45 100755
--- a/ap/os/linux/linux-3.4.x/drivers/tty/serial/zx29_uart.c
+++ b/ap/os/linux/linux-3.4.x/drivers/tty/serial/zx29_uart.c
@@ -237,8 +237,8 @@
  * 1:  able console input, can input commands
  */
 static ssize_t console_input_store(struct device *_dev,
-				struct device_attribute *attr,
-				const char *buf, size_t count)
+				 struct device_attribute *attr,
+				 const char *buf, size_t count)
 {
     uint32_t  flag = 0;
 	flag = simple_strtoul(buf, NULL, 16);
@@ -260,8 +260,8 @@
 }
 
 static ssize_t ctsrts_input_store(struct device *_dev,
-				struct device_attribute *attr,
-				const char *buf, size_t count)
+				 struct device_attribute *attr,
+				 const char *buf, size_t count)
 {
     uint32_t  flag = 0;
 	struct platform_device *pdev = container_of(_dev, struct platform_device, dev);
@@ -285,8 +285,8 @@
 }
 
 static ssize_t wakeup_enable_store(struct device *_dev,
-				struct device_attribute *attr,
-				const char *buf, size_t count)
+				 struct device_attribute *attr,
+				 const char *buf, size_t count)
 {
     uint32_t  flag = 0;
 	struct platform_device *pdev = container_of(_dev, struct platform_device, dev);
@@ -404,11 +404,10 @@
 	return sprintf(buf, "\n console_uart_toggle_show %d. \n", g_ps_uart_toggle);
 }
 static ssize_t console_uart_toggle_store(struct device *_dev,
-				struct device_attribute *attr,
-				const char *buf, size_t count)
+				 struct device_attribute *attr,
+				 const char *buf, size_t count)
 {
     uint32_t  flag = 0;
-	g_up_init_done = 1;
 	flag = simple_strtoul(buf, NULL, 16);
 	if(flag == ENABLE_TOGGLE){
 		g_ps_uart_toggle = 1;
@@ -440,10 +439,11 @@
 	return sprintf(buf, "\n core %d occupy cons uart now! \n",g_core_id_occupy_uart);
 }
 static ssize_t coreid_occupy_uart_store(struct device *_dev,
-				struct device_attribute *attr,
-				const char *buf, size_t count)
+				 struct device_attribute *attr,
+				 const char *buf, size_t count)
 {
     uint32_t  flag = 0;
+	g_up_init_done = 1;
 	flag = simple_strtoul(buf, NULL, 16);
 	g_core_id_occupy_uart = flag;
 	if(flag == SYMB_PS_CORE_ID){
@@ -667,32 +667,20 @@
 #endif
 {
 #ifdef _USE_VEHICLE_DC
+	if((port->line == DEBUG_CONSOLE) && (g_up_init_done == 1)){
+		if(g_core_id_occupy_uart == SYMB_CAP_CORE_ID){
+			count = uart_circ_chars_pending(xmit);
+			while(count-- > 0) 
+			{
+				xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
+				if (uart_circ_empty(xmit))
+					break;
+			}
+		return;
+	}
+	}
+#endif 
 
-    if((port->line == DEBUG_CONSOLE) && (g_up_init_done == 1)){
-
-       if(g_core_id_occupy_uart == SYMB_CAP_CORE_ID){
-
-           count = uart_circ_chars_pending(xmit);
-
-           while(count-- > 0) 
-
-           {
-
-              xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
-
-              if (uart_circ_empty(xmit))
-
-                  break;
-
-           }
-
-       return;
-
-    }
-
-    }
-
-#endif
 	if(!(UART_GET_RIS(port)&UART_TXIS) && (UART_GET_FR(port) & UART_FR_TXFE))
 	{
 		if(!(UART_GET_RIS(port)&UART_TXIS))	
@@ -714,8 +702,8 @@
 	}
 #if CONFIG_SERIAL_ZX29_DMA	 
 	if(!uart_console(port))
-	{ 
-		if (!zx29_dma_tx_start(zup))
+	 { 
+		 if (!zx29_dma_tx_start(zup))
 		   	{
 				zup->imr |= UART_TXIM;
 				UART_PUT_IMSC(port, zup->imr);
@@ -816,7 +804,7 @@
 		      //printk("yanming dma_complete_thread, dma2tty:%d\n", dma_count);			
 			if (dma_count < pending)
 				dev_info(zup->port.dev,
-					"couldn't insert all characters (TTY is full?)\n");
+					 "couldn't insert all characters (TTY is full?)\n");
 			
 
 		}
@@ -1046,7 +1034,7 @@
 #if CONFIG_SERIAL_ZX29_DMA
 	/* If we are using DMA mode, try to send some characters. */
 	if(!uart_console(&(zup->port)))
-	{ 
+	 { 
 		if (zx29_dma_tx_irq(zup))
 			return;
 	}
@@ -1101,10 +1089,10 @@
 		return false;
 
 	/*
-	* If we already have a TX buffer queued, but received a
-	* TX interrupt, it will be because we've just sent an X-char.
-	* Ensure the TX DMA is enabled and the TX IRQ is disabled.
-	*/
+	 * If we already have a TX buffer queued, but received a
+	 * TX interrupt, it will be because we've just sent an X-char.
+	 * Ensure the TX DMA is enabled and the TX IRQ is disabled.
+	 */
 	if (zup->dmatx.queued) {
 		zup->dmacr |= UART_TXDMAE;
 		UART_PUT_DMACR(&zup->port, zup->dmacr);
@@ -1114,9 +1102,9 @@
 	}
 
 	/*
-	* We don't have a TX buffer queued, so try to queue one.
-	* If we successfully queued a buffer, mask the TX IRQ.
-	*/
+	 * We don't have a TX buffer queued, so try to queue one.
+	 * If we successfully queued a buffer, mask the TX IRQ.
+	 */
 	if (zx29_uart_dma_tx_chars(zup) > 0) {
 		zup->imr &= ~UART_TXIM;
 		UART_PUT_IMSC(&zup->port,zup->imr);
@@ -1175,19 +1163,19 @@
 	}
 
 	/*
-	* We have an X-char to send.  Disable DMA to prevent it loading
-	* the TX fifo, and then see if we can stuff it into the FIFO.
-	*/
+	 * We have an X-char to send.  Disable DMA to prevent it loading
+	 * the TX fifo, and then see if we can stuff it into the FIFO.
+	 */
 	dmacr = zup->dmacr;
 	zup->dmacr &= ~UART_TXDMAE;
 	UART_PUT_DMACR(&zup->port, zup->dmacr);
 
 	if (UART_GET_FR(&zup->port) & UART_FR_TXFF) {
 		/*
-		* No space in the FIFO, so enable the transmit interrupt
-		* so we know when there is space.  Note that once we've
-		* loaded the character, we should just re-enable DMA.
-		*/
+		 * No space in the FIFO, so enable the transmit interrupt
+		 * so we know when there is space.  Note that once we've
+		 * loaded the character, we should just re-enable DMA.
+		 */
 		return false;
 	}
 
@@ -1262,10 +1250,10 @@
 	dmaengine_slave_config(zup->dmarx.chan, (struct dma_slave_config*)&zup->dmarx.rx_def[zup->dmarx.rx_index]);
 	desc = zup->dmarx.chan->device->device_prep_interleaved_dma(zup->dmarx.chan,NULL,0);
 	/*
-	* If the DMA engine is busy and cannot prepare a
-	* channel, no big deal, the driver will fall back
-	* to interrupt mode as a result of this error code.
-	*/
+	 * If the DMA engine is busy and cannot prepare a
+	 * channel, no big deal, the driver will fall back
+	 * to interrupt mode as a result of this error code.
+	 */
 	if (!desc) {
 		printk(KERN_INFO "!!ERROR DESC !!![%s][%d]Port:[%d]\n",__func__,__LINE__,zup->port.line);
 		zup->dmarx.running = false;
@@ -1371,17 +1359,17 @@
 	int ret;
 	unsigned long flags;
 	/*
-	* This completion interrupt occurs typically when the
-	* RX buffer is totally stuffed but no timeout has yet
-	* occurred. When that happens, we just want the RX
-	* routine to flush out the secondary DMA buffer while
-	* we immediately trigger the next DMA job.
-	*/
+	 * This completion interrupt occurs typically when the
+	 * RX buffer is totally stuffed but no timeout has yet
+	 * occurred. When that happens, we just want the RX
+	 * routine to flush out the secondary DMA buffer while
+	 * we immediately trigger the next DMA job.
+	 */
 	raw_spin_lock_irqsave(&zup->port.lock, flags);
 	/*
-	* Rx data can be taken by the UART interrupts during
-	* the DMA irq handler. So we check the residue here.
-	*/
+	 * Rx data can be taken by the UART interrupts during
+	 * the DMA irq handler. So we check the residue here.
+	 */
 	rxchan->device->device_tx_status(rxchan, dmarx->cookie, &state);
 	
 
@@ -1404,10 +1392,10 @@
 	raw_spin_unlock_irqrestore(&zup->port.lock, flags);
 #endif	
 	/*
-	* Do this check after we picked the DMA chars so we don't
-	* get some IRQ immediately from RX.
-	*/
-	/*
+	 * Do this check after we picked the DMA chars so we don't
+	 * get some IRQ immediately from RX.
+	 */
+	 /*
 	if (ret) {
 		dev_dbg(zup->port.dev, "could not retrigger RX DMA job "
 			"fall back to interrupt mode\n");
@@ -1425,7 +1413,7 @@
 	zup->dmacr &= ~UART_RXDMAE;
 	UART_PUT_DMACR(&zup->port,zup->dmacr);
 	zx29_dma_stop(rx_id);
-	zup->curr_sg = NULL;
+	 zup->curr_sg = NULL;
 }
 
 static void zx29_dma_remove(struct zx29_uart_port *zup)
@@ -1436,6 +1424,8 @@
 	if (zup->dmarx.chan)
 		dma_release_channel(zup->dmarx.chan);
 }
+
+
 static void zx29_dma_shutdown(struct zx29_uart_port *zup)
 {
 	unsigned long flags;
@@ -1451,7 +1441,7 @@
 	zup->dmacr &= ~(UART_DMAONERR | UART_RXDMAE | UART_TXDMAE);
 	UART_PUT_DMACR(&zup->port,zup->dmacr);
 	zx29_dma_stop(rx_id);
-	zup->curr_sg = NULL;
+	 zup->curr_sg = NULL;
 	raw_spin_unlock_irqrestore(&zup->port.lock, flags);
 	if (zup->using_tx_dma) {
 		/* In theory, this should already be done by zx29_dma_flush_buffer */
@@ -1530,14 +1520,14 @@
 	UART_PUT_DMACR(&zup->port,zup->dmacr);
 
 	/*
-	* If TX DMA was disabled, it means that we've stopped the DMA for
-	* some reason (eg, XOFF received, or we want to send an X-char.)
-	*
-	* Note: we need to be careful here of a potential race between DMA
-	* and the rest of the driver - if the driver disables TX DMA while
-	* a TX buffer completing, we must update the tx queued status to
-	* get further refills (hence we check dmacr).
-	*/
+	 * If TX DMA was disabled, it means that we've stopped the DMA for
+	 * some reason (eg, XOFF received, or we want to send an X-char.)
+	 *
+	 * Note: we need to be careful here of a potential race between DMA
+	 * and the rest of the driver - if the driver disables TX DMA while
+	 * a TX buffer completing, we must update the tx queued status to
+	 * get further refills (hence we check dmacr).
+	 */
 	if (!(dmacr & UART_TXDMAE) || uart_tx_stopped(&zup->port) ||
 	    uart_circ_empty(&zup->port.state->xmit)) {
 		zup->dmatx.queued = false;
@@ -1552,9 +1542,9 @@
 
 	if (zx29_uart_dma_tx_chars(zup) <= 0) {
 		/*
-		* We didn't queue a DMA buffer for some reason, but we
-		* have data pending to be sent.  Re-enable the TX IRQ.
-		*/
+		 * We didn't queue a DMA buffer for some reason, but we
+		 * have data pending to be sent.  Re-enable the TX IRQ.
+		 */
 		zup->imr |= UART_TXIM;
 		UART_PUT_IMSC(&zup->port, zup->imr);
 	}
@@ -1571,11 +1561,11 @@
 	unsigned int count;
 
 	/*
-	* Try to avoid the overhead involved in using DMA if the
-	* transaction fits in the first half of the FIFO, by using
-	* the standard interrupt handling.  This ensures that we
-	* issue a uart_write_wakeup() at the appropriate time.
-	*/
+	 * Try to avoid the overhead involved in using DMA if the
+	 * transaction fits in the first half of the FIFO, by using
+	 * the standard interrupt handling.  This ensures that we
+	 * issue a uart_write_wakeup() at the appropriate time.
+	 */
  
 	count = uart_circ_chars_pending(xmit);
 	if (count < (16 >> 1)) {
@@ -1590,9 +1580,9 @@
 	}
 */
 	/*
-	* Bodge: don't send the last character by DMA, as this
-	* will prevent XON from notifying us to restart DMA.
-	*/
+	 * Bodge: don't send the last character by DMA, as this
+	 * will prevent XON from notifying us to restart DMA.
+	 */
 	//count -= 1;
 
 	/* Else proceed to copy the TX chars to the DMA buffer and fire DMA */
@@ -1629,9 +1619,9 @@
 	dma_unmap_sg(dma_dev->dev, &dmatx->sg, 1, DMA_TO_DEVICE);
 	zup->dmatx.queued = false;
 	/*
-	* If DMA cannot be used right now, we complete this
-	* transaction via IRQ and let the TTY layer retry.
-	*/
+	 * If DMA cannot be used right now, we complete this
+	 * transaction via IRQ and let the TTY layer retry.
+	 */
 	dev_dbg(zup->port.dev, "TX DMA busy\n");
 	return -EBUSY;
 	}	
@@ -1645,9 +1635,9 @@
 	zup->dmatx.queued = true;
 
 	/*
-	* Now we know that DMA will fire, so advance the ring buffer
-	* with the stuff we just dispatched.
-	*/
+	 * Now we know that DMA will fire, so advance the ring buffer
+	 * with the stuff we just dispatched.
+	 */
 	xmit->tail = (xmit->tail + count) & (UART_XMIT_SIZE - 1);
 	zup->port.icount.tx += count;
 
@@ -1680,10 +1670,10 @@
 		dma_sync_sg_for_cpu(dev, &sgbuf->sg, 1, DMA_FROM_DEVICE);
 
 		/*
-		* First take all chars in the DMA pipe, then look in the FIFO.
-		* Note that tty_insert_flip_buf() tries to take as many chars
-		* as it can.
-		*/
+		 * First take all chars in the DMA pipe, then look in the FIFO.
+		 * Note that tty_insert_flip_buf() tries to take as many chars
+		 * as it can.
+		 */
 	
 	raw_spin_unlock_irqrestore(&zup->port.lock, *flags);
 	
@@ -1700,28 +1690,28 @@
 		    //  printk("yanming uart_dma_rx_chars, dma2tty:%d\n", dma_count);			
 		if (dma_count < pending)
 			dev_info(zup->port.dev,
-				"couldn't insert all characters (TTY is full?)\n");
+				 "couldn't insert all characters (TTY is full?)\n");
 	}
 
 	/*
-	* Only continue with trying to read the FIFO if all DMA chars have
-	* been taken first.
-	*/
+	 * Only continue with trying to read the FIFO if all DMA chars have
+	 * been taken first.
+	 */
 	//if (dma_count == pending && readfifo) {
 	if ((pending > 0) && readfifo) {
 		/* Clear any error flags */
 		//UART_PUT_ICR(&zup->port,UART_OEIC | UART_BEIC | UART_PEIC | UART_FEIC);
 		/*
-		* If we read all the DMA'd characters, and we had an
-		* incomplete buffer, that could be due to an rx error, or
-		* maybe we just timed out. Read any pending chars and check
-		* the error status.
-		*
-		* Error conditions will only occur in the FIFO, these will
-		* trigger an immediate interrupt and stop the DMA job, so we
-		* will always find the error in the FIFO, never in the DMA
-		* buffer.
-		*/
+		 * If we read all the DMA'd characters, and we had an
+		 * incomplete buffer, that could be due to an rx error, or
+		 * maybe we just timed out. Read any pending chars and check
+		 * the error status.
+		 *
+		 * Error conditions will only occur in the FIFO, these will
+		 * trigger an immediate interrupt and stop the DMA job, so we
+		 * will always find the error in the FIFO, never in the DMA
+		 * buffer.
+		 */
 		fifotaken = zx29_uart_fifo_to_tty(zup);
 			//if(zup->port.line == 0)
 		     // printk("yanming uart_dma_rx_chars, fifo2tty:%d\n", fifotaken);			
@@ -1764,10 +1754,10 @@
 
 	if(zx29_dma_rx_running(zup)){
 		/*
-		* Pause the transfer so we can trust the current counter,
-		* do this before we pause the block, else we may
-		* overflow the FIFO.
-		*/
+		 * Pause the transfer so we can trust the current counter,
+		 * do this before we pause the block, else we may
+		 * overflow the FIFO.
+		 */
 	//	if(zx29_dma_stop(rx_id))
 		//	printk( "uart%d unable to pause DMA transfer\n", zup->port.line);
 		zup->dmacr &= ~UART_RXDMAE;
@@ -1786,9 +1776,9 @@
 	
 	dmarx->use_buf_b = !dmarx->use_buf_b;
 		/*
-		* This will take the chars we have so far and insert
-		* into the framework.
-		*/
+		 * This will take the chars we have so far and insert
+		 * into the framework.
+		 */
 			zx29_uart_dma_rx_chars(zup, pending, sgbuf, false, flags);
 	}
 
@@ -1911,10 +1901,10 @@
 
 	if(zx29_dma_rx_running(zup)){
 		/*
-		* Pause the transfer so we can trust the current counter,
-		* do this before we pause the block, else we may
-		* overflow the FIFO.
-		*/
+		 * Pause the transfer so we can trust the current counter,
+		 * do this before we pause the block, else we may
+		 * overflow the FIFO.
+		 */
 		 
 		zup->dmacr &= ~UART_RXDMAE;
 		UART_PUT_DMACR(&zup->port,zup->dmacr);
@@ -2326,7 +2316,7 @@
 		dev_err(zup->port.dev, "failed to init DMA %s: %d\n",
 			"RX buffer B", ret);
 		zx29_sgbuf_free(zup->dmarx.chan, &zup->dmarx.sgbuf_a,
-				DMA_FROM_DEVICE);
+				 DMA_FROM_DEVICE);
 		goto skip_rx;
 	}
 
@@ -2420,9 +2410,9 @@
 	port->icount.overrun = port->icount.parity = port->icount.rng = 0;
 	port->icount.rx = port->icount.tx = 0;
 	/* 
-	*enable uart clock 
-	*if uart is used for console, don't need do these, these was done before
-	*/
+	 *enable uart clock 
+	 *if uart is used for console, don't need do these, these was done before
+	 */
 	if (DEBUG_CONSOLE != pdev->id) {	
 	    /*  config uart apb_clk   */
 		clk_prepare_enable(zup->busclk);
@@ -2496,7 +2486,7 @@
 				pcu_int_clear(PCU_UART0_RXD_INT); 
 				ret = request_irq(zup->irq, zx29_uart_rxd_irq,
 			      		IRQF_ONESHOT , "uart_rxd_irq",
-			    		zup);
+			    		 zup);
 				printk(KERN_INFO"zx29_uart_startup, retval:%d\n",ret);
 				irq_set_irq_wake(zup->irq,1);
 #ifdef CONFIG_CPU_IDLE	
@@ -2603,10 +2593,10 @@
 	UART_PUT_CR(port, control);
 
 	/*
-	* Finally, enable interrupts, only timeouts when using DMA
-	* if initial RX DMA job failed, start in interrupt mode
-	* as well.
-	*/
+	 * Finally, enable interrupts, only timeouts when using DMA
+	 * if initial RX DMA job failed, start in interrupt mode
+	 * as well.
+	 */
 	raw_spin_lock_irqsave(&zup->port.lock, flags);
 	/* Clear out any spuriously appearing RX interrupts */
 	UART_PUT_ICR(port, (UART_RTIS | UART_RXIS));
@@ -2831,8 +2821,8 @@
 	raw_spin_lock_irqsave(&port->lock, flags);
 
 	/*
-	* Update the per-port timeout.
-	*/
+	 * Update the per-port timeout.
+	 */
 	uart_update_timeout(port, termios->c_cflag, baud);
 
 	port->read_status_mask = UART_DR_OE | 255;
@@ -2842,24 +2832,24 @@
 		port->read_status_mask |= UART_DR_BE;
 
 	/*
-	* Characters to ignore
-	*/
+	 * Characters to ignore
+	 */
 	port->ignore_status_mask = 0;
 	if (termios->c_iflag & IGNPAR)
 		port->ignore_status_mask |= UART_DR_FE | UART_DR_PE;
 	if (termios->c_iflag & IGNBRK) {
 		port->ignore_status_mask |= UART_DR_BE;
 		/*
-		* If we're ignoring parity and break indicators,
-		* ignore overruns too (for real raw support).
-		*/
+		 * If we're ignoring parity and break indicators,
+		 * ignore overruns too (for real raw support).
+		 */
 		if (termios->c_iflag & IGNPAR)
 			port->ignore_status_mask |= UART_DR_OE;
 	}
 
 	/*
-	* Ignore all characters if CREAD is not set.
-	*/
+	 * Ignore all characters if CREAD is not set.
+	 */
 	if ((termios->c_cflag & CREAD) == 0)
 		port->ignore_status_mask |= UART_DUMMY_DR_RX;
 
@@ -2882,10 +2872,10 @@
 	}
 
 	/*
-	* ----------v----------v----------v----------v-----
-	* NOTE: MUST BE WRITTEN AFTER UARTLCR_M & UARTLCR_L
-	* ----------^----------^----------^----------^-----
-	*/
+	 * ----------v----------v----------v----------v-----
+	 * NOTE: MUST BE WRITTEN AFTER UARTLCR_M & UARTLCR_L
+	 * ----------^----------^----------^----------^-----
+	 */
 	UART_PUT_LCRH(port, lcr_h);
 	UART_PUT_CR(port, old_cr);
 
@@ -3067,7 +3057,7 @@
         * just configure clock, 
         * actually pin configuration is needed, but now gpio driver is not OK
         * use bootloader default configuration
-	*/
+	 */
     if(DEBUG_CONSOLE == pdev->id){
 		/*  config uart apb_clk   */
 		clk_prepare_enable(zx29_port->busclk);
@@ -3081,6 +3071,7 @@
 
 #ifdef CONFIG_SERIAL_ZX29_UART_CONSOLE
 
+
 /****************************************************************************/
 static void zx29_uart_console_putc(struct uart_port *port, const char c)
 {
@@ -3089,6 +3080,7 @@
 	UART_PUT_CHAR(port, c);
 }
 
+
 #ifndef _USE_VEHICLE_DC
 
 /****************************************************************************/
@@ -3109,68 +3101,45 @@
 	//raw_spin_unlock(&port->lock);
 }
 #else
-
 static void zx29_uart_console_putc_share(struct uart_port *port, const char c)
-
 {
-
-    if(g_core_id_occupy_uart == SYMB_CAP_CORE_ID)
-
-       return;
-
-    int ret = soft_spin_lock_printf(UART_SFLOCK);
-
-    if(ret)
-
-       return;
-
-    while (UART_GET_FR(port) & UART_FR_TXFF)
-       barrier();
-    UART_PUT_CHAR(port, c);
-    soft_spin_unlock(UART_SFLOCK);
-
+	if(g_core_id_occupy_uart == SYMB_CAP_CORE_ID)
+		return;
+	int ret = soft_spin_lock_printf(UART_SFLOCK);
+	if(ret)
+		return;
+	
+	while (UART_GET_FR(port) & UART_FR_TXFF)
+		barrier();
+	UART_PUT_CHAR(port, c);
+	
+	soft_spin_unlock(UART_SFLOCK);
 }
+
 static void zx29_uart_console_write(struct console *co, const char *s, unsigned int count)
-
 {
-
-    struct uart_port *port = &zx29_uart_ports[co->index].port;
-
+	struct uart_port *port = &zx29_uart_ports[co->index].port;
 #if 0
-
-    if(!g_console_open_flag)
-
-       return;
-
-#endif
-
-    //raw_spin_lock(&port->lock);
-
-    for (; (count); count--, s++) {
-
-       zx29_uart_console_putc_share(port, *s);
-
-       if (*s == '\n')
-
-           zx29_uart_console_putc_share(port, '\r');
-
-    }
-
-   
-
-    //raw_spin_unlock(&port->lock);
-
+	if(!g_console_open_flag)
+		return;
+#endif	
+	//raw_spin_lock(&port->lock);
+	for (; (count); count--, s++) {
+		zx29_uart_console_putc_share(port, *s);
+		if (*s == '\n')
+			zx29_uart_console_putc_share(port, '\r');
+	}
+	
+	//raw_spin_unlock(&port->lock);
 }
 
- 
-
 #endif
 /***************************************************************************
  * If the port was already initialised (eg, by a boot loader),
  * try to determine the current setup.
  ****************************************************************************/
 static void __init zx29_console_get_options(struct uart_port *port, int *baud,
-						int *parity, int *bits)
+						 int *parity, int *bits)
 {
 	if (UART_GET_CR(port) & UART_CR_UARTEN) {
 		unsigned int lcr_h, ibrd, fbrd;
@@ -3321,14 +3290,14 @@
 #endif
 		return ret;
 		}
-	sema_init(&port->sema, 0);
+	 sema_init(&port->sema, 0);
 	/*platform_set_drvdata(pdev, port);*/
 	
 	if(pdev->id == DEBUG_CONSOLE){
 		g_console_open_flag = pdata->uart_input_enable ? pdata->uart_input_enable : 0;
 		error = device_create_file(&pdev->dev, &dev_attr_console_input);
 #ifdef _USE_VEHICLE_DC
-       		g_up_init_done = 0;
+		g_up_init_done = 0;
 		error = device_create_file(&pdev->dev, &dev_attr_console_uart_toggle);
 		error = device_create_file(&pdev->dev, &dev_attr_coreid_occupy_uart);
 		int ret;
@@ -3363,7 +3332,7 @@
 #endif
 	int i;
 	if(pdev->id == DEBUG_CONSOLE){		
-		device_remove_file(&pdev->dev, &dev_attr_console_input);
+		 device_remove_file(&pdev->dev, &dev_attr_console_input);
 	}
 	
 	if(pdev->id != DEBUG_CONSOLE){
@@ -3425,3 +3394,4 @@
 
 module_init(zx29_uart_init);
 module_exit(zx29_uart_exit);
+
diff --git a/ap/os/linux/linux-3.4.x/drivers/usb/dwc_otg/dwc_otg_pcd.c b/ap/os/linux/linux-3.4.x/drivers/usb/dwc_otg/dwc_otg_pcd.c
index 989ff03..8b7455b 100644
--- a/ap/os/linux/linux-3.4.x/drivers/usb/dwc_otg/dwc_otg_pcd.c
+++ b/ap/os/linux/linux-3.4.x/drivers/usb/dwc_otg/dwc_otg_pcd.c
@@ -49,6 +49,7 @@
  */
 
 #include "dwc_otg_pcd.h"
+#include <linux/android_notify.h>
 #include <mach/highspeed_debug.h>
 #include <mach/iomap.h>
 #ifdef DWC_UTE_CFI
@@ -57,6 +58,7 @@
 extern int init_cfi(cfiobject_t * cfiobj);
 #endif
 extern struct platform_device * dwc_get_platformdev(void);
+extern void usb_record_dbginfo(usb_dbginfo_type inf_type, int status, int info_value);
 
 /**
  * Choose endpoint from ep arrays using usb_ep structure.
@@ -1094,6 +1096,7 @@
 
 	printk("setup_phase_done_timeout, restart usb\n");
 	USBHAL_DBG("setup_phase_done_timeout, restart usb\n");
+	usb_record_dbginfo(USB_DEV_EXCEPT_RESET, 0, 0);
 	schedule_work(&pcd->work);
 }
 
@@ -2038,30 +2041,35 @@
 			}
 		}
 	}
-#if 0
+#if 1
 	/* Free DMA Descriptors */
 	if (GET_CORE_IF(pcd)->dma_desc_enable) {
 		if (ep->dwc_ep.type != UE_ISOCHRONOUS) {
-			desc_addr = ep->dwc_ep.desc_addr;
-			dma_desc_addr = ep->dwc_ep.dma_desc_addr;
+			if(ep->dwc_ep.desc_addr){
+				desc_addr = ep->dwc_ep.desc_addr;
+				dma_desc_addr = ep->dwc_ep.dma_desc_addr;
 
-			/* Cannot call dma_free_coherent() with IRQs disabled */
-			DWC_SPINUNLOCK_IRQRESTORE(pcd->lock, flags);
-			dwc_otg_ep_free_desc_chain(desc_addr, dma_desc_addr,
-						   MAX_DMA_DESC_CNT);
-
+				/* Cannot call dma_free_coherent() with IRQs disabled */
+				DWC_SPINUNLOCK_IRQRESTORE(pcd->lock, flags);
+				dwc_otg_ep_free_desc_chain(desc_addr, dma_desc_addr,
+							   MAX_DMA_DESC_CNT);
+			}
+			ep->dwc_ep.desc_addr = ep->dwc_ep.dma_desc_addr = NULL;
 		} else {
-			desc_addr = ep->dwc_ep.desc_addr;
-			dma_desc_addr = ep->dwc_ep.dma_desc_addr;
+			if(ep->dwc_ep.desc_addr){
+				desc_addr = ep->dwc_ep.desc_addr;
+				dma_desc_addr = ep->dwc_ep.dma_desc_addr;
 
-			/* Cannot call dma_free_coherent() with IRQs disabled */
-			DWC_SPINUNLOCK_IRQRESTORE(pcd->lock, flags);
-			dwc_otg_ep_free_desc_chain(desc_addr, dma_desc_addr,
-				MAX_DMA_DESC_CNT/2);
-			desc_addr = ep->dwc_ep.desc_addr1;
-			dma_desc_addr = ep->dwc_ep.dma_desc_addr1;
-			dwc_otg_ep_free_desc_chain(desc_addr, dma_desc_addr,
-				MAX_DMA_DESC_CNT/2);
+				/* Cannot call dma_free_coherent() with IRQs disabled */
+				DWC_SPINUNLOCK_IRQRESTORE(pcd->lock, flags);
+				dwc_otg_ep_free_desc_chain(desc_addr, dma_desc_addr,
+					MAX_DMA_DESC_CNT/2);
+				desc_addr = ep->dwc_ep.desc_addr1;
+				dma_desc_addr = ep->dwc_ep.dma_desc_addr1;
+				dwc_otg_ep_free_desc_chain(desc_addr, dma_desc_addr,
+					MAX_DMA_DESC_CNT/2);
+			}
+			ep->dwc_ep.desc_addr = ep->dwc_ep.dma_desc_addr = NULL;
 		}
 		goto out_unlocked;
 	}
diff --git a/ap/os/linux/linux-3.4.x/drivers/usb/dwc_otg/dwc_otg_pcd_intr.c b/ap/os/linux/linux-3.4.x/drivers/usb/dwc_otg/dwc_otg_pcd_intr.c
index 3c113d0..7c5c9e8 100644
--- a/ap/os/linux/linux-3.4.x/drivers/usb/dwc_otg/dwc_otg_pcd_intr.c
+++ b/ap/os/linux/linux-3.4.x/drivers/usb/dwc_otg/dwc_otg_pcd_intr.c
@@ -39,6 +39,7 @@
 #endif
 
 #include <mach/highspeed_debug.h>
+#include <linux/android_notify.h>
 #include <mach/iomap.h>
 #include "dwc_otg_driver.h"
 
@@ -46,6 +47,7 @@
 #include <mach/pcu.h>
 
 extern unsigned int get_panic_flag(void);
+extern void usb_record_dbginfo(usb_dbginfo_type inf_type, int status, int info_value);
 
 #ifdef DWC_UTE_PER_IO
 extern void complete_xiso_ep(dwc_otg_pcd_ep_t * ep);
@@ -6659,12 +6661,14 @@
 		if(gintr_status.b.usbsuspend){
 			USBHAL_DBG("usbsuspend\n");
 			printk("usbsuspend intr\n");
+		usb_record_dbginfo(USB_USB_SUSPEND, 0, 0);
 			retval |= dwc_otg_pcd_handle_suspend_intr(pcd);
 		}
 
 		if (gintr_status.b.wkupintr) {
 			USBHAL_DBG("wkupintr\n");
 			printk("wkupintr\n");
+		usb_record_dbginfo(USB_USB_RESUME, 0, 0);
 			retval |= dwc_otg_pcd_handle_wakeup_intr(pcd);
 		}
 
@@ -6694,7 +6698,8 @@
 		}
 		if (gintr_status.b.usbreset) {
 			USBHAL_DBG("usbreset intr\n");
-			printk("usbreset intr\n");			
+			printk("usbreset intr\n");	
+		usb_record_dbginfo(USB_USB_RESET, 0, 0);		
 			panic_flag = get_panic_flag();
 			if(panic_flag & 1)
 				panic("erlysuspend intr coming\n");
@@ -6703,6 +6708,7 @@
 		if (gintr_status.b.enumdone) {
 			USBHAL_DBG("enumdone intr\n");
 			printk("enumdone intr\n");
+		usb_record_dbginfo(USB_USB_ENUM_DONE, 0, 0);
 			retval |= dwc_otg_pcd_handle_enum_done_intr(pcd);
 		}
 		if (gintr_status.b.isooutdrop) {
diff --git a/ap/os/linux/linux-3.4.x/drivers/usb/gadget/adb_server.c b/ap/os/linux/linux-3.4.x/drivers/usb/gadget/adb_server.c
new file mode 100644
index 0000000..832c5e8
--- /dev/null
+++ b/ap/os/linux/linux-3.4.x/drivers/usb/gadget/adb_server.c
@@ -0,0 +1,637 @@
+/*
+ * Gadget Driver for Android ADB
+ *
+ * Copyright (C) 2008 Google, Inc.
+ * Author: Mike Lockwood <lockwood@android.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/poll.h>
+#include <linux/delay.h>
+#include <linux/wait.h>
+#include <linux/err.h>
+#include <linux/interrupt.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/device.h>
+#include <linux/miscdevice.h>
+#include <linux/soc/zte/rpm/rpmsg.h>
+#include <linux/soc/zte/rpm/icp.h>
+
+#define ADB_BULK_BUFFER_SIZE           4096
+#define ADB_AGENT_BUF_SIZE           640
+#define ADB_RPMSG_MAX_SIZE           512
+#define ADB_RPMSG_CH                  channel_3
+
+ struct adb_dev *g_adb_agent;
+ssize_t adb_server_write2usb( const char *buf,size_t count);
+
+void adb_recv_from_ap(void *buf, unsigned int len)
+{
+	int i;
+	unsigned char *data;
+	struct adb_dev *dev = _adb_dev;
+	char*tmp= (char*)buf;
+	if(dev == NULL)
+		return;
+	
+
+	if (len==0){
+	USBSTACK_DBG("adb_recv_from_cap, len 0, notify \n ", len);
+		atomic_set(&dev->write_busy, 0);		
+		wake_up(&dev->agt_write_wq);
+		return ;
+	}
+	USBSTACK_DBG("adb_recv_from_cap, len %d, write2usb \n ", len);
+#if 0
+	if(len < 32){
+		printk(" adb_recv_from_ap, send to usb start:\n");
+		for(i = 0; i < len; i++){
+			printk(" %x", tmp[i]);
+			if((i != 0) &&(i % 16) == 0)
+				printk("\n");
+		}
+		printk("\n adb_recv_from_ap, send to usb end\n");
+	}
+#endif
+	
+	adb_server_write2usb((char *)buf, len);
+} 
+#if 0
+static ssize_t adb_server_read(struct file *fp, char __user *buf,
+				size_t count, loff_t *pos)
+{
+	struct adb_dev *dev = fp->private_data;
+	struct usb_request *req;
+	int r = count, xfer;
+	int ret;
+
+	pr_debug("adb_read(%d)\n", count);
+	if (!_adb_dev)
+		return -ENODEV;
+
+	if (count > ADB_BULK_BUFFER_SIZE)
+		return -EINVAL;
+
+	if (adb_lock(&dev->read_excl))
+		return -EBUSY;
+
+	/* we will block until we're online */
+	while (!(dev->online || dev->agt_error)) {
+		pr_debug("adb_read: waiting for online state\n");
+		ret = wait_event_interruptible(dev->read_wq,
+				(dev->online || dev->agt_error));
+		if (ret < 0) {
+			adb_unlock(&dev->read_excl);
+			return ret;
+		}
+	}
+	if (dev->agt_error) {
+		r = -EIO;
+		printk("adb_read block fail ret:%d", r);
+		goto done;
+	}
+
+requeue_req:
+	/* queue a request */
+	req = dev->rx_req;
+	req->length = count;
+	dev->rx_done = 0;
+	if(!dev->online){
+		printk("adb_read dev is offline\n");
+		r = -EIO;
+		goto done;
+	}
+	ret = usb_ep_queue(dev->ep_out, req, GFP_ATOMIC);
+	if (ret < 0) {
+		pr_debug("adb_read: failed to queue req %p (%d)\n", req, ret);
+		r = -EIO;
+		dev->agt_error = 1;
+		printk("adb_read ep-queue fail ret:%d", r);
+		goto done;
+	} else {
+		pr_debug("rx %p queue\n", req);
+	}
+
+	/* wait for a request to complete */
+	ret = wait_event_interruptible(dev->read_wq, dev->rx_done);
+	if (ret < 0) {
+		if (ret != -ERESTARTSYS)
+			dev->agt_error = 1;
+		r = ret;
+		usb_ep_dequeue(dev->ep_out, req);
+		printk("adb_read stop ret: 0x%x", ret);
+		goto done;
+	}
+	if (!dev->agt_error) {
+		if(!dev->online){
+			printk("adb_read dev is offline cannot requeue req\n");
+			r = -EIO;
+			goto done;
+		}
+		/* If we got a 0-len packet, throw it back and try again. */
+		if (req->actual == 0)
+			goto requeue_req;
+
+		pr_debug("rx %p %d\n", req, req->actual);
+		xfer = (req->actual < count) ? req->actual : count;
+		if (copy_to_user(buf, req->buf, xfer))
+			r = -EFAULT;
+
+	} else{
+		printk("adb_read fail %d", r);
+		r = -EIO;
+	}
+
+done:
+	adb_unlock(&dev->read_excl);
+	pr_debug("adb_read returning %d\n", r);
+	return r;
+}
+#endif
+
+void adb_agent_inform_work(struct work_struct *work)
+{
+	struct adb_dev	*dev = container_of(work, struct adb_dev, agent_inform_work);
+	
+	kobject_uevent(&adb_device.this_device->kobj, (dev->agent_state == 1) ? KOBJ_OFFLINE : KOBJ_ONLINE);
+}
+
+
+int adb_rpmsg_write2ap(void *buf, unsigned int len)
+{
+	int ret = 0;
+	int i;
+	char *tmp = (char *)buf;
+	
+	int transfer_cnt, total_cnt; 
+	if (!g_adb_agent)
+		return -1;
+	
+	T_ZDrvRpMsg_Msg *rpmsg = &g_adb_agent->rpmsg_tx;
+	
+	rpmsg->flag = 0;
+	rpmsg->flag |= 1;
+	USBSTACK_DBG("adb_rpmsg_write2ap datalen:%d\n",  len);
+#if 0
+	if(len && len < 32){
+		printk(" data from usb, send to cap start:\n");
+		for(i = 0; i < len; i++){
+			printk(" %x", tmp[i]);
+			if((i != 0) &&(i % 16) == 0)
+				printk("\n");
+		}
+		printk("\n data from usb, send to cap end\n");
+	}
+#endif	
+	if(len == 0){//just send notify
+		rpmsg->len = len;
+		ret = zDrvRpMsg_Write_Cap(&g_adb_agent->rpmsg_tx);
+		if(ret < 0)
+			printk("adb_rpmsg_write2ap notify send fail, ret:%d\n", ret);	
+		return ret;
+	}
+	total_cnt = len;
+	while(total_cnt){
+		transfer_cnt = total_cnt > ADB_RPMSG_MAX_SIZE ? ADB_RPMSG_MAX_SIZE: total_cnt;
+		memcpy(g_adb_agent->rx2agt_buf, tmp, transfer_cnt);
+		rpmsg->len = transfer_cnt;
+		rpmsg->buf = g_adb_agent->rx2agt_buf;
+		atomic_set(&g_adb_agent->write_busy, 1);		
+		ret = zDrvRpMsg_Write_Cap(&g_adb_agent->rpmsg_tx);
+		if(rpmsg->len != ret){
+			atomic_set(&g_adb_agent->write_busy, 0);
+			printk("[adb_rpmsg_write2ap] msg send error:(%d)", ret);
+			return ret;
+		}
+		//should wait for ap recv ok
+			USBSTACK_DBG("adb_rpmsg_recv_thread, brfore agt_write_wq len:%d, write_busy:%d\n",  transfer_cnt, atomic_read(&g_adb_agent->write_busy));
+		ret = wait_event_interruptible(g_adb_agent->agt_write_wq,
+			(!atomic_read(&g_adb_agent->write_busy)) || g_adb_agent->agt_error);
+		USBSTACK_DBG("adb_rpmsg_recv_thread, after agt_write_wq len:%d, write_busy:%d\n",  transfer_cnt, atomic_read(&g_adb_agent->write_busy));
+
+		if (ret < 0) {
+			break;
+		}
+		total_cnt -= transfer_cnt;
+		tmp += transfer_cnt;
+		
+	}
+	atomic_set(&g_adb_agent->write_busy, 0);
+	
+	return 0;  
+}
+
+ssize_t adb_server_write2usb( const char *buf,size_t count)
+{
+	struct usb_request *req = NULL;
+	int r = count, xfer;
+	int ret = 0;
+	if (!g_adb_agent)
+		return -ENODEV;
+	//pr_debug("adb_write(%d)\n", count);
+	//printk("adb_server_write2usb begin\n");
+
+#ifdef CONFIG_PM
+	if (g_adb_agent->suspend_state == 1){
+		g_dbg_adb_times++;
+		//usb_printk("%s, %u  wrtime:%d\n", __func__, __LINE__,  g_dbg_adb_times);
+		//USBSTACK_DBG("%s, %u  wrtime:%d", __func__, __LINE__,  g_dbg_adb_times);
+		return -EBUSY;
+#if 0
+        usb_gadget_wakeup(dev->cdev->gadget);
+		do{
+			msleep(2);
+		}while(dev->suspend_state==1);
+#endif
+	}
+#endif
+	if (adb_lock(&g_adb_agent->write_excl))
+		return -EBUSY;
+	
+	while (count > 0) {
+		if (g_adb_agent->agt_error) {
+			printk("adb_write dev->agt_error\n");
+			r = -EIO;
+			break;
+		}
+
+		/* get an idle tx request to use */
+		req = NULL;
+	USBSTACK_DBG("adb_server_write2usb waiting write_wq, agt_error:%d, txempty:%d\n",g_adb_agent->agt_error, list_empty(&g_adb_agent->tx_idle));
+		ret = wait_event_interruptible(g_adb_agent->write_wq,
+			(req = adb_req_get(g_adb_agent, &g_adb_agent->tx_idle)) || g_adb_agent->agt_error);
+
+			USBSTACK_DBG("adb_server_write2usb req:0x%x\n", req);
+		if (ret < 0) {
+			r = ret;
+			break;
+		}
+		if(g_adb_agent->agt_error){
+			printk("get agt_error err, break write\n");
+			r = -EIO;
+			break;			
+		}
+
+		if (req != 0) {
+			if (count > ADB_BULK_BUFFER_SIZE)
+				xfer = ADB_BULK_BUFFER_SIZE;
+			else
+				xfer = count;
+			memcpy(req->buf, buf, xfer);
+			adb_rpmsg_write2ap(NULL, 0);
+			
+			req->length = xfer;
+			ret = usb_ep_queue(g_adb_agent->ep_in, req, GFP_ATOMIC);
+			if (ret < 0) {
+				printk("adb_write: xfer agt_error %d\n", ret);
+				g_adb_agent->agt_error = 1;
+				r = -EIO;
+				break;
+			}
+
+			buf += xfer;
+			count -= xfer;
+
+			/* zero this so we don't try to free it on error exit */
+			req = NULL;
+		}
+	}
+
+	if (req)
+		adb_req_put(g_adb_agent, &g_adb_agent->tx_idle, req);
+
+	adb_unlock(&g_adb_agent->write_excl);
+	USBSTACK_DBG("adb_server_write2usb returning %d\n", r);
+	return r;
+}
+#if 1
+static int adb_agent_open(void)
+{
+	//pr_info("adb_open\n");
+	if (!g_adb_agent)
+		return -ENODEV;
+	//if(g_adb_agent->)
+	
+	printk("%s", __func__);
+
+
+
+	/* clear the agt_error latch */
+	g_adb_agent->agt_error = 0;
+
+	//adb_ready_callback();
+
+	if(atomic_read(&g_adb_agent->enable_excl)){
+		g_adb_agent->online = 1;
+		wake_up(&g_adb_agent->agt_start_wait);
+	}
+
+	return 0;
+}
+#endif
+static int adb_agent_close(void)
+{
+	int ret;
+	//pr_info("adb_release\n");
+	USBSTACK_DBG("%s", __func__);
+	printk("adb_agent_close\n");
+	//adb_closed_callback();
+	struct usb_request *req = g_adb_agent->rx_req;
+
+
+	g_adb_agent->agent_start = 0;
+	g_adb_agent->agent_state = 0;
+	g_adb_agent->agt_error = 1;
+	
+
+#if 0	
+	g_adb_agent->rx_done = 1;
+	wake_up(&g_adb_agent->read_wq);
+#endif	
+#if 0
+	//if(atomic_read(&g_adb_agent->read_excl)){		
+		USBSTACK_DBG("adb_agent_close, disable and reenable ep_out");
+		ret = usb_ep_disable(g_adb_agent->ep_out);
+		if(ret){
+			printk("adb_agent_close, usb_ep_disable fail,%d\n", ret);
+			WARN_ON(1);
+		}
+		ret = usb_ep_enable(g_adb_agent->ep_out);
+		if(ret){
+			printk("adb_agent_close, usb_ep_enable fail,%d\n", ret);
+			WARN_ON(1);
+		}
+			USBSTACK_DBG("adb_agent_close, ep_out enable ok\n");
+
+	//}
+#endif	
+	if(list_empty(&g_adb_agent->tx_idle) && atomic_read(&g_adb_agent->write_excl)){
+		printk("adb_agent_close, disable and reenable ep_in");
+		ret = usb_ep_disable(g_adb_agent->ep_in);
+		if(ret){
+			printk("adb_agent_close, usb_ep_disable fail,%d\n", ret);
+			WARN_ON(1);
+		}
+		ret = usb_ep_enable(g_adb_agent->ep_in);
+		if(ret){
+			printk("adb_agent_close, usb_ep_enable fail,%d\n", ret);
+			WARN_ON(1);
+		}		
+	}
+	//adb_unlock(&g_adb_agent->open_excl);
+	return 0;
+}
+
+int adb_agent_monitor_thread(void *ptr)
+{
+	unsigned long			flags;
+	struct adb_dev *dev = (struct adb_dev *)ptr;
+
+	int ret;	
+	
+	while(!kthread_should_stop()){
+		USBSTACK_DBG("adb_agent_monitor_thread waiting for agent_monitor_wq\n");
+		ret = wait_event_interruptible(dev->agent_monitor_wq,
+				(atomic_read(&dev->agent_switch) ||kthread_should_stop()));
+		if (ret < 0) {
+			printk("monitor_thread wait fail\n");
+			//return ret;
+			continue;
+		}
+		
+		if(kthread_should_stop())
+		{
+			printk("unbind thread stop");
+			break;
+		}
+		USBSTACK_DBG("adb_agent_monitor_thread,got, agent_switch:%d, agent_state:%d\n", 
+			atomic_read(&dev->agent_switch), dev->agent_state);
+		atomic_set(&dev->agent_switch, 0);
+		if(dev->agent_state){//enable agent		
+			dev->agent_start = 1;	
+			dev->agt_error = 0;
+			//wake_up(&dev->agt_start_wait);
+		//wakeup adb read and return	
+		dev->rx_done = 1;
+		wake_up(&dev->read_wq);
+		}else{	
+			//dev->agent_start = 0;
+			//disable agent
+			adb_agent_close();
+		}
+		
+		schedule_work(&dev->agent_inform_work);
+		
+	}
+	return 0;
+}
+
+int adb_rpmsg_agent_state(void)
+{
+	if(!g_adb_agent){
+		printk("adb_rpmsg_agent_state, adb is NULL, fail\n");
+		return -1;
+	}
+
+	return g_adb_agent->agent_state;
+}
+EXPORT_SYMBOL_GPL(adb_rpmsg_agent_state);
+
+int adb_enable_rpmsg_agent(int flag)
+{
+	if(!g_adb_agent){
+		printk("adb_enable_rpmsg_agent, adb is NULL, fail\n");
+	}
+	g_adb_agent->agent_state = ((flag != 0) ? 1 : 0);
+	atomic_set(&g_adb_agent->agent_switch, 1);
+	USBSTACK_DBG("adb_enable_rpmsg_agent,now %s adb agent\n", (g_adb_agent->agent_state == 1) ? "start" : "stop");
+	//do switch agent in monitor thread
+	wake_up(&g_adb_agent->agent_monitor_wq);
+	return 0;
+}
+EXPORT_SYMBOL_GPL(adb_enable_rpmsg_agent);
+
+
+void adb_rpmsg_recv_thread(void *ptr)
+{
+
+	unsigned long			flags;
+	struct adb_dev *dev = (struct adb_dev *)ptr;
+	struct usb_request *req;
+	int r , xfer;
+	int ret = 0;
+	r = xfer = 0;
+	
+	while(!kthread_should_stop()){	
+		/* we will block until we're online */
+		while (!dev->agent_start) {
+			USBSTACK_DBG("adb_rpmsg_recv_thread: waiting foragt_start_wait\n");
+			ret = wait_event_interruptible(dev->agt_start_wait,
+					( dev->agent_start ||kthread_should_stop()));
+			if (ret < 0) {
+				//adb_unlock(&dev->read_excl);
+				return ret;
+			}
+		}
+		
+		if(kthread_should_stop())
+		{
+			USBSTACK_DBG("unbind thread stop");
+			break;
+		}
+			USBSTACK_DBG("adb_rpmsg_recv_thread: now send request\n");
+
+requeue_req:
+		/* queue a request */
+		req = dev->rx_req;
+		req->length = ADB_BULK_BUFFER_SIZE;
+		dev->rx_done = 0;
+		if(!dev->online){
+			printk("rpmsg_recv dev is offline\n");
+			r = -EIO;
+			goto done;
+		}
+#if 0		
+		if(atomic_read(&dev->adb_read_flag)){
+			printk("\nadb_rpmsg_recv_thread adb_read_flag, wait_read_wq\n");
+			goto wait_read_wq;
+		}	
+#endif		
+		USBSTACK_DBG("\nadb_rpmsg_recv_thread read usb again\n");
+		ret = usb_ep_queue(dev->ep_out, req, GFP_ATOMIC);
+		if (ret < 0) {
+			pr_debug("rpmsg_recv: failed to queue req %p (%d)\n", req, ret);
+			r = -EIO;
+			dev->agt_error = 1;
+			printk("rpmsg_recv ep-queue fail ret:%d", r);
+			goto done;
+		} else {
+			pr_debug("rx %p queue\n", req);
+		}
+		atomic_set(&dev->agt_read_flag, 1);
+		
+		/* wait for a request to complete */
+wait_read_wq:		
+		ret = wait_event_interruptible(dev->read_wq, dev->rx_done);
+			USBSTACK_DBG("adb_rpmsg_recv_thread: read from usb end, ret:%d, agt_error:%d\n", ret, dev->agt_error);
+		
+		atomic_set(&dev->agt_read_flag, 0);
+		if (ret < 0) {
+			if (ret != -ERESTARTSYS)
+				dev->agt_error = 1;
+			r = ret;
+			usb_ep_dequeue(dev->ep_out, req);
+			printk("rpmsg_recv stop ret: 0x%x", ret);
+			goto done;
+		}
+		if (!dev->agt_error) {
+			if(!dev->online){
+				printk("rpmsg_recv dev is offline cannot requeue req\n");
+				r = -EIO;
+				goto done;
+			}
+			/* If we got a 0-len packet, throw it back and try again. */
+			if (req->actual == 0){
+				printk("rpmsg_recv actual is 0, requeue_req again\n");				
+				goto requeue_req;
+			}
+			USBSTACK_DBG("rpmsg_recv rx %p actual:%d\n", req, req->actual);
+			
+			xfer = req->actual;
+			r = adb_rpmsg_write2ap(req->buf, xfer);
+			if(ret){
+				printk("adb_rpmsg_write fail, err:%d \n", ret);
+			}
+			
+			goto requeue_req;
+		} else{
+			if(dev->agent_start){
+				printk("rpmsg_recv  fail ,len:%d, status:%d\n", req->actual, req->status);				
+				r = -EIO;
+				dev->rx_done = 0;
+			}else{
+				USBSTACK_DBG("adb_rpmsg_write wake_up agt_read_wq, len:%d, status:%d\n", req->actual, req->status);
+			
+				wake_up(&dev->agt_read_wq);
+			}
+			
+		}
+
+done:
+		//adb_unlock(&dev->read_excl);
+		USBSTACK_DBG("rpmsg_recv returning %d\n", r);
+
+				
+	}
+}
+
+
+
+int adb_server_init(struct adb_dev *dev)
+{
+	int ret = 0;
+	dev->agt_error = 0;
+	init_waitqueue_head(&dev->agent_monitor_wq);
+	init_waitqueue_head(&dev->agt_start_wait);
+	init_waitqueue_head(&dev->agt_read_wq);
+	init_waitqueue_head(&dev->agt_write_wq);	
+	INIT_WORK(&dev->agent_inform_work, adb_agent_inform_work);
+	atomic_set(&dev->agent_switch, 0);
+	atomic_set(&dev->write_busy, 0);
+	atomic_set(&dev->agt_read_flag, 0);
+	atomic_set(&dev->adb_read_flag, 0);
+	
+	/* create channel */
+	//if(zDrvRpMsg_CreateChannel(AP_ID, ADB_RPMSG_CH, ADB_BULK_BUFFER_SIZE))
+	if(zDrvRpMsg_CreateChannel_Cap(CAP_ID, ADB_RPMSG_CH, ADB_AGENT_BUF_SIZE))
+	{
+		printk("[adb_server_init] Failed create psm icp channel ! \n");
+		BUG();
+	}
+	
+	printk("[adb_server_init] Success create psm icp channel!!! \n");	
+	//macro not defined now, using 1 replace
+	//zDrvRpMsg_RegCallBack(AP_ID, ADB_RPMSG_CH, adb_recv_from_ap);
+	zDrvRpMsg_RegCallBack_Cap(CAP_ID, ADB_RPMSG_CH, adb_recv_from_ap);
+	dev->rpmsg_thread = kthread_run(adb_rpmsg_recv_thread, (unsigned long)dev+1, "adb_rpmsg_recv");
+	BUG_ON(IS_ERR(dev->rpmsg_thread));
+	
+	dev->agent_monitor_thread = kthread_run(adb_agent_monitor_thread, (unsigned long)dev+1, "adb_agent_monitor");
+	BUG_ON(IS_ERR(dev->agent_monitor_thread));
+	g_adb_agent = dev;
+	g_adb_agent->rpmsg_tx.actorID = CAP_ID;
+	g_adb_agent->rpmsg_tx.chID = ADB_RPMSG_CH;
+	//g_adb_agent->rpmsg_tx.flag= 0x1;
+	//alloc 512
+	g_adb_agent->rx2agt_buf = kmalloc(ADB_BULK_BUFFER_SIZE, GFP_KERNEL);
+	if(!g_adb_agent->rx2agt_buf){
+		panic("rx2agt_buf malloc fail\n");
+	}
+	return ret;		
+}
+
+int adb_server_release(void)
+{
+
+	flush_work_sync(&g_adb_agent->agent_inform_work);
+	kthread_stop(g_adb_agent->rpmsg_thread);
+	kthread_stop(g_adb_agent->agent_monitor_thread);
+	
+	if(g_adb_agent->rx2agt_buf)
+		kfree(g_adb_agent->rx2agt_buf);
+	
+	g_adb_agent	= NULL;	
+	return 0;
+}
diff --git a/ap/os/linux/linux-3.4.x/drivers/usb/gadget/android.c b/ap/os/linux/linux-3.4.x/drivers/usb/gadget/android.c
index 9094fd3..1ec687f 100755
--- a/ap/os/linux/linux-3.4.x/drivers/usb/gadget/android.c
+++ b/ap/os/linux/linux-3.4.x/drivers/usb/gadget/android.c
@@ -52,6 +52,11 @@
 #include "f_acm.c"
 #include "f_serial.c"
 #include "f_adb.c"
+#ifdef _USE_VEHICLE_DC
+#include "adb_server.c"
+#include "usb_rpmsg_server.c"
+
+#endif
 //#include "f_mtp.c"
 //#include "f_accessory.c"
 #define USB_ETH_RNDIS y
@@ -168,6 +173,7 @@
 void usb_mods_activate(void);
 void usb_set_ms_auto_reject(int flag);
 extern void dwc_otg_clk_enable(int isOn);
+extern void usb_record_dbginfo(usb_dbginfo_type inf_type, int status, int info_value);
 
 typedef enum usb_enum_mode_type{
 	USB_ENUM_MODE_DEBUG = 0,
@@ -2522,6 +2528,7 @@
 		}
 		android_enable(dev);
 		dev->enabled = true;
+		usb_record_dbginfo(USB_DEV_ENABLE, 0, 0);
 	} else if (!enabled && dev->enabled) {
 		USB_DEBUG("USB DISENABLE");
 		USBSTACK_DBG("USB DISENABLE");
@@ -2532,7 +2539,8 @@
 		}
 		dev->enabled = false;
 		//close usb power
-		usb_gadget_clear_selfpowered(cdev->gadget);		
+		usb_gadget_clear_selfpowered(cdev->gadget);	
+		usb_record_dbginfo(USB_DEV_DISABLE, 0, 0);	
 	} else {
 		pr_err("android_usb: already %s\n",
 				dev->enabled ? "enabled" : "disabled");
@@ -3051,6 +3059,88 @@
 	return 0;
 }
 
+#ifdef _USE_VEHICLE_DC
+extern const char *usb_speed_string(enum usb_device_speed speed);
+
+void android_set_rpmsg_resp(int type, char*resp)
+{
+	usb_rpmsg_cmd *t_resp = (usb_rpmsg_cmd *)resp;
+	unsigned long flags;
+    struct android_usb_function *func_t;
+	
+	if(!_android_dev){
+		printk("android_set_rpmsg_resp, _android_dev is NULL\n");
+		return ;
+	}
+
+	struct usb_composite_dev *cdev = _android_dev->cdev;
+    if(NULL == cdev)
+    {
+		printk("android_set_rpmsg_resp, cdev is NULL\n");
+        return ;
+    }
+	printk("android_set_rpmsg_resp cmd type:%d\n", type);
+	switch(type){
+		case USB_RPMSG_GET_NET_TYPE:
+			t_resp->cmd = USB_RPMSG_GET_NET_TYPE;
+			mutex_lock(&_android_dev->mutex);
+			func_t = list_first_entry(&_android_dev->enabled_functions, struct android_usb_function, enabled_list);
+			if(func_t){
+				if(strcmp(func_t->name, "rndis") == 0 ||
+					strcmp(func_t->name, "ecm") == 0){
+					sprintf(t_resp->param, "%s\n", func_t->name);
+				}else{
+					sprintf(t_resp->param, "%s\n", "none net mode");				
+				}
+			}else{
+					sprintf(t_resp->param, "%s\n", "none net mode");				
+			}
+			mutex_unlock(&_android_dev->mutex);			
+			
+			break;
+		case USB_RPMSG_GET_USB_SPEED:
+			t_resp->cmd = USB_RPMSG_GET_USB_SPEED;
+
+			struct usb_gadget		*gadget = cdev->gadget;
+		    if(NULL == cdev)
+		    {
+				printk("android_set_rpmsg_resp, gadget is NULL\n");
+				sprintf(t_resp->param, "%s\n",  "invalid state");
+		        return ;
+		    }			
+			sprintf(t_resp->param, "%s\n", usb_speed_string(gadget->speed));
+			
+			break;
+		case USB_RPMSG_GET_USB_STATE:			
+			t_resp->cmd = USB_RPMSG_GET_USB_STATE;
+
+			spin_lock_irqsave(&cdev->lock, flags);
+			if (cdev->config)
+				sprintf(t_resp->param, "%s\n", "CONFIGURED"); 
+			else if (_android_dev->connected)
+				sprintf(t_resp->param, "%s\n",  "CONNECTED");
+			else
+				sprintf(t_resp->param, "%s\n",  "unknown state");
+				
+			spin_unlock_irqrestore(&cdev->lock, flags);			
+			
+			
+			break;
+		case USB_RPMSG_GET_USB_LINK_STATE:
+			t_resp->cmd = USB_RPMSG_GET_USB_LINK_STATE;
+			sprintf(t_resp->param, "%s\n", _android_dev->enabled ? "enabled" : "disabled");
+			
+			break;
+			//usb_set_rpmsg_resp(t_cmd->cmd, usb_resp);
+		//case:
+		//	break;
+		default:
+			break;
+	}
+}
+EXPORT_SYMBOL_GPL(android_set_rpmsg_resp);
+#endif
+
 
 static int __init init(void)
 {
diff --git a/ap/os/linux/linux-3.4.x/drivers/usb/gadget/composite.c b/ap/os/linux/linux-3.4.x/drivers/usb/gadget/composite.c
index 0dc9051..a141218 100755
--- a/ap/os/linux/linux-3.4.x/drivers/usb/gadget/composite.c
+++ b/ap/os/linux/linux-3.4.x/drivers/usb/gadget/composite.c
@@ -21,6 +21,7 @@
 #include <linux/utsname.h>
 
 #include <linux/usb/composite.h>
+#include <linux/android_notify.h>
 #include <asm/unaligned.h>
 #include <mach/highspeed_debug.h>
 
@@ -45,6 +46,8 @@
 static struct usb_composite_driver *composite;
 static int (*composite_gadget_bind)(struct usb_composite_dev *cdev);
 
+extern void usb_record_dbginfo(usb_dbginfo_type inf_type, int status, int info_value);
+
 /* Some systems will need runtime overrides for the  product identifiers
  * published in the device descriptor, either numbers or strings or both.
  * String parameters are in UTF-8 (superset of ASCII's 7 bit characters).
@@ -1609,6 +1612,7 @@
 		composite->suspend(cdev);
 
 	cdev->suspended = 1;
+	usb_record_dbginfo(USB_DEV_SUSPEND, 0, 0);
 
 	usb_gadget_vbus_draw(gadget, 2);
 }
@@ -1639,6 +1643,7 @@
 		}
 
 		maxpower = cdev->config->bMaxPower;
+		usb_record_dbginfo(USB_DEV_RESUME, 0, 0);
 
 		usb_gadget_vbus_draw(gadget, maxpower ?
 			(2 * maxpower) : CONFIG_USB_GADGET_VBUS_DRAW);
diff --git a/ap/os/linux/linux-3.4.x/drivers/usb/gadget/f_adb.c b/ap/os/linux/linux-3.4.x/drivers/usb/gadget/f_adb.c
index 17259b7..0a0bb6d 100644
--- a/ap/os/linux/linux-3.4.x/drivers/usb/gadget/f_adb.c
+++ b/ap/os/linux/linux-3.4.x/drivers/usb/gadget/f_adb.c
@@ -26,11 +26,16 @@
 #include <linux/types.h>
 #include <linux/device.h>
 #include <linux/miscdevice.h>
-
+#ifdef _USE_VEHICLE_DC
+#include <linux/soc/zte/rpm/rpmsg.h>
+#endif
 #define ADB_BULK_BUFFER_SIZE           4096
 
 /* number of tx requests to allocate */
 #define TX_REQ_MAX 4
+#ifdef _USE_VEHICLE_DC
+extern int adb_rpmsg_write2ap(void *buf, unsigned int len);
+#endif
 
 static const char adb_shortname[] = "android_adb";
 
@@ -56,6 +61,29 @@
 	wait_queue_head_t write_wq;
 	struct usb_request *rx_req;
 	int rx_done;
+
+#ifdef _USE_VEHICLE_DC	
+	atomic_t write_busy;
+	atomic_t agt_read_flag;
+	atomic_t adb_read_flag;
+	int agt_error;
+	T_ZDrvRpMsg_Msg rpmsg_tx;	
+	char   *rx2agt_buf;
+	struct task_struct	*rpmsg_thread;	
+	struct task_struct	*agent_monitor_thread;	
+	wait_queue_head_t agent_monitor_wq;	
+	wait_queue_head_t agt_start_wait;
+	wait_queue_head_t agt_read_wq;
+	wait_queue_head_t agt_write_wq;
+	atomic_t agent_switch;
+	int agent_state;
+	
+	int agent_start;//using for recv thread
+	struct work_struct agent_inform_work;	 /* inform USB adb state */	
+#endif	
+	struct work_struct online_inform;	 /* online inform USB adb  */	
+	struct work_struct offline_inform;	 /* offline inform USB adb  */	
+	
 #ifdef CONFIG_PM
 	u32 suspend_state;
 #endif
@@ -118,8 +146,14 @@
 static void adb_ready_callback(void);
 static void adb_closed_callback(void);
 
+#ifdef _USE_VEHICLE_DC
+extern int adb_server_init(struct adb_dev *dev);
+extern int adb_server_release(void);
+#endif
+
+
 /* temporary variable used between adb_open() and adb_gadget_bind() */
-static struct adb_dev *_adb_dev;
+ struct adb_dev *_adb_dev;
 
 static inline struct adb_dev *func_to_adb(struct usb_function *f)
 {
@@ -199,8 +233,9 @@
 	struct adb_dev *dev = _adb_dev;
 
 	if (req->status != 0)
-		USBSTACK_DBG("adb_complete_in err: %d", req->status);
+		USBSTACK_DBG("adb_complete_in err: %d\n", req->status);
 	//	dev->error = 1;
+		USBSTACK_DBG("adb_complete_in status: %d\n", req->status);
 
 	adb_req_put(dev, &dev->tx_idle, req);
 
@@ -215,8 +250,9 @@
 	//if (req->status != 0 && req->status != -ECONNRESET)
 	//	dev->error = 1;
 
+		USBSTACK_DBG("adb_complete_out status: %d, len:%d\n", req->status, req->actual);
 	if (req->status != 0)
-		USBSTACK_DBG("adb_complete_out err: %d", req->status);
+		USBSTACK_DBG("adb_complete_out err: %d\n", req->status);
 
 	wake_up(&dev->read_wq);
 }
@@ -280,7 +316,7 @@
 	int r = count, xfer;
 	int ret;
 
-	pr_debug("adb_read(%d)\n", count);
+	USBSTACK_DBG("adb_read   enter(%d)\n", count);
 	if (!_adb_dev)
 		return -ENODEV;
 
@@ -305,6 +341,27 @@
 		USBSTACK_DBG("adb_read block fail ret:%d", r);
 		goto done;
 	}
+#ifdef _USE_VEHICLE_DC	
+	if(atomic_read(&dev->agt_read_flag)){
+		USBSTACK_DBG("adb_read wait for agt_read_wq\n");
+		
+		req = dev->rx_req;
+		ret = wait_event_interruptible(dev->agt_read_wq, dev->rx_done);
+		if (ret < 0) {
+			if (ret != -ERESTARTSYS)
+				dev->error = 1;
+			printk("adb_read wait agt_read_wq fail ret: 0x%x", ret);
+			goto done;
+		}
+		
+		USBSTACK_DBG("adb_read after agt_read_wq rx %p len:%d\n", req, req->actual);
+		xfer = (req->actual < count) ? req->actual : count;
+		
+		if (copy_to_user(buf, req->buf, xfer))
+			r = -EFAULT;
+		goto done;			
+	}
+#endif	
 
 requeue_req:
 	/* queue a request */
@@ -316,17 +373,22 @@
 		r = -EIO;
 		goto done;
 	}
+		USBSTACK_DBG("adb_read waiting usb_ep_queue \n");
 	ret = usb_ep_queue(dev->ep_out, req, GFP_ATOMIC);
 	if (ret < 0) {
 		pr_debug("adb_read: failed to queue req %p (%d)\n", req, ret);
 		r = -EIO;
 		dev->error = 1;
-		USBSTACK_DBG("adb_read ep-queue fail ret:%d", r);
+		printk("adb_read ep-queue fail ret:%d", r);
 		goto done;
 	} else {
 		pr_debug("rx %p queue\n", req);
 	}
 
+#ifdef _USE_VEHICLE_DC
+	atomic_set(&dev->adb_read_flag, 1);
+#endif
+		USBSTACK_DBG("adb_read waiting for read_wq, rx_done:%d\n", dev->rx_done);
 	/* wait for a request to complete */
 	ret = wait_event_interruptible(dev->read_wq, dev->rx_done);
 	if (ret < 0) {
@@ -334,9 +396,13 @@
 			dev->error = 1;
 		r = ret;
 		usb_ep_dequeue(dev->ep_out, req);
-		USBSTACK_DBG("adb_read stop ret: 0x%x", ret);
+		printk("adb_read stop ret: 0x%x", ret);
 		goto done;
 	}
+
+#ifdef _USE_VEHICLE_DC	
+	atomic_set(&dev->adb_read_flag, 0);	
+#endif	
 	if (!dev->error) {
 		if(!dev->online){
 			printk("adb_read dev is offline cannot requeue req\n");
@@ -344,22 +410,35 @@
 			goto done;
 		}
 		/* If we got a 0-len packet, throw it back and try again. */
-		if (req->actual == 0)
+		if (req->actual == 0
+#ifdef _USE_VEHICLE_DC			
+			&& _adb_dev->agent_start == 0
+#endif			
+			){
+			USBSTACK_DBG("adb_read actual == 0, agent_start == 0, requeue\n");
+			
 			goto requeue_req;
-
-		pr_debug("rx %p %d\n", req, req->actual);
+		}
+		USBSTACK_DBG("adb_read rx %p len:%d\n", req, req->actual);
 		xfer = (req->actual < count) ? req->actual : count;
+#ifdef _USE_VEHICLE_DC
+		r = xfer;
+		if(_adb_dev->agent_start && req->actual){
+			adb_rpmsg_write2ap(req->buf, xfer);
+			goto done;
+		}
+#endif
 		if (copy_to_user(buf, req->buf, xfer))
 			r = -EFAULT;
 
 	} else{
-		USBSTACK_DBG("adb_read fail %d", r);
+		printk("adb_read fail %d", r);
 		r = -EIO;
 	}
 
 done:
 	adb_unlock(&dev->read_excl);
-	pr_debug("adb_read returning %d\n", r);
+	USBSTACK_DBG("adb_read returning %d\n", r);
 	return r;
 }
 #ifdef CONFIG_PM
@@ -456,6 +535,13 @@
 	//pr_info("adb_open\n");
 	if (!_adb_dev)
 		return -ENODEV;
+	printk("\n adb_open----enter\n");
+#ifdef _USE_VEHICLE_DC	
+	if(_adb_dev->agent_state){
+		printk("\n adb_open,now is agent mode ,return\n");
+		return -ENODEV;
+	}
+#endif	
 	USBSTACK_DBG("%s", __func__);
 	if (adb_lock(&_adb_dev->open_excl))
 		return -EBUSY;
@@ -480,12 +566,12 @@
 	int ret;
 	//pr_info("adb_release\n");
 	USBSTACK_DBG("%s", __func__);
-	printk("adb_release\n");
+	printk("\n adb_release----enter, read_excl:%d\n", atomic_read(&_adb_dev->read_excl));
 	//adb_closed_callback();
 
 	_adb_dev->error = 1;
 	if(list_empty(&_adb_dev->tx_idle) && atomic_read(&_adb_dev->write_excl)){
-		printk("adb_release, disable and reenable endpoint");
+		USBSTACK_DBG("adb_release, disable and reenable endpoint\n");
 		ret = usb_ep_disable(_adb_dev->ep_in);
 		if(ret){
 			printk("adb_release, usb_ep_disable fail,%d\n", ret);
@@ -497,8 +583,8 @@
 			WARN_ON(1);
 		}		
 	}
-	if(atomic_read(&_adb_dev->read_excl)){		
-		printk("adb_release, disable and reenable endpoint");
+	//if(atomic_read(&_adb_dev->read_excl)){		
+		printk("adb_release, disable and reenable ep_out\n");
 		ret = usb_ep_disable(_adb_dev->ep_out);
 		if(ret){
 			printk("adb_release, usb_ep_disable fail,%d\n", ret);
@@ -510,8 +596,16 @@
 			WARN_ON(1);
 		}
 
+		adb_unlock(&_adb_dev->open_excl);
+	//}
+#ifdef _USE_VEHICLE_DC	
+	if(_adb_dev->agent_state){
+		wake_up(&_adb_dev->agt_start_wait);
+		printk("\n now is agent mode ,switch\n");
+		
 	}
-	adb_unlock(&_adb_dev->open_excl);
+#endif	
+
 	return 0;
 }
 
@@ -709,6 +803,55 @@
 	return usb_add_function(c, &dev->function);
 }
 
+
+void adb_online_inform_work(struct work_struct *work)
+{
+	struct adb_dev	*dev = container_of(work, struct adb_dev, online_inform);
+
+	kobject_uevent(&adb_device.this_device->kobj, KOBJ_ONLINE);
+}
+
+void adb_offline_inform_work(struct work_struct *work)
+{
+	struct adb_dev	*dev = container_of(work, struct adb_dev, offline_inform);
+
+	kobject_uevent(&adb_device.this_device->kobj,  KOBJ_OFFLINE);
+}
+
+
+
+#ifdef _USE_VEHICLE_DC
+static ssize_t agent_state_show(struct device *_dev,
+				struct device_attribute *attr, char *buf)
+{
+	if(_adb_dev){	
+		return sprintf(buf, "\n agent_state = %d\n",_adb_dev->agent_state);
+	}
+	
+	return sprintf(buf, "\n _adb_dev is NULL agent_state = NULL\n");
+}
+
+static ssize_t agent_state_store(struct device *_dev,
+				 struct device_attribute *attr,
+				 const char *buf, size_t count)
+{
+ 	int flag = 0;
+	flag = simple_strtoul(buf, NULL, 16);
+	if(_adb_dev){
+		if(_adb_dev->agent_state == flag){
+			printk("agent_state_store, already in this state,don't change again\n");
+			return count;
+		}
+		_adb_dev->agent_state = (flag ? 1 : 0);
+		atomic_set(&_adb_dev->agent_switch, 1);
+		wake_up(&_adb_dev->agent_monitor_wq);
+	}
+
+	return count;
+}
+DEVICE_ATTR(agent_state, S_IRUGO | S_IWUSR, agent_state_show,
+	    agent_state_store);
+#endif
 static int adb_setup(void)
 {
 	struct adb_dev *dev;
@@ -727,7 +870,9 @@
 	atomic_set(&dev->read_excl, 0);
 	atomic_set(&dev->write_excl, 0);
 	atomic_set(&dev->enable_excl, 0);
-
+	
+	INIT_WORK(&dev->online_inform, adb_online_inform_work);
+	INIT_WORK(&dev->offline_inform, adb_offline_inform_work);
 	INIT_LIST_HEAD(&dev->tx_idle);
 
 	_adb_dev = dev;
@@ -736,16 +881,30 @@
 	if (ret)
 		goto err;
 
+#ifdef _USE_VEHICLE_DC
+	ret = device_create_file(adb_device.this_device, &dev_attr_agent_state);
+	if(ret){
+		printk(KERN_ERR "adb create attr_agent_state fail\n");
+	}
+	ret = adb_server_init(dev);
+#endif	
 	return 0;
 
 err:
 	kfree(dev);
+	_adb_dev = NULL;
 	printk(KERN_ERR "adb gadget driver failed to initialize\n");
 	return ret;
 }
 
 static void adb_cleanup(void)
 {
+
+	flush_work_sync(&_adb_dev->online_inform);
+	flush_work_sync(&_adb_dev->offline_inform);
+#ifdef _USE_VEHICLE_DC
+	adb_server_release();
+#endif
 	misc_deregister(&adb_device);
 
 	kfree(_adb_dev);
diff --git a/ap/os/linux/linux-3.4.x/drivers/usb/gadget/usb_netlink.c b/ap/os/linux/linux-3.4.x/drivers/usb/gadget/usb_netlink.c
index 649d5ec..232ca1a 100755
--- a/ap/os/linux/linux-3.4.x/drivers/usb/gadget/usb_netlink.c
+++ b/ap/os/linux/linux-3.4.x/drivers/usb/gadget/usb_netlink.c
@@ -19,8 +19,16 @@
 #include <linux/android_notify.h>

 #include <mach/highspeed_debug.h>

 #include <mach/iomap.h>

+#include "pub_debug_info.h"

 

 extern int detected_charger(void);

+#ifdef _USE_VEHICLE_DC

+extern int usb_server_init(void);

+

+extern int adb_enable_rpmsg_agent(int flag);

+extern int adb_rpmsg_agent_state(void);

+#endif

+

 static unsigned int charger_plug = 0;

 static unsigned int usb_plug = 0;

 //static unsigned int sys_id = 1;//0 is windows, other value not windows(mac or linux)

@@ -31,6 +39,7 @@
 EXPORT_SYMBOL_GPL(usb_printk_en);

 unsigned int mmc_printk_en = 1;

 unsigned int gmac_printk_en = 1;

+unsigned int adb_agent_state = 0;

 

 unsigned int force_net = 0;

 unsigned int set_panic = 0;

@@ -62,6 +71,7 @@
 #define RAMDUMP_FLAG		"ramdumpFlag"

 #define RNDIS_VPLST_MAX     "lstmax"

 #define USB_GPIO_DETECT_ENABLE "gpio_detect"

+#define USB_ADB_AGENT "adb_agent"

 

 #define USB_LOG_MEM_SIZE	(15*1000)

 #define USB_LOG_MAX_SIZE	512

@@ -161,6 +171,12 @@
 		.mode = S_IRUGO|S_IWUSR,

 };

 

+

+static struct attribute usb_adb_agent_attr =

+{

+		.name = "adb_agent",

+		.mode = S_IRUGO|S_IWUSR,

+};

 static struct attribute *usb_status_attrs[] =

 {

 	&charger_plug_attr,

@@ -178,6 +194,7 @@
 	&set_panic_attr,

 	&list_max_attr,

 	&usb_gpio_detect_enable_attr,

+	&usb_adb_agent_attr,

        NULL,

 };

 

@@ -239,6 +256,93 @@
 /* MODSµ¯¹âÅÌÑÓʱһ°ã·¶Î§Îª3~5Ã룬ÔÝÉèΪ3Ãë */

 #define USB_MODS_TIMER_EXPIRES 	3000 

 

+void usb_record_dbginfo(usb_dbginfo_type inf_type, int status, int info_value)

+{

+	char *str_info = NULL;

+	switch(inf_type){

+		case USB_DEV_PLUGIN:

+			str_info = "plugin";

+			break;

+		case USB_DEV_PLUGOUT:

+			str_info = "plugout";

+			break;

+		case USB_SWITCH_TO_USER:

+			str_info = "to user mode";

+			break;

+		case USB_SWITCH_TO_DEBUG:

+			str_info = "to dbg mode";

+			break;

+		case USB_SWITCH_TO_FACTORY:

+			str_info = "to factory mode";

+			break;

+		case USB_SWITCH_TO_AMT:

+			str_info = "to amt mode";

+			break;

+		case USB_DEV_EXCEPT_RESET:

+			str_info = "except reset";

+			break;

+		case USB_DEV_SUSPEND:

+			str_info = "suspend";

+			break;

+		case USB_DEV_RESUME:

+			str_info = "resume";

+			break;

+		case USB_USB_SUSPEND:

+			str_info = " usb suspend";

+			break;

+		case USB_USB_RESUME:

+			str_info = " usb resume";

+			break;

+		case USB_USB_REMOTE_WAKEUP:

+			str_info = " usb rmt wakeup";

+			break;

+		case USB_USB_RESET:

+			str_info = " usb reset";

+			break;

+		case USB_USB_ENUM_DONE:

+			str_info = "usb enum done";

+			break;

+		case USB_DEV_ENABLE:

+			str_info = "enable";

+			break;

+		case USB_DEV_DISABLE:

+			str_info = "disable";

+			break;

+		case USB_DEV_OPEN:

+			str_info = "open";

+			break;

+		case USB_DEV_CLOSE:

+			str_info = "close";

+			break;

+		case USB_DEV_ONLINE:

+			str_info = "online";

+			break;

+		case USB_DEV_OFFLINE:

+			str_info = "offline";

+			break;

+			

+		default :

+			break;

+	}

+	if(status && info_value){

+		sc_debug_info_record(MODULE_ID_AP_USB, "%s,st:%d,v:%d\n", str_info, status, info_value);

+		return;

+	}

+	

+	if(status){

+		sc_debug_info_record(MODULE_ID_AP_USB, "%s,st:%d\n", str_info, status);

+		return;

+	}

+	

+	if(info_value){

+		sc_debug_info_record(MODULE_ID_AP_USB, "%s,v:%d\n", str_info, info_value);

+		return;

+	}

+	

+	sc_debug_info_record(MODULE_ID_AP_USB, "%s\n", str_info);

+

+}

+EXPORT_SYMBOL_GPL(usb_record_dbginfo);

 

 int usb_do_reject_cdrom(void)

 {

@@ -423,6 +527,11 @@
 	  		 sprintf(buf, "%u",rndis_vplist_max);

 	  } else if(!strcmp(attr->name, USB_GPIO_DETECT_ENABLE)){

 	  		 sprintf(buf, "%u",usb_gpio_detect_enable);

+	  }else if(!strcmp(attr->name, USB_ADB_AGENT)){

+#ifdef _USE_VEHICLE_DC

+			  adb_agent_state = adb_rpmsg_agent_state();

+	  		 sprintf(buf, "%u",adb_agent_state);

+#endif			 

 	  } 	  

 

       return strlen(buf);

@@ -468,6 +577,11 @@
 		rndis_vplist_max =value;

 	}else if(!strcmp(attr->name,USB_GPIO_DETECT_ENABLE)){

 		usb_gpio_detect_enable =value;

+	}else if(!strcmp(attr->name,USB_ADB_AGENT)){

+		adb_agent_state =value;

+#ifdef _USE_VEHICLE_DC

+		adb_enable_rpmsg_agent(adb_agent_state);

+#endif

 	}

 	

 	return size;

@@ -626,7 +740,9 @@
   // usbkobj = kobject_create_and_add("usbconfig", &kset_p->kobj);

   // usbkobj->kset = kset_p;

    //usbkobj->ktype = &ktype;

-    

+#ifdef _USE_VEHICLE_DC   

+    usb_server_init();

+#endif

    return ret;

 }

 

@@ -795,6 +911,34 @@
 }

 EXPORT_SYMBOL_GPL(usb_dbg_showLog);

 

+#ifdef _USE_VEHICLE_DC

+void usb_set_rpmsg_resp(int type, char*resp)

+{

+

+	usb_rpmsg_cmd *t_resp = (usb_rpmsg_cmd *)resp;

+	

+	switch(type){

+		case USB_RPMSG_GET_USB_STATE:

+			t_resp->cmd = USB_RPMSG_GET_USB_STATE;

+			//sprintf(t_resp->param, "%s", );

+			

+			break;

+		case USB_RPMSG_GET_USB_LINK_STATE:

+			t_resp->cmd = USB_RPMSG_GET_USB_LINK_STATE;

+			//sprintf(t_resp->param, "%s", );

+			

+			break;

+			//usb_set_rpmsg_resp(t_cmd->cmd, usb_resp);

+		//case:

+		//	break;

+		default:

+			break;

+	}

+}

+EXPORT_SYMBOL_GPL(usb_set_rpmsg_resp);

+#endif

+

+

 void usb_dbg_ep0reg(void)

 {

 #if 0

diff --git a/ap/os/linux/linux-3.4.x/drivers/usb/gadget/usb_rpmsg_server.c b/ap/os/linux/linux-3.4.x/drivers/usb/gadget/usb_rpmsg_server.c
new file mode 100644
index 0000000..b6a86e3
--- /dev/null
+++ b/ap/os/linux/linux-3.4.x/drivers/usb/gadget/usb_rpmsg_server.c
@@ -0,0 +1,301 @@
+/*
+ * usb attributes rpmsg server
+ *
+ * Copyright (C) 2023 Sanechips, Inc.
+ * Author: Guo Shanning <10117327@sanechips.com.cn>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/wait.h>
+#include <linux/err.h>
+#include <linux/interrupt.h>
+#include <linux/kthread.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/device.h>
+#include <linux/soc/zte/rpm/rpmsg.h>
+#include <linux/soc/zte/rpm/icp.h>
+#include <linux/android_notify.h>
+
+//#define ADB_BULK_BUFFER_SIZE           4096
+#define USB_AGENT_BUF_SIZE           256
+#define USB_RPMSG_CH                  channel_5
+
+extern void usb_set_rpmsg_resp(int type, char*resp);
+extern void android_set_rpmsg_resp(int type, char*resp);
+
+struct task_struct	*rpmsg_thread;
+wait_queue_head_t usb_agt_wq;
+wait_queue_head_t usb_write_wq;
+atomic_t rpmsg_flag;
+atomic_t write_busy;
+
+char usb_msg[USB_AGENT_BUF_SIZE] = {0};
+char usb_resp[USB_AGENT_BUF_SIZE] = {0};
+#if 0
+#define USB_RPMSG_RESP  1
+#define USB_RPMSG_NOTIFY  2
+
+typedef enum __usb_rpmsg_cmd_type{
+	USB_RPMSG_CMD = 0,
+	USB_RPMSG_GET_NET_TYPE = USB_RPMSG_CMD,
+	USB_RPMSG_GET_USB_SPEED,
+	USB_RPMSG_GET_USB_STATE,
+	USB_RPMSG_GET_USB_LINK_STATE,
+	//USB_RPMSG_GET_,
+	//USB_RPMSG_GET_,
+	
+	USB_RPMSG_CMD_MAX,
+}e_usb_rpmsg_cmd_type;
+
+
+typedef struct __usb_cmd_msg{
+	int cmd;
+	char *param;	
+}usb_rpmsg_cmd;
+
+#endif
+
+int usb_rpmsg2ap(void *buf, unsigned int len);
+
+
+void usb_rpmsg_notify_ap(usb_rpmsg_cmd *notify)
+{
+	usb_rpmsg_cmd *t_data = NULL;
+	
+	memset(usb_resp, 0, USB_AGENT_BUF_SIZE);
+	t_data = (usb_rpmsg_cmd *)usb_resp;
+	t_data->cmd = notify->cmd;
+	memcpy(t_data->param, notify->param, strlen(notify->param));
+	
+	usb_rpmsg2ap(usb_resp, strlen(usb_resp));
+}
+EXPORT_SYMBOL_GPL(usb_rpmsg_notify_ap);
+
+
+int usb_dispatch_cmd(char * buf, int len)
+{
+	int ret = 0;
+	memset(usb_resp, 0, USB_AGENT_BUF_SIZE);
+	wmb();
+	usb_rpmsg_cmd *resp = (usb_rpmsg_cmd *)usb_resp;
+
+			//printk("usb_dispatch_cmd, len:%d\n", len);
+
+	usb_rpmsg_cmd *t_cmd = (usb_rpmsg_cmd *)buf;
+	if(t_cmd->cmd < USB_RPMSG_CMD || t_cmd->cmd >= USB_RPMSG_CMD_MAX){
+		printk("usb_dispatch_cmd, invalid cmd\n");
+		return -1;
+	}
+	
+#if 1
+	usb_set_rpmsg_resp(t_cmd->cmd, usb_resp);
+	android_set_rpmsg_resp(t_cmd->cmd, usb_resp);
+#else
+
+	switch(t_cmd->cmd){
+		case USB_RPMSG_GET_NET_TYPE:
+		case USB_RPMSG_GET_USB_SPEED:
+		case USB_RPMSG_GET_USB_STATE:
+		case USB_RPMSG_GET_USB_LINK_STATE:
+			usb_set_rpmsg_resp(t_cmd->cmd, usb_resp);
+		//case:
+			break;
+		default:
+			break;
+	}
+#endif
+	
+	return usb_rpmsg2ap(usb_resp, 4+strlen(resp->param));	
+}
+
+
+void usb_rpmsg_from_ap(void *buf, unsigned int len)
+{
+	int i;
+	unsigned char *data;
+	
+	char*tmp= (char*)buf;
+
+
+	if (len==0){
+		printk("usb_rpmsg_from_ap, len 0, notify \n ", len);
+		atomic_set(&write_busy, 0);
+		wake_up(&usb_write_wq);
+		return ;
+	}
+	//printk("usb_rpmsg_from_ap, len %d, \n ", len);
+#if 0
+	if(len < 32){
+		printk(" adb_recv_from_ap, send to usb start:\n");
+		for(i = 0; i < len; i++){
+			printk(" %x", tmp[i]);
+			if((i != 0) &&(i % 16) == 0)
+				printk("\n");
+		}
+		printk("\n adb_recv_from_ap, send to usb end\n");
+	}
+#endif
+	memcpy(usb_msg,buf, len);
+	//usb_rpmsg2ap((char *)buf, len);
+	
+	atomic_set(&rpmsg_flag, 1);
+	wake_up(&usb_agt_wq);
+} 
+
+
+int usb_rpmsg2ap(void *buf, unsigned int len)
+{
+	int ret = 0;
+	int i;
+	T_ZDrvRpMsg_Msg rpmsg;
+	char *tmp = (char *)buf;
+	
+	int transfer_cnt, total_cnt; 
+	
+	
+	rpmsg.actorID =  CAP_ID;
+	rpmsg.chID = USB_RPMSG_CH;	
+	rpmsg.flag |= 1;
+	
+	printk("usb_rpmsg2ap datalen:%d\n",  len);
+#if 0
+	if(len && len < 32){
+		printk(" data from usb, send to cap start:\n");
+		for(i = 0; i < len; i++){
+			printk(" %x", tmp[i]);
+			if((i != 0) &&(i % 16) == 0)
+				printk("\n");
+		}
+		printk("\n data from usb, send to cap end\n");
+	}
+#endif	
+	if(len == 0){//just send notify
+		rpmsg.len = len;
+		ret = zDrvRpMsg_Write_Cap(&rpmsg);
+		if(ret < 0)
+			printk("usb_rpmsg2ap notify send fail, ret:%d\n", ret);	
+		return ret;
+	}
+	total_cnt = len;
+#if 1	
+		rpmsg.len = len;
+		rpmsg.buf = usb_resp;
+		
+		ret = zDrvRpMsg_Write_Cap(&rpmsg);
+		if(rpmsg.len != ret){
+			atomic_set(&write_busy, 0);
+			printk("[usb_rpmsg2ap] msg send error:(%d)", ret);
+			return ret;
+		}		
+#else
+	while(total_cnt){
+		transfer_cnt = total_cnt > USB_AGENT_BUF_SIZE ? USB_AGENT_BUF_SIZE: total_cnt;
+		memcpy(usb_resp, tmp, transfer_cnt);
+		rpmsg.len = transfer_cnt;
+		rpmsg.buf = usb_resp;
+		
+		ret = zDrvRpMsg_Write_Cap(&rpmsg);
+		if(rpmsg.len != ret){
+			atomic_set(&write_busy, 0);
+			printk("[usb_rpmsg2ap] msg send error:(%d)", ret);
+			return ret;
+		}
+		//should wait for ap recv ok
+			printk("usb_rpmsg2ap, brfore agt_write_wq len:%d, write_busy:%d\n",  transfer_cnt, atomic_read(&write_busy));
+		ret = wait_event_interruptible(usb_write_wq, !atomic_read(&write_busy));
+		printk("usb_rpmsg2ap, after agt_write_wq len:%d, write_busy:%d\n",  transfer_cnt, atomic_read(&write_busy));
+
+		if (ret < 0) {
+			break;
+		}
+		total_cnt -= transfer_cnt;
+		tmp += transfer_cnt;
+		
+	}
+#endif	
+	atomic_set(&write_busy, 0);
+	
+	return 0;  
+}
+
+
+void usb_rpmsg_thread(void *ptr)
+{
+
+	unsigned long			flags;
+	
+	int r , xfer;
+	int ret = 0;
+	r = xfer = 0;
+	usb_rpmsg_cmd *t_cmd = NULL;
+	
+	while(!kthread_should_stop()){	
+		/* we will block until we're online */
+		
+		//printk("usb_rpmsg_thread: waiting foragt_start_wait\n");
+		ret = wait_event_interruptible(usb_agt_wq,
+				(atomic_read(&rpmsg_flag) ||kthread_should_stop()));
+		if (ret < 0) {
+			//adb_unlock(&dev->read_excl);
+			return ret;
+		}
+			
+		
+		if(kthread_should_stop())
+		{
+			printk("unbind thread stop");
+			break;
+		}
+		
+		//printk("usb_rpmsg_thread: now usb_dispatch_cmd\n");
+
+		atomic_set(&rpmsg_flag, 0);
+		t_cmd = (usb_rpmsg_cmd *)usb_msg;
+		//android_set_rpmsg_resp(t_cmd->cmd, usb_resp);
+		usb_dispatch_cmd(usb_msg, 4+ strlen(t_cmd->param));
+	}
+}
+
+
+
+int usb_server_init(void)
+{
+	int ret = 0;
+	
+	atomic_set(&rpmsg_flag, 0);
+	atomic_set(&write_busy, 0);
+	init_waitqueue_head(&usb_agt_wq);
+	
+	/* create channel */
+	if(zDrvRpMsg_CreateChannel_Cap(CAP_ID, USB_RPMSG_CH,USB_AGENT_BUF_SIZE))
+	{
+		printk("[usb_server_init] Failed create psm icp channel ! \n");
+		BUG();
+	}
+	
+	//printk("[usb_server_init] Success create psm icp channel!!! \n");
+	zDrvRpMsg_RegCallBack_Cap(CAP_ID, USB_RPMSG_CH, usb_rpmsg_from_ap);
+	
+	rpmsg_thread = kthread_run(usb_rpmsg_thread, NULL, "usb_rpmsg_thread");
+	BUG_ON(IS_ERR(rpmsg_thread));
+#if 0	
+	dev->agent_monitor_thread = kthread_run(adb_agent_monitor_thread, (unsigned long)dev+1, "adb_agent_monitor");
+	BUG_ON(IS_ERR(dev->agent_monitor_thread));
+#endif	
+	memset(usb_msg, 0, USB_AGENT_BUF_SIZE);
+}
+EXPORT_SYMBOL_GPL(usb_server_init);
+
diff --git a/ap/os/linux/linux-3.4.x/drivers/watchdog/zx_soft_wdt.c b/ap/os/linux/linux-3.4.x/drivers/watchdog/zx_soft_wdt.c
index 7fccf2c..101048d 100644
--- a/ap/os/linux/linux-3.4.x/drivers/watchdog/zx_soft_wdt.c
+++ b/ap/os/linux/linux-3.4.x/drivers/watchdog/zx_soft_wdt.c
@@ -15,6 +15,7 @@
 #include <linux/cpps_init2.h>

 #include <linux/cp_types.h>

 #include "NvParam_drv.h"

+#include "pub_debug_info.h"

 

 #define WDT_DEFAULT 	(30)

 #define WDT_INT_TIME 	(5)

@@ -49,10 +50,24 @@
 #define RM_WDT_SET_EN_REG   (ZX_RM_WDT_BASE + 0x18)  /* Watchdog enable refresh work clock domain register */

 #define RM_WDT_START_REG    (ZX_RM_WDT_BASE + 0x1c)  /* Watchdog start or stop register */

 

+#define WDT_REBOOT_RECORD_BASE	(ZX_IRAM1_BASE+0x2410)

+#define START_UP_STATUS_BASE	(ZX_IRAM1_BASE+0x2420)

+#define USER_RESERVED_BASE	(ZX_IRAM1_BASE+0x2424)

+

 

 MODULE_AUTHOR("ZTE");

 MODULE_LICENSE("GPL");

 

+

+typedef enum _T_WdtId

+{

+	M0_WDT = 0,

+	PS_WDT,

+	AP_WDT,

+	PHY_WDT,

+	MAX_WDT

+} T_WdtId;

+

 /* Each of a wdt's open files has private_data pointing to soft_wdt_file_private */

 struct soft_wdt_file_private {

 	struct list_head list;

@@ -460,6 +475,42 @@
 	}

 }

 

+

+static void zx_reboot_reason(void)

+{

+	u32 wdt_reason=zx_read_reg(WDT_REBOOT_RECORD_BASE);  //set at rpm

+	u32 status=zx_read_reg(START_UP_STATUS_BASE); //set at uboot

+	u32 user=zx_read_reg(USER_RESERVED_BASE); //set at uboot

+	

+	char reason[20] ={0};

+	

+	switch (wdt_reason) 

+	{

+		case PS_WDT:

+			memcpy(reason, "ps wdt reboot!\n", 20);

+			break;

+		case AP_WDT:

+			memcpy(reason, "ap wdt reboot!\n", 20);

+			break;

+		case PHY_WDT:

+			memcpy(reason, "phy wdt reboot!\n", 20);

+			break;			

+		case MAX_WDT:

+			memcpy(reason, "rpm wdt reboot!\n", 20);

+			break;	

+		default:

+			memcpy(reason, "not wdt reboot!\n", 20);			

+			break;	

+	}

+

+	sc_debug_info_record(MODULE_ID_AP_REBOOT, "%s\n", reason);

+	sc_debug_info_record(MODULE_ID_AP_REBOOT, "START_UP_STATUS:%x; USER_RESERVED:%x\n", status, user);

+	printk( "%s", reason);

+	printk( "START_UP_STATUS:%x; USER_RESERVED:%x\n", status, user);	

+	

+}

+

+

 #define TEST_CNTTT  20

 volatile u32 test_flagggg1=0;

 volatile u32 test_flagggg2=0;

@@ -563,9 +614,12 @@
 		if (zx_wdt_get_global_cnt() > priv->handle_timeout) {

 		    priv->handle_timeout_cnt++;

 

-		    if (priv->handle_timeout_cnt >= 3) {

-    			printk(KERN_ERR"[zx soft wdt]: zx soft wdt handle time-out(thread name:%s, timeout val = %d)!\n", priv->current_task->comm, priv->handle_timeout);

-    			BUG();

+			if (priv->handle_timeout_cnt >= 3) {

+				printk(KERN_ERR"[zx soft wdt]: zx soft wdt handle time-out(thread name:%s, timeout val = %d)!\n", priv->current_task->comm, priv->handle_timeout);

+				#ifdef CONFIG_PREEMPT_RT_FULL

+				zx_wdt_m0_stop();

+				#endif		

+				panic("zx_wdt_process_handle!!!!!\n ");

 			}

 		}

 	}

@@ -693,6 +747,8 @@
 {

 	int err = 0;

 

+	zx_reboot_reason();

+

 #ifdef CONFIG_PREEMPT_RT_FULL

 #ifndef CONFIG_ARCH_ZX297520V3_CAP

 	err = zx_wdt_get_nv();

@@ -737,7 +793,7 @@
 #endif

 

 #if defined(_USE_CAP_SYS) && !defined(CONFIG_ARCH_ZX297520V3_CAP)

-	err = zDrvRpMsg_CreateChannel_Cap(CAP_ID, channel_2, 0x10);

+	err = zDrvRpMsg_CreateChannel_Cap(CAP_ID, channel_2, 0x30);

 	if (err) {

 		printk(KERN_ERR"[zx soft wdt]: Fail to AP 2 CAP create chan (err=%d)!\n", err);

 		return -EPERM;

diff --git a/ap/os/linux/linux-3.4.x/include/linux/android_notify.h b/ap/os/linux/linux-3.4.x/include/linux/android_notify.h
index 9e3b33b..f505c4e 100644
--- a/ap/os/linux/linux-3.4.x/include/linux/android_notify.h
+++ b/ap/os/linux/linux-3.4.x/include/linux/android_notify.h
@@ -32,12 +32,60 @@
 	USB_EVNET_NUM,

 }usb_notify_event;

 

+typedef enum{

+	USB_DEV_PLUGIN 	= 0,

+	USB_DEV_PLUGOUT,

+	USB_SWITCH_TO_USER,

+	USB_SWITCH_TO_DEBUG,

+	USB_SWITCH_TO_FACTORY,

+	USB_SWITCH_TO_AMT,

+	USB_DEV_EXCEPT_RESET,

+	USB_DEV_SUSPEND,

+	USB_DEV_RESUME,

+	USB_USB_SUSPEND,

+	USB_USB_RESUME,

+	USB_USB_REMOTE_WAKEUP,

+	USB_USB_RESET,

+	USB_USB_ENUM_DONE,

+	USB_DEV_ENABLE,

+	USB_DEV_DISABLE,

+	USB_DEV_OPEN,

+	USB_DEV_CLOSE,

+	USB_DEV_ONLINE,

+	USB_DEV_OFFLINE,

+	USB_DBGINFO_NUM,

+}usb_dbginfo_type;

 void usb_notify_up(usb_notify_event notify_type, void* puf);

 void usb_set_sys_id(int sysId);

 void usb_set_ms_auto_eject(int flag);

 int usb_get_ms_auto_reject(void);

 int is_reject_cdrom(void);

 

+#ifdef _USE_VEHICLE_DC

+

+#define USB_RPMSG_RESP  1

+#define USB_RPMSG_NOTIFY  2

+

+typedef enum __usb_rpmsg_cmd_type{

+	USB_RPMSG_CMD = 0,

+	USB_RPMSG_GET_NET_TYPE = USB_RPMSG_CMD,

+	USB_RPMSG_GET_USB_SPEED,

+	USB_RPMSG_GET_USB_STATE,

+	USB_RPMSG_GET_USB_LINK_STATE,

+	//USB_RPMSG_GET_,

+	//USB_RPMSG_GET_,

+	

+	USB_RPMSG_CMD_MAX,

+}e_usb_rpmsg_cmd_type;

+

+

+typedef struct __usb_cmd_msg{

+	int cmd;

+	char param[0];	

+}usb_rpmsg_cmd;

+#endif

+

+

 

 #endif

 

diff --git a/ap/os/linux/linux-3.4.x/include/linux/module.h b/ap/os/linux/linux-3.4.x/include/linux/module.h
index c9822da..04380b0 100755
--- a/ap/os/linux/linux-3.4.x/include/linux/module.h
+++ b/ap/os/linux/linux-3.4.x/include/linux/module.h
@@ -721,13 +721,15 @@
     int (*halVoice_Close3G)(void); 	
 	int (*zDrv_Audio_Printf)(void *, ...);
 	int (*zDrvVp_SetTone_Wrap)(int);
-	int (*zDrvVp_SetMute_Wrap)(int);
-	int (*zDrvVp_GetMute_Wrap)(void);
-	int (*zDrvVp_SetVol_Wrap)(int);
-	int (*zDrvVp_GetVol_Wrap)(void);
+	int (*zDrvVp_SetMute_Wrap)(int);//tx mute
+	int (*zDrvVp_GetMute_Wrap)(void);//tx mute
+	int (*zDrvVp_SetVol_Wrap)(int);//rx vol
+	int (*zDrvVp_GetVol_Wrap)(void);//rx vol
 	void (*zDrvVp_SetDtmfMute_Wrap)(void);
 	int (*zDrvVp_SetTxVol_Wrap)(int);
 	int (*zDrvVp_GetTxVol_Wrap)(void);	
+	int (*zDrvVp_SetRxMute_Wrap)(int);
+	int (*zDrvVp_GetRxMute_Wrap)(void);
 
 	int (*zDrvVp_GetPath_Wrap)(void);
 	int (*zDrvVp_Loop)(int);
diff --git a/ap/os/linux/linux-3.4.x/include/linux/skbuff.h b/ap/os/linux/linux-3.4.x/include/linux/skbuff.h
index 8a6f5a6..3a6199c 100755
--- a/ap/os/linux/linux-3.4.x/include/linux/skbuff.h
+++ b/ap/os/linux/linux-3.4.x/include/linux/skbuff.h
@@ -298,6 +298,32 @@
 /* This data is invariant across clones and lives at
  * the end of the header data, ie. at skb->end.
  */
+#if _USE_VEHICLE_DC
+struct skb_shared_info {
+	unsigned short  gso_type;//for 5.10
+	unsigned char	nr_frags;
+	__u8		tx_flags;
+	unsigned short	gso_size;
+	/* Warning: this field is not always filled in (UFO)! */
+	unsigned short	gso_segs;
+	struct sk_buff	*frag_list;
+	struct skb_shared_hwtstamps hwtstamps;
+
+	/*
+	 * Warning : all fields before dataref are cleared in __alloc_skb()
+	 */
+	atomic_t	dataref;
+
+	/* Intermediate layers must ensure that destructor_arg
+	 * remains valid until skb destructor */
+	void *		destructor_arg;
+
+	/* must be last field, see pskb_expand_head() */
+	skb_frag_t	frags[MAX_SKB_FRAGS];
+	__be32          ip6_frag_id;//for 5.10
+	unsigned char	__unused[64];//for 5.10 sizeof 184->248
+};
+#else
 struct skb_shared_info {
 	unsigned char	nr_frags;
 	__u8		tx_flags;
@@ -321,6 +347,7 @@
 	/* must be last field, see pskb_expand_head() */
 	skb_frag_t	frags[MAX_SKB_FRAGS];
 };
+#endif
 
 /* We divide dataref into two halves.  The higher 16 bits hold references
  * to the payload part of skb->data.  The lower 16 bits hold references to
@@ -373,11 +400,6 @@
 #define NET_SKBUFF_NF_DEFRAG_NEEDED 1
 #endif
 
-//2017.6.3  add by linxu the last packet will tigger transmit
-#ifndef LAST_PACKET_TRANSMIT
-#define LAST_PACKET_TRANSMIT 1
-#endif
-
 /** 
  *	struct sk_buff - socket buffer
  *	@next: Next buffer in list
@@ -537,9 +559,8 @@
 		__u32		dropcount;
 		__u32		reserved_tailroom;
 	};
-#ifdef LAST_PACKET_TRANSMIT
-	unsigned char		 last_packet_flag; //2017.6.3  add by linxu the last packet will tigger transmit
-#endif
+	void * capHead;
+	unsigned char		 isTocap; //µ±Îª1ʱ£¬±íʾdataÒÑת·¢capºË£¬²»ÓÃÊÍ·Å
 	//sunquan£¬Á㿽±´¼°cache»úÖÆ
 	unsigned char		 isExtern;  //µ±Îª1ʱ£¬±íʾdataÀ´Ô´ÓÚÍⲿºË£»
 	unsigned char		 isFastnat; //µ±Îª1ʱ£¬±íʾ¸ÃÊý¾Ý°ü³É¹¦½øÐÐת·¢Àà¿ìËÙת·¢£»
diff --git a/ap/os/linux/linux-3.4.x/include/linux/soc/zte/pm/drv_idle.h b/ap/os/linux/linux-3.4.x/include/linux/soc/zte/pm/drv_idle.h
index ef50fc9..c597cdb 100755
--- a/ap/os/linux/linux-3.4.x/include/linux/soc/zte/pm/drv_idle.h
+++ b/ap/os/linux/linux-3.4.x/include/linux/soc/zte/pm/drv_idle.h
@@ -43,6 +43,7 @@
 	IDLE_FLAG_CAM,
 	IDLE_FLAG_XP2XP,
 	IDLE_FLAG_CODEC,
+	IDLE_FLAG_VOICE,
 
 	IDLE_FLAG_MAX
 
diff --git a/ap/os/linux/linux-3.4.x/include/linux/volte_drv.h b/ap/os/linux/linux-3.4.x/include/linux/volte_drv.h
index 010d9ac..27e6d17 100755
--- a/ap/os/linux/linux-3.4.x/include/linux/volte_drv.h
+++ b/ap/os/linux/linux-3.4.x/include/linux/volte_drv.h
@@ -85,6 +85,17 @@
 #define VOICE_IOCTL_GET_SLIC_USE_FLAG	_IOR ('v', 12, int)
 #define VOICE_IOCTL_VPLOOP	_IOW('v', 13, int)
 
+#ifdef _USE_VEHICLE_DC
+#define VOICE_IOCTL_SET_VOL	_IOW('v', 14, int)
+#define VOICE_IOCTL_GET_VOL	_IOR('v', 15, int) 
+
+#define VOICE_IOCTL_SET_MUTE	_IOW('v', 16, bool)
+#define VOICE_IOCTL_GET_MUTE	_IOR('v', 17, bool)
+
+#define VOICE_IOCTL_SET_PATH	_IOW('v', 18, int)
+#define VOICE_IOCTL_GET_PATH	_IOR('v', 19, int) 
+#endif
+
 #ifdef __KERNEL__
 #define  print_audio(fmt, ...)  \
 		printk(fmt, ##__VA_ARGS__)
diff --git a/ap/os/linux/linux-3.4.x/include/sound/zx29_snd_platform.h b/ap/os/linux/linux-3.4.x/include/sound/zx29_snd_platform.h
index 5a71fe0..5957903 100644
--- a/ap/os/linux/linux-3.4.x/include/sound/zx29_snd_platform.h
+++ b/ap/os/linux/linux-3.4.x/include/sound/zx29_snd_platform.h
@@ -77,6 +77,20 @@
 #define ZX29_SND_CODEC_PDATA  NULL

 

 #endif

+

+#if (defined CONFIG_SND_SOC_DUMMY) || (defined CONFIG_SND_SOC_DUMMY_MODULE)

+

+#include "../../../sound/soc/codecs/tlv320aic31xx.h"

+

+#define CODEC_NAME  "dummy"

+#define CODEC_ADDR  0x18

+

+

+

+#define ZX29_SND_CODEC_PDATA NULL

+#endif

+

+

 //#define ZX29_SND_CODEC_PDATA (&snd_codec_pdata)

 

 //#define ZX29_SND_CODEC_PDATA  NULL     //ifndef snd_codec_pdata

@@ -146,6 +160,23 @@
 

 #endif

 

+#if (defined CONFIG_SND_SOC_ZX297520V3_DUMMY) || (defined CONFIG_SND_SOC_ZX297520V3_DUMMY_MODULE)

+

+#define  SND_MACHINE_PDEV_NAME  "zx29_snd_machine"

+

+struct zx297520v3_dummy_pdata {

+	int codec_refclk;

+};

+

+static struct zx297520v3_dummy_pdata snd_machine_pdata = {

+	//.codec_refclk = CODEC_REFCLK,

+};

+

+#endif

+

+

+

+

 #define  ZX29_SND_MACH_PDATA  (&snd_machine_pdata)

 

 //#define  ZX29_SND_MACH_PDATA  NULL    //ifndef snd_machine_pdata

diff --git a/ap/os/linux/linux-3.4.x/net/core/SI/ext_mem.c b/ap/os/linux/linux-3.4.x/net/core/SI/ext_mem.c
index ca37719..e11b918 100755
--- a/ap/os/linux/linux-3.4.x/net/core/SI/ext_mem.c
+++ b/ap/os/linux/linux-3.4.x/net/core/SI/ext_mem.c
@@ -403,6 +403,7 @@
 

 }

 

+extern void write_free_capbuf(void *head);

 //²Î¿¼pskb_expand_head½Ó¿Ú£¬¸Ã½Ó¿ÚÖ»ÄÜÔÚfastnatºÍfastbr½Ôʧ°Üºó²ÅÄܵ÷Ó㬷ñÔò»áÔì³ÉÔàÊý¾Ý£¬²¢Ó°ÏìÐÔÄÜ£»

 //¼ì²âµ½ÊÇÀ´×ÔCP²àµÄpsbuf¿Õ¼ä£¬ÉêÇë±ê×¼linuxµÄdataÄÚ´æ¿Õ¼ä,½øÈë±ê×¼IPЭÒéÕ»£¬´Ë´¦ÐèҪȷ±£network_headerµÈÆ«ÒÆÖµ¶¼ÕýÈ·

 int skb_copy_psbuf(struct sk_buff *skb, gfp_t gfp_mask)

@@ -414,7 +415,7 @@
 	bool fastpath;

 

 	//½öÊÊÓÃÓÚÀ´×ÔPSBUFµÄÄÚ´æµÄ¿½±´

-	if(skb->isExtern == 0)

+	if(skb->isExtern == 0 && skb->capHead == NULL)

 		return 0;

 	

 	if (skb_shared(skb))

@@ -462,6 +463,12 @@
 				fromext_free_track(skb);

 				skb_free_extpsbuf(skb);

 			}

+#if _USE_VEHICLE_DC

+			else if(skb->capHead)

+			{

+				write_free_capbuf(skb->capHead);

+			}

+#endif

 			else

 			{

 #if 0			

@@ -512,6 +519,7 @@
 	skb->isFastnat= 0;

 	skb->isFastbr= 0;

 	skb->isvlan= 0;

+	skb->capHead = NULL;

 	atomic_set(&skb_shinfo(skb)->dataref, 1);

 	skbdata_alloc_track(skb);

 	//print_sun(SUN_DBG,"copy  psbuf  to  skbuff !!! \n");

diff --git a/ap/os/linux/linux-3.4.x/net/core/SI/net_cache.c b/ap/os/linux/linux-3.4.x/net/core/SI/net_cache.c
index 3982265..4d20226 100755
--- a/ap/os/linux/linux-3.4.x/net/core/SI/net_cache.c
+++ b/ap/os/linux/linux-3.4.x/net/core/SI/net_cache.c
@@ -44,7 +44,7 @@
 

 extern void dma_cache_maint(const void *vir_addr, const void *phy_addr, size_t size, int direction);

 extern void copy_skb_header(struct sk_buff *new, const struct sk_buff *old);

-

+extern unsigned long virt_to_phys_cap(unsigned long virt);

 #ifndef WAN_NAME

 #define WAN_NAME	"wan"

 #endif

@@ -250,6 +250,11 @@
 

 unsigned long virtaddr_to_phys(unsigned long virt)

 {

+#if _USE_VEHICLE_DC

+	unsigned long addr = virt_to_phys_cap(virt);

+	if(addr)

+		return addr;

+#endif

 	return  __pa(virt);

 }

 EXPORT_SYMBOL(virtaddr_to_phys);

@@ -263,7 +268,7 @@
 void invalid_cache(unsigned char *data,int len)

 {

 	const void* phy_data;

-#ifndef CONFIG_PREEMPT_RT_FULL

+#if _USE_VEHICLE_DC //ndef CONFIG_PREEMPT_RT_FULL

 	phy_data = virtaddr_to_phys(data);

 #else

 	phy_data = data;

@@ -275,7 +280,7 @@
 void clean_cache(unsigned char *data,int len)

 {

 	const void* phy_data;

-#ifndef CONFIG_PREEMPT_RT_FULL

+#if _USE_VEHICLE_DC//ndef CONFIG_PREEMPT_RT_FULL

 	phy_data = virtaddr_to_phys(data);

 #else

 	phy_data = data;

diff --git a/ap/os/linux/linux-3.4.x/net/core/skbuff.c b/ap/os/linux/linux-3.4.x/net/core/skbuff.c
index a629894..4b7c797 100755
--- a/ap/os/linux/linux-3.4.x/net/core/skbuff.c
+++ b/ap/os/linux/linux-3.4.x/net/core/skbuff.c
@@ -495,7 +495,8 @@
 		skb_get(list);
 }
 
-
+extern void write_free_capbuf(void *head);
+extern void check_skb_test(struct sk_buff *skb);
 void skb_release_data(struct sk_buff *skb) 
 {
 	dump_net_stack(skb, 0);	
@@ -524,8 +525,14 @@
 
 		if (skb_has_frag_list(skb))
 			skb_drop_fraglist(skb);
-
-		
+#if _USE_VEHICLE_DC
+		//check_skb_test(skb);
+		if(skb->capHead){
+			write_free_capbuf(skb->capHead);
+			skb->capHead = NULL;
+			return;
+		}
+#endif
 		if(skb->isExtern == 0)
 		{	
 			skbdata_free_track(skb);
@@ -834,6 +841,7 @@
 	C(truesize);
 	
 	//¶ÔÓÚdataµÄÐÂÔöÊôÐÔ£¬skb¿½±´Ê±Òª¼Ì³Ð£¬ÒòΪÁ½¸öskbÖ¸ÏòµÄÊÇͬһ¸ödataÇøÓò
+	C(capHead);
 	C(isExtern);
 	C(isFastbr);
 	C(isFastnat);
@@ -1157,11 +1165,11 @@
 		fastpath = atomic_read(&skb_shinfo(skb)->dataref) == delta;
 	}
 #ifndef CONFIG_SPEED_OPT
-	if (fastpath && skb->isExtern==0 && size + sizeof(struct skb_shared_info) <= ksize(skb->head)) {
+	if (fastpath && skb->isExtern==0 && skb->capHead == NULL && size + sizeof(struct skb_shared_info) <= ksize(skb->head)) 
 #else
-	if (fastpath && skb->isExtern==0 && size + sizeof(struct skb_shared_info) <= skb_sys_pool_size(skb->head)) {
+	if (fastpath && skb->isExtern==0 && skb->capHead == NULL && size + sizeof(struct skb_shared_info) <= skb_sys_pool_size(skb->head)) 
 #endif
-		memmove(skb->head + size, skb_shinfo(skb),
+	{	memmove(skb->head + size, skb_shinfo(skb),
 			offsetof(struct skb_shared_info,
 				 frags[skb_shinfo(skb)->nr_frags]));
 		memmove(skb->head + nhead, skb->head,
@@ -1193,7 +1201,7 @@
 	       skb_shinfo(skb),
 	       offsetof(struct skb_shared_info, frags[skb_shinfo(skb)->nr_frags]));
 
-	if (fastpath) {
+	if (fastpath && skb->capHead == NULL) {
 		{
 			if(skb->isExtern == 1)
 			{
@@ -1246,6 +1254,7 @@
 	skb->cloned   = 0;
 	skb->hdr_len  = 0;
 	skb->nohdr    = 0;
+	skb->capHead = NULL;
 	skb->isExtern = 0;
 	skb->isFastnat= 0;
 	skb->isFastbr= 0;
diff --git a/ap/os/linux/linux-3.4.x/sound/soc/sanechips/Kconfig b/ap/os/linux/linux-3.4.x/sound/soc/sanechips/Kconfig
index ba6a099..b481212 100644
--- a/ap/os/linux/linux-3.4.x/sound/soc/sanechips/Kconfig
+++ b/ap/os/linux/linux-3.4.x/sound/soc/sanechips/Kconfig
@@ -20,6 +20,9 @@
 config SND_SOC_ZX297520V3_ES8312
 	tristate "SoC I2S Audio support for ZX297520V3 - ES8312"	
 	select SND_SOC_ES8312 if I2C
+config SND_SOC_ZX297520V3_DUMMY
+	tristate "SoC I2S Audio support for ZX297520V3 - DUMMY"	
+		select SND_SOC_DUMMY
 config SND_SOC_ZX_VOICE
 	tristate "SoC 2/3G Voice support"	
 	
@@ -49,3 +52,6 @@
 config SND_EXTRA_CTRL
 	tristate "Soc add extra snd controls"			
 
+config SND_SOC_DUMMY
+	tristate "Soc dummy codec"	
+
diff --git a/ap/os/linux/linux-3.4.x/sound/soc/sanechips/Makefile b/ap/os/linux/linux-3.4.x/sound/soc/sanechips/Makefile
index 71daf42..b509eb0 100644
--- a/ap/os/linux/linux-3.4.x/sound/soc/sanechips/Makefile
+++ b/ap/os/linux/linux-3.4.x/sound/soc/sanechips/Makefile
@@ -17,5 +17,7 @@
 obj-$(CONFIG_SND_SOC_ZX297520V3_ES8374) += snd-soc-zx297520v3-es8374.o
 snd-soc-zx297520v3-es8312-objs := zx297520v3_es8312.o
 obj-$(CONFIG_SND_SOC_ZX297520V3_ES8312) += snd-soc-zx297520v3-es8312.o
+snd-soc-zx297520v3-dummy-objs := zx297520v3_dummy.o
+obj-$(CONFIG_SND_SOC_ZX297520V3_DUMMY) += snd-soc-zx297520v3-dummy.o
 
 ccflags-y += -I/$(CP_ROOT_DIR)/ps/driver/inc/misc
diff --git a/ap/os/linux/linux-3.4.x/sound/soc/sanechips/zx297520v3_dummy.c b/ap/os/linux/linux-3.4.x/sound/soc/sanechips/zx297520v3_dummy.c
new file mode 100755
index 0000000..0124154
--- /dev/null
+++ b/ap/os/linux/linux-3.4.x/sound/soc/sanechips/zx297520v3_dummy.c
@@ -0,0 +1,629 @@
+/*
+ * zx297520v3_dummy.c  --  ZX297520v3_dummy ALSA SoC Audio board driver
+ *
+ * Copyright (C) 2017, ZTE Corporation.
+ *
+ * Based on smdk_wm8994.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/clk.h>
+#include <linux/gpio.h>
+#include <linux/module.h>
+#include <sound/tlv.h>
+#include <sound/soc.h>
+#include <sound/jack.h>
+#include <sound/zx29_snd_platform.h>
+#include <mach/iomap.h>
+#include <mach/board.h>
+#include "../codecs/tlv320aic31xx.h"
+#include <sound/pcm_params.h>
+#include "i2s.h"
+
+#define  AIC31XX_MCLK  26000000
+
+#define AON_WIFI_BT_CLK_CFG2  ((volatile unsigned int *)(ZX_TOP_CRM_BASE + 0x94))
+
+static struct platform_device *zx297520v3_dummy_snd_device;
+#if (defined CONFIG_SND_EXTRA_CTRL) || (defined CONFIG_SND_EXTRA_CTRL_MODULE)
+extern  const struct snd_kcontrol_new voice_process_controls[];
+extern int vp_controls_size;
+int new_ctrls_add_flag = 1; 
+#endif
+/*
+static const struct snd_kcontrol_new controls[] = {
+	SOC_DAPM_PIN_SWITCH("Main Speaker"),
+	SOC_DAPM_PIN_SWITCH("Main Mic"),
+};
+*/
+
+#ifdef CONFIG_PREEMPT_RT_FULL
+extern int zDrv_Audio_Printf(void *pFormat, ...);
+extern int zDrvVp_GetVol_Wrap(void);
+extern int zDrvVp_SetVol_Wrap(int volume);
+extern int zDrvVp_GetPath_Wrap(void);
+extern int zDrvVp_SetPath_Wrap(int path);
+extern int zDrvVp_SetMute_Wrap(bool enable);
+extern bool zDrvVp_GetMute_Wrap(void);
+extern int zDrvVp_SetTone_Wrap(int toneNum);
+ extern int zDrvVp_SetRxMute_Wrap(bool enable);
+ extern int zDrvVp_GetRxMute_Wrap(void);
+ extern int zDrvVp_GetTxVol_Wrap(void); 
+ extern int zDrvVp_SetTxVol_Wrap(int volume);
+
+static int vp_GetPath(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
+static int vp_SetPath(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
+static int vp_SetVol(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
+static int vp_GetVol(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
+static int vp_SetMute(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
+static int vp_GetMute(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
+static int vp_SetTone(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
+static int vp_getTone(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
+
+static int audio_GetPath(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
+static int audio_SetPath(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
+static int vp_GetTxVol(struct snd_kcontrol *kcontrol,struct snd_ctl_elem_value *ucontrol);
+static int vp_SetTxVol(struct snd_kcontrol *kcontrol,struct snd_ctl_elem_value *ucontrol);
+static int vp_SetRxMute(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); 
+static int vp_GetRxMute(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
+
+ 								
+
+static const DECLARE_TLV_DB_SCALE(vp_path_tlv, 0, 300, 0);
+
+static const char * const vpath_in_text[] = {
+	"handset", "speak", "headset", "bluetooth",
+};
+
+static const char *tone_class[] = {
+	"Lowpower", "Sms", "Callstd", "Alarm", "Calltime",
+};
+
+static const struct soc_enum vpath_in_enum =	SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(vpath_in_text), vpath_in_text); 
+
+static const struct soc_enum tone_class_enum[] = {
+	SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(tone_class),	tone_class),
+};
+
+static const struct snd_kcontrol_new vp_snd_controls[] = {	
+	SOC_ENUM_EXT("voice processing path select",vpath_in_enum,vp_GetPath,vp_SetPath),
+	SOC_SINGLE_EXT_TLV("voice processing path Volume",0, 5, 5, 0,vp_GetVol, vp_SetVol,vp_path_tlv),	
+	//SOC_SINGLE_EXT("voice processing path Volume",0, 5, 5, 0,vp_GetVol, vp_SetVol),
+	SOC_SINGLE_EXT("voice processing tx path Volume",0, 5, 5, 0,vp_GetTxVol, vp_SetTxVol),	
+	SOC_SINGLE_EXT("voice uplink mute", 0, 1, 1, 0,vp_GetMute, vp_SetMute),
+	SOC_SINGLE_EXT("voice downlink mute", 0, 1, 1, 0,vp_GetRxMute, vp_SetRxMute),	
+	SOC_ENUM_EXT("voice tone sel", tone_class_enum[0], vp_getTone, vp_SetTone),
+	SOC_ENUM_EXT("audio path select",vpath_in_enum,audio_GetPath,audio_SetPath),
+};
+
+static int curtonetype = 0;
+static int vp_getTone(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+{
+	ucontrol->value.integer.value[0] = curtonetype;
+	return 0;
+}
+
+static int vp_SetTone(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+{
+	int vol = 0,ret = 0, tonenum;
+	tonenum = ucontrol->value.integer.value[0];
+	curtonetype = tonenum;
+	//printk("Alsa vp_SetTone tonenum=%d\n", tonenum);
+	ret = CPPS_FUNC(cpps_callbacks, zDrvVp_SetTone_Wrap)(tonenum);
+	if(ret < 0)
+	{
+		printk(KERN_ERR "vp_SetTone fail = %d\n", tonenum);
+		return ret;
+	}
+	return 0;
+}
+
+static int vp_SetMute(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+{
+	int enable = 0,ret = 0;
+	enable = ucontrol->value.integer.value[0];
+	ret = CPPS_FUNC(cpps_callbacks, zDrvVp_SetMute_Wrap)(enable);
+	if(ret < 0)
+	{
+	  printk(KERN_ERR "vp_SetMute fail = %d\n",enable);
+	  return ret;
+	}
+	return 0;
+}
+
+static int vp_GetMute(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+{       
+       ucontrol->value.integer.value[0] = CPPS_FUNC(cpps_callbacks, zDrvVp_GetMute_Wrap)();
+       return 0;
+}
+ static int vp_SetRxMute(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+ {
+	 int enable = 0,ret = 0;
+	 enable = ucontrol->value.integer.value[0];
+	 ret = CPPS_FUNC(cpps_callbacks, zDrvVp_SetRxMute_Wrap)(enable);
+	 
+	 if(ret < 0)
+	 {
+	   printk(KERN_ERR "vp_SetRxMute fail = %d\n",enable);
+	   return ret;
+	 }
+	 return 0;
+ }
+ 
+ static int vp_GetRxMute(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+ {		 
+		ucontrol->value.integer.value[0] =  CPPS_FUNC(cpps_callbacks, zDrvVp_GetRxMute_Wrap)();
+		return 0;
+ }
+  
+static int vp_SetVol(struct snd_kcontrol *kcontrol,
+                               struct snd_ctl_elem_value *ucontrol)
+{
+	   int vol = 0,ret = 0;
+	   vol = ucontrol->value.integer.value[0];
+	   ret = CPPS_FUNC(cpps_callbacks, zDrvVp_SetVol_Wrap)(vol);
+	   if(ret < 0)
+	   {
+		  printk(KERN_ERR "vp_SetVol fail = %d\n",vol);
+		  return ret;
+	  }
+	return 0;
+}
+static int vp_GetVol(struct snd_kcontrol *kcontrol,
+                               struct snd_ctl_elem_value *ucontrol)
+{       
+       ucontrol->value.integer.value[0] = CPPS_FUNC(cpps_callbacks, zDrvVp_GetVol_Wrap)();
+       return 0;
+}
+static int vp_SetTxVol(struct snd_kcontrol *kcontrol,
+                               struct snd_ctl_elem_value *ucontrol)
+{
+	   int vol = 0,ret = 0;
+	   vol = ucontrol->value.integer.value[0];
+	   ret = CPPS_FUNC(cpps_callbacks, zDrvVp_SetTxVol_Wrap)(vol);
+	   if(ret < 0)
+	   {
+		  printk(KERN_ERR "vp_SetTxVol fail = %d\n",vol);
+		  return ret;
+	  }
+	return 0;
+}
+static int vp_GetTxVol(struct snd_kcontrol *kcontrol,
+                               struct snd_ctl_elem_value *ucontrol)
+{       
+       ucontrol->value.integer.value[0] = CPPS_FUNC(cpps_callbacks, zDrvVp_GetTxVol_Wrap)();
+       return 0;
+}							   
+static int vp_GetPath(struct snd_kcontrol *kcontrol,
+			struct snd_ctl_elem_value *ucontrol)
+{	
+	ucontrol->value.enumerated.item[0] = CPPS_FUNC(cpps_callbacks, zDrvVp_GetPath_Wrap)();
+	return 0;
+}
+static int vp_SetPath(struct snd_kcontrol *kcontrol,
+			struct snd_ctl_elem_value *ucontrol)
+{
+	int ret = 0,path = 0;
+	
+	path = ucontrol->value.enumerated.item[0];
+	ret = CPPS_FUNC(cpps_callbacks, zDrvVp_SetPath_Wrap)(path);
+	if(ret < 0)
+	{
+	  printk(KERN_ERR "vp_SetPath fail = %d\n",path);
+	  return ret;
+	}
+	return 0;
+}
+
+static int curpath = 0;
+static int audio_GetPath(struct snd_kcontrol *kcontrol,
+			struct snd_ctl_elem_value *ucontrol)
+{	
+	ucontrol->value.enumerated.item[0] = curpath;
+	return 0;
+}
+
+static int audio_SetPath(struct snd_kcontrol *kcontrol,
+			struct snd_ctl_elem_value *ucontrol)
+{
+	int ret = 0,path = 0;
+	
+	path = ucontrol->value.enumerated.item[0];
+	curpath = path;
+#if 0
+	switch (path) {
+	case 0:
+		break;
+	case 1:
+		break;
+	case 2:
+		break;
+	case 3:
+		break;
+	default
+		break;
+	}
+#endif
+	return 0;
+}
+
+
+typedef enum
+{
+    VP_PATH_HANDSET    =0,     
+    VP_PATH_SPEAKER,  		
+    VP_PATH_HEADSET,                     
+    VP_PATH_BLUETOOTH,                    
+    VP_PATH_BLUETOOTH_NO_NR,                    
+    VP_PATH_HSANDSPK,
+    
+    VP_PATH_OFF = 255,					
+    
+    MAX_VP_PATH = VP_PATH_OFF               
+}T_ZDrv_VpPath;
+
+extern int zDrvVp_Loop(T_ZDrv_VpPath path);
+int zx297520v3_dummy_prepare2(struct snd_pcm_substream *substream)
+{
+	int path, ret;
+	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+		ret = CPPS_FUNC(cpps_callbacks, zDrvVp_Loop)(VP_PATH_SPEAKER);
+		if (ret < 0)
+			return -1;
+	}
+	
+	return 0;
+}
+
+#endif
+
+
+static int zx297520v3_dummy_startup(struct snd_pcm_substream *substream)
+{
+	int ret = 0;
+//	print_audio("Alsa Entered func %s\n", __func__);
+	CPPS_FUNC(cpps_callbacks, zDrv_Audio_Printf)("Alsa: zx297520v3_dummy_startup device=%d,stream=%d\n", substream->pcm->device, substream->stream);
+
+	struct snd_pcm *pcmC0D0p = snd_lookup_minor_data(16, SNDRV_DEVICE_TYPE_PCM_PLAYBACK);
+	struct snd_pcm *pcmC0D1p = snd_lookup_minor_data(17, SNDRV_DEVICE_TYPE_PCM_PLAYBACK);
+	struct snd_pcm *pcmC0D2p = snd_lookup_minor_data(18, SNDRV_DEVICE_TYPE_PCM_PLAYBACK);   
+	struct snd_pcm *pcmC0D3p = snd_lookup_minor_data(19, SNDRV_DEVICE_TYPE_PCM_PLAYBACK);  
+	if ((pcmC0D0p == NULL) || (pcmC0D1p == NULL) || (pcmC0D2p == NULL) || (pcmC0D3p == NULL))
+		return  -EINVAL;  
+	if ((pcmC0D0p->streams[0].substream_opened && pcmC0D1p->streams[0].substream_opened) || 
+		(pcmC0D0p->streams[0].substream_opened && pcmC0D2p->streams[0].substream_opened) || 
+		(pcmC0D0p->streams[0].substream_opened && pcmC0D3p->streams[0].substream_opened) || 
+		(pcmC0D1p->streams[0].substream_opened && pcmC0D2p->streams[0].substream_opened) ||
+		(pcmC0D1p->streams[0].substream_opened && pcmC0D3p->streams[0].substream_opened) ||
+		(pcmC0D2p->streams[0].substream_opened && pcmC0D3p->streams[0].substream_opened))
+		BUG();
+
+#ifdef _USE_7520V3_PHONE_TYPE_FWP
+	unsigned int  armRegBit = 0;
+	armRegBit = zx_read_reg(AON_WIFI_BT_CLK_CFG2);
+	armRegBit &= 0xfffffffe;
+	armRegBit |= 0x1;
+	zx_write_reg(AON_WIFI_BT_CLK_CFG2, armRegBit);
+#endif	
+	return ret;
+}
+
+static void zx297520v3_dummy_shutdown(struct snd_pcm_substream *substream)
+{
+	CPPS_FUNC(cpps_callbacks, zDrv_Audio_Printf)("Alsa: zx297520v3_dummy_shutdown device=%d, stream=%d\n", substream->pcm->device, substream->stream);
+
+	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	struct snd_soc_codec *codec = rtd->codec;
+	struct snd_soc_dapm_context *dapm = &codec->dapm;
+//	print_audio("Alsa Entered func %s\n", __func__);
+
+	if (rtd->cpu_dai->active)
+		return;
+	
+#ifdef _USE_7520V3_PHONE_TYPE_FWP
+	unsigned int  armRegBit = 0;
+	armRegBit = zx_read_reg(AON_WIFI_BT_CLK_CFG2);
+	armRegBit &= 0xfffffffe;
+	armRegBit |= 0x0;
+	zx_write_reg(AON_WIFI_BT_CLK_CFG2, armRegBit);
+#endif	
+//	snd_soc_dapm_disable_pin(&codec->dapm, "MICBIAS");
+}
+
+static void zx297520v3_dummy_shutdown2(struct snd_pcm_substream *substream)
+{
+	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	struct snd_soc_codec *codec = rtd->codec;
+	struct snd_soc_dapm_context *dapm = &codec->dapm;
+	CPPS_FUNC(cpps_callbacks, zDrv_Audio_Printf)("Alsa: zx297520v3_dummy_shutdown2 device=%d, stream=%d\n", substream->pcm->device, substream->stream);
+
+	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+#ifdef CONFIG_PREEMPT_RT_FULL
+		CPPS_FUNC(cpps_callbacks, zDrvVp_Loop)(VP_PATH_OFF);
+#endif
+	}
+#ifdef _USE_7520V3_PHONE_TYPE_FWP
+	unsigned int  armRegBit = 0;
+	armRegBit = zx_read_reg(AON_WIFI_BT_CLK_CFG2);
+	armRegBit &= 0xfffffffe;
+	armRegBit |= 0x0;
+	zx_write_reg(AON_WIFI_BT_CLK_CFG2, armRegBit);
+#endif	
+
+}
+
+static int zx297520v3_dummy_init_paiftx(struct snd_soc_pcm_runtime *rtd)
+{
+	int ret = 0;
+
+	/* Other pins NC */
+//	snd_soc_dapm_nc_pin(dapm, "HPOUT2P");
+#if (defined CONFIG_SND_EXTRA_CTRL) || (defined CONFIG_SND_EXTRA_CTRL_MODULE)
+
+	/* add voice process specific controls */
+	if(new_ctrls_add_flag == 1){
+	ret = snd_soc_add_card_controls(rtd->card, voice_process_controls,vp_controls_size);
+	if (ret)
+		return ret;
+	  new_ctrls_add_flag = 0;
+	}
+#endif	
+
+	return ret;
+}
+static int zx297520v3_dummy_hw_params(struct snd_pcm_substream *substream,
+                                       struct snd_pcm_hw_params *params)
+{
+//	print_audio("Alsa Entered func %s\n", __func__);
+	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+	struct snd_soc_dai *codec_dai = rtd->codec_dai;
+	int ret;
+#if 0
+	/* Set the Codec DAI configuration */
+	ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S
+	                          | SND_SOC_DAIFMT_NB_NF
+	                          | SND_SOC_DAIFMT_CBS_CFS);
+	if (ret < 0)
+		return ret;
+
+	/* Set the AP DAI configuration */
+	ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S
+	                          | SND_SOC_DAIFMT_NB_NF
+	                          | SND_SOC_DAIFMT_CBS_CFS);
+	if (ret < 0)
+		return ret;
+
+	ret = snd_soc_dai_set_sysclk(codec_dai, AIC31XX_PLL_CLKIN_MCLK,
+	                             AIC31XX_MCLK, SND_SOC_CLOCK_IN);
+	if (ret < 0)
+		return ret;
+
+	ret = snd_soc_dai_set_sysclk(cpu_dai, ZX29_I2S_WCLK_SEL,
+	                             ZX29_I2S_WCLK_FREQ_26M, SND_SOC_CLOCK_IN);
+	if (ret < 0)
+		return ret;
+#endif
+	
+	return 0;
+}
+
+static int zx297520v3_dummy_hw_params1(struct snd_pcm_substream *substream,
+                                        struct snd_pcm_hw_params *params)
+{
+//	print_audio("Alsa Entered func %s\n", __func__);
+
+
+
+
+	return 0;
+}
+static void zx29_i2s_top_reg_cfg(void)
+{
+	unsigned int i2s_top_reg;
+	int ret = 0;
+
+#ifdef CONFIG_USE_PIN_I2S0
+	ret = gpio_request(PIN_I2S0_WS, "i2s0_ws");
+	if (ret < 0)
+		BUG();
+	ret = gpio_request(PIN_I2S0_CLK, "i2s0_clk");
+	if (ret < 0)
+		BUG();
+	ret = gpio_request(PIN_I2S0_DIN, "i2s0_din");
+	if (ret < 0)
+		BUG();
+	ret = gpio_request(PIN_I2S0_DOUT, "i2s0_dout");
+	if (ret < 0)
+		BUG();
+	zx29_gpio_config(PIN_I2S0_WS, FUN_I2S0_WS);
+	zx29_gpio_config(PIN_I2S0_CLK, FUN_I2S0_CLK);
+	zx29_gpio_config(PIN_I2S0_DIN, FUN_I2S0_DIN);
+	zx29_gpio_config(PIN_I2S0_DOUT, FUN_I2S0_DOUT);
+	
+	//top i2s1 cfg
+	i2s_top_reg = zx_read_reg(ZX29_I2S_LOOP_CFG);
+	i2s_top_reg &= 0xfffffff8;
+	i2s_top_reg |= 0x00000001; //  inter arm_i2s1--top i2s1
+	zx_write_reg(ZX29_I2S_LOOP_CFG, i2s_top_reg);
+#elif defined (CONFIG_USE_PIN_I2S1)
+	ret = gpio_request(PIN_I2S1_WS,"i2s1_ws");
+	if(ret < 0)
+		BUG();
+	ret = gpio_request(PIN_I2S1_CLK,"i2s1_clk");
+	if(ret < 0)
+		BUG();
+	ret = gpio_request(PIN_I2S1_DIN,"i2s1_din");
+	if(ret < 0)
+		BUG();
+	ret = gpio_request(PIN_I2S1_DOUT,"i2s1_dout");
+	if(ret < 0)
+		BUG();
+	zx29_gpio_config(PIN_I2S1_WS, FUN_I2S1_WS);
+	zx29_gpio_config(PIN_I2S1_CLK, FUN_I2S1_CLK);
+	zx29_gpio_config(PIN_I2S1_DIN, FUN_I2S1_DIN);
+	zx29_gpio_config(PIN_I2S1_DOUT, FUN_I2S1_DOUT);
+		
+	//top i2s2 cfg
+	i2s_top_reg = zx_read_reg(ZX29_I2S_LOOP_CFG);
+	i2s_top_reg &= 0xfff8ffff;
+	i2s_top_reg |= 0x00010000; //  inter arm_i2s1--top i2s2
+	zx_write_reg(ZX29_I2S_LOOP_CFG, i2s_top_reg);
+#endif
+
+	// inter loop
+    i2s_top_reg = zx_read_reg(ZX29_I2S_LOOP_CFG);
+    i2s_top_reg &= 0xfffffe07;
+    i2s_top_reg |= 0x000000a8; //  inter arm_i2s2--afe i2s
+    zx_write_reg(ZX29_I2S_LOOP_CFG, i2s_top_reg);
+	
+//	print_audio("Alsa %s i2s loop cfg reg=%x\n",__func__, zx_read_reg(ZX29_I2S_LOOP_CFG));	
+}
+
+
+
+static struct snd_soc_ops zx297520v3_dummy_ops = {
+	.startup = zx297520v3_dummy_startup,
+	.shutdown = zx297520v3_dummy_shutdown,
+	.hw_params = zx297520v3_dummy_hw_params,
+};
+
+static struct snd_soc_ops zx297520v3_dummy_ops1 = {
+	.startup = zx297520v3_dummy_startup,
+	.shutdown = zx297520v3_dummy_shutdown,
+	.hw_params = zx297520v3_dummy_hw_params1,
+};
+
+static struct snd_soc_ops zx297520v3_dummy_ops2 = {
+	.startup = zx297520v3_dummy_startup,
+	.shutdown = zx297520v3_dummy_shutdown2,
+	.hw_params = zx297520v3_dummy_hw_params1,
+	.prepare = zx297520v3_dummy_prepare2,
+};
+
+static struct snd_soc_dai_link zx297520v3_dummy_dai_link[] = {
+	{
+		.name = "dummy_Media",
+		.stream_name = "MultiMedia",
+		.codec_name = "snd-soc-dummy",
+		.codec_dai_name = "snd-soc-dummy-dai",
+		.cpu_dai_name = "snd-soc-dummy-dai", //"zx29_i2s.0"
+		.ops = &zx297520v3_dummy_ops,
+		.init = zx297520v3_dummy_init_paiftx,
+		.platform_name	= "snd-soc-dummy",
+	},
+	{
+		.name = "voice_call",
+		.stream_name = "voice",
+		.codec_name = "snd-soc-dummy",
+		.codec_dai_name = "snd-soc-dummy-dai",
+		.cpu_dai_name = "snd-soc-dummy-dai", //"snd-soc-dummy-dai",
+		.platform_name	= "snd-soc-dummy",
+		.init = zx297520v3_dummy_init_paiftx,
+		.ops = &zx297520v3_dummy_ops1,
+	},
+#ifdef CONFIG_PREEMPT_RT_FULL
+	{
+		.name = "2&3g_voice",
+		.stream_name = "2_3g_voice",
+		.codec_name = "snd-soc-dummy",
+		.codec_dai_name = "snd-soc-dummy-dai",
+		.cpu_dai_name = "voice", //"snd-soc-dummy-dai",
+		.platform_name	= "voice_audio",
+		.init = zx297520v3_dummy_init_paiftx,
+		.ops = &zx297520v3_dummy_ops1,
+	},
+	{
+		.name = "loop_test",
+		.stream_name = "loop_voice",
+		.codec_name = "snd-soc-dummy",
+		.codec_dai_name = "snd-soc-dummy-dai",
+		.cpu_dai_name = "snd-soc-dummy-dai", //"snd-soc-dummy-dai",
+		.platform_name	= "snd-soc-dummy",
+		.init = zx297520v3_dummy_init_paiftx,
+		.ops = &zx297520v3_dummy_ops2,
+	},
+	{
+		.name = "3g_voice", // 3g nb,wb
+		.stream_name = "3g_voice",
+		.codec_name = "snd-soc-dummy",
+		.codec_dai_name = "snd-soc-dummy-dai",
+		.cpu_dai_name = "voice", //"snd-soc-dummy-dai",
+		.platform_name	= "voice_audio",
+		.init = zx297520v3_dummy_init_paiftx,
+		.ops = &zx297520v3_dummy_ops1,
+	},
+#endif
+};
+
+static struct snd_soc_card snd_soc_zx297520v3_dummy = {
+	.name = "zx297520v3_dummy",
+	.owner = THIS_MODULE,
+	.dai_link = &zx297520v3_dummy_dai_link,
+	.num_links = ARRAY_SIZE(zx297520v3_dummy_dai_link),
+#ifdef CONFIG_PREEMPT_RT_FULL
+	.controls = vp_snd_controls,
+	.num_controls = ARRAY_SIZE(vp_snd_controls),
+#endif
+	//.dapm_widgets = widgets,
+	//.num_dapm_widgets = ARRAY_SIZE(widgets),
+	//.dapm_routes = audio_paths,
+	//.num_dapm_routes = ARRAY_SIZE(audio_paths),
+	.fully_routed = true,
+};
+
+static struct zx297520v3_dummy_platform_data *zx297520v3_dummy_pow_pins;
+
+
+
+static int zx297520v3_dummy_probe(struct platform_device *pdev)
+{
+	int ret;
+
+	print_audio("Alsa zx297520v3_dummy SoC Audio driver\n");
+
+#ifndef	_ALSA_CODEC_IN_CAP
+	zx29_i2s_top_reg_cfg();
+#endif
+	zx297520v3_dummy_snd_device = platform_device_alloc("soc-audio", -1);
+	if (!zx297520v3_dummy_snd_device) {
+		printk(KERN_ERR "Alsa zx297520v3_dummy SoC Audio: Unable to register\n");
+		return -ENOMEM;
+	}
+
+	platform_set_drvdata(zx297520v3_dummy_snd_device,
+	                     &snd_soc_zx297520v3_dummy);
+//	platform_device_add_data(zx29xx_dummy_snd_device, &zx29xx_dummy, sizeof(zx29xx_dummy));
+	ret = platform_device_add(zx297520v3_dummy_snd_device);
+	if (ret) {
+		printk(KERN_ERR "Alsa zx297520v3_dummy SoC Audio: Unable to add\n");
+		platform_device_put(zx297520v3_dummy_snd_device);
+	}
+
+	return ret;
+}
+
+static int zx297520v3_dummy_remove(struct platform_device *pdev)
+{
+
+	platform_device_unregister(zx297520v3_dummy_snd_device);
+	return 0;
+}
+
+static struct platform_driver zx297520v3_dummy_driver = {
+	.probe  = zx297520v3_dummy_probe,
+	.remove = zx297520v3_dummy_remove,
+	.driver = {
+		.name = "zx29_snd_machine",
+		.owner = THIS_MODULE,
+	},
+};
+
+module_platform_driver(zx297520v3_dummy_driver);
+
+MODULE_DESCRIPTION("ZX297520V3_dummy ALSA SoC audio driver");
+MODULE_LICENSE("GPL");
+
diff --git a/ap/os/linux/linux-3.4.x/sound/soc/sanechips/zx29_voice.c b/ap/os/linux/linux-3.4.x/sound/soc/sanechips/zx29_voice.c
index 1d961e5..4546eed 100644
--- a/ap/os/linux/linux-3.4.x/sound/soc/sanechips/zx29_voice.c
+++ b/ap/os/linux/linux-3.4.x/sound/soc/sanechips/zx29_voice.c
@@ -21,6 +21,8 @@
 #include <linux/cp_types.h>

 #include "drvs_volte.h"

 #endif

+#include <linux/wakelock.h>

+#include <linux/soc/zte/pm/drv_idle.h>

 

 #ifdef  CONFIG_PREEMPT_RT_FULL

 typedef enum {

@@ -117,6 +119,14 @@
 //extern T_DrvVoice_3G_Opt  gDrvVoice_3G_Obj;

 #endif

 

+struct zx29_voice {

+

+	struct mutex         mutex;

+	struct wake_lock     pm_lock;

+

+};

+

+static struct zx29_voice voice = {0};

 

 static const struct snd_pcm_hardware dma_hardware = {

 	.info			= SNDRV_PCM_INFO_INTERLEAVED |

@@ -227,15 +237,21 @@
 	int ret = 0;

 //	print_audio("Alsa Entered func %s, cmd=%d\n", __func__, cmd);

 	struct snd_soc_pcm_runtime *rtd = substream->private_data;

+	CPPS_FUNC(cpps_callbacks, zDrv_Audio_Printf)("Alsa: %s start,rtd->dai_link->name=%s,cmd=%d\n", __func__, rtd->dai_link->name,cmd);

+

 	if (rtd->dai_link->name != NULL && (!strcmp(rtd->dai_link->name, "3g_voice"))) {

 

 		print_audio("Alsa Entered func %s  3g soft amr !\n", __func__);

-		return 0;

+		//return 0;

 	}

 	switch (cmd) {

 	case SNDRV_PCM_TRIGGER_START:

+		zx_cpuidle_set_busy(IDLE_FLAG_VOICE);

+		wake_lock(&voice.pm_lock);

 		break;

 	case SNDRV_PCM_TRIGGER_STOP:

+		zx_cpuidle_set_free(IDLE_FLAG_VOICE);

+		wake_unlock(&voice.pm_lock);

 		break;

 	default:

 		ret = -EINVAL;

@@ -251,6 +267,7 @@
 	int ret = 0;

 	struct snd_soc_pcm_runtime *rtd = substream->private_data;

 	snd_soc_set_runtime_hwparams(substream, &dma_hardware);

+	CPPS_FUNC(cpps_callbacks, zDrv_Audio_Printf)("Alsa: %s start,rtd->dai_link->name=%s\n", __func__, rtd->dai_link->name);

 

 #ifdef CONFIG_PREEMPT_RT_FULL

 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {

@@ -259,14 +276,19 @@
 

 			ret = CPPS_FUNC(cpps_callbacks, halVoice_Open3G)();

 			print_audio("Alsa Entered func %s  3g soft amr  ret=%d!\n", __func__, ret);

+		    CPPS_FUNC(cpps_callbacks, zDrv_Audio_Printf)("Alsa Entered func %s  3g soft amr  ret=%d!\n", __func__, ret);

+		

 

 		} else {

 			ret = CPPS_FUNC(cpps_callbacks, halVoice_Open)();

 			print_audio("Alsa Entered func %s  2/3G teaklit  ret=%d!\n", __func__, ret);

+		    CPPS_FUNC(cpps_callbacks, zDrv_Audio_Printf)("Alsa Entered func %s  2/3G teaklit  ret=%d!\n", __func__, ret);

 

 		}

 	}

 #endif

+	CPPS_FUNC(cpps_callbacks, zDrv_Audio_Printf)("Alsa: %s end,rtd->dai_link->name=%s\n", __func__, rtd->dai_link->name);

+

 	return ret;

 }

 

@@ -276,23 +298,34 @@
 //	print_audio("Alsa Entered func %s\n", __func__);

 	int ret = 0;

 	struct snd_soc_pcm_runtime *rtd = substream->private_data;

+	CPPS_FUNC(cpps_callbacks, zDrv_Audio_Printf)("Alsa: %s start,rtd->dai_link->name=%s\n", __func__, rtd->dai_link->name);

+

+	//dump_stack();	

+	WARN_ON(1);

 #ifdef CONFIG_PREEMPT_RT_FULL

 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {

 		if ((rtd->dai_link->name != NULL) && (!strcmp(rtd->dai_link->name, "3g_voice"))) {

 			ret = CPPS_FUNC(cpps_callbacks, halVoice_Close3G)();

 			print_audio("Alsa Entered func %s  3g soft amr  ret=%d!\n", __func__, ret);

+			CPPS_FUNC(cpps_callbacks, zDrv_Audio_Printf)("Alsa Entered func %s  3g soft amr  ret=%d!\n", __func__, ret);

 

 		} else {

 

 			ret = CPPS_FUNC(cpps_callbacks, halVoice_Disable)();

-			if (ret < 0)

-				print_audio("Alsa Entered func %s  2/3G teakl err ret=%d\n", __func__, ret);

+			if (ret < 0){

+				print_audio("Alsa Entered func %s  2/3G teakl disable err ret=%d\n", __func__, ret);

+				

+		   		CPPS_FUNC(cpps_callbacks, zDrv_Audio_Printf)("Alsa Entered func %s  2/3G teakl disable err ret=%d\n", __func__, ret);

+			}

 			ret += CPPS_FUNC(cpps_callbacks, halVoice_Close)();

+			

+		    CPPS_FUNC(cpps_callbacks, zDrv_Audio_Printf)("Alsa Entered func %s  2/3G teaklit close end ret=%d!\n", __func__, ret);

 		}

 

 

 	}

 #endif

+	CPPS_FUNC(cpps_callbacks, zDrv_Audio_Printf)("Alsa: %s end,rtd->dai_link->name=%s\n", __func__, rtd->dai_link->name);

 

 	return ret;

 }

@@ -316,6 +349,9 @@
 static int __devinit voice_asoc_platform_probe(struct platform_device *pdev)

 {

 //	print_audio("Alsa voice_asoc_platform_probe start\n");

+	mutex_init(&voice.mutex);

+	wake_lock_init(&voice.pm_lock, WAKE_LOCK_SUSPEND, "zx29-voice");

+

 	return snd_soc_register_platform(&pdev->dev, &voice_asoc_platform);

 }

 

diff --git a/ap/os/linux/linux-3.4.x/sound/soc/soc-utils.c b/ap/os/linux/linux-3.4.x/sound/soc/soc-utils.c
index 6005370..37f4872 100644
--- a/ap/os/linux/linux-3.4.x/sound/soc/soc-utils.c
+++ b/ap/os/linux/linux-3.4.x/sound/soc/soc-utils.c
@@ -89,9 +89,35 @@
 	.ops = &dummy_dma_ops,
 };
 
+#define ZX29_I2S_RATES \
+				(SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | SNDRV_PCM_RATE_16000 | \
+				 SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \
+				 SNDRV_PCM_RATE_48000)
+			
+#define ZX29_I2S_FMTBIT \
+				(SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | \
+				SNDRV_PCM_FMTBIT_S32_LE)
+
+
 static struct snd_soc_codec_driver dummy_codec;
 static struct snd_soc_dai_driver dummy_dai = {
 	.name = "snd-soc-dummy-dai",
+#ifdef _USE_VEHICLE_DC	
+	.playback = {
+		.stream_name	= "Playback",
+		.channels_min	= 1,
+		.channels_max	= 384,
+		.rates		= ZX29_I2S_RATES,
+		.formats	= ZX29_I2S_FMTBIT,
+	},
+	.capture = {
+		.stream_name	= "Capture",
+		.channels_min	= 1,
+		.channels_max	= 384,
+		.rates		= ZX29_I2S_RATES,
+		.formats	= ZX29_I2S_FMTBIT,
+	 },	
+#endif	 
 };
 
 static __devinit int snd_soc_dummy_probe(struct platform_device *pdev)