static s32 parse_jpeg_info(u8 *dp,logo_object_t *plogo) { int len = 0; int end=0; u8 *p = dp + 2; u8 tag; int ret=-EINVAL; if((u32)dp&7) goto exit ; //logo not align at 8byte boundary. if ((dp[0] != JPEG_TAG) || (dp[1] != JPEG_TAG_SOI)) goto exit; if (*p++ != JPEG_TAG) goto exit; tag = *p++; len = ((u32)(p[0]) << 8) | p[1]; amlog_mask_level(LOG_MASK_PARSER,LOG_LEVEL_LOW,"picture format jpeg\n"); plogo->parser=&logo_jpeg_parser; while (!end) { switch(tag) { case JPEG_TAG_SOF0: //get picture info plogo->parser->logo_pic_info.height= ((u32)p[3] << 8) | p[4]; plogo->parser->logo_pic_info.width = ((u32)p[5] << 8) | p[6]; plogo->parser->logo_pic_info.color_info=p[7]*8; amlog_mask_level(LOG_MASK_PARSER,LOG_LEVEL_LOW,"[picture info]%dx%d \n",plogo->parser->logo_pic_info.width ,plogo->parser->logo_pic_info.height); break; case JPEG_TAG_SOS: //goto file end amlog_mask_level(LOG_MASK_PARSER,LOG_LEVEL_LOW,"[0x%p]start scan line\n",p); while(p[0]!=JPEG_TAG || p[1]!=JPEG_TAG_EOI ) { p++; //to speed up we need setup file_size outof parser. if(p-dp>JPEG_INVALID_FILE_SIZE)//exception check { end=1; continue; } } ret=p-dp+2; end=1; amlog_mask_level(LOG_MASK_PARSER,LOG_LEVEL_LOW,"jpeg parser end,file size:%d\n",ret); continue; default: break; } amlog_mask_level(LOG_MASK_PARSER,LOG_LEVEL_LOW,"tag:0x%x,len:0x%x\n",tag,len); p += len; if (*p++ != JPEG_TAG) break; tag = *p++; len = ((u32)p[0] << 8) | p[1]; } exit: return ret; }
static int osd_check_var(struct fb_var_screeninfo *var, struct fb_info *info) { struct fb_fix_screeninfo *fix; struct myfb_dev *fbdev=( struct myfb_dev*)info->par; const color_bit_define_t *color_format_pt; fix = &info->fix; color_format_pt=_find_color_format(var); if (color_format_pt == NULL || color_format_pt->color_index==0) { return -EFAULT ; } amlog_mask_level(LOG_MASK_PARA,LOG_LEVEL_LOW,"select color format :index%d,bpp %d\r\n",color_format_pt->color_index, \ color_format_pt->bpp) ; fbdev->color=color_format_pt ; var->red.offset = color_format_pt->red_offset; var->red.length = color_format_pt->red_length; var->red.msb_right= color_format_pt->red_msb_right ; var->green.offset = color_format_pt->green_offset; var->green.length = color_format_pt->green_length; var->green.msb_right = color_format_pt->green_msb_right; var->blue.offset = color_format_pt->blue_offset; var->blue.length = color_format_pt->blue_length; var->blue.msb_right = color_format_pt->blue_msb_right; var->transp.offset= color_format_pt->transp_offset ; var->transp.length = color_format_pt->transp_length ; var->transp.msb_right = color_format_pt->transp_msb_right ; var->bits_per_pixel=color_format_pt->bpp ; amlog_mask_level(LOG_MASK_PARA,LOG_LEVEL_LOW, "rgba(L/O):%d/%d-%d/%d-%d/%d-%d/%d\n", var->red.length,var->red.offset, var->green.length,var->green.offset, var->blue.length,var->blue.offset, var->transp.length,var->transp.offset); fix->visual=color_format_pt->color_type ; //adjust memory length. fix->line_length = var->xres_virtual*var->bits_per_pixel/8; if(var->xres_virtual*var->yres_virtual*var->bits_per_pixel/8> fbdev->fb_len ) { amlog_mask_level(LOG_MASK_PARA,LOG_LEVEL_HIGH,"no enough memory for %d*%d*%d\r\n",var->xres,var->yres,var->bits_per_pixel); return -ENOMEM; } if (var->xres_virtual < var->xres) var->xres_virtual = var->xres; if (var->yres_virtual < var->yres) var->yres_virtual = var->yres; var->left_margin = var->right_margin = var->upper_margin = var->lower_margin = 0; if (var->xres + var->xoffset > var->xres_virtual) var->xoffset = var->xres_virtual - var->xres; if (var->yres + var->yoffset > var->yres_virtual) var->yoffset = var->yres_virtual - var->yres; return 0; }
/***************************************************************** ** ** vout driver interface ** ******************************************************************/ static int __init meson_vout_probe(struct platform_device *pdev) { int ret =-1; vout_info.base_class=NULL; amlog_mask_level(LOG_MASK_INIT,LOG_LEVEL_HIGH,"start init vout module \r\n"); #ifdef CONFIG_HAS_EARLYSUSPEND early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN; early_suspend.suspend = meson_vout_early_suspend; early_suspend.resume = meson_vout_late_resume; early_suspend.param = pdev; register_early_suspend(&early_suspend); #endif ret =create_vout_attr(); if(ret==0) { amlog_mask_level(LOG_MASK_INIT,LOG_LEVEL_HIGH,"create vout attribute ok \r\n"); } else { amlog_mask_level(LOG_MASK_INIT,LOG_LEVEL_HIGH,"create vout attribute fail \r\n"); } return ret; }
static int __init tv_init_module(void) { int ret ; info=(disp_module_info_t*)kmalloc(sizeof(disp_module_info_t),GFP_KERNEL) ; if (!info) { amlog_mask_level(LOG_MASK_INIT,LOG_LEVEL_HIGH,"can't alloc display info struct\r\n"); return -ENOMEM; } memset(info, 0, sizeof(disp_module_info_t)); sprintf(info->name,TV_CLASS_NAME) ; ret=register_chrdev(TV_CONF_MAJOR,info->name,&am_tv_fops); if(ret <0) { amlog_mask_level(LOG_MASK_INIT,LOG_LEVEL_HIGH,"register char dev tv error\r\n"); return ret ; } info->major=TV_CONF_MAJOR; amlog_mask_level(LOG_MASK_INIT,LOG_LEVEL_HIGH,"major number %d for disp\r\n",ret); if(vout_register_server(&tv_server)) { amlog_mask_level(LOG_MASK_INIT,LOG_LEVEL_HIGH,"register tv module server fail \r\n"); } else { amlog_mask_level(LOG_MASK_INIT,LOG_LEVEL_HIGH,"register tv module server ok \r\n"); } create_tv_attr(info); return 0; }
static int create_tv_attr(disp_module_info_t* info) { //create base class for display int i; info->base_class=class_create(THIS_MODULE,info->name); if(IS_ERR(info->base_class)) { amlog_mask_level(LOG_MASK_INIT,LOG_LEVEL_HIGH,"create tv display class fail\n"); return -1 ; } //create class attr for(i=0;i<ARRAY_SIZE(tv_attr);i++) { if ( class_create_file(info->base_class,tv_attr[i])) { amlog_mask_level(LOG_MASK_INIT,LOG_LEVEL_HIGH,"create disp attribute %s fail\n",tv_attr[i]->attr.name); } } sprintf(vdac_setting,"%x",get_current_vdac_setting()); #ifdef CONFIG_AML_VOUT_FRAMERATE_AUTOMATION sprintf(policy_fr_auto, "%d", DEFAULT_POLICY_FR_AUTO); #endif return 0; }
static void set_vout_mode(char * name) { #ifdef CONFIG_AML_HDMI_TX extern void hdmi_pre_set_change_mode(void); #endif vmode_t mode; amlog_mask_level(LOG_MASK_PARA,LOG_LEVEL_HIGH,"tvmode set to %s\r\n",name); mode=validate_vmode(name); if(VMODE_MAX==mode) { amlog_mask_level(LOG_MASK_PARA,LOG_LEVEL_HIGH,"no matched vout mode\n"); return ; } if(mode==get_current_vmode()) { amlog_mask_level(LOG_MASK_PARA,LOG_LEVEL_HIGH,"don't set the same mode as current.\r\n"); return ; } #ifdef CONFIG_AML_HDMI_TX if(mode < VMODE_LCD) hdmi_pre_set_change_mode(); #endif set_current_vmode(mode); amlog_mask_level(LOG_MASK_PARA,LOG_LEVEL_HIGH,"new mode %s set ok\r\n",name); vout_notifier_call_chain(VOUT_EVENT_MODE_CHANGE,&mode) ; printk("%s[%d]\n", __func__, __LINE__); }
static int create_vout_attr(void) { //create base class for display int i; extern const vinfo_t *get_current_vinfo(void); vinfo_t * init_mode; vout_info.base_class=class_create(THIS_MODULE,VOUT_CLASS_NAME); if(IS_ERR(vout_info.base_class)) { amlog_mask_level(LOG_MASK_INIT,LOG_LEVEL_HIGH,"create vout class fail\n"); return -1 ; } //create class attr for(i=0;i<VOUT_ATTR_MAX;i++) { if ( class_create_file(vout_info.base_class,vout_attr[i])) { amlog_mask_level(LOG_MASK_INIT,LOG_LEVEL_HIGH,"create disp attribute %s fail\n",vout_attr[i]->attr.name); } } // Init /sys/class/display/mode value init_mode = (vinfo_t *)get_current_vinfo(); if(init_mode) strcpy(mode, init_mode->name); return 0; }
/***************************************************************** ** ** vout driver interface ** ******************************************************************/ static int meson_vout_probe(struct platform_device *pdev) { int ret =-1; vout_info.base_class=NULL; amlog_mask_level(LOG_MASK_INIT,LOG_LEVEL_HIGH,"start init vout module\n"); #ifdef CONFIG_HAS_EARLYSUSPEND early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN; early_suspend.suspend = meson_vout_early_suspend; early_suspend.resume = meson_vout_late_resume; register_early_suspend(&early_suspend); #endif if(pdev->dev.of_node != NULL) { ret = of_property_read_u32(pdev->dev.of_node,"power_level",&power_level); } ret =create_vout_attr(); if(ret==0) { amlog_mask_level(LOG_MASK_INIT,LOG_LEVEL_HIGH,"create vout attribute ok\n"); } else { amlog_mask_level(LOG_MASK_INIT,LOG_LEVEL_HIGH,"create vout attribute fail\n"); } return ret; }
void set_vout_mode_fr_auto(char* name) { vmode_t vmode; amlog_mask_level(LOG_MASK_PARA,LOG_LEVEL_HIGH,"tvmode set to %s\n",name); vmode=validate_vmode(name); if(VMODE_MAX==vmode) { amlog_mask_level(LOG_MASK_PARA,LOG_LEVEL_HIGH,"no matched vout mode\n"); return ; } if(vmode==get_current_vmode()) { amlog_mask_level(LOG_MASK_PARA,LOG_LEVEL_HIGH,"don't set the same mode as current.\n"); return ; } update_vmode_status(name); set_current_vmode(vmode); amlog_mask_level(LOG_MASK_PARA,LOG_LEVEL_HIGH,"new mode %s set ok\n",name); vout_notifier_call_chain(VOUT_EVENT_MODE_CHANGE,&vmode) ; printk("%s[%d]\n", __func__, __LINE__); }
static void set_vout_mode(char * name) { vmode_t mode; amlog_mask_level(LOG_MASK_PARA,LOG_LEVEL_HIGH,"tvmode set to %s\n",name); mode=validate_vmode(name); if(VMODE_MAX==mode) { amlog_mask_level(LOG_MASK_PARA,LOG_LEVEL_HIGH,"no matched vout mode\n"); return ; } #ifdef CONFIG_AML_VOUT_FRAMERATE_AUTOMATION mode_by_user = mode; #endif if(mode==get_current_vmode()) { amlog_mask_level(LOG_MASK_PARA,LOG_LEVEL_HIGH,"don't set the same mode as current.\n"); return ; } #ifdef CONFIG_AML_VOUT_FRAMERATE_AUTOMATION //if plug hdmi during fps (stream is playing), then adjust mode to fps vmode fps_auto_adjust_mode(&mode); printk("%s[%d]fps_target_mode=%d\n",__func__,__LINE__,mode); update_vmode_status(get_name_from_vmode(mode)); #endif set_current_vmode(mode); #ifdef CONFIG_AML_VOUT_FRAMERATE_AUTOMATION amlog_mask_level(LOG_MASK_PARA,LOG_LEVEL_HIGH,"new mode =%s set ok\n",get_name_from_vmode(mode)); #endif vout_notifier_call_chain(VOUT_EVENT_MODE_CHANGE,&mode) ; printk("%s[%d]\n", __func__, __LINE__); }
static int bmp_decode(logo_object_t *plogo) { char *in=plogo->para.mem_addr ; char *out=plogo->parser->output_addr; char *bmp_data; int i; bmp_header_t *bmp_header=(bmp_header_t *)plogo->parser->priv; int bpp=plogo->parser->logo_pic_info.color_info/8 ; int width=plogo->parser->logo_pic_info.width; int height=plogo->parser->logo_pic_info.height; int line_length=width*bpp; int bmp_size=line_length*height; if(NULL==in || NULL==out) return FAIL; amlog_mask_level(LOG_MASK_PARSER,LOG_LEVEL_LOW,"in addr:0x%p out addr:0x%p,bmp size :%d,osd width:%d,bmp_width:%d\n",in,out,bmp_size,plogo->dev->vinfo->width,width); bmp_data=(char*)(in+bmp_header->bmp_file_header->bfOffBits+line_length*(height-1)); amlog_mask_level(LOG_MASK_PARSER,LOG_LEVEL_LOW,"data offset:%d\n",bmp_header->bmp_file_header->bfOffBits); //decode data to out buffer for (i=0;i<height ;i++) { memcpy(out,bmp_data,line_length); out+=plogo->dev->vinfo->width*bpp; bmp_data-=line_length; } amlog_mask_level(LOG_MASK_PARSER,LOG_LEVEL_LOW,"get bmp data completed\n"); return SUCCESS; }
static int vid_transfer(logo_object_t *plogo) { amlog_mask_level(LOG_MASK_DEVICE,LOG_LEVEL_LOW,"start video transfer\n");; SET_MPEG_REG_MASK(VPP_MISC, VPP_VD1_PREBLEND | VPP_PREBLEND_EN | VPP_VD1_POSTBLEND); CLEAR_MPEG_REG_MASK(VPP_MISC, VPP_OSD1_POSTBLEND | VPP_OSD2_POSTBLEND); return SUCCESS; }
static int osd_pan_display(struct fb_var_screeninfo *var, struct fb_info *fbi) { osddev_pan_display(var,fbi); amlog_mask_level(LOG_MASK_PARA,LOG_LEVEL_LOW,"osd_pan_display:=>osd%d\r\n",fbi->node); return 0; }
const color_bit_define_t* _find_color_format(struct fb_var_screeninfo * var) { u32 upper_margin,lower_margin,i,level; const color_bit_define_t *ret=NULL; level=(var->bits_per_pixel -1)/8; switch(level) { case 0: upper_margin=COLOR_INDEX_08_PAL256; lower_margin=COLOR_INDEX_02_PAL4; break; case 1: upper_margin=COLOR_INDEX_16_565; lower_margin=COLOR_INDEX_16_655; break; case 2: upper_margin=COLOR_INDEX_24_RGB; lower_margin=COLOR_INDEX_24_6666_A; break; case 3: upper_margin=COLOR_INDEX_32_ARGB; lower_margin=COLOR_INDEX_32_BGRA; break; case 4: upper_margin=COLOR_INDEX_YUV_422; lower_margin=COLOR_INDEX_YUV_422; break; default : return NULL; } //if not provide color component length then we find the first depth match. if((var->red.length==0)||(var->green.length==0)||(var->blue.length==0)|| var->bits_per_pixel != (var->red.length+var->green.length+var->blue.length+var->transp.length)) { amlog_mask_level(LOG_MASK_PARA,LOG_LEVEL_LOW,"not provide color component length,use default color \n"); ret =&default_color_format_array[upper_margin]; } else { for ( i=upper_margin;i>=lower_margin;i--) { if( (default_color_format_array[i].red_length==var->red.length)&& (default_color_format_array[i].green_length==var->green.length)&& (default_color_format_array[i].blue_length==var->blue.length)&& (default_color_format_array[i].transp_length ==var->transp.length)&& (default_color_format_array[i].transp_offset==var->transp.offset)&& (default_color_format_array[i].green_offset==var->green.offset)&& (default_color_format_array[i].blue_offset==var->blue.offset)&& (default_color_format_array[i].red_offset==var->red.offset)) { ret = &default_color_format_array[i]; break; } } } return ret; }
static int hardware_init(logo_object_t *plogo,int logo_size) { #ifdef CONFIG_AM_STREAMING u32 *mc_addr_aligned = (u32 *)vmjpeg_mc; #endif int ret = 0; if(plogo->para.output_dev_type <=LOGO_DEV_VID ) //now only support display on video layer. { if(plogo->para.output_dev_type < LOGO_DEV_VID) plogo->need_transfer=TRUE; else plogo->need_transfer=FALSE; } else { return -EINVAL; } WRITE_MPEG_REG(RESET0_REGISTER, RESET_VCPU | RESET_CCPU); #ifdef CONFIG_AM_STREAMING if (amvdec_loadmc(mc_addr_aligned) < 0) { amlog_mask_level(LOG_MASK_PARSER,LOG_LEVEL_LOW,"[jpeglogo]: Can not loading HW decoding ucode.\n"); return -EBUSY; } #endif amlog_mask_level(LOG_MASK_PARSER,LOG_LEVEL_LOW,"load micro code completed\n"); jpeglogo_prot_init(plogo); /*ret= request_irq(INT_MAILBOX_1A, jpeglogo_isr, IRQF_SHARED, "jpeglogo-irq", (void *)hardware_init);*/ if (ret) { amlog_mask_level(LOG_MASK_PARSER,LOG_LEVEL_LOW,"jpeglogo_init irq register error.\n"); return -ENOENT; } amlog_mask_level(LOG_MASK_PARSER,LOG_LEVEL_LOW,"jpeg irq request ok\n"); setup_vb((u32)virt_to_phys(plogo->para.mem_addr),logo_size); WRITE_MPEG_REG(M4_CONTROL_REG, 0x0300); WRITE_MPEG_REG(POWER_CTL_VLD, 0); //set initial screen mode : return SUCCESS; }
static int jpeg_decode(logo_object_t *plogo) { ulong timeout; jpeg_private_t *priv=(jpeg_private_t*)plogo->parser->priv; #ifdef CONFIG_AM_STREAMING amvdec_start(); #endif feed_vb(plogo->parser->logo_pic_info.size); timeout = jiffies + HZ * 2;//wait 2s while (time_before(jiffies, timeout)) { if (priv->state == PIC_DECODED) { /* disable OSD layer to expose logo on video layer */ amlog_mask_level(LOG_MASK_PARSER,LOG_LEVEL_LOW,"[jpeglogo]: logo decoded.\n"); break; } } #ifdef CONFIG_AM_STREAMING amvdec_stop(); #endif free_irq(INT_MAILBOX_1A, (void *)hardware_init); if (priv->state > PIC_NA) { if(plogo->para.output_dev_type == LOGO_DEV_VID) { #ifdef CONFIG_AM_VIDEO vf_provider_init(&jpeglogo_vf_prov, "jpeglogo_provider", &jpeglogo_vf_provider_op, NULL); vf_reg_provider(&jpeglogo_vf_prov); #endif kernel_thread(thread_progress, plogo, 0); }else { plogo->parser->decoder.jpg.out_canvas_index=priv->canvas_index; kfree(priv); } } else { amlog_mask_level(LOG_MASK_PARSER,LOG_LEVEL_LOW,"deocod jpeg uncompleted\n"); return FAIL; } return SUCCESS; }
static int thread_progress(void *para) { logo_object_t *plogo=(logo_object_t*)para; jpeg_private_t *priv=(jpeg_private_t*)plogo->parser->priv; ulong timeout; timeout = jiffies + HZ*8; while (time_before(jiffies, timeout)) { if (priv->state== PIC_FETCHED) { vf_unreg_provider(); kfree(priv); amlog_mask_level(LOG_MASK_PARSER,LOG_LEVEL_LOW,"logo fetched\n"); return SUCCESS; } } amlog_mask_level(LOG_MASK_PARSER,LOG_LEVEL_LOW,"logo unfetched\n"); return FAIL; }
static int __init tv_init_module(void) { int ret ; #ifdef CONFIG_HIBERNATION INIT_LIST_HEAD(&tvconf_ops.node); register_syscore_ops(&tvconf_ops); #endif info=&disp_module_info; printk("%s\n", __func__); /*if (!info) { amlog_mask_level(LOG_MASK_INIT,LOG_LEVEL_HIGH,"can't alloc display info struct\n"); return -ENOMEM; }*/ memset(info, 0, sizeof(disp_module_info_t)); sprintf(info->name,TV_CLASS_NAME) ; ret=register_chrdev(0,info->name,&am_tv_fops); if(ret <0) { amlog_mask_level(LOG_MASK_INIT,LOG_LEVEL_HIGH,"register char dev tv error\n"); return ret ; } info->major=ret; _init_vout(); amlog_mask_level(LOG_MASK_INIT,LOG_LEVEL_HIGH,"major number %d for disp\n",ret); if(vout_register_server(&tv_server)) { amlog_mask_level(LOG_MASK_INIT,LOG_LEVEL_HIGH,"register tv module server fail\n"); } else { amlog_mask_level(LOG_MASK_INIT,LOG_LEVEL_HIGH,"register tv module server ok\n"); } create_tv_attr(info); return 0; }
static void set_vout_mode(char * name) { vmode_t mode; amlog_mask_level(LOG_MASK_PARA,LOG_LEVEL_LOW,"tvmode2 set to %s\r\n",name); mode=validate_vmode2(name); if(VMODE_MAX==mode) { amlog_mask_level(LOG_MASK_PARA,LOG_LEVEL_HIGH,"no matched vout2 mode\n"); return ; } if(mode==get_current_vmode2()) { amlog_mask_level(LOG_MASK_PARA,LOG_LEVEL_HIGH,"don't set the same mode as current.\r\n"); return ; } set_current_vmode2(mode); amlog_mask_level(LOG_MASK_PARA,LOG_LEVEL_LOW,"new mode2 %s set ok\r\n",name); vout2_notifier_call_chain(VOUT_EVENT_MODE_CHANGE,&mode) ; }
static int am_gpio_open(struct inode * inode, struct file * file) { cmd_t *op; op = (cmd_t*)kmalloc(sizeof(cmd_t), GFP_KERNEL); if (IS_ERR(op)) { amlog_mask_level(LOG_MASK_INIT, LOG_LEVEL_HIGH, "cant alloc an op_target struct\n");; return -1; } file->private_data = op; return 0; }
static int create_vout_attr(void) { //create base class for display int i; vout_info.base_class=class_create(THIS_MODULE,VOUT_CLASS_NAME); if(IS_ERR(vout_info.base_class)) { amlog_mask_level(LOG_MASK_INIT,LOG_LEVEL_HIGH,"create vout class fail\r\n"); return -1 ; } //create class attr for(i=0;i<VOUT_ATTR_MAX;i++) { if ( class_create_file(vout_info.base_class,vout_attr[i])) { amlog_mask_level(LOG_MASK_INIT,LOG_LEVEL_HIGH,"create disp attribute %s fail\r\n",vout_attr[i]->attr.name); } } return 0; }
static int bmp_init(logo_object_t *logo) { BITMAPFILEHEADER *header; BITMAPINFOHEADER *bmp_info_header; bmp_header_t *bmp_header; void __iomem* logo_vaddr=logo->para.mem_addr; header=(BITMAPFILEHEADER*)logo_vaddr; bmp_info_header=(BITMAPINFOHEADER*)(logo_vaddr+sizeof(BITMAPFILEHEADER)); if (NULL==header) goto error; if(header->bfType == 0x4d42) //"BM" { logo->parser=&logo_bmp_parser; logo->parser->decoder.bmp.color_depth=bmp_info_header->biBitCount; logo->parser->logo_pic_info.color_info=logo->parser->decoder.bmp.color_depth; logo->parser->logo_pic_info.width=bmp_info_header->biWidth; logo->parser->logo_pic_info.height=bmp_info_header->biHeight; amlog_mask_level(LOG_MASK_PARSER,LOG_LEVEL_LOW,"bmp color depth:%d\n",logo->parser->decoder.bmp.color_depth); if(bmp_info_header->biBitCount<16) { amlog_mask_level(LOG_MASK_PARSER,LOG_LEVEL_HIGH,"color depth less than 16 not supported\n"); goto error; } if(!setup_parser_output_addr(logo)) { bmp_header=kmalloc(sizeof(bmp_header_t),GFP_KERNEL); bmp_header->bmp_file_header=header; bmp_header->bmp_info_header=bmp_info_header; logo->parser->priv=bmp_header ; logo->para.mem_addr=(char *)logo_vaddr; return PARSER_FOUND; } amlog_mask_level(LOG_MASK_PARSER,LOG_LEVEL_HIGH,"bmp can only display on osd0 or osd1 ,other layer not supported\n"); } error: return PARSER_UNFOUND; }
static int create_tv_attr(disp_module_info_t* info) { //create base class for display int i; info->base_class=class_create(THIS_MODULE,info->name); if(IS_ERR(info->base_class)) { amlog_mask_level(LOG_MASK_INIT,LOG_LEVEL_HIGH,"create tv display class fail\r\n"); return -1 ; } //create class attr for(i=0;i<ARRAY_SIZE(tv_attr);i++) { if ( class_create_file(info->base_class,tv_attr[i])) { amlog_mask_level(LOG_MASK_INIT,LOG_LEVEL_HIGH,"create disp attribute %s fail\r\n",tv_attr[i]->attr.name); } } sprintf(vdac_setting,"%x",get_current_vdac_setting()); return 0; }
static int jpeg_init(logo_object_t *plogo) { int logo_size; void __iomem* vaddr; jpeg_private_t *priv; vaddr=(void __iomem*)plogo->para.mem_addr; amlog_mask_level(LOG_MASK_PARSER,LOG_LEVEL_LOW,"logo vaddr:0x%p\n ",vaddr); if((logo_size=parse_jpeg_info(vaddr,plogo)) <=0 ) return PARSER_UNFOUND; vaddr = ioremap_wc((unsigned int)virt_to_phys(plogo->para.mem_addr), logo_size + PADDINGSIZE); if(NULL==vaddr) { amlog_mask_level(LOG_MASK_PARSER,LOG_LEVEL_LOW,"remapping logo data failed\n"); return -ENOMEM; } priv=(jpeg_private_t *)kmalloc(sizeof(jpeg_private_t),GFP_KERNEL); if(IS_ERR(priv)) { amlog_mask_level(LOG_MASK_PARSER,LOG_LEVEL_LOW,"can't alloc memory for jpeg private data\n"); return -ENOMEM; } memset(priv, 0, sizeof(jpeg_private_t)); priv->vf.width=plogo->parser->logo_pic_info.width; priv->vf.height=plogo->parser->logo_pic_info.height; plogo->parser->priv=priv; g_jpeg_parser=priv; priv->vaddr=vaddr; swap_tailzero_data((u8 *)vaddr, logo_size); if(hardware_init(plogo,logo_size) !=SUCCESS) { return PARSER_UNFOUND; } amlog_mask_level(LOG_MASK_PARSER,LOG_LEVEL_LOW,"jpeg parser hardware init ok\n"); plogo->parser->logo_pic_info.size=logo_size; return PARSER_FOUND; }
/*************************************************** ** ** The first digit control component Y output DAC number ** The 2nd digit control component U output DAC number ** The 3rd digit control component V output DAC number ** The 4th digit control composite CVBS output DAC number ** The 5th digit control s-video Luma output DAC number ** The 6th digit control s-video chroma output DAC number ** examble : ** echo 120120 > /sys/class/display/vdac_setting ** the first digit from the left side . ******************************************************/ static void parse_vdac_setting(char *para) { int i; char *pt=strstrip(para); int len=strlen(pt); u32 vdac_sequence=get_current_vdac_setting(); amlog_mask_level(LOG_MASK_PARA,LOG_LEVEL_LOW,"origin vdac setting:0x%x,strlen:%d\n",vdac_sequence,len); if(len!=6) { amlog_mask_level(LOG_MASK_PARA,LOG_LEVEL_HIGH,"can't parse vdac settings\n"); return ; } vdac_sequence=0; for(i=0;i<6;i++) { vdac_sequence<<=4; vdac_sequence|=*pt -'0'; pt++; } amlog_mask_level(LOG_MASK_PARA,LOG_LEVEL_LOW,"current vdac setting:0x%x\n",vdac_sequence); change_vdac_setting(vdac_sequence,get_current_vmode()); }
ge2d_context_t* dev_ge2d_setup(void* para) { config_para_t *config=(config_para_t*)para; static ge2d_context_t context; if(NULL==config) return NULL; amlog_mask_level(LOG_MASK_DEVICE,LOG_LEVEL_LOW,"current ge2d type:%d\n",config->src_dst_type); if(0==ge2d_context_config(&context,config)) { return &context; }else{ return NULL; } }
static int tv_set_current_vmode(vmode_t mod) { vmode_t mode = mod&VMODE_MODE_BIT_MASK; //if (mode > VMODE_1080P_50HZ) { if (mode >= TVMODE_MAX) { amlog_mask_level(LOG_MASK_PARA, LOG_LEVEL_HIGH,"Invalid vmode: %d\n", mod); return -EINVAL; } info->vinfo = &tv_info[mode]; if (mod & VMODE_LOGO_BIT_MASK) return 0; tvoutc_setmode(vmode_tvmode_tab[mode]); change_vdac_setting(get_current_vdac_setting(),mode); return 0; }
/************************************************************************** ** before we setup parser output addr ,output device info and ************************ ** pic info has been setup already. ********************** ** different pic type will select different output place ************************** **************************************************************************/ static int setup_parser_output_addr(logo_object_t *plogo) { int screen_mem_start; int screen_size ; if(plogo->para.output_dev_type > LOGO_DEV_OSD1) //bmp pic decoded into video layer { //not supported . return -1; } screen_mem_start=plogo->platform_res[plogo->para.output_dev_type].mem_start; screen_size=plogo->dev->vinfo->width*plogo->dev->vinfo->height*(plogo->parser->decoder.bmp.color_depth>>3); //double buffer ,bottom part . plogo->parser->output_addr=(char *)phys_to_virt(screen_mem_start + screen_size) ; plogo->need_transfer=TRUE; amlog_mask_level(LOG_MASK_PARSER,LOG_LEVEL_LOW,"bmp decode output addr:0x%p,%s\n",plogo->parser->output_addr,plogo->need_transfer?"transfer":"no transfer"); return 0; }
static int vid_init(logo_object_t *plogo) { if(plogo->para.output_dev_type==output_vid.idx) { set_current_vmode(plogo->para.vout_mode); output_vid.vinfo=get_current_vinfo(); plogo->dev=&output_vid; plogo->dev->window.x=0; plogo->dev->window.y=0; plogo->dev->window.w=plogo->dev->vinfo->width; plogo->dev->window.h=plogo->dev->vinfo->height; plogo->dev->output_dev.vid.mem_start=plogo->platform_res[LOGO_DEV_VID].mem_start; plogo->dev->output_dev.vid.mem_end=plogo->platform_res[LOGO_DEV_VID].mem_end; amlog_mask_level(LOG_MASK_DEVICE,LOG_LEVEL_LOW,"display on video layer\n"); return OUTPUT_DEV_FOUND; } return OUTPUT_DEV_UNFOUND; }
//axis type : 0x12 0x100 0x120 0x130 static void set_vout_window(char *para) { #define OSD_COUNT 2 static disp_rect_t disp_rect[OSD_COUNT]; char count=OSD_COUNT*4; int *pt=&disp_rect[0].x; //parse window para . memcpy(pt,parse_para(para,&count),sizeof(disp_rect_t)*OSD_COUNT); if(count >=4 && count <8 ) { disp_rect[1]=disp_rect[0] ; } amlog_mask_level(LOG_MASK_PARA,LOG_LEVEL_LOW,"osd0=>x:%d ,y:%d,w:%d,h:%d\r\n osd1=> x:%d,y:%d,w:%d,h:%d \r\n", \ *pt,*(pt+1),*(pt+2),*(pt+3),*(pt+4),*(pt+5),*(pt+6),*(pt+7)); vout2_notifier_call_chain(VOUT_EVENT_OSD_DISP_AXIS,&disp_rect[0]) ; }