drivers: video: rockchip: vcodec_dma_map_sg maybe fail
[firefly-linux-kernel-4.4.55.git] / drivers / video / rockchip / wimo.c
1 /* drivers/video/wimo.c\r
2  *\r
3  * Copyright (C) 2010 ROCKCHIP, Inc.\r
4  * author: chenhengming chm@rock-chips.com\r
5  *\r
6  * This software is licensed under the terms of the GNU General Public\r
7  * License version 2, as published by the Free Software Foundation, and\r
8  * may be copied, distributed, and modified under those terms.\r
9  *\r
10  * This program is distributed in the hope that it will be useful,\r
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
13  * GNU General Public License for more details.\r
14  *\r
15  */\r
16 #include <linux/miscdevice.h>
17 #include <linux/platform_device.h>
18 #include <linux/fs.h>
19 #include <linux/file.h>
20 #include <linux/mm.h>
21 #include <linux/list.h>
22 #include <linux/debugfs.h>
23 #include <linux/mempolicy.h>
24 #include <linux/sched.h>\r
25 #include <asm/io.h>\r
26 #include <asm/uaccess.h>\r
27 #include <asm/cacheflush.h>\r
28 #include <linux/fb.h>\r
29 #include <plat/ipp.h>\r
30 #include "linux/wimo.h"\r
31 #include<linux/rk_fb.h>\r
32 #define WIMO_MIN_ALLOC               PAGE_SIZE\r
33 #define WIMO_IS_PAGE_ALIGNED(addr)   (!((addr) & (~PAGE_MASK)))\r
34 \r
35 #define WIMO_DEBUG                   0\r
36 #define WIMO_DEBUG_MSGS              0\r
37 \r
38 #if WIMO_DEBUG_MSGS\r
39 #define DLOG(fmt,args...) \\r
40         do { printk(KERN_INFO "[%s:%s:%d] "fmt, __FILE__, __func__, __LINE__, \\r
41                     ##args); } \\r
42         while (0)\r
43 #else\r
44 #define DLOG(x...) do {} while (0)\r
45 #endif\r
46 #define WIMO_WRITE_FILE
47 \r
48 struct win_set {
49         volatile u32 y_offset;
50         volatile u32 c_offset;
51 };
52
53 struct win0_par {
54     u32 refcount;
55     u32 pseudo_pal[16];
56     u32 y_offset;
57     u32 c_offset;
58     u32 xpos;         //size in panel
59     u32 ypos;
60     u32 xsize;        //start point in panel
61     u32 ysize;
62     u32 format;
63
64     wait_queue_head_t wait;
65     struct win_set mirror;
66     struct win_set displ;
67     struct win_set done;
68
69     u8 par_seted;
70     u8 addr_seted;
71 };
72 \r
73 \r
74 /**\r
75  * struct for global wimo info\r
76  */\r
77 struct enc_buff_info{\r
78         u32 bitperpixel;\r
79         u32 mode;\r
80         u32     xaff;\r
81         u32     yaff;\r
82         u32 xpos;\r
83         u32 ypos;\r
84         u32 xsize;\r
85         u32 ysize;\r
86         u32 src_y;\r
87         u32 src_uv;\r
88         u32 dst_width;\r
89         u32 dst_height;\r
90         u32 dst_vir_w;\r
91         u32 dst_vir_h;\r
92         u32 y_offset;\r
93         u32 c_offset;\r
94         u32 src_width;\r
95         u32 src_height;\r
96         long long       Frame_Time;
97         unsigned char* ui_buffer;
98         unsigned char* ui_buffer_map;
99         int rotation_flag;\r
100         
101         
102 };
103 struct wimo_video_info{\r
104         u32                             bitperpixel;\r
105         u32                             mode;\r
106         u32                             xaff;\r
107         u32                             yaff;\r
108         u32                             xpos;\r
109         u32                             ypos;\r
110         u32                             xsize;\r
111         u32                             ysize;\r
112         u32                             src_y;\r
113         u32                             src_uv;\r
114         u32                             dst_width;\r
115         u32                             dst_height;\r
116         u32                             rot_dst_width;\r
117         u32                             rot_dst_height;\r
118         u32                             src_width;\r
119         u32                             src_height;\r
120         u32                             set_flag;\r
121         int                     Last_rotation_flag;\r
122         int                     rotation_flag;\r
123         long long       Last_Frame_Time;
124         struct timeval Wimo_RGB_time;
125         struct timeval Wimo_YUV_time;
126         struct timeval Wimo_Cur_time;
127         struct enc_buff_info enc_buff[4];
128         u32 buffer_num;\r
129         u32 avail_index;\r
130         u32 work_index;\r
131         volatile u32 avail_frame;\r
132         int test_sign;
133         u32 frame_num;\r
134 \r
135 };\r
136 struct wimo_audio_info{\r
137         volatile u32                    buffer_size;\r
138         volatile u32                    head_offset;\r
139         volatile u32                    tail_offset;\r
140         volatile u32                    data_len;\r
141         u32                                     nSamplePerFrame;\r
142         u32                                     nChannel;\r
143         u32                                     nBytePerSample;\r
144         u32                                     nBytePerFrame;\r
145         unsigned char*          Out_Buffer;\r
146         struct  timeval         *time_stamp;\r
147         unsigned char           *audio_data;\r
148 \r
149 };\r
150 struct wimo_audio_param{\r
151         u32                                     buffer_size;\r
152         u32                                     nSamplePerFrame;\r
153         u32                                     nChannel;\r
154         u32                                     nBytePerSample;\r
155         u32                                     nBytePerFrame;\r
156         u32                                     Reserverd[7];\r
157 };\r
158 int rgb_time;\r
159 int yuv_time;\r
160 struct wimo_info{\r
161         struct wimo_video_info          video_info;\r
162         struct wimo_audio_info          audio_info;\r
163         struct rw_semaphore             rw_sem;\r
164         struct miscdevice                       dev;\r
165         int video_start_sign;\r
166         int audio_start_sign;\r
167         int start_sign;\r
168         int volumn_open_sign;\r
169         int rotation_flag;\r
170 };\r
171 struct mutex video_lock;\r
172 struct mutex audio_lock;\r
173 struct mutex wimo_lock;\r
174 //int wimo_prepare_para(struct fb_info *info);\r
175 //int wimo_prepare_buff(struct fb_info *info);\r
176 //int wimo_prepare(struct fb_info *info);\r
177
178 \r
179 static int wimo_count = 0;\r
180 static struct wimo_info wimo;\r
181 #define wdm_rwsem               (wimo.rw_sem)\r
182 extern int (*audio_data_to_wimo)(void* data,int size,int channel);\r
183 extern int (*video_data_to_wimo)(struct fb_info *info,u32 yuv_phy[2]);\r
184 \r
185 unsigned long temp_vv;\r
186 static int frame_num = 0;\r
187 static int Is_Wimo_Loaded()\r
188 {\r
189         int ret = -1;\r
190         if(wimo_count > 0)\r
191                 ret = 0;\r
192         return ret;\r
193 }\r
194 static int wimo_start(void)\r
195 {\r
196         int ret = 0;\r
197         wimo.start_sign = 1;\r
198         \r
199         return ret;\r
200 }\r
201 static int wimo_stop(void)\r
202 {\r
203         int ret = 0;\r
204         \r
205         wimo.start_sign = 0;\r
206         return ret;\r
207 }\r
208 static int wimo_set_rotation(int rotation_flag)\r
209 {\r
210         int ret = 0;\r
211         \r
212         wimo.rotation_flag = rotation_flag;\r
213         return ret;\r
214 }\r
215 struct file* wimo_filp;\r
216 mm_segment_t old_fs;\r
217 struct file* wimo_filp_output;\r
218 mm_segment_t old_fs_output;\r
219 static int wimo_audio_open(unsigned long *temp)\r
220 {\r
221         int ret = 0;\r
222         struct wimo_audio_info *audio_info = &wimo.audio_info;\r
223         struct timeval timeFirst;\r
224                 do_gettimeofday(&timeFirst);    \r
225         if(wimo.start_sign == 0)\r
226         {\r
227                 printk("Apk didn't start when audio start \n");\r
228                 return -1;\r
229         }\r
230         memset(audio_info, 0, sizeof(struct wimo_audio_info));\r
231         wimo.audio_start_sign                   = 1;    \r
232         audio_info->Out_Buffer          = NULL;\r
233 \r
234         audio_info->buffer_size                 = 50;\r
235         audio_info->nSamplePerFrame     = 1024;\r
236         audio_info->nBytePerSample              = 2;\r
237         audio_info->nChannel                    = 2;\r
238         audio_info->nBytePerFrame               = 4096;\r
239         \r
240         \r
241         audio_info->head_offset         = 0;\r
242         audio_info->tail_offset                         = 0;\r
243         audio_info->data_len                    = 0;\r
244         \r
245         audio_info->audio_data  = (unsigned char*)kmalloc(audio_info->buffer_size * audio_info->nBytePerFrame,GFP_KERNEL);\r
246         audio_info->time_stamp  = (struct timeval*)kmalloc(audio_info->buffer_size * sizeof(struct timeval),GFP_KERNEL);\r
247         memset(audio_info->audio_data, 0,audio_info->buffer_size * audio_info->nBytePerFrame);\r
248         printk("audio_info->buffer_size * audio_info->nBytePerFrame  timestamp %d  audio_info->Out_Buffer        %x time %lld %x %x\n",\r
249                 audio_info->buffer_size * audio_info->nBytePerFrame,audio_info->time_stamp,audio_info->Out_Buffer,(int64_t)timeFirst.tv_sec*1000000ll + timeFirst.tv_usec\r
250                 ,__pa(audio_info->audio_data),__pa(audio_info->time_stamp));\r
251         #ifdef  WIMO_WRITE_FILE\r
252         wimo_filp = NULL;\r
253         wimo_filp = filp_open("/data/test/input_cmp.pcm",O_CREAT|O_TRUNC|O_RDWR,0);\r
254         if (wimo_filp)\r
255         {\r
256           old_fs = get_fs();\r
257           set_fs(get_ds());\r
258         }\r
259         wimo_filp_output = NULL;\r
260         wimo_filp_output = filp_open("/data/test/output_cmp.pcm",O_CREAT|O_TRUNC|O_RDWR,0);\r
261         if (wimo_filp_output)\r
262         {\r
263           old_fs_output = get_fs();\r
264           set_fs(get_ds());\r
265         }\r
266         #endif\r
267         return ret;\r
268 }\r
269 static int wimo_audio_close(void)\r
270 {\r
271         int ret = 0;\r
272         struct wimo_audio_info *audio_info = &wimo.audio_info;\r
273         #ifdef  WIMO_WRITE_FILE\r
274         set_fs(old_fs);\r
275         filp_close(wimo_filp,NULL);\r
276 \r
277         set_fs(old_fs_output);\r
278         filp_close(wimo_filp_output,NULL);\r
279 \r
280         #endif\r
281         printk("wimo_audio_close\n");\r
282         kfree((void *)audio_info->time_stamp);\r
283         kfree((void *)audio_info->audio_data);\r
284         \r
285         audio_info->Out_Buffer  = NULL;\r
286         wimo.audio_start_sign           = 0;\r
287         return ret;\r
288 }\r
289 static void wimo_audio_set_para(struct wimo_audio_param *param)\r
290 {\r
291         struct wimo_audio_info *audio_info = &wimo.audio_info;\r
292         audio_info->buffer_size                 = param->buffer_size;\r
293         audio_info->nSamplePerFrame     = param->nSamplePerFrame;\r
294         audio_info->nChannel                    = param->nChannel;\r
295         audio_info->nBytePerSample      = param->nBytePerSample;\r
296         audio_info->nBytePerFrame               = param->nBytePerFrame;\r
297         DLOG("param %d %d %d %d %d  audio_info %d %d %d %d %d",\r
298                 param->buffer_size,param->nSamplePerFrame,param->nChannel,param->nBytePerSample,param->nBytePerFrame,\r
299                 audio_info->buffer_size,audio_info->nSamplePerFrame,audio_info->nChannel,audio_info->nBytePerSample,audio_info->nBytePerFrame);\r
300         return;\r
301 }\r
302 \r
303 static void wimo_audio_set_vol(u32 temp_data)\r
304 {\r
305         wimo.volumn_open_sign = temp_data;\r
306         return;\r
307 }\r
308 static int wimo_audio_find_frame()\r
309 {\r
310         struct wimo_audio_info *audio_info = &wimo.audio_info;\r
311         int ret = 0;\r
312         if(audio_info->data_len >= 1)\r
313         {\r
314                 audio_info->Out_Buffer = (void*)(&audio_info->audio_data[audio_info->head_offset * audio_info->nBytePerFrame]);\r
315                 //wimo_filp_output->f_op->write(wimo_filp_output, audio_info->Out_Buffer, audio_info->nBytePerFrame, &wimo_filp_output->f_pos);\r
316                 audio_info->data_len --;\r
317                 audio_info->head_offset ++;\r
318                 audio_info->head_offset %= audio_info->buffer_size;\r
319         }\r
320         else\r
321         {\r
322                 ret = -1;\r
323         }\r
324         \r
325         return ret;\r
326 }\r
327 static int wimo_audio_prepare(void* data,int size,int channel)\r
328 {\r
329         int ret = 0;\r
330         mutex_lock(&audio_lock);\r
331         \r
332         if(wimo.audio_start_sign && wimo.start_sign)\r
333         {\r
334                 struct timeval timeFirst;\r
335                 unsigned long* temp = (unsigned long*)data;\r
336                 struct wimo_audio_info *audio_info = &wimo.audio_info;\r
337                 unsigned char* buf = data;\r
338                 do_gettimeofday(&timeFirst);    \r
339                 memcpy((void*)(&audio_info->audio_data[audio_info->tail_offset * audio_info->nBytePerFrame]), (void*)data,size);\r
340                 memcpy((void*)(&audio_info->time_stamp[audio_info->tail_offset]),(void*)(&timeFirst),sizeof(struct timeval));\r
341                 audio_info->tail_offset ++;\r
342                 audio_info->tail_offset %= audio_info->buffer_size;\r
343                 wimo_filp->f_op->write(wimo_filp, data, size, &wimo_filp->f_pos);\r
344                 if(audio_info->data_len + 1 < audio_info->buffer_size)\r
345                 {\r
346                         audio_info->data_len ++;\r
347                 }\r
348                 else\r
349                 {\r
350                         audio_info->head_offset=audio_info->tail_offset;\r
351                         audio_info->data_len = audio_info->buffer_size;\r
352                 }\r
353 //              if(wimo.volumn_open_sign==0)\r
354 //              {\r
355 //                      memset((void*)data,0,size);\r
356 //\r
357 //              }\r
358         }               \r
359         else\r
360         {\r
361                 //DLOG("wimo_video not open\n");\r
362                 ret = AUDIO_ENCODER_CLOSED;\r
363         }\r
364         if(wimo.start_sign && wimo.volumn_open_sign == 0)\r
365                 memset((void*)data,0,size);\r
366         \r
367         mutex_unlock(&audio_lock);\r
368         return ret;\r
369 }\r
370 /*\r
371         wimo_video can be opened once at a time.\r
372         Other user must wait for last open closed.\r
373 */\r
374 static int wimo_video_open(unsigned long *temp)\r
375 {
376         struct wimo_video_info *video_info = &wimo.video_info;\r
377         int i;\r
378         int ret =0 ;\r
379         printk("wimo_video_open\n");\r
380         if(wimo.start_sign == 0)\r
381         {\r
382                 printk("Apk didn't start when video start ");\r
383                 return -1;\r
384         }\r
385         if(wimo.video_start_sign == 1)\r
386         {\r
387                 printk("last wimo_video still opened ,something wrong\n");\r
388                 \r
389         }\r
390         memset(&wimo.video_info,0,sizeof(struct wimo_video_info));\r
391         if(wimo.rotation_flag < 0 )\r
392                 DLOG("wimo_set_buff rotation_flag < 0,maybe something wrong\n");\r
393                 \r
394         video_info->Last_rotation_flag = -1;\r
395         video_info->rotation_flag = wimo.rotation_flag;\r
396         for(i = 0; i < temp[3]; i++)\r
397         {
398                 video_info->enc_buff[i].ui_buffer= (unsigned char*)temp[i+4];\r
399                 video_info->enc_buff[i].ui_buffer_map= ioremap(temp[i+4],temp[2]);\r
400                 if(video_info->enc_buff[i].ui_buffer_map == NULL)\r
401                 {
402                         printk("can't map a buffer for ui\n");
403                         return -EFAULT;
404                 }
405         }\r
406         video_info->buffer_num = temp[3];\r
407         video_info->dst_width   = (temp[0] + 15) & 0xfff0;\r
408         video_info->dst_height  = (temp[1] + 15) & 0xfff0;\r
409         video_info->xsize               = video_info->dst_width;\r
410         video_info->ysize               = video_info->dst_height;\r
411         wimo.video_start_sign = 1;      \r
412         printk("video_info->dst_width %d video_info->dst_height %d num %d %x ui_buffer %x %x   size %d map %x %x\n",\r
413                 video_info->dst_width,video_info->dst_height,video_info->buffer_num,(long)&wimo.video_info.buffer_num,\r
414                 video_info->enc_buff[0].ui_buffer,video_info->enc_buff[1].ui_buffer,temp[2],video_info->enc_buff[0].ui_buffer_map\r
415                 ,video_info->enc_buff[1].ui_buffer_map);\r
416         rgb_time = yuv_time = 0;\r
417         return ret;\r
418 }\r
419 /*\r
420 close wimo_video .\r
421 release resources.\r
422 \r
423 */\r
424 static int wimo_video_close(struct wimo_video_info *video_info)\r
425 {
426         int i ;\r
427         int ret = 0;\r
428         if(video_info->buffer_num && wimo.video_start_sign && wimo.start_sign)\r
429                 printk("something is okay with wimo video in close");\r
430                 
431         else
432                 printk("somethint wrong with wimo video in close");\r
433         wimo.video_start_sign = 0;\r
434         DLOG("video_info->dst_width %d video_info->dst_height %d ui_buffer %x %x  ui_buffer_map %x %x\n",\r
435                 video_info->dst_width,video_info->dst_height,video_info->enc_buff[0].ui_buffer,video_info->enc_buff[1].ui_buffer,\r
436                 video_info->enc_buff[0].ui_buffer_map,video_info->enc_buff[1].ui_buffer_map);\r
437         \r
438         for(i = 0; i < 4; i++)
439         {       
440                 DLOG("closebuf ui_buffer %x ui_buffer_map %x  ui_buffer_map addr %x wimo_info.buffer_num %d i %d\n",\r
441                         (unsigned int)video_info->enc_buff[i].ui_buffer,(unsigned int)video_info->enc_buff[i].ui_buffer_map,(unsigned long)(&video_info->enc_buff[i].ui_buffer_map),video_info->buffer_num,i);\r
442                 if(video_info->enc_buff[i].ui_buffer_map!=0)\r
443                 {
444                         iounmap(video_info->enc_buff[i].ui_buffer_map);\r
445                         video_info->enc_buff[i].ui_buffer_map = 0;\r
446                         video_info->enc_buff[i].ui_buffer = 0;\r
447                 }
448         }\r
449         return ret;\r
450 }
451
452 /*\r
453 get video frame \r
454 it return -1  when no frame is availiable\r
455 */\r
456 static int wimo_video_find_frame(unsigned long* temp_data,struct wimo_video_info *video_info)\r
457 {
458         
459         int ret = 0;\r
460         do_gettimeofday(&video_info->Wimo_Cur_time);\r
461         DLOG("wimo_find_frame video_info %x video_info->buffer_num %d avail_index %d avail_frame %d work_index %d  testIgn %d time %lld curtime %lld last_time %lld %lld %lld yuv rgb time %lld %lld  yuv_time %d\n",\r
462                 (unsigned long)video_info,video_info->buffer_num, video_info->avail_index,video_info->avail_frame,video_info->work_index,video_info->test_sign,video_info->enc_buff[video_info->avail_index].Frame_Time,\r
463                 (long long)video_info->Wimo_Cur_time.tv_sec * 1000000ll + video_info->Wimo_Cur_time.tv_usec,video_info->Last_Frame_Time,video_info->enc_buff[video_info->avail_index].Frame_Time,\r
464                 video_info->enc_buff[1-video_info->avail_index].Frame_Time,(long long)video_info->Wimo_YUV_time.tv_sec * 1000000ll + video_info->Wimo_YUV_time.tv_usec\r
465                 ,(long long)video_info->Wimo_RGB_time.tv_sec * 1000000ll + video_info->Wimo_RGB_time.tv_usec,yuv_time);\r
466         if(video_info->avail_frame)\r
467         {
468                 if(video_info->Last_Frame_Time >  video_info->enc_buff[video_info->avail_index].Frame_Time)\r
469                 {
470                         
471                         DLOG("wimo_find_frame error avail_index %d avail_frame %d work_index %d  testIgn %d time %lld curtime %lld last_time %lld %lld %lld yuv rgb time %lld %lld  yuv_time %d\n",\r
472                                 video_info->avail_index,video_info->avail_frame,video_info->work_index,video_info->test_sign,video_info->enc_buff[video_info->avail_index].Frame_Time,\r
473                         (long long)video_info->Wimo_Cur_time.tv_sec * 1000000ll + video_info->Wimo_Cur_time.tv_usec,video_info->Last_Frame_Time,video_info->enc_buff[video_info->avail_index].Frame_Time,\r
474                                 video_info->enc_buff[1-video_info->avail_index].Frame_Time,(long long)video_info->Wimo_YUV_time.tv_sec * 1000000ll + video_info->Wimo_YUV_time.tv_usec\r
475                                 ,(long long)video_info->Wimo_RGB_time.tv_sec * 1000000ll + video_info->Wimo_RGB_time.tv_usec,yuv_time);\r
476                         video_info->test_sign = 2;\r
477                 }
478                 video_info->Last_Frame_Time = video_info->enc_buff[video_info->avail_index].Frame_Time;\r
479                 
480         }
481         else
482         {
483                 if(((long long)video_info->Wimo_Cur_time.tv_sec * 1000000ll + video_info->Wimo_Cur_time.tv_usec  >   video_info->Last_Frame_Time + 1000000ll || video_info->frame_num < 30) && video_info->frame_num!=0)\r
484                 {
485                         
486                         DLOG("wimo_find_frame wait  second avail_index %d avail_frame %d work_index %d  testIgn %d time %lld curtime %lld last_time %lld %lld %lld yuv rgb time %lld %lld  yuv_time %d\n",\r
487                                 video_info->avail_index,video_info->avail_frame,video_info->work_index,\r
488                                 video_info->test_sign,video_info->enc_buff[video_info->avail_index].Frame_Time,\r
489                         (long long)video_info->Wimo_Cur_time.tv_sec * 1000000ll + video_info->Wimo_Cur_time.tv_usec,video_info->Last_Frame_Time,video_info->enc_buff[video_info->avail_index].Frame_Time,\r
490                                 video_info->enc_buff[1- video_info->avail_index].Frame_Time,(long long)video_info->Wimo_YUV_time.tv_sec * 1000000ll + video_info->Wimo_YUV_time.tv_usec\r
491                                 ,(long long)video_info->Wimo_RGB_time.tv_sec * 1000000ll + video_info->Wimo_RGB_time.tv_usec,yuv_time);\r
492                         video_info->test_sign = 3;\r
493                         video_info->Last_Frame_Time =(long long)video_info->Wimo_Cur_time.tv_sec * 1000000ll + video_info->Wimo_Cur_time.tv_usec;\r
494                         if(video_info->mode == 0 )\r
495                         {
496                                 video_info->Wimo_RGB_time.tv_sec = video_info->Wimo_Cur_time.tv_sec;\r
497                                 video_info->Wimo_RGB_time.tv_usec = video_info->Wimo_Cur_time.tv_usec;\r
498                         }
499                         \r
500                         video_info->avail_index--;\r
501                         video_info->avail_index %= video_info->buffer_num;\r
502                         video_info->avail_frame++;\r
503                         \r
504                 }
505                 else
506                 {
507                         video_info->test_sign = 4;\r
508                         DLOG ("no avail frame \n");\r
509                         return -1;
510                 }
511                 
512         }
513         temp_data[0] = (video_info->enc_buff[video_info->avail_index].bitperpixel << 16);\r
514         temp_data[0] |= video_info->enc_buff[video_info->avail_index].mode;\r
515         
516         temp_data[1] = video_info->avail_index ;\r
517         memcpy(&temp_data[2],&video_info->enc_buff[video_info->avail_index].Frame_Time,8);\r
518         temp_data[4] = video_info->enc_buff[video_info->avail_index].rotation_flag| (yuv_time<<16);\r
519         temp_data[5] = video_info->Wimo_Cur_time.tv_sec;\r
520         temp_data[6] = video_info->Wimo_Cur_time.tv_usec;\r
521 \r
522         video_info->avail_index++;\r
523         video_info->avail_index %= video_info->buffer_num;\r
524         video_info->avail_frame--;\r
525         video_info->frame_num++;\r
526         yuv_time = rgb_time = 0;
527         \r
528         return ret;\r
529 }
530 \r
531 #if 1
532  int wimo_prepare_para(struct fb_info *info,struct wimo_video_info *video_info,struct enc_buff_info *enc_buff)\r
533 {
534         
535         //struct rk29fb_inf *inf = dev_get_drvdata(info->device);\r
536         struct rk_fb_inf *inf = dev_get_drvdata(info->device);
537         struct fb_var_screeninfo *var = &info->var;\r
538         int ret = 0;\r
539         struct layer_par *par = NULL;   \r
540         struct fb_fix_screeninfo * fix = &info->fix;\r
541         struct rk_lcdc_device_driver *dev_drv = (struct rk_lcdc_device_driver *)info->par;              \r
542         int layer_id = 0;               \r
543         layer_id = get_fb_layer_id(fix);                \r
544         if (layer_id < 0) \r
545         {                       \r
546                 return -ENODEV;         \r
547         } \r
548         else \r
549         {                       \r
550                 par = dev_drv->layer_par[layer_id];             \r
551         }\r
552         video_info->mode = inf->video_mode;\r
553         video_info->src_width =  var->xres_virtual;\r
554         video_info->src_height = var->yres_virtual/2;\r
555         if(inf->video_mode == 0 )
556         {\r
557                 \r
558 \r
559                 if(par->format == 1)
560                 {
561                         enc_buff->bitperpixel = 16;
562                         enc_buff->rotation_flag = video_info->rotation_flag;\r
563                 }
564                 else
565                 {
566                         enc_buff->bitperpixel =32;// wimo_info.bitperpixel_fb1;
567                         enc_buff->rotation_flag = video_info->rotation_flag + 8;\r
568                 }
569                 enc_buff->dst_width = video_info->dst_width;\r
570                 enc_buff->dst_height = video_info->dst_height;\r
571                 
572                 
573                 
574                 enc_buff->src_width = video_info->src_width;\r
575                 enc_buff->src_height = video_info->src_height;\r
576
577                 
578                 enc_buff->dst_vir_w = video_info->dst_width;\r
579                 enc_buff->dst_vir_h = video_info->dst_height;\r
580                 enc_buff->y_offset = enc_buff->c_offset = 0;
581                 enc_buff->mode = 0;
582                 
583                 enc_buff->src_y = info->fix.smem_start + par->y_offset;//info->screen_base + par->y_offset;//info_buffer[8];
584                 enc_buff->src_uv = info->fix.smem_start + par->y_offset + video_info->src_width * video_info->src_height;//dst_width*dst_height;//+ par->y_offset + dst_width*dst_height;//info_buffer[9];\r
585                 enc_buff->Frame_Time = (long long)video_info->Wimo_RGB_time.tv_sec * 1000000ll + video_info->Wimo_RGB_time.tv_usec;\r
586                 
587                 if(0)//rotation_sign == IPP_ROT_90  || rotation_sign == IPP_ROT_270)
588                 {
589                         if(enc_buff->dst_vir_w > enc_buff->dst_vir_h)
590                         {
591                                 enc_buff->dst_height = enc_buff->dst_vir_h;
592                                 enc_buff->dst_width = ((enc_buff->dst_vir_h * enc_buff->dst_vir_h) / enc_buff->dst_vir_w) & 0xfffc;
593                                 if(par->format == 1)
594                                         enc_buff->c_offset = enc_buff->y_offset = ((enc_buff->dst_vir_w - enc_buff->dst_width ) )  & 0xfffc; 
595
596                                 else
597                                 enc_buff->c_offset = enc_buff->y_offset = ((enc_buff->dst_vir_w - enc_buff->dst_width ) *2)  & 0xfffc; 
598                                 
599                         }
600                         else
601                         {
602                                 enc_buff->dst_width = enc_buff->dst_vir_w;
603                                 enc_buff->dst_height = ((enc_buff->dst_vir_w * enc_buff->dst_vir_w) / enc_buff->dst_vir_h) ;
604                                 enc_buff->y_offset = (enc_buff->dst_vir_h - enc_buff->dst_height ) *  enc_buff->dst_vir_w * 2; 
605                                 enc_buff->c_offset = (enc_buff->dst_vir_h - enc_buff->dst_height ) * enc_buff->dst_vir_w ;  ; 
606                         }
607                 }
608         //      printk("width height %d %d  vir_w %d vir_h %d y_offset %d c_offset %d rotation_sign %d\n",enc_buff->dst_width,enc_buff->dst_height,enc_buff->dst_vir_w,enc_buff->dst_vir_h,enc_buff->y_offset,
609                 //      enc_buff->c_offset,rotation_sign);
610         //      printk("mode 0 enc_buff.src0.w %d %d enc_buff %x enc_buff->mode %d bit %d format %d\n",enc_buff->src_width,enc_buff->src_height,(unsigned long)enc_buff
611                 //      ,enc_buff->mode,enc_buff->bitperpixel,par->format);
612
613         }       
614         DLOG(" test %d %d %d %d %d %d %x %x\n",enc_buff->dst_vir_w,enc_buff->dst_width,enc_buff->dst_vir_h,enc_buff->dst_height\r
615                 ,video_info->Last_rotation_flag , enc_buff->rotation_flag,\r
616                 video_info->enc_buff[0].ui_buffer_map,video_info->enc_buff[1].ui_buffer_map);\r
617         if((enc_buff->dst_vir_w != enc_buff->dst_width  || enc_buff->dst_vir_h != enc_buff->dst_height )   && video_info->Last_rotation_flag != enc_buff->rotation_flag)//wimo_info.Last_rotation_flag != enc_buff->rotation_sign)\r
618         {
619                 int i;
620                 if(enc_buff->rotation_flag & 0x8)\r
621                 {
622                         for(i = 0; i < video_info->buffer_num; i++)\r
623                         {
624                                 memset(video_info->enc_buff[i].ui_buffer_map,0,enc_buff->dst_vir_w * enc_buff->dst_vir_h * 4);//dst_width*dst_height);\r
625                         }
626                 }
627                 else if((enc_buff->rotation_flag & 0x8 )== 0)\r
628                 {
629                         for(i = 0; i < video_info->buffer_num; i++)\r
630                         {
631                                 memset(video_info->enc_buff[i].ui_buffer_map,0,enc_buff->dst_vir_w * enc_buff->dst_vir_h * 2);//dst_width*dst_height);\r
632                         }
633                 }
634         //      memset(ui_buffer_map,0,enc_buff->dst_vir_w * enc_buff->dst_vir_h * 4);//dst_width*dst_height);
635                 //memset(ui_buffer_map + enc_buff->dst_height * enc_buff->dst_width, 0x80,enc_buff->dst_height * enc_buff->dst_width / 2);//dst_width*dst_height,0x80,dst_width*dst_height/2);
636         //      printk("rotation change wimo_info.Last_rotation_flag %d enc_buff->rotation_sign %d\n",wimo_info.Last_rotation_flag,enc_buff->rotation_sign);
637         }
638         video_info->Last_rotation_flag = enc_buff->rotation_flag;\r
639         
640         return ret;\r
641 }
642  int wimo_prepare_buff(struct enc_buff_info *enc_buff)\r
643 {
644         
645         struct rk29_ipp_req overlay_req;
646         struct rk29_ipp_req overlay_req_1;
647         int err = 0;\r
648         \r
649         memset(&overlay_req, 0 , sizeof(overlay_req));
650         memset(&overlay_req_1, 0 , sizeof(overlay_req_1));
651         //printk("inf->video_mode %d\n",inf->video_mode);       
652         if(enc_buff->mode == 0 )
653         {
654                 \r
655                 overlay_req.src0.YrgbMst = enc_buff->src_y;//info->fix.smem_start + par->y_offset;//info->screen_base + par->y_offset;//info_buffer[8];
656                 overlay_req.src0.CbrMst =  enc_buff->src_uv;//info->fix.smem_start + par->y_offset + enc_buff->src_width * enc_buff->src_height;//dst_width*dst_height;//+ par->y_offset + dst_width*dst_height;//info_buffer[9];
657                 overlay_req.src0.w = enc_buff->src_width ;//dst_width;//info_buffer[2];
658                 overlay_req.src0.h = enc_buff->src_height ;//dst_height;//info_buffer[3];
659                 overlay_req.src0.fmt = (enc_buff->bitperpixel == 16) ? 1 : 0;//3;
660                 overlay_req.dst0.YrgbMst = (unsigned long)(enc_buff->ui_buffer + enc_buff->y_offset);//overlay_buffer + info_buffer[4] + info_buffer[5] * dst_width;\r
661                 overlay_req.dst0.CbrMst = (unsigned long)(enc_buff->ui_buffer + enc_buff->dst_vir_w * enc_buff->dst_height +  enc_buff->c_offset);//dst_width*dst_height;//(unsigned char*) overlay_buffer + dst_width*dst_height +info_buffer[4] + (  info_buffer[5] * dst_width) / 2;// info_buffer[6] * info_buffer[7];\r
662
663                 overlay_req.dst0.w = enc_buff->dst_width ;//dst_width;//info_buffer[6];
664                 overlay_req.dst0.h = enc_buff->dst_height ;//dst_height;//info_buffer[7];
665                 overlay_req.dst0.fmt = (enc_buff->bitperpixel== 16) ? 1 : 0;//3;3;
666                 overlay_req.deinterlace_enable = 0;
667                 overlay_req.timeout = 1000000;
668                 overlay_req.src_vir_w = enc_buff->src_width ;//dst_width;//info_buffer[2];
669                 overlay_req.dst_vir_w = enc_buff->dst_vir_w ;//dst_width; 
670
671                 
672                 //printk("mode 0 overlay_req.src0.w %d %d enc_buff %x\n",overlay_req.src0.w,overlay_req.src0.h,(unsigned long)enc_buff);
673                 overlay_req.flag = enc_buff->rotation_flag & 0x7;\r
674                 err = ipp_blit_sync(&overlay_req);\r
675                 if(err)
676                                 goto WIMO_IPP_ERROR;
677                                 //printk("mode 0err %d w h fmt time out %d %d %d %d",err,overlay_req.src0.w,overlay_req.src0.h,overlay_req.src0.fmt,overlay_req.timeout);
678                 //              printk("overlay_req.dst0.w %d overlay_req.dst0.h %d overlay_req.src0.w %d overlay_req.src0.h %d\n",overlay_req.dst0.w,overlay_req.dst0.h,overlay_req.src0.w,overlay_req.src0.h);
679
680                 
681                 
682                 
683                 
684         }       
685         else
686         {
687
688         \r
689                 if(enc_buff->xaff * 3 < enc_buff->xsize || enc_buff->yaff * 3 < enc_buff->ysize)// 3time or bigger scale up\r
690                 {
691                         unsigned long mid_width, mid_height;
692                         struct rk29_ipp_req overlay_req_1;
693                         if(enc_buff->xaff * 3 < enc_buff->xsize)
694                                 mid_width = enc_buff->xaff * 3;
695                         else
696                                 mid_width = enc_buff->xsize;
697                         
698                         if(enc_buff->yaff * 3 < enc_buff->ysize)
699                                 mid_height =  enc_buff->yaff * 3;
700                         else
701                                 mid_height = enc_buff->ysize;
702                         overlay_req.src0.YrgbMst = enc_buff->src_y;//info_buffer[8];
703                         overlay_req.src0.CbrMst = enc_buff->src_uv;//info_buffer[9];
704                         overlay_req.src0.w = enc_buff->xaff;// info_buffer[2];
705                         overlay_req.src0.h = enc_buff->yaff;// info_buffer[3];
706                         overlay_req.src0.fmt = 3;
707                         overlay_req.dst0.YrgbMst = (unsigned long)(enc_buff->ui_buffer + 2048000) ;//info_buffer[4] + info_buffer[5] * dst_width;   //С³ß´çƬԴÐèÒª2´Î·Å´ó£¬ËùÒÔ½«bufferµÄºó°ë¶ÎÓÃÓÚ»º´æ\r
708                         overlay_req.dst0.CbrMst = (unsigned long)( (unsigned char*) enc_buff->ui_buffer + mid_height * mid_width + 2048000);\r
709                 
710                         overlay_req.dst0.w = mid_width;//info_buffer[6];
711                         overlay_req.dst0.h = mid_height;//info_buffer[7];
712                         overlay_req.dst0.fmt = 3;
713                         overlay_req.timeout = 100000;
714                         overlay_req.src_vir_w = enc_buff->xaff;//info_buffer[2];
715                         overlay_req.dst_vir_w = mid_width;//dst_width;
716                         overlay_req.flag = IPP_ROT_0;
717 \r
718 \r
719 \r
720 \r
721                         overlay_req_1.src0.YrgbMst = (unsigned long)(enc_buff->ui_buffer + 2048000);\r
722                         overlay_req_1.src0.CbrMst = (unsigned long)((unsigned char*) enc_buff->ui_buffer + mid_height * mid_width + 2048000);\r
723                         overlay_req_1.src0.w = mid_width;
724                         overlay_req_1.src0.h = mid_height;// info_buffer[3];
725                         overlay_req_1.src0.fmt = 3;
726                         overlay_req_1.dst0.YrgbMst = (unsigned long)(enc_buff->ui_buffer + ((enc_buff->xpos + 1)&0xfffe) + enc_buff->ypos * enc_buff->dst_width);//info_buffer[4] + info_buffer[5] * dst_width;\r
727                         overlay_req_1.dst0.CbrMst = (unsigned long)((unsigned char*) enc_buff->ui_buffer + enc_buff->dst_width * enc_buff->dst_height + \r
728                                 ((enc_buff->xpos + 1)&0xfffe) + ( enc_buff->ypos  / 2)* enc_buff->dst_width) ;\r
729                         
730                         overlay_req_1.dst0.w = enc_buff->xsize;//info_buffer[6];
731                         overlay_req_1.dst0.h = enc_buff->ysize;//info_buffer[7];
732                         overlay_req_1.dst0.fmt = 3;
733                         overlay_req_1.timeout = 100000;
734                         overlay_req_1.src_vir_w = mid_width;//info_buffer[2];
735                         overlay_req_1.dst_vir_w = enc_buff->dst_vir_w;//dst_width;
736                         overlay_req_1.flag = IPP_ROT_0;
737                         
738
739                         err = ipp_blit_sync(&overlay_req);
740                         if(err)
741                                 goto WIMO_IPP_ERROR;
742                         dmac_flush_range(enc_buff->ui_buffer_map,enc_buff->ui_buffer_map + enc_buff->dst_height * enc_buff->dst_width * 3/2);//dst_width*dst_height*3/2);\r
743                         err = ipp_blit_sync(&overlay_req_1);
744                         if(err)
745                                 goto WIMO_IPP_ERROR;
746                 //      printk("err1 %d w h fmt time out %d %d %d %d workindex %d encbuff %x xaff %d yaff %d xsize %d ysize %d",
747                         //      err,overlay_req.src0.w,overlay_req.src0.h,overlay_req.src0.fmt,overlay_req.timeout,wimo_info.work_index,(unsigned long)enc_buff
748                         //      ,enc_buff->xaff,enc_buff->yaff,enc_buff->xsize,enc_buff->ysize);
749                 }
750                 else
751                 {
752                         overlay_req.src0.YrgbMst = enc_buff->src_y;//info_buffer[8];
753                         overlay_req.src0.CbrMst = enc_buff->src_uv;//info_buffer[9];
754                         overlay_req.src0.w = enc_buff->xaff;// info_buffer[2];
755                         overlay_req.src0.h = enc_buff->yaff;// info_buffer[3];
756                         overlay_req.src0.fmt = 3;
757                         overlay_req.dst0.YrgbMst = (unsigned long)(enc_buff->ui_buffer + ((enc_buff->xpos + 1)&0xfffe) + enc_buff->ypos * enc_buff->dst_width);//info_buffer[4] + info_buffer[5] * dst_width;\r
758                         overlay_req.dst0.CbrMst = (unsigned long)((unsigned char*) enc_buff->ui_buffer +  ((enc_buff->xpos + 1)&0xfffe) + \r
759                                 ( enc_buff->ypos  / 2)* enc_buff->dst_width +  enc_buff->dst_width *  enc_buff->dst_height);\r
760                         
761                         overlay_req.dst0.w = enc_buff->xsize;//wimo_info.xsize;//wimo_info.xaff;// wimo_info.xsize;//info_buffer[6];
762                         overlay_req.dst0.h = (enc_buff->ysize + 1) & 0xfffe;//(wimo_info.ysize + 1) & 0xfffe;//wimo_info.yaff;//(wimo_info.ysize + 1) & 0xfffe;//info_buffer[7];
763                         overlay_req.dst0.fmt = 3;
764                         overlay_req.timeout = 100000;
765                         overlay_req.src_vir_w = (enc_buff->xaff + 15) & 0xfff0;//enc_buff->xaff;//info_buffer[2];
766                         overlay_req.dst_vir_w = enc_buff->dst_vir_w;//wimo_info.dst_width;//wimo_info.yaff;//wimo_info.dst_width;//dst_width;
767                         overlay_req.flag = IPP_ROT_0;
768                         
769                         
770                         dmac_flush_range(enc_buff->ui_buffer_map,enc_buff->ui_buffer_map + enc_buff->dst_height *enc_buff->dst_width * 3/2);//dst_width*dst_height*3/2);\r
771                         err = ipp_blit_sync(&overlay_req);
772                         //printk("mode 1 overlay_req.src0.w %d %d overlay_req.dst0.w %d %d overlay_req.src_vir_w %d %d overlay_req.src0.YrgbMst %x %x overlay_req.dst0.YrgbMst %x %x ui_buffer %x pixel%x %x   %x  %x\n",
773                         //      overlay_req.src0.w,overlay_req.src0.h,overlay_req.dst0.w,overlay_req.dst0.h,overlay_req.src_vir_w ,overlay_req.dst_vir_w,overlay_req.src0.YrgbMst,overlay_req.src0.CbrMst,
774                         //      overlay_req.dst0.YrgbMst,overlay_req.dst0.CbrMst,ui_buffer,ui_buffer_map[0],ui_buffer_map[1],ui_buffer_map[1024],ui_buffer_map[1025]);
775                         if(err)
776                                 goto WIMO_IPP_ERROR;
777                         
778                                 //printk("err %d w h fmt time out %d %d %d %d",err,overlay_req.src0.w,overlay_req.src0.h,overlay_req.src0.fmt,overlay_req.timeout);
779                 }
780         }
781         
782         \r
783        
784         return 0;
785 WIMO_IPP_ERROR:
786         \r
787         return -1;
788 }
789 \r
790 int wimo_video_prepare(struct fb_info *info,u32 yuv_phy[2])\r
791 {\r
792         int ret = 0;\r
793         static int comin_time = 0;\r
794         if(wimo_count < 1)\r
795                 return WIMO_COUNT_ZERO;\r
796         mutex_lock(&video_lock);\r
797         DLOG("before wimo prepare para wimo_count %d wimo.video_start_sign %d  %d %d %x %x\n"\r
798                         ,wimo_count,wimo.video_start_sign,wimo.start_sign,wimo.video_info.avail_frame,wimo.video_info.buffer_num,(long)&wimo.video_info.buffer_num);\r
799         if(wimo.video_start_sign && wimo.start_sign)\r
800         {\r
801                 struct wimo_video_info *video_info = &wimo.video_info;\r
802                 struct enc_buff_info *enc_buff = &video_info->enc_buff[video_info->work_index]; \r
803                 //struct rk29fb_inf *inf = dev_get_drvdata(info->device);\r
804                 struct rk_fb_inf *inf = dev_get_drvdata(info->device);
805                 int ret;\r
806                 if(comin_time == 1)\r
807                 {\r
808                         printk("ENCODER_BUFFER_FULL wimo.video_info.avail_frame %d wimo.video_info.buffer_num %d\n",wimo.video_info.avail_frame,wimo.video_info.buffer_num);\r
809                 //      ret = ENCODER_BUFFER_FULL;\r
810                 //      goto buffer_full;\r
811                 }\r
812                 comin_time++;\r
813                 if((wimo.video_info.avail_frame>=wimo.video_info.buffer_num-1) )\r
814                 {\r
815                         DLOG("ENCODER_BUFFER_FULL wimo.video_info.avail_frame %d wimo.video_info.buffer_num %d\n",wimo.video_info.avail_frame,wimo.video_info.buffer_num);\r
816                         ret = ENCODER_BUFFER_FULL;\r
817                         goto buffer_full;\r
818                 }\r
819                 \r
820                 if(inf->video_mode == 0)\r
821                 {\r
822                                 do_gettimeofday(&wimo.video_info.Wimo_RGB_time);\r
823                                 rgb_time++;\r
824                 }\r
825                 else\r
826                 {       \r
827                         printk("videomode = %d err \n",inf->video_mode);\r
828                 }\r
829                 \r
830                 \r
831                 wimo_prepare_para(info,video_info,enc_buff);\r
832                 ret = wimo_prepare_buff(enc_buff);\r
833                 if(ret == 0)\r
834                 {\r
835                         video_info->avail_frame++;\r
836                         //wimo_info.avail_frame%=(wimo_info.buffer_num + 1);\r
837                         video_info->work_index++;\r
838                         video_info->work_index%= video_info->buffer_num;\r
839                         DLOG("prepare video_info->avail_frame %d video_info->work_index %d video_info->avail_index %d\n",video_info->avail_frame,video_info->work_index,video_info->avail_index);\r
840         //              if(((wimo_info.avail_index + wimo_info.avail_frame) % wimo_info.buffer_num)!=wimo_info.work_index)\r
841                         //      DLOG("wimo_prepare_buff 2 test_sign %d avail_index %d avail_frame %d work_index %d mode %d %d time %lld %lld  bitperpixel %d src_width %d src_height %d dst_width %d dst_height %d dst_y %x dst_uv %x\n",\r
842                         //      wimo_info.test_sign,wimo_info.avail_index,wimo_info.avail_frame,wimo_info.work_index,enc_buff[wimo_info.avail_index].mode,enc_buff[1-wimo_info.avail_index].mode,\r
843                         //      wimo_info.enc_buff[wimo_info.avail_index].Frame_Time,\r
844                         //              wimo_info.enc_buff[1-wimo_info.avail_index].Frame_Time, \r
845                         //              enc_buff->bitperpixel,enc_buff->src_width,enc_buff->src_height,enc_buff->dst_width,enc_buff->dst_height\r
846                         //              ,overlay_req.dst0.YrgbMst,overlay_req.dst0.CbrMst);\r
847                 }\r
848                 else\r
849                 {\r
850                         DLOG("Wimo_IPP_ERROR err %d  enc_buff.src0.w %x %x enc_buff %x enc_buff->mode %x format %x workindex %x xaff %x yaff %x xsize %x ysize %x yuv_num %d %x %x %x %x\n"\r
851                                 ,ret,enc_buff->src_width,enc_buff->src_height,(u32)enc_buff,enc_buff->mode,enc_buff->bitperpixel,video_info->work_index,\r
852                                 enc_buff->xaff,enc_buff->yaff,enc_buff->xsize,\r
853                                 enc_buff->ysize,yuv_time,enc_buff->ui_buffer_map[0],enc_buff->ui_buffer_map[1],enc_buff->ui_buffer_map[2],enc_buff->ui_buffer_map[3]);\r
854                 }\r
855         }\r
856         else\r
857         {\r
858                 //DLOG("wimo_video not open\n");\r
859                 ret = VIDEO_ENCODER_CLOSED;\r
860         }\r
861         mutex_unlock(&video_lock);\r
862         \r
863         return ret;\r
864 buffer_full:\r
865         mutex_unlock(&video_lock);\r
866         return ret;\r
867 }\r
868 #endif
869 \r
870 \r
871 static int wimo_open(struct inode *inode, struct file *file)\r
872 {\r
873     int ret = 0;\r
874 \r
875     DLOG("wimo_open current %u \n", current->pid);\r
876     \r
877     return ret;\r
878 }\r
879 \r
880 static int wimo_mmap(struct file *file, struct vm_area_struct *vma)\r
881 {\r
882         int ret = 0;\r
883         DLOG("wimo_mmap do  nothing current->pid %u\n",current->pid);\r
884 //error:\r
885         return ret;\r
886 }\r
887 \r
888 static int wimo_release(struct inode *inode, struct file *file)\r
889 {\r
890     DLOG("wimo_release do  nothing current->pid %u\n",current->pid);\r
891 \r
892 \r
893     return 0;\r
894 }\r
895 \r
896 static long wimo_ioctl(struct file *file, unsigned int cmd, unsigned long arg)\r
897 {\r
898         long  ret = 0;\r
899 //      DLOG("wimo_ioctl cmd %d \n",cmd);\r
900         switch (cmd) {\r
901         case  WIMO_START:       \r
902                 {\r
903                         {\r
904                                 \r
905                                 mutex_lock(&wimo_lock);\r
906                                 wimo_start();\r
907                                 mutex_unlock(&wimo_lock);\r
908                                 printk("wimo_ioctl WIMO_START wimo.start_sign %d\n",wimo.start_sign);\r
909                         }\r
910                 }\r
911                 break;\r
912         case  WIMO_STOP:\r
913                 {\r
914                         {\r
915                                 mutex_lock(&wimo_lock);\r
916                                 wimo_stop();\r
917                                 mutex_unlock(&wimo_lock);\r
918                                 printk("wimo_ioctl WIMO_STOP wimo.start_sign %d\n",wimo.start_sign);\r
919                         }\r
920                         {\r
921                                 \r
922                         }\r
923                 }\r
924                 break;\r
925         case  WIMO_SET_ROTATION:                        \r
926                 break;\r
927         case  WIMO_VIDEO_OPEN:          \r
928                 \r
929                 {\r
930                         unsigned long temp[6];\r
931                         \r
932                         if (copy_from_user(temp, (void*)arg, 24))\r
933                                 return -EFAULT;\r
934                         mutex_lock(&video_lock);\r
935                         ret = wimo_video_open(temp);\r
936                         mutex_unlock(&video_lock);\r
937                 }\r
938                 \r
939                 break;\r
940         case  WIMO_VIDEO_CLOSE: \r
941                 \r
942                 {\r
943                         mutex_lock(&video_lock);\r
944                         ret = wimo_video_close(&wimo.video_info);\r
945                         mutex_unlock(&video_lock);\r
946                 }\r
947                 \r
948                 break;\r
949         case  WIMO_VIDEO_GET_BUF:               \r
950                 \r
951                 {\r
952                         \r
953                         unsigned long temp_data[8];\r
954                         mutex_lock(&video_lock);\r
955                         \r
956                         if(wimo.video_start_sign == 1 && wimo.start_sign == 1 && wimo.video_info.buffer_num)\r
957                         {\r
958                                 \r
959                                 ret = wimo_video_find_frame(temp_data,&wimo.video_info);\r
960                                 if(ret == 0)\r
961                                 {\r
962                                         yuv_time =      rgb_time = 0;\r
963                                 }\r
964                         }       \r
965                         else\r
966                         {\r
967                                 ret = -1111;\r
968                                 DLOG("WIMO_VIDEO_GET_BUF starg_sign %d start_video_sign %d",wimo.start_sign,wimo.video_start_sign);\r
969                         }\r
970                         mutex_unlock(&video_lock);\r
971                         if (copy_to_user((void*)arg, temp_data, 28))\r
972                                 return -EFAULT;\r
973                 }\r
974                 \r
975                 break;\r
976                 \r
977         case  WIMO_AUDIO_OPEN:          \r
978                 \r
979                 {\r
980                         unsigned long temp[6];\r
981                         struct wimo_audio_info *audio_info = &wimo.audio_info;\r
982                         if (copy_from_user(temp, (void*)arg, 24))\r
983                                 return -EFAULT;\r
984                         mutex_lock(&audio_lock);\r
985                         ret = wimo_audio_open(temp);\r
986                         mutex_unlock(&audio_lock);\r
987                         printk(" wimo_audio_open ret %daudio_info->Out_Buffer    %x  temp[0] %x audio_info->audio_data %x audio_info->time_stamp  %x  len = 3",\r
988                                 ret,(unsigned long)audio_info->Out_Buffer       ,(unsigned long)(temp[0]),audio_info->audio_data,audio_info->time_stamp );\r
989                 }\r
990                 \r
991                 break;\r
992         case  WIMO_AUDIO_CLOSE: \r
993                 \r
994                 {\r
995                         printk("WIMO_AUDIO_CLOSE\n");\r
996                         mutex_lock(&audio_lock);\r
997                         ret = wimo_audio_close();\r
998                         mutex_unlock(&audio_lock);\r
999                 }\r
1000                 \r
1001                 break;\r
1002         case  WIMO_AUDIO_SET_PARA:      \r
1003                 \r
1004                 {\r
1005                         struct wimo_audio_param temp_data;\r
1006                         if (copy_from_user((void*)(&temp_data), (void*)arg, sizeof(struct wimo_audio_param)))\r
1007                                 return -EFAULT;\r
1008                         mutex_lock(&audio_lock);\r
1009                         wimo_audio_set_para(&temp_data);\r
1010                         mutex_unlock(&audio_lock);\r
1011                 }\r
1012                 \r
1013                 break;\r
1014         case  WIMO_AUDIO_SET_VOL:       \r
1015                 \r
1016                 {\r
1017                         unsigned long temp_data;\r
1018                         \r
1019                         if (copy_from_user(&temp_data, (void*)arg, 4))\r
1020                                 return -EFAULT;\r
1021                         //printk("WIMO_AUDIO_SET_VOL set vol %d\n",temp_data);\r
1022                         mutex_lock(&audio_lock);\r
1023                         wimo.volumn_open_sign = temp_data;\r
1024                         mutex_unlock(&audio_lock);\r
1025                 }\r
1026                 \r
1027                 break;  \r
1028         case  WIMO_AUDIO_GET_VOL:\r
1029                 {\r
1030                         //printk("WIMO_AUDIO_SET_VOL get vol %d\n",wimo.volumn_open_sign);      \r
1031                         if(copy_to_user((void*)arg,&wimo.volumn_open_sign,4))\r
1032                                 return -EFAULT;\r
1033                 }\r
1034                 break;\r
1035         case  WIMO_AUDIO_GET_BUF:               \r
1036                 \r
1037                 {\r
1038                         struct wimo_audio_info *audio_info = &wimo.audio_info;\r
1039                         mutex_lock(&audio_lock); \r
1040                         if(wimo.audio_start_sign == 1 && wimo.start_sign == 1 && wimo.audio_info.buffer_size)\r
1041                         {\r
1042                                 if(audio_info->data_len >= 1)\r
1043                                 {\r
1044                                         struct timeval timeFirst;\r
1045                                         do_gettimeofday(&timeFirst);    \r
1046                                         audio_info->Out_Buffer = (void*)(&audio_info->audio_data[audio_info->head_offset * audio_info->nBytePerFrame]);\r
1047                                         \r
1048                                         \r
1049                                         wimo_filp_output->f_op->write(wimo_filp_output, audio_info->Out_Buffer, audio_info->nBytePerFrame, &wimo_filp_output->f_pos);\r
1050                                         if (copy_to_user((void*)arg,audio_info->Out_Buffer,  4096))\r
1051                                                 ret = -EFAULT;\r
1052                                         if (copy_to_user((void*)arg+4096,(void*)(&audio_info->time_stamp[audio_info->head_offset]),  8))\r
1053                                                 ret = -EFAULT;\r
1054                                         if (copy_to_user((void*)arg+4104,&timeFirst,  8))\r
1055                                                 ret = -EFAULT;\r
1056                                         if (copy_to_user((void*)arg+4112,&audio_info->head_offset,  8))\r
1057                                                 ret = -EFAULT;\r
1058                                         audio_info->data_len --;\r
1059                                         audio_info->head_offset ++;\r
1060                                         audio_info->head_offset %= audio_info->buffer_size;\r
1061                                 }\r
1062                                 else\r
1063                                 {\r
1064                                         ret = -1;\r
1065                                 }\r
1066                         }       \r
1067                         else\r
1068                         {\r
1069                                 ret = -1111;\r
1070                         }\r
1071                         \r
1072                         mutex_unlock(&audio_lock);\r
1073                 }\r
1074                 \r
1075                 break;\r
1076         default:\r
1077                 return -EINVAL;\r
1078         }\r
1079         return ret;\r
1080 }\r
1081 \r
1082 struct file_operations wimo_fops = {\r
1083         .open = wimo_open,\r
1084         .mmap = wimo_mmap,\r
1085         .unlocked_ioctl = wimo_ioctl,\r
1086         .release = wimo_release,\r
1087 };\r
1088 \r
1089 #if WIMO_DEBUG\r
1090 static ssize_t debug_open(struct inode *inode, struct file *file)\r
1091 {\r
1092         file->private_data = inode->i_private;\r
1093         return 0;\r
1094 }\r
1095 \r
1096 static ssize_t debug_read(struct file *file, char __user *buf, size_t count,\r
1097                           loff_t *ppos)\r
1098 {\r
1099         wdm_region *region, *tmp_region;\r
1100         const int debug_bufmax = 4096;\r
1101         static char buffer[4096];\r
1102         int n = 0;\r
1103 \r
1104         DLOG("debug open\n");\r
1105         n = scnprintf(buffer, debug_bufmax,\r
1106                       "pid #: mapped regions (offset, len, used, post) ...\n");\r
1107         down_read(&wdm_rwsem);\r
1108      {\r
1109         n += scnprintf(buffer + n, debug_bufmax - n,\r
1110                 "(%d,%d,%d,%d) ",\r
1111                 region->index, region->pfn, region->used, region->post);\r
1112         }\r
1113         up_read(&wdm_rwsem);\r
1114         n++;\r
1115         buffer[n] = 0;\r
1116         return simple_read_from_buffer(buf, count, ppos, buffer, n);\r
1117 }\r
1118 \r
1119 static struct file_operations debug_fops = {\r
1120         .read = debug_read,\r
1121         .open = debug_open,\r
1122 };\r
1123 #endif\r
1124 \r
1125 int wimo_setup(struct wimo_platform_data *pdata)\r
1126 {\r
1127         int err = 0;\r
1128     DLOG("wimo_setup pdata->name %s\n",pdata->name);\r
1129     if (wimo_count) {\r
1130                 printk(KERN_ALERT "Only one wimo driver can be register!\n");\r
1131         goto err_cant_register_device;\r
1132     }\r
1133 \r
1134     memset(&wimo, 0, sizeof(struct wimo_info));\r
1135 \r
1136     wimo.rotation_flag = IPP_ROT_0;     \r
1137 \r
1138     init_rwsem(&wdm_rwsem);\r
1139     wimo.dev.name = pdata->name;\r
1140     wimo.dev.minor = MISC_DYNAMIC_MINOR;\r
1141     wimo.dev.fops = &wimo_fops;\r
1142    \r
1143     err = misc_register(&wimo.dev);\r
1144     if (err) {\r
1145         printk(KERN_ALERT "Unable to register wimo driver!\n");\r
1146         goto err_cant_register_device;\r
1147     }\r
1148     mutex_init(&video_lock);    \r
1149     mutex_init(&audio_lock);            \r
1150         mutex_init(&wimo_lock);\r
1151     audio_data_to_wimo = wimo_audio_prepare;\r
1152     video_data_to_wimo = wimo_video_prepare;\r
1153     printk("set audio_data_to_wimo %x %x\n",(unsigned long)wimo_audio_prepare,(unsigned long)audio_data_to_wimo);\r
1154     #if WIMO_DEBUG\r
1155     debugfs_create_file(pdata->name, S_IFREG | S_IRUGO, NULL, (void *)wimo.dev.minor,\r
1156                         &debug_fops);\r
1157     #endif\r
1158     printk("%s: %d initialized\n", pdata->name, wimo.dev.minor);\r
1159     wimo_count++;\r
1160         return 0;\r
1161   \r
1162 //err_no_mem_for_metadata:\r
1163         misc_deregister(&wimo.dev);\r
1164 err_cant_register_device:\r
1165         return -1;\r
1166 }\r
1167 \r
1168 static int wimo_probe(struct platform_device *pdev)\r
1169 {\r
1170         struct wimo_platform_data *pdata;\r
1171         printk("wimo_probe\n");\r
1172         if (!pdev || !pdev->dev.platform_data) {\r
1173                 printk(KERN_ALERT "Unable to probe wimo!\n");\r
1174                 return -1;\r
1175         }\r
1176         pdata = pdev->dev.platform_data;\r
1177         return wimo_setup(pdata);\r
1178 }\r
1179 \r
1180 static int wimo_remove(struct platform_device *pdev)\r
1181 {\r
1182     if (!pdev || !pdev->dev.platform_data) {\r
1183         printk(KERN_ALERT "Unable to remove wimo!\n");\r
1184         return -1;\r
1185     }\r
1186         mutex_destroy(&wimo_lock);\r
1187     mutex_destroy(&audio_lock); \r
1188     mutex_destroy(&video_lock); \r
1189     if (wimo_count) {\r
1190             misc_deregister(&wimo.dev);\r
1191         wimo_count--;\r
1192     } else {\r
1193                 printk(KERN_ALERT "no wimo to remove!\n");\r
1194     }\r
1195         return 0;\r
1196 }\r
1197 \r
1198 static struct platform_driver wimo_driver = {\r
1199         .probe  = wimo_probe,\r
1200         .remove = wimo_remove,\r
1201         .driver = {.name = "wimo"}\r
1202         \r
1203 };\r
1204 \r
1205 \r
1206 static int __init wimo_init(void)\r
1207 {\r
1208         printk("wimo_init\n");\r
1209         return platform_driver_register(&wimo_driver);\r
1210 }\r
1211 \r
1212 static void __exit wimo_exit(void)\r
1213 {\r
1214         platform_driver_unregister(&wimo_driver);\r
1215 }\r
1216 \r
1217 module_init(wimo_init);\r
1218 module_exit(wimo_exit);\r
1219 \r
1220 #if     0//def CONFIG_PROC_FS\r
1221 #include <linux/proc_fs.h>\r
1222 #include <linux/seq_file.h>\r
1223 \r
1224 static int proc_wimo_show(struct seq_file *s, void *v)\r
1225 {\r
1226         if (wimo_count) {\r
1227                 seq_printf(s, "wimo opened\n");\r
1228         } else {\r
1229                 seq_printf(s, "wimo closed\n");\r
1230         return 0;\r
1231         }\r
1232 \r
1233     down_read(&wdm_rwsem);\r
1234         {\r
1235         }\r
1236 \r
1237     up_read(&wdm_rwsem);\r
1238     return 0;\r
1239 }\r
1240 \r
1241 static int proc_wimo_open(struct inode *inode, struct file *file)\r
1242 {\r
1243         return single_open(file, proc_wimo_show, NULL);\r
1244 }\r
1245 \r
1246 static const struct file_operations proc_wimo_fops = {\r
1247         .open           = proc_wimo_open,\r
1248         .read           = seq_read,\r
1249         .llseek         = seq_lseek,\r
1250         .release        = single_release,\r
1251 };\r
1252 \r
1253 static int __init wimo_proc_init(void)\r
1254 {\r
1255         proc_create("wimo", 0, NULL, &proc_wimo_fops);\r
1256         return 0;\r
1257 \r
1258 }\r
1259 late_initcall(wimo_proc_init);\r
1260 #endif /* CONFIG_PROC_FS */\r
1261 \r