123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410 |
- /*******************************************************************
- *
- * Copyright C 2010 by Amlogic, Inc. All Rights Reserved.
- *
- * Description:
- *
- * Author: Amlogic Software
- * Created: 2010/4/1 19:46
- *
- *******************************************************************/
-
- #include <linux/kernel.h>
- #include <linux/types.h>
- #include <linux/errno.h>
- #include <linux/interrupt.h>
- #include <linux/timer.h>
- #include <linux/time.h>
- #include <linux/vout/vinfo.h>
- #include <linux/vout/vout_notify.h>
- #include <linux/platform_device.h>
- #include <linux/amports/ptsserv.h>
- #include <linux/amports/canvas.h>
- #include <linux/amports/vframe.h>
- #include <linux/amports/vframe_provider.h>
- #include <linux/amports/vframe_receiver.h>
- #include <mach/am_regs.h>
- #include <linux/amlog.h>
- #include <linux/ge2d/ge2d_main.h>
- #include <linux/ge2d/ge2d.h>
- #include <linux/kthread.h>
- #include <linux/delay.h>
- #include <linux/semaphore.h>
- #include <linux/sched.h>
- #include <linux/platform_device.h>
- #include <linux/ge2d/ge2d_main.h>
- #include <linux/ge2d/ge2d.h>
- #include "vm_log.h"
- #include "vm.h"
- #include <linux/amlog.h>
- #include <linux/ctype.h>
- #include <linux/io.h>
- #include <linux/videodev2.h>
- #include <media/videobuf-core.h>
- #include <media/videobuf-dma-contig.h>
- #include <media/videobuf-vmalloc.h>
- #include <media/videobuf-dma-sg.h>
- #include <media/amlogic/656in.h>
- #include <linux/ctype.h>
- /*class property info.*/
- #include "vmcls.h"
- static int task_running = 0;
- #ifdef CONFIG_ARCH_MESON6
- #define GE2D_NV
- #endif
- #if 0
- static unsigned amlvm_time_log_enable = 0;
- module_param(amlvm_time_log_enable, uint, 0644);
- MODULE_PARM_DESC(amlvm_time_log_enable, "enable vm time log when get frames");
- #endif
- #define MAGIC_SG_MEM 0x17890714
- #define MAGIC_DC_MEM 0x0733ac61
- #define MAGIC_VMAL_MEM 0x18221223
- #define VIDTYPE_3D_LR 0x10000
- #define VIDTYPE_3D_BT 0x20000
- #define MAX_VM_POOL_SIZE 8
- #define MAX_VF_POOL_SIZE 8
- /*same as tvin pool*/
- static int VM_POOL_SIZE = 6 ;
- static int VF_POOL_SIZE = 6;
- static int VM_CANVAS_INDEX = 24;
- /*same as tvin pool*/
- static int vm_skip_count = 0 ; //skip 5 frames from vdin
- static int test_zoom = 0;
- static inline void vm_vf_put_from_provider(vframe_t *vf);
- #define INCPTR(p) ptr_atomic_wrap_inc(&p)
- #define VM_DEPTH_16_CANVAS 0x50 //for single canvas use ,RGB16, YUV422,etc
- #define VM_DEPTH_24_CANVAS 0x52
- #define VM_DEPTH_8_CANVAS_Y 0x54 // for Y/CbCr 4:2:0
- #define VM_DEPTH_8_CANVAS_UV 0x55
- #define VM_DEPTH_8_CANVAS_U 0x57
- #define VM_DEPTH_8_CANVAS_V 0x58
- #define VM_DMA_CANVAS_INDEX 0x5e
- #define VM_CANVAS_MX 0x5f
- static int vmdecbuf_size[] ={
- 0xE79C00,//5M
- 0x900000,//3M
- 0x591000,//2M
- 0x384000,//1M3
- 0x240000,//1M
- 0xE1000,//VGA
- 0x3C000,//QVGA
- };
- static struct v4l2_frmsize_discrete canvas_config_wh[]={
- {2592,1952},
- {2048,1536},
- {1600,1216},
- {1280,960},
- {1024,768},
- {640,480},
- {320,256},
- };
- #define GE2D_ENDIAN_SHIFT 24
- #define GE2D_ENDIAN_MASK (0x1 << GE2D_ENDIAN_SHIFT)
- #define GE2D_BIG_ENDIAN (0 << GE2D_ENDIAN_SHIFT)
- #define GE2D_LITTLE_ENDIAN (1 << GE2D_ENDIAN_SHIFT)
- #define PROVIDER_NAME "vm"
- #define RECEIVER_NAME "vm"
- static DEFINE_SPINLOCK(lock);
- static inline void ptr_atomic_wrap_inc(u32 *ptr)
- {
- u32 i = *ptr;
- i++;
- if (i >= VM_POOL_SIZE)
- i = 0;
- *ptr = i;
- }
- int start_vm_task(void) ;
- int start_simulate_task(void);
- static struct vframe_s vfpool[MAX_VF_POOL_SIZE];
- /*static u32 vfpool_idx[MAX_VF_POOL_SIZE];*/
- static s32 vfbuf_use[MAX_VF_POOL_SIZE];
- static s32 fill_ptr, get_ptr, putting_ptr, put_ptr;
- struct semaphore vb_start_sema;
- struct semaphore vb_done_sema;
- static inline vframe_t *vm_vf_get_from_provider(void);
- static inline vframe_t *vm_vf_peek_from_provider(void);
- static inline void vm_vf_put_from_provider(vframe_t *vf);
- static vframe_receiver_op_t* vf_vm_unreg_provider(void);
- static vframe_receiver_op_t* vf_vm_reg_provider(void);
- static void stop_vm_task(void) ;
- static int prepare_vframe(vframe_t *vf);
- /************************************************
- *
- * buffer op for video sink.
- *
- *************************************************/
- static inline u32 index2canvas(u32 index)
- {
- int i;
- int start_canvas, count;
- u32 canvas_tab[6] ;
- get_tvin_canvas_info(&start_canvas,&count);
- VM_POOL_SIZE = count ;
- VF_POOL_SIZE = count ;
- VM_CANVAS_INDEX = start_canvas;
- for(i =0; i< count; i++)
- canvas_tab[i] = VM_CANVAS_INDEX +i;
- return canvas_tab[index];
- }
- static struct vframe_s* vm_vf_peek(void *op_arg)
- {
- vframe_t *vf = NULL;
- vf = vm_vf_peek_from_provider();
- if(vf){
- if(vm_skip_count > 0){
- vm_skip_count--;
- vm_vf_get_from_provider();
- vm_vf_put_from_provider(vf);
- vf = NULL;
- }
- }
- return vf;
- }
- static struct vframe_s* vm_vf_get(void *op_arg)
- {
- return vm_vf_get_from_provider();
- }
- static void vm_vf_put(vframe_t *vf, void* op_arg)
- {
- prepare_vframe(vf);
- }
- static int vm_vf_states(vframe_states_t *states, void* op_arg)
- {
- return 0;
- }
- static vframe_t *local_vf_peek(void)
- {
- if (get_ptr == fill_ptr)
- return NULL;
- return &vfpool[get_ptr];
- }
- static vframe_t *local_vf_get(void)
- {
- vframe_t *vf;
- if (get_ptr == fill_ptr)
- return NULL;
- vf = &vfpool[get_ptr];
- INCPTR(get_ptr);
- return vf;
- }
- static void local_vf_put(vframe_t *vf)
- {
- int i;
- int canvas_addr;
- if(!vf)
- return;
- INCPTR(putting_ptr);
- for (i = 0; i < VF_POOL_SIZE; i++) {
- canvas_addr = index2canvas(i);
- if(vf->canvas0Addr == canvas_addr ){
- vfbuf_use[i] = 0;
- vm_vf_put_from_provider(vf);
- }
- }
- }
- /*static int local_vf_states(vframe_states_t *states)
- {
- unsigned long flags;
- int i;
- spin_lock_irqsave(&lock, flags);
- states->vf_pool_size = VF_POOL_SIZE;
- i = put_ptr - fill_ptr;
- if (i < 0) i += VF_POOL_SIZE;
- states->buf_free_num = i;
-
- i = putting_ptr - put_ptr;
- if (i < 0) i += VF_POOL_SIZE;
- states->buf_recycle_num = i;
-
- i = fill_ptr - get_ptr;
- if (i < 0) i += VF_POOL_SIZE;
- states->buf_avail_num = i;
-
- spin_unlock_irqrestore(&lock, flags);
- return 0;
- }*/
- static int vm_receiver_event_fun(int type, void *data, void *private_data)
- {
- switch(type){
- case VFRAME_EVENT_PROVIDER_VFRAME_READY:
- //up(&vb_start_sema);
- //printk("vdin frame ready !!!!!\n");
- break;
- case VFRAME_EVENT_PROVIDER_START:
- //printk("vm register!!!!!\n");
- vf_vm_reg_provider();
- vm_skip_count = 0;
- test_zoom = 0;
- break;
- case VFRAME_EVENT_PROVIDER_UNREG:
- //printk("vm unregister!!!!!\n");
- vm_local_init();
- vf_vm_unreg_provider();
- //printk("vm unregister succeed!!!!!");
- break;
- default:
- break;
- }
- return 0;
- }
- static vframe_receiver_op_t vm_vf_receiver =
- {
- .event_cb = vm_receiver_event_fun
- };
- static const struct vframe_operations_s vm_vf_provider =
- {
- .peek = vm_vf_peek,
- .get = vm_vf_get,
- .put = vm_vf_put,
- .vf_states = vm_vf_states,
- };
- static struct vframe_provider_s vm_vf_prov;
- static struct vframe_receiver_s vm_vf_recv;
- int get_unused_vm_index(void)
- {
- int i;
- for (i = 0; i < VF_POOL_SIZE; i++){
- if(vfbuf_use[i] == 0)
- return i;
- }
- return -1;
- }
- static int prepare_vframe(vframe_t *vf)
- {
- vframe_t* new_vf;
- int index;
-
- index = get_unused_vm_index();
- if(index < 0)
- return -1;
- new_vf = &vfpool[fill_ptr];
- memcpy(new_vf, vf, sizeof(vframe_t));
- vfbuf_use[index]++;
- INCPTR(fill_ptr);
- return 0;
- }
- /*************************************************
- *
- * buffer op for decoder, camera, etc.
- *
- *************************************************/
- /* static const vframe_provider_t *vfp = NULL; */
- void vm_local_init(void)
- {
- int i;
- for(i=0;i<MAX_VF_POOL_SIZE;i++)
- {
- vfbuf_use[i] = 0;
- }
- fill_ptr=get_ptr=putting_ptr=put_ptr=0;
- }
- static vframe_receiver_op_t* vf_vm_unreg_provider(void)
- {
- // ulong flags;
- vf_unreg_provider(&vm_vf_prov);
- stop_vm_task();
- // spin_lock_irqsave(&lock, flags);
- // vfp = NULL;
- // spin_unlock_irqrestore(&lock, flags);
- return (vframe_receiver_op_t*)NULL;
- }
- EXPORT_SYMBOL(vf_vm_unreg_provider);
- static vframe_receiver_op_t* vf_vm_reg_provider( )
- {
- ulong flags;
- spin_lock_irqsave(&lock, flags);
- spin_unlock_irqrestore(&lock, flags);
- vm_buffer_init();
-
- vf_reg_provider(&vm_vf_prov);
- start_vm_task();
- #if 0
- start_simulate_task();
- #endif
-
- return &vm_vf_receiver;
- }
- EXPORT_SYMBOL(vf_vm_reg_provider);
- /*static const struct vframe_provider_s * vm_vf_get_vfp_from_provider(void)
- {
- return vfp;
- } */
- static inline vframe_t *vm_vf_peek_from_provider(void)
- {
- struct vframe_provider_s *vfp;
- vframe_t *vf;
-
- vfp = vf_get_provider(RECEIVER_NAME);
- if (!(vfp && vfp->ops && vfp->ops->peek))
- return NULL;
- vf = vfp->ops->peek(vfp->op_arg);
- return vf;
- }
- static inline vframe_t *vm_vf_get_from_provider(void)
- {
- struct vframe_provider_s *vfp;
-
- vfp = vf_get_provider(RECEIVER_NAME);
- if (!(vfp && vfp->ops && vfp->ops->peek))
- return NULL;
- return vfp->ops->get(vfp->op_arg);
- }
- static inline void vm_vf_put_from_provider(vframe_t *vf)
- {
- struct vframe_provider_s *vfp;
- vfp = vf_get_provider(RECEIVER_NAME);
- if (!(vfp && vfp->ops && vfp->ops->peek))
- return;
- vfp->ops->put(vf,vfp->op_arg);
- }
- /************************************************
- *
- * main task functions.
- *
- *************************************************/
- static int get_input_format(vframe_t* vf)
- {
- int format= GE2D_FORMAT_M24_YUV420;
- if(vf->type&VIDTYPE_VIU_422)
- format = GE2D_FORMAT_S16_YUV422;
- else
- format = GE2D_FORMAT_M24_YUV420;
- return format;
- }
- static int get_input_frame(display_frame_t* frame ,vframe_t* vf)
- {
- int ret = 0;
- int top, left, bottom ,right;
- if (!vf)
- return -1;
- frame->frame_top = 0;
- frame->frame_left = 0 ;
- frame->frame_width = vf->width;
- frame->frame_height = vf->height;
- ret = get_curren_frame_para(&top ,&left , &bottom, &right);
- if(ret >= 0 ){
- frame->content_top = top&(~1);
- frame->content_left = left&(~1);
- frame->content_width = vf->width - 2*frame->content_left ;
- frame->content_height = vf->height - 2*frame->content_top;
- }else{
- frame->content_top = 0;
- frame->content_left = 0 ;
- frame->content_width = vf->width;
- frame->content_height = vf->height;
- }
- return 0;
- }
- static int get_output_format(int v4l2_format)
- {
- int format = GE2D_FORMAT_S24_YUV444;
- switch(v4l2_format){
- case V4L2_PIX_FMT_RGB565X:
- format = GE2D_FORMAT_S16_RGB_565;
- break;
- case V4L2_PIX_FMT_YUV444:
- format = GE2D_FORMAT_S24_YUV444;
- break;
- case V4L2_PIX_FMT_VYUY:
- format = GE2D_FORMAT_S16_YUV422;
- break;
- case V4L2_PIX_FMT_BGR24:
- format = GE2D_FORMAT_S24_RGB ;
- break;
- case V4L2_PIX_FMT_RGB24:
- format = GE2D_FORMAT_S24_BGR;
- break;
- case V4L2_PIX_FMT_NV12:
- #ifdef GE2D_NV
- format = GE2D_FORMAT_M24_NV12;
- break;
- #endif
- case V4L2_PIX_FMT_NV21:
- #ifdef GE2D_NV
- format = GE2D_FORMAT_M24_NV21;
- break;
- #endif
- case V4L2_PIX_FMT_YUV420:
- format = GE2D_FORMAT_S8_Y;
- break;
- default:
- break;
- }
- return format;
- }
- typedef struct output_para{
- int width;
- int height;
- int bytesperline;
- int v4l2_format;
- int index;
- int v4l2_memory;
- unsigned vaddr;
- }output_para_t;
- static output_para_t output_para = {0,0,0,0,0};
- typedef struct vm_dma_contig_memory {
- u32 magic;
- void *vaddr;
- dma_addr_t dma_handle;
- unsigned long size;
- int is_userptr;
- }vm_contig_memory_t;
- int is_need_ge2d_pre_process(void)
- {
- int ret = 0;
- switch(output_para.v4l2_format) {
- case V4L2_PIX_FMT_RGB565X:
- case V4L2_PIX_FMT_YUV444:
- case V4L2_PIX_FMT_VYUY:
- case V4L2_PIX_FMT_BGR24:
- case V4L2_PIX_FMT_RGB24:
- case V4L2_PIX_FMT_YUV420:
- case V4L2_PIX_FMT_NV12:
- case V4L2_PIX_FMT_NV21:
- ret = 1;
- break;
- default:
- break;
- }
- return ret;
- }
- int is_need_sw_post_process(void)
- {
- int ret = 0;
- switch(output_para.v4l2_memory){
- case MAGIC_DC_MEM:
- goto exit;
- break;
- case MAGIC_SG_MEM:
- case MAGIC_VMAL_MEM:
- default:
- ret = 1;
- break;
- }
- exit:
- return ret;
- }
- int get_canvas_index(int v4l2_format, int *depth)
- {
- int canvas = VM_DEPTH_16_CANVAS;
- *depth = 16;
- switch(v4l2_format){
- case V4L2_PIX_FMT_RGB565X:
- case V4L2_PIX_FMT_VYUY:
- canvas = VM_DEPTH_16_CANVAS;
- *depth = 16 ;
- break;
- case V4L2_PIX_FMT_YUV444:
- case V4L2_PIX_FMT_BGR24:
- case V4L2_PIX_FMT_RGB24:
- canvas = VM_DEPTH_24_CANVAS;
- *depth = 24;
- break;
- case V4L2_PIX_FMT_NV12:
- case V4L2_PIX_FMT_NV21:
- #ifdef GE2D_NV
- canvas = VM_DEPTH_8_CANVAS_Y | (VM_DEPTH_8_CANVAS_UV<<8);
- #else
- canvas = VM_DEPTH_8_CANVAS_Y|(VM_DEPTH_8_CANVAS_U<<8)|(VM_DEPTH_8_CANVAS_V<<16);
- #endif
- *depth = 12;
- break;
- case V4L2_PIX_FMT_YUV420:
- canvas = VM_DEPTH_8_CANVAS_Y|(VM_DEPTH_8_CANVAS_U<<8)|(VM_DEPTH_8_CANVAS_V<<16);
- *depth = 12;
- break;
- default:
- break;
- }
- return canvas;
- }
- int vm_fill_buffer(struct videobuf_buffer* vb , int v4l2_format , int magic,void* vaddr)
- {
- vm_contig_memory_t *mem = NULL;
- char *buf_start,*vbuf_start;
- int buf_size;
- int depth=0;
- int ret = -1;
- int canvas_index = -1 ;
- struct videobuf_buffer buf={0};
- get_vm_buf_info((const char **)&buf_start,&buf_size,&vbuf_start);
- #if 0
- if(!vb)
- goto exit;
- #else
- if(!vb) {
- buf.width = 640;
- buf.height = 480;
- magic = MAGIC_VMAL_MEM ;
- v4l2_format = V4L2_PIX_FMT_YUV444 ;
- vb = &buf;
- }
- if(!task_running){
- return ret;
- }
- #endif
- switch(magic){
- case MAGIC_DC_MEM:
- mem = vb->priv;
- canvas_config(VM_DMA_CANVAS_INDEX,
- mem->dma_handle,
- vb->bytesperline, vb->height,
- CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32);
- canvas_index = VM_DMA_CANVAS_INDEX ;
- depth = (vb->bytesperline <<3)/vb->width;
- break;
- case MAGIC_SG_MEM:
- case MAGIC_VMAL_MEM:
- if(buf_start && buf_size)
- canvas_index = get_canvas_index(v4l2_format,&depth);
- break;
- default:
- canvas_index = VM_DEPTH_16_CANVAS ;
- break;
- }
- output_para.width = vb->width;
- output_para.height = vb->height;
- output_para.bytesperline = (vb->width *depth)>>3;
- output_para.index = canvas_index ;
- output_para.v4l2_format = v4l2_format ;
- output_para.v4l2_memory = magic ;
- output_para.vaddr = (unsigned)vaddr;
- up(&vb_start_sema);
- ret = down_interruptible(&vb_done_sema);
- return ret;
- }
- /*for decoder input processing
- 1. output window should 1:1 as source frame size
- 2. keep the frame ratio
- 3. input format should be YUV420 , output format should be YUV444
- */
- int vm_ge2d_pre_process(vframe_t* vf, ge2d_context_t *context,config_para_ex_t* ge2d_config)
- {
- int ret;
- int src_top ,src_left ,src_width, src_height;
- canvas_t cs0,cs1,cs2,cd;
- int current_mirror = camera_mirror_flag;
- display_frame_t input_frame={0};
- ret = get_input_frame(&input_frame , vf);
- src_top = input_frame.content_top;
- src_left = input_frame.content_left;
- src_width = input_frame.content_width;
- src_height = input_frame.content_height;
- if(test_zoom){
- test_zoom = 0;
- printk("top is %d , left is %d , width is %d , height is %d\n",input_frame.content_top ,input_frame.content_left,input_frame.content_width,input_frame.content_height);
- }
- /* data operating. */
- ge2d_config->alu_const_color= 0;//0x000000ff;
- ge2d_config->bitmask_en = 0;
- ge2d_config->src1_gb_alpha = 0;//0xff;
- ge2d_config->dst_xy_swap = 0;
- canvas_read(vf->canvas0Addr&0xff,&cs0);
- canvas_read((vf->canvas0Addr>>8)&0xff,&cs1);
- canvas_read((vf->canvas0Addr>>16)&0xff,&cs2);
- ge2d_config->src_planes[0].addr = cs0.addr;
- ge2d_config->src_planes[0].w = cs0.width;
- ge2d_config->src_planes[0].h = cs0.height;
- ge2d_config->src_planes[1].addr = cs1.addr;
- ge2d_config->src_planes[1].w = cs1.width;
- ge2d_config->src_planes[1].h = cs1.height;
- ge2d_config->src_planes[2].addr = cs2.addr;
- ge2d_config->src_planes[2].w = cs2.width;
- ge2d_config->src_planes[2].h = cs2.height;
- canvas_read(output_para.index&0xff,&cd);
- ge2d_config->dst_planes[0].addr = cd.addr;
- ge2d_config->dst_planes[0].w = cd.width;
- ge2d_config->dst_planes[0].h = cd.height;
- ge2d_config->src_key.key_enable = 0;
- ge2d_config->src_key.key_mask = 0;
- ge2d_config->src_key.key_mode = 0;
- ge2d_config->src_para.canvas_index=vf->canvas0Addr;
- ge2d_config->src_para.mem_type = CANVAS_TYPE_INVALID;
- ge2d_config->src_para.format = get_input_format(vf);
- ge2d_config->src_para.fill_color_en = 0;
- ge2d_config->src_para.fill_mode = 0;
- ge2d_config->src_para.x_rev = 0;
- ge2d_config->src_para.y_rev = 0;
- ge2d_config->src_para.color = 0xffffffff;
- ge2d_config->src_para.top = 0;
- ge2d_config->src_para.left = 0;
- ge2d_config->src_para.width = vf->width;
- ge2d_config->src_para.height = vf->height;
- /* printk("vf_width is %d , vf_height is %d \n",vf->width ,vf->height); */
- ge2d_config->src2_para.mem_type = CANVAS_TYPE_INVALID;
- ge2d_config->dst_para.canvas_index = output_para.index&0xff;
- #ifdef GE2D_NV
- if(output_para.v4l2_format != V4L2_PIX_FMT_YUV420)
- ge2d_config->dst_para.canvas_index = output_para.index;
- #endif
- ge2d_config->dst_para.mem_type = CANVAS_TYPE_INVALID;
- ge2d_config->dst_para.format = get_output_format(output_para.v4l2_format)|GE2D_LITTLE_ENDIAN;
- ge2d_config->dst_para.fill_color_en = 0;
- ge2d_config->dst_para.fill_mode = 0;
- ge2d_config->dst_para.x_rev = 0;
- ge2d_config->dst_para.y_rev = 0;
- ge2d_config->dst_para.color = 0;
- ge2d_config->dst_para.top = 0;
- ge2d_config->dst_para.left = 0;
- ge2d_config->dst_para.width = output_para.width;
- ge2d_config->dst_para.height = output_para.height;
- if(current_mirror==1){
- ge2d_config->dst_para.x_rev = 1;
- ge2d_config->dst_para.y_rev = 0;
- }else if(current_mirror==2){
- ge2d_config->dst_para.x_rev = 0;
- ge2d_config->dst_para.y_rev = 1;
- }else{
- ge2d_config->dst_para.x_rev = 0;
- ge2d_config->dst_para.y_rev = 0;
- }
- if(ge2d_context_config_ex(context,ge2d_config)<0) {
- printk("++ge2d configing error.\n");
- return -1;
- }
- stretchblt_noalpha(context,src_left ,src_top ,src_width, src_height,0,0,output_para.width,output_para.height);
- /* for cr of yuv420p or yuv420sp. */
- if(output_para.v4l2_format==V4L2_PIX_FMT_YUV420) {
- /* for cb. */
- canvas_read((output_para.index>>8)&0xff,&cd);
- ge2d_config->dst_planes[0].addr = cd.addr;
- ge2d_config->dst_planes[0].w = cd.width;
- ge2d_config->dst_planes[0].h = cd.height;
- ge2d_config->dst_para.canvas_index=(output_para.index>>8)&0xff;
- ge2d_config->dst_para.format=GE2D_FORMAT_S8_CB|GE2D_LITTLE_ENDIAN;
- ge2d_config->dst_para.width = output_para.width/2;
- ge2d_config->dst_para.height = output_para.height/2;
- if(current_mirror==1){
- ge2d_config->dst_para.x_rev = 1;
- ge2d_config->dst_para.y_rev = 0;
- }else if(current_mirror==2){
- ge2d_config->dst_para.x_rev = 0;
- ge2d_config->dst_para.y_rev = 1;
- }else{
- ge2d_config->dst_para.x_rev = 0;
- ge2d_config->dst_para.y_rev = 0;
- }
- if(ge2d_context_config_ex(context,ge2d_config)<0) {
- printk("++ge2d configing error.\n");
- return -1;
- }
- stretchblt_noalpha(context, src_left, src_top, src_width, src_height,
- 0, 0, ge2d_config->dst_para.width,ge2d_config->dst_para.height);
- }
- #ifndef GE2D_NV
- else if (output_para.v4l2_format==V4L2_PIX_FMT_NV12||
- output_para.v4l2_format==V4L2_PIX_FMT_NV21) {
- canvas_read((output_para.index>>8)&0xff,&cd);
- ge2d_config->dst_planes[0].addr = cd.addr;
- ge2d_config->dst_planes[0].w = cd.width;
- ge2d_config->dst_planes[0].h = cd.height;
- ge2d_config->dst_para.canvas_index=(output_para.index>>8)&0xff;
- ge2d_config->dst_para.format=GE2D_FORMAT_S8_CB|GE2D_LITTLE_ENDIAN;
- ge2d_config->dst_para.width = output_para.width/2;
- ge2d_config->dst_para.height = output_para.height/2;
- if(current_mirror==1){
- ge2d_config->dst_para.x_rev = 1;
- ge2d_config->dst_para.y_rev = 0;
- }else if(current_mirror==2){
- ge2d_config->dst_para.x_rev = 0;
- ge2d_config->dst_para.y_rev = 1;
- }else{
- ge2d_config->dst_para.x_rev = 0;
- ge2d_config->dst_para.y_rev = 0;
- }
- if(ge2d_context_config_ex(context,ge2d_config)<0) {
- printk("++ge2d configing error.\n");
- return -1;
- }
- stretchblt_noalpha(context,src_left ,src_top ,src_width, src_height,0,0,ge2d_config->dst_para.width,ge2d_config->dst_para.height);
- }
- #endif
- /* for cb of yuv420p or yuv420sp. */
- if(output_para.v4l2_format==V4L2_PIX_FMT_YUV420
- #ifndef GE2D_NV
- ||output_para.v4l2_format==V4L2_PIX_FMT_NV12||
- output_para.v4l2_format==V4L2_PIX_FMT_NV21
- #endif
- ) {
- canvas_read((output_para.index>>16)&0xff,&cd);
- ge2d_config->dst_planes[0].addr = cd.addr;
- ge2d_config->dst_planes[0].w = cd.width;
- ge2d_config->dst_planes[0].h = cd.height;
- ge2d_config->dst_para.canvas_index=(output_para.index>>16)&0xff;
- ge2d_config->dst_para.format=GE2D_FORMAT_S8_CR|GE2D_LITTLE_ENDIAN;
- ge2d_config->dst_para.width = output_para.width/2;
- ge2d_config->dst_para.height = output_para.height/2;
- if(current_mirror==1){
- ge2d_config->dst_para.x_rev = 1;
- ge2d_config->dst_para.y_rev = 0;
- }else if(current_mirror==2){
- ge2d_config->dst_para.x_rev = 0;
- ge2d_config->dst_para.y_rev = 1;
- }else{
- ge2d_config->dst_para.x_rev = 0;
- ge2d_config->dst_para.y_rev = 0;
- }
- if(ge2d_context_config_ex(context,ge2d_config)<0) {
- printk("++ge2d configing error.\n");
- return -1;
- }
- stretchblt_noalpha(context, src_left, src_top, src_width, src_height,
- 0, 0, ge2d_config->dst_para.width, ge2d_config->dst_para.height);
- }
- return output_para.index;
- }
- int vm_sw_post_process(int canvas , int addr)
- {
- int poss=0,posd=0;
- int i=0;
- void __iomem * buffer_y_start;
- void __iomem * buffer_u_start;
- void __iomem * buffer_v_start = 0;
- canvas_t canvas_work_y;
- canvas_t canvas_work_u;
- canvas_t canvas_work_v;
-
- if(!addr)
- return -1;
-
- canvas_read(canvas&0xff,&canvas_work_y);
- buffer_y_start = ioremap_wc(canvas_work_y.addr,canvas_work_y.width*canvas_work_y.height);
- if(buffer_y_start == NULL) {
- printk(" vm.postprocess:mapping buffer error\n");
- return -1;
- }
- if (output_para.v4l2_format == V4L2_PIX_FMT_BGR24||
- output_para.v4l2_format == V4L2_PIX_FMT_RGB24||
- output_para.v4l2_format== V4L2_PIX_FMT_RGB565X) {
- for(i=0;i<output_para.height;i++) {
- memcpy((void *)(addr+poss),(void *)(buffer_y_start+posd),output_para.bytesperline);
- poss+=output_para.bytesperline;
- posd+= canvas_work_y.width;
- }
- } else if (output_para.v4l2_format== V4L2_PIX_FMT_NV12||
- output_para.v4l2_format== V4L2_PIX_FMT_NV21) {
- #ifdef GE2D_NV
- unsigned uv_width = output_para.width;
- unsigned uv_height = output_para.height>>1;
- posd = 0;
- for(i=output_para.height;i>0;i--) { /* copy y */
- memcpy((void *)(addr+poss),(void *)(buffer_y_start+posd),output_para.width);
- poss+=output_para.width;
- posd+= canvas_work_y.width;
- }
- posd=0;
- canvas_read((canvas>>8)&0xff,&canvas_work_u);
- buffer_u_start = ioremap_wc(canvas_work_u.addr,canvas_work_u.width*canvas_work_u.height);
- for(i=uv_height; i > 0; i--) { /* copy y */
- memcpy((void *)(addr+poss), (void *)(buffer_u_start+posd), uv_width);
- poss += uv_width;
- posd+= canvas_work_u.width;
- }
- iounmap(buffer_u_start);
- #else
- char* dst_buff=NULL;
- char* src_buff=NULL;
- char* src2_buff=NULL;
- canvas_read((canvas>>8)&0xff,&canvas_work_u);
- buffer_u_start = ioremap_wc(canvas_work_u.addr,canvas_work_u.width*canvas_work_u.height);
-
- poss = posd = 0 ;
- for(i=0;i<output_para.height;i+=2) { /* copy y */
- memcpy((void *)(addr+poss),(void *)(buffer_y_start+posd),output_para.width);
- poss+=output_para.width;
- posd+= canvas_work_y.width;
- memcpy((void *)(addr+poss),(void *)(buffer_y_start+posd),output_para.width);
- poss+=output_para.width;
- posd+= canvas_work_y.width;
- }
- posd=0;
- canvas_read((canvas>>16)&0xff,&canvas_work_v);
- buffer_v_start = ioremap_wc(canvas_work_v.addr,canvas_work_v.width*canvas_work_v.height);
- dst_buff= (char*)addr+output_para.width* output_para.height;
- src_buff = (char*)buffer_u_start;
- src2_buff= (char*)buffer_v_start;
- if(output_para.v4l2_format== V4L2_PIX_FMT_NV12) {
- for(i = 0 ;i < output_para.height/2; i++){
- interleave_uv(src_buff, src2_buff, dst_buff, output_para.width/2);
- src_buff += canvas_work_u.width;
- src2_buff += canvas_work_v.width;
- dst_buff += output_para.width;
- }
- } else {
- for(i = 0 ;i < output_para.height/2; i++){
- interleave_uv(src2_buff, src_buff, dst_buff, output_para.width/2);
- src_buff += canvas_work_u.width;
- src2_buff += canvas_work_v.width;
- dst_buff += output_para.width;
- }
- }
- iounmap(buffer_u_start);
- iounmap(buffer_v_start);
- #endif
- } else if (output_para.v4l2_format == V4L2_PIX_FMT_YUV420) {
- int uv_width = output_para.width>>1;
- int uv_height = output_para.height>>1;
- posd=0;
- for(i=output_para.height;i>0;i--) { /* copy y */
- memcpy((void *)(addr+poss),(void *)(buffer_y_start+posd),output_para.width);
- poss+=output_para.width;
- posd+= canvas_work_y.width;
- }
-
- posd=0;
- canvas_read((canvas>>8)&0xff,&canvas_work_u);
- buffer_u_start = ioremap_wc(canvas_work_u.addr,canvas_work_u.width*canvas_work_u.height);
- canvas_read((canvas>>16)&0xff,&canvas_work_v);
- buffer_v_start = ioremap_wc(canvas_work_v.addr,canvas_work_v.width*canvas_work_v.height);
- for(i=uv_height;i>0;i--) { /* copy y */
- memcpy((void *)(addr+poss),(void *)(buffer_u_start+posd),uv_width);
- poss+=uv_width;
- posd+= canvas_work_u.width;
- }
- posd=0;
- for(i=uv_height;i>0;i--) { /* copy y */
- memcpy((void *)(addr+poss),(void *)(buffer_v_start+posd),uv_width);
- poss+=uv_width;
- posd+= canvas_work_v.width;
- }
- iounmap(buffer_u_start);
- iounmap(buffer_v_start);
- }
- iounmap(buffer_y_start);
- return 0;
- }
- static struct task_struct *task=NULL;
- static struct task_struct *simulate_task_fd=NULL;
- /* static int reset_frame = 1; */
- static int vm_task(void *data) {
- int ret = 0;
- vframe_t *vf;
- int src_canvas;
- int timer_count = 0 ;
- struct sched_param param = {.sched_priority = MAX_RT_PRIO - 1 };
- ge2d_context_t *context=create_ge2d_work_queue();
- config_para_ex_t ge2d_config;
-
- #ifdef CONFIG_AMLCAP_LOG_TIME_USEFORFRAMES
- struct timeval start;
- struct timeval end;
- unsigned long time_use=0;
- #endif
- memset(&ge2d_config,0,sizeof(config_para_ex_t));
- amlog_level(LOG_LEVEL_HIGH,"vm task is running\n ");
- sched_setscheduler(current, SCHED_FIFO, ¶m);
- allow_signal(SIGTERM);
- while(1) {
- ret = down_interruptible(&vb_start_sema);
- timer_count = 0;
- if (kthread_should_stop()){
- up(&vb_done_sema);
- break;
- }
- /* wait for frame from 656 provider until 500ms runs out */
- vf = local_vf_peek();
- while((vf == NULL) && (timer_count < 200)) {
- if(!task_running){
- up(&vb_done_sema);
- goto vm_exit;
- break;
- }
- vf = local_vf_peek();
- timer_count++;
- msleep(5);
- }
-
- /* start to convert frame. */
- #ifdef CONFIG_AMLCAP_LOG_TIME_USEFORFRAMES
- do_gettimeofday(&start);
- #endif
- vf = local_vf_get();
- if (vf) {
- src_canvas = vf->canvas0Addr;
- /* step1 convert 422 format to other format.*/
- if (is_need_ge2d_pre_process())
- src_canvas = vm_ge2d_pre_process(vf,context,&ge2d_config);
- local_vf_put(vf);
- #ifdef CONFIG_AMLCAP_LOG_TIME_USEFORFRAMES
- do_gettimeofday(&end);
- time_use = (end.tv_sec - start.tv_sec)*1000 +
- (end.tv_usec - start.tv_usec) / 1000;
- printk("step 1, ge2d use: %ldms\n", time_use);
- do_gettimeofday(&start);
- #endif
- /* step2 copy to user memory. */
- if (is_need_sw_post_process())
- vm_sw_post_process(src_canvas ,output_para.vaddr);
- #ifdef CONFIG_AMLCAP_LOG_TIME_USEFORFRAMES
- do_gettimeofday(&end);
- time_use = (end.tv_sec - start.tv_sec) * 1000+
- (end.tv_usec - start.tv_usec) / 1000;
- printk("step 2, memcpy use: %ldms\n", time_use);
- #endif
- }
- if (kthread_should_stop()){
- up(&vb_done_sema);
- break;
- }
- up(&vb_done_sema);
- }
- vm_exit:
- destroy_ge2d_work_queue(context);
- while(!kthread_should_stop()){
- /* may not call stop, wait..
- it is killed by SIGTERM,eixt on down_interruptible
- if not call stop,this thread may on do_exit and
- kthread_stop may not work good;
- */
- msleep(10);
- }
- return ret;
- }
- /*simulate v4l2 device to request filling buffer,only for test use*/
- static int simulate_task(void *data)
- {
- while (1) {
- msleep(50);
- vm_fill_buffer(NULL,0,0,NULL);
- printk("simulate succeed\n");
- }
- return 0;
- }
- /************************************************
- *
- * init functions.
- *
- *************************************************/
- int vm_buffer_init(void)
- {
- int i;
- u32 canvas_width, canvas_height;
- u32 decbuf_size;
- char *buf_start,*vbuf_start;
- int buf_size;
- int buf_num = 0;
- int local_pool_size = 0;
- get_vm_buf_info((const char **)&buf_start,&buf_size,&vbuf_start);
- sema_init(&vb_start_sema,0);
- sema_init(&vb_done_sema,0);
-
- if(!buf_start || !buf_size)
- goto exit;
- for(i=0; i<ARRAY_SIZE(vmdecbuf_size);i++){
- if( buf_size >= vmdecbuf_size[i])
- break;
- }
- if(i==ARRAY_SIZE(vmdecbuf_size)){
- printk("vmbuf size=%d less than the smallest vmbuf size%d\n",
- buf_size, vmdecbuf_size[i-1]);
- return -1;
- }
- canvas_width = canvas_config_wh[i].width;//1920;
- canvas_height = canvas_config_wh[i].height;//1200;
- decbuf_size = vmdecbuf_size[i];//0x700000;
- buf_num = buf_size/decbuf_size;
-
- if(buf_num > 0)
- local_pool_size = 1;
- else {
- local_pool_size = 0;
- printk("need at least one buffer to handle 1920*1080 data.\n");
- }
-
- for (i = 0; i < local_pool_size; i++)
- {
- canvas_config((VM_DEPTH_16_CANVAS+i),
- (unsigned long)(buf_start + i * decbuf_size),
- canvas_width*2, canvas_height,
- CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_LINEAR);
- canvas_config((VM_DEPTH_24_CANVAS+i),
- (unsigned long)(buf_start + i * decbuf_size),
- canvas_width*3, canvas_height,
- CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_LINEAR);
- canvas_config((VM_DEPTH_8_CANVAS_Y+ i),
- (unsigned long)(buf_start + i*decbuf_size/2),
- canvas_width, canvas_height,
- CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_LINEAR);
- canvas_config(VM_DEPTH_8_CANVAS_UV + i,
- (unsigned long)(buf_start + (i+1)*decbuf_size/2),
- canvas_width, canvas_height/2,
- CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_LINEAR);
- canvas_config((VM_DEPTH_8_CANVAS_U + i),
- (unsigned long)(buf_start + (i+1)*decbuf_size/2),
- canvas_width/2, canvas_height/2,
- CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_LINEAR);
- canvas_config((VM_DEPTH_8_CANVAS_V + i),
- (unsigned long)(buf_start + (i+3)*decbuf_size/4),
- canvas_width/2, canvas_height/2,
- CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_LINEAR);
- vfbuf_use[i] = 0;
- }
- exit:
- return 0;
- }
- int start_vm_task(void) {
- /* init the device. */
- vm_local_init();
- if(!task) {
- task=kthread_create(vm_task,0,"vm");
- if(IS_ERR(task)) {
- amlog_level(LOG_LEVEL_HIGH, "thread creating error.\n");
- return -1;
- }
- wake_up_process(task);
- }
- task_running = 1;
- return 0;
- }
- int start_simulate_task(void)
- {
- if(!simulate_task_fd) {
- simulate_task_fd=kthread_create(simulate_task,0,"vm");
- if(IS_ERR(simulate_task_fd)) {
- amlog_level(LOG_LEVEL_HIGH, "thread creating error.\n");
- return -1;
- }
- wake_up_process(simulate_task_fd);
- }
- return 0;
- }
- void stop_vm_task(void) {
- if(task){
- task_running = 0;
- send_sig(SIGTERM, task, 1);
- up(&vb_start_sema);
- kthread_stop(task);
- task = NULL;
- }
- vm_local_init();
- }
- /***********************************************************************
- *
- * global status.
- *
- ************************************************************************/
- static int vm_enable_flag=0;
- int get_vm_status() {
- return vm_enable_flag;
- }
- void set_vm_status(int flag) {
- if(flag >= 0)
- vm_enable_flag=flag;
- else
- vm_enable_flag=0;
- }
- /***********************************************************************
- *
- * file op section.
- *
- ************************************************************************/
- typedef struct {
- char name[20];
- unsigned int open_count;
- int major;
- unsigned int dbg_enable;
- struct class *cla;
- struct device *dev;
- char *buffer_start;
- unsigned int buffer_size;
- void __iomem *buffer_v_start;
- }vm_device_t;
- static vm_device_t vm_device;
- void set_vm_buf_info(char* start,unsigned int size) {
- vm_device.buffer_start=start;
- vm_device.buffer_size=size;
- vm_device.buffer_v_start = ioremap_wc((unsigned long)start,size);
- amlog_level(LOG_LEVEL_HIGH,"#############%x\n",vm_device.buffer_v_start);
- }
- void get_vm_buf_info(const char** start,unsigned int* size,char** vaddr) {
- *start = vm_device.buffer_start;
- *size = vm_device.buffer_size;
- *vaddr = vm_device.buffer_v_start;
- }
- static int vm_open(struct inode *inode, struct file *file)
- {
- ge2d_context_t *context=NULL;
- amlog_level(LOG_LEVEL_LOW,"open one vm device\n");
- file->private_data=context;
- vm_device.open_count++;
- return 0;
- }
- static long vm_ioctl(struct file *filp, unsigned int cmd, unsigned long args)
- {
- int ret=0 ;
- ge2d_context_t *context;
- void __user* argp;
-
- context=(ge2d_context_t *)filp->private_data;
- argp =(void __user*)args;
- switch (cmd)
- {
- case VM_IOC_2OSD0:
- break;
- case VM_IOC_ENABLE_PP:
- break;
- case VM_IOC_CONFIG_FRAME:
- break;
- default :
- return -ENOIOCTLCMD;
- }
- return ret;
- }
- static int vm_release(struct inode *inode, struct file *file)
- {
- ge2d_context_t *context=(ge2d_context_t *)file->private_data;
-
- if(context && (0==destroy_ge2d_work_queue(context)))
- {
- vm_device.open_count--;
- return 0;
- }
- amlog_level(LOG_LEVEL_LOW,"release one vm device\n");
- return -1;
- }
- /***********************************************************************
- *
- * file op init section.
- *
- ************************************************************************/
- static const struct file_operations vm_fops = {
- .owner = THIS_MODULE,
- .open = vm_open,
- .unlocked_ioctl = vm_ioctl,
- .release = vm_release,
- };
- int init_vm_device(void)
- {
- int ret=0;
- strcpy(vm_device.name,"vm");
- ret=register_chrdev(0,vm_device.name,&vm_fops);
- if(ret <=0)
- {
- amlog_level(LOG_LEVEL_HIGH,"register vm device error\r\n");
- return ret ;
- }
- vm_device.major=ret;
- vm_device.dbg_enable=0;
- amlog_level(LOG_LEVEL_LOW,"vm_dev major:%d\r\n",ret);
- vm_device.cla = init_vm_cls();
- if(vm_device.cla == NULL)
- return -1;
- vm_device.dev=device_create(vm_device.cla,NULL,MKDEV(vm_device.major,0)
- ,NULL,vm_device.name);
- if (IS_ERR(vm_device.dev)) {
- amlog_level(LOG_LEVEL_HIGH,"create vm device error\n");
- goto unregister_dev;
- }
- if(vm_buffer_init()<0) goto unregister_dev;
- vf_provider_init(&vm_vf_prov, PROVIDER_NAME ,&vm_vf_provider, NULL);
- //vf_reg_provider(&vm_vf_prov);
- vf_receiver_init(&vm_vf_recv, RECEIVER_NAME, &vm_vf_receiver, NULL);
- vf_reg_receiver(&vm_vf_recv);
- return 0;
- unregister_dev:
- class_unregister(vm_device.cla);
- return -1;
- }
- int uninit_vm_device(void)
- {
- stop_vm_task();
- if(vm_device.cla)
- {
- if(vm_device.dev)
- device_destroy(vm_device.cla, MKDEV(vm_device.major, 0));
- class_unregister(vm_device.cla);
- }
-
- unregister_chrdev(vm_device.major, vm_device.name);
- return 0;
- }
- /*******************************************************************
- *
- * interface for Linux driver
- *
- * ******************************************************************/
- MODULE_AMLOG(AMLOG_DEFAULT_LEVEL, 0xff, LOG_LEVEL_DESC, LOG_MASK_DESC);
- /* for driver. */
- static int vm_driver_probe(struct platform_device *pdev)
- {
- char* buf_start;
- unsigned int buf_size;
- struct resource *mem;
- if (!(mem = platform_get_resource(pdev, IORESOURCE_MEM, 0)))
- {
- buf_start = 0;
- buf_size = 0;
- } else {
- buf_start = (char *)mem->start;
- buf_size = mem->end - mem->start + 1;
- }
- set_vm_buf_info((char *)mem->start,buf_size);
- init_vm_device();
- return 0;
- }
- static int vm_drv_remove(struct platform_device *plat_dev)
- {
- uninit_vm_device();
- iounmap(vm_device.buffer_v_start);
- return 0;
- }
- /* general interface for a linux driver .*/
- static struct platform_driver vm_drv = {
- .probe = vm_driver_probe,
- .remove = vm_drv_remove,
- .driver = {
- .name = "vm",
- .owner = THIS_MODULE,
- }
- };
- static int __init
- vm_init_module(void)
- {
- int err;
- amlog_level(LOG_LEVEL_HIGH,"vm_init\n");
- if ((err = platform_driver_register(&vm_drv))) {
- printk(KERN_ERR "Failed to register vm driver (error=%d\n", err);
- return err;
- }
- return err;
- }
- static void __exit
- vm_remove_module(void)
- {
- platform_driver_unregister(&vm_drv);
- amlog_level(LOG_LEVEL_HIGH,"vm module removed.\n");
- }
- module_init(vm_init_module);
- module_exit(vm_remove_module);
- MODULE_DESCRIPTION("Amlogic Video Input Manager");
- MODULE_LICENSE("GPL");
- MODULE_AUTHOR("Simon Zheng <simon.zheng@amlogic.com>");
|