static long matv_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { int *user_data_addr; long ret = 0; U8 *pReadData = 0; U8 *pWriteData = 0; U8 *ptr; U8 reg8, bAutoInc; U16 len; switch(cmd) { case TEST_MATV_PRINT : MATV_LOGD("**** mt519x matv ioctl : test\n"); break; case MATV_READ: user_data_addr = (int *)arg; ret = copy_from_user(matv_in_data, user_data_addr, 4); ptr = (U8*)matv_in_data; reg8 = ptr[0]; bAutoInc = ptr[1]; len = ptr[2]; len+= ((U16)ptr[3])<<8; //MATV_LOGD("**** mt519x matv ioctl : read length = %d\n",len); #ifdef _MATV_HIGH_SPEED_DMA_ pReadData = gpDMABuf_va; pa_addr = gpDMABuf_pa; if(!pReadData){ MATV_LOGE("[Error] dma_alloc_coherent failed!\n"); break; } mt519x_dma_read_m_byte(reg8, pReadData, pa_addr, len, bAutoInc); ret = copy_to_user(user_data_addr, pReadData, len); #else pReadData = (U8 *)kmalloc(len,GFP_ATOMIC); if(!pReadData){ MATV_LOGE("[Error] kmalloc failed!\n"); break; } mt519x_read_m_byte(reg8, pReadData, len, bAutoInc); ret = copy_to_user(user_data_addr, pReadData, len); if(pReadData) kfree(pReadData); #endif //#ifdef _MATV_HIGH_SPEED_DMA_ break; case MATV_WRITE: user_data_addr = (int *)arg; ret = copy_from_user(matv_in_data, user_data_addr, 4); ptr = (U8*)matv_in_data; reg8 = ptr[0]; bAutoInc = ptr[1]; len = ptr[2]; len+= ((U16)ptr[3])<<8; //MATV_LOGD("**** mt519x matv ioctl : write length = %d\n",len); #ifdef _MATV_HIGH_SPEED_DMA_ pWriteData = gpDMABuf_va; pa_addr = gpDMABuf_pa; if(!pWriteData){ MATV_LOGE("[Error] dma_alloc_coherent failed!\n"); break; } ret = copy_from_user(pWriteData+1, ((void*)user_data_addr)+4, len); //printk("\n[MATV]Write data = %d\n",*(pWriteData+1)); mt519x_dma_write_m_byte(reg8, pWriteData, pa_addr, len, bAutoInc); #else pWriteData = (U8 *)kmalloc(len,GFP_ATOMIC); if(!pWriteData){ MATV_LOGE("[Error] kmalloc failed!\n"); break; } ret = copy_from_user(pWriteData, ((void*)user_data_addr)+4, len); //printk("\n[MATV]Write data = %d\n",*pWriteData); mt519x_write_m_byte(reg8, pWriteData, len, bAutoInc); //ret = copy_to_user(user_data_addr, pReadData, len); if(pWriteData) kfree(pWriteData); #endif //#ifdef _MATV_HIGH_SPEED_DMA_ break; case MATV_SET_PWR: user_data_addr = (int *)arg; ret = copy_from_user(matv_in_data, user_data_addr, sizeof(int)); //MATV_LOGD("**** mt519x matv ioctl : set pwr = %d\n",user_data_addr[0]); #ifdef GPIO_MATV_PWR_ENABLE if(matv_in_data[0]!=0) mt_set_gpio_out(GPIO_MATV_PWR_ENABLE, GPIO_OUT_ONE); else mt_set_gpio_out(GPIO_MATV_PWR_ENABLE, GPIO_OUT_ZERO); #endif break; case MATV_SET_RST: user_data_addr = (int *)arg; ret = copy_from_user(matv_in_data, user_data_addr, sizeof(int)); //MATV_LOGD("**** mt519x matv ioctl : set rst = %d\n",user_data_addr[0]); #ifdef GPIO_MATV_N_RST if(matv_in_data[0]!=0){ mt_set_gpio_out(GPIO_MATV_N_RST, GPIO_OUT_ONE); } else mt_set_gpio_out(GPIO_MATV_N_RST, GPIO_OUT_ZERO); #endif break; case MATV_SET_STRAP: user_data_addr = (int *)arg; ret = copy_from_user(matv_in_data, user_data_addr, sizeof(int)); #ifdef GPIO_MATV_I2S_DAT_PIN if(matv_in_data[0]==0){ //Enable I2D Data pin and pull low mt_set_gpio_mode(GPIO_MATV_I2S_DAT_PIN,GPIO_MODE_00); mt_set_gpio_dir(GPIO_MATV_I2S_DAT_PIN, GPIO_DIR_OUT); mt_set_gpio_pull_enable(GPIO_MATV_I2S_DAT_PIN,true); mt_set_gpio_out(GPIO_MATV_I2S_DAT_PIN, GPIO_OUT_ZERO); printk("force I2s data pin low \n"); //~ } else if (matv_in_data[0]==1) { //Disable I2D Data pin #ifdef GPIO_MATV_I2S_DAT_PIN_M_I2S0_DAT mt_set_gpio_mode(GPIO_MATV_I2S_DAT_PIN,GPIO_MATV_I2S_DAT_PIN_M_I2S0_DAT); #endif #ifdef GPIO_MATV_I2S_DAT_PIN_M_I2SIN_DAT mt_set_gpio_mode(GPIO_MATV_I2S_DAT_PIN,GPIO_MATV_I2S_DAT_PIN_M_I2SIN_DAT); #endif mt_set_gpio_pull_enable(GPIO_MATV_I2S_DAT_PIN,false); mt_set_gpio_out(GPIO_MATV_I2S_DAT_PIN, GPIO_OUT_ZERO); printk("put I2S data pin back \n"); //~ } #else MATV_LOGD("**** mt519x ioctl : GPIO_MATV_I2S_DAT_PIN is not defined!!!!!!!!!\\n"); #endif break; case MATV_SLEEP: { long timeout_jiff; static wait_queue_head_t matvWaitQueue; struct timeval t1,t2; int time_diff = 0; int timeOut = 0; init_waitqueue_head(&matvWaitQueue); user_data_addr = (int *)arg; ret = copy_from_user(matv_in_data, user_data_addr, sizeof(int)); timeout_jiff = (matv_in_data[0]+2) * HZ / 1000; // wait 80 ms do_gettimeofday(&t1); timeOut = wait_event_interruptible_timeout(matvWaitQueue, NULL, timeout_jiff); if(0 != timeOut) MATV_LOGE("[MATV] Fail to sleep enough time %d\n", timeOut); do_gettimeofday(&t2); time_diff = (t2.tv_sec - t1.tv_sec)*1000000 + (t2.tv_usec - t1.tv_usec); if (time_diff < (matv_in_data[0]-2)*1000){ //MATV_LOGE("[MATV]TimeDiff=%d\n",time_diff); udelay(matv_in_data[0]*1000 - time_diff); } } break; case MATV_SET_TP_MODE: { user_data_addr = (int *)arg; ret = copy_from_user(matv_in_data, user_data_addr, sizeof(int)); MATV_LOGD("[MATV]MATV_SET_TP_MODE = %d\n",matv_in_data[0]); if(matv_in_data[0] == 0) { tpd_switch_single_mode(); } else if(matv_in_data[0] == 1) { tpd_switch_multiple_mode(); } else if(matv_in_data[0] == 2) { tpd_switch_sleep_mode(); } else if(matv_in_data[0] == 3) { tpd_switch_normal_mode(); } else { MATV_LOGE("[MATV] TP's mode value(%d) is wrong!\n",matv_in_data[0]); } } break; case MATV_QUERY_I2S_INFO: { user_data_addr = (int *)arg; ret = copy_to_user(user_data_addr, &i2s_info, sizeof(i2s_info)); } break; default: break; } return 0; }
static int matv_resume(struct platform_device *dev) { MATV_LOGD("[MATV] resume\n"); return 0; }
static void matv_shutdown(struct platform_device *dev) { MATV_LOGD("[MATV] shutdown\n"); }
static int matv_suspend(struct platform_device *dev, pm_message_t state) { MATV_LOGD("[MATV] suspend\n"); return 0; }
static int matv_probe(struct platform_device *dev) { MATV_LOGD(KERN_ERR "[MATV] probe done\n"); return 0; }