static void csi2_timer_func(unsigned long arg) { struct amcsi_dev_s *csi_devp = (struct amcsi_dev_s *) arg; if( csi_devp->period >= jiffies_to_msecs(WDG_STEP_JIFFIES) ){ csi_devp->t.expires = jiffies + WDG_STEP_JIFFIES;//msecs_to_jiffies(csi_devp->period); csi_devp->period -= jiffies_to_msecs(WDG_STEP_JIFFIES); }else if(0 == csi_devp->period){ if(1 == csi_devp->reset){ printk("reset csi\n"); am_mipi_csi2_init(&csi_devp->csi_parm); csi_devp->reset_count ++; printk("period=%d, jiffies=%d\n", csi_devp->period, msecs_to_jiffies(csi_devp->period)); } //printk("min_frmrate=%d\n", csi_devp->min_frmrate); csi_devp->period = 1000 / csi_devp->min_frmrate; csi_devp->t.expires = jiffies + WDG_STEP_JIFFIES; csi_devp->period -= jiffies_to_msecs(WDG_STEP_JIFFIES); csi_devp->reset = 1; }else if( csi_devp->period < jiffies_to_msecs(WDG_STEP_JIFFIES) ){ csi_devp->t.expires = jiffies + msecs_to_jiffies(csi_devp->period); csi_devp->period = 0; } //printk("left period=%d\n", csi_devp->period); add_timer(&csi_devp->t); }
static ssize_t csi_attr_store(struct device *dev,struct device_attribute *attr,const char *buf, size_t len) { struct amcsi_dev_s *csi_devp; unsigned int n=0, fps=0; unsigned char ret=0; char *buf_orig, *ps, *token; char *parm[6] = {NULL}; if(!buf) return len; buf_orig = kstrdup(buf, GFP_KERNEL); //printk(KERN_INFO "input cmd : %s",buf_orig); csi_devp = dev_get_drvdata(dev); ps = buf_orig; while (1) { if ( n >=ARRAY_SIZE(parm) ){ printk("parm array overflow, n=%d, ARRAY_SIZE(parm)=%d\n", n, ARRAY_SIZE(parm)); return len; } token = strsep(&ps, " \n"); if (token == NULL) break; if (*token == '\0') continue; parm[n++] = token; } if ( 0 == strcmp(parm[0],"reset")){ printk("reset\n"); am_mipi_csi2_init(&csi_devp->csi_parm); } else if ( 0 == strcmp(parm[0],"init")){ printk("init mipi measure clock\n"); init_am_mipi_csi2_clock();// init mipi csi measure clock } else if ( 0 == strcmp(parm[0],"min")){ csi_devp->min_frmrate = simple_strtol(parm[1], NULL, 16); if (HZ < csi_devp->min_frmrate * WDG_STEP_JIFFIES){ csi_devp->min_frmrate = HZ/WDG_STEP_JIFFIES; } printk("min_frmrate=%d\n", csi_devp->min_frmrate); } kfree(buf_orig); return len; }
static void start_mipi_vdin(vdin_ops_privdata_t* data,unsigned int mem_start, unsigned int mem_size, fmt_info_t fmt_info,enum tvin_port_e port) { if(data->run_flag == true){ mipi_dbg("mipi_vdin is processing, don't do starting operation \n"); return; } mipi_dbg("start_mipi_vdin. \n"); data->param.port = port; mipi_vdin_canvas_init(data,mem_start, mem_size); init_mipi_vdin_parameter(data,fmt_info); data->wr_canvas_index = 0xff; data->reset_flag = 0; data->done_flag = true; data->hw_info.frame = NULL; data->mipi_vdin_skip = MIPI_SKIP_FRAME_NUM; am_mipi_csi2_init(&data->hw_info); data->watchdog_cnt = 0; data->run_flag = true; return; }
static void csi2_vdin_check(vdin_ops_privdata_t* data) { data->watchdog_cnt++; if(data->watchdog_cnt > 20){ am_mipi_csi2_uninit(); data->hw_info.frame = NULL; data->mipi_vdin_skip = MIPI_SKIP_FRAME_NUM; data->reset_flag = 1; wake_up_interruptible(&data->complete); data->done_flag = true; am_mipi_csi2_init(&data->hw_info); data->watchdog_cnt = 0; data->param.status = TVIN_SIG_STATUS_NOSIG; mipi_error("[mipi_vdin]:csi2_vdin_check-- time out !!!!\n"); return ; } if (data->run_flag != true) mipi_error("csi2_vdin_check: mipi still not run. \n"); return ; }
/* *power on mipi module&init the parameters,such as color fmt...,will be used by vdin */ static int amcsi_feopen(struct tvin_frontend_s *fe, enum tvin_port_e port) { struct amcsi_dev_s *csi_devp = container_of(fe, amcsi_dev_t, frontend); struct vdin_parm_s *parm = fe->private_data; csi_parm_t *p = &csi_devp->csi_parm; int ret; if((port != TVIN_PORT_MIPI)){ DPRINT("[mipi..]%s:invaild port %d.\n",__func__, port); return -1; } /*copy the param from vdin to csi*/ if(!memcpy(&csi_devp->para, parm, sizeof(vdin_parm_t))){ DPRINT("[mipi..]%s memcpy error.\n",__func__); return -1; } init_am_mipi_csi2_clock();// init mipi csi measure clock csi_devp->para.port = port; memcpy( &csi_devp->csi_parm, &parm->csi_hw_info, sizeof( csi_parm_t)); csi_devp->csi_parm.skip_frames = parm->skip_count; csi_devp->reset = 0; csi_devp->reset_count = 0; #if 0 csi_devp->irq_num = INT_MIPI_PHY; //INT_CSI2_HOST; ret = request_irq(csi_devp->irq_num, csi_hst_isr, IRQF_SHARED, "csi-hst1"/*devp->irq_name*/, csi_devp); //SET_CSI_HST_REG_MASK(MIPI_CSI2_HOST_MASK1, ~((1<< p->lanes) - 1)); //WRITE_CSI_HST_REG_BITS(MIPI_CSI2_HOST_MASK1, 0, 28, 1); // enable err_ecc_double //SET_CSI_HST_REG_MASK(MIPI_CSI2_HOST_MASK1, ~((1<< p->lanes) - 1)); DPRINT("INT_CSI2_HOST = %d, INT_CSI2_HOST_2=%d\n", INT_CSI2_HOST, INT_CSI2_HOST_2) DPRINT("mask1=%x\n", ~((1<< p->lanes) - 1)); #if 0 csi_devp->irq_num = INT_CSI2_HOST_2; ret = request_irq(csi_devp->irq_num, csi_hst_isr, IRQF_SHARED, "csi-hst2"/*devp->irq_name*/, csi_devp); #endif if( ret < 0 ){ printk("failed to request csi_adapter irq \n"); } #endif init_timer (&csi_devp->t); csi_devp->t.data = csi_devp; csi_devp->t.function = csi2_timer_func; csi_devp->t.expires = jiffies + WDG_STEP_JIFFIES; //reset after 50ms=5jiffies if(0 == csi_devp->min_frmrate){ csi_devp->min_frmrate = 1; } csi_devp->period = 1000 / parm->frame_rate; //printk("period=%d, jiffies=%d\n", csi_devp->period, msecs_to_jiffies(csi_devp->period)); if(csi_devp->period <= jiffies_to_msecs(WDG_STEP_JIFFIES)) { csi_devp->period = 0; }else{ csi_devp->period -= jiffies_to_msecs(WDG_STEP_JIFFIES); } add_timer(&csi_devp->t); cal_csi_para(&csi_devp->csi_parm); am_mipi_csi2_init(&csi_devp->csi_parm); return 0; //csi_devp->skip_vdin_frame_count = parm->reserved; }