static int matv_release(struct inode *inode, struct file *file)
{
    MATV_LOGD(KERN_ERR "******** mt5912 matv release %d I2C Err: %d\n", g_mATVCnt, g_mI2CErrCnt);
    down(&g_mATVLock);

	if((--g_mATVCnt) > 0)
    {
        up(&g_mATVLock);
        return 0;
    }

#ifdef 	GPIO_MATV_PWR_ENABLE
    mt_set_gpio_out(GPIO_MATV_PWR_ENABLE, GPIO_OUT_ZERO);
#endif

#ifdef GPIO_MATV_N_RST
    mt_set_gpio_out(GPIO_MATV_N_RST, GPIO_OUT_ZERO);
#endif

    //Disable I2D Data pin
#ifdef _MATV_HIGH_SPEED_DMA_    
    if(gpDMABuf_va){
        dma_free_coherent(NULL, 4096, gpDMABuf_va, gpDMABuf_pa);
        gpDMABuf_va = NULL;
        gpDMABuf_pa = NULL;
    }
#endif

    if(0!=cust_matv_power_off())
    {
        MATV_LOGE("[MATV] Fail to power off analog gain\n");     
        up(&g_mATVLock);
        return -EIO;
    }
    //Switch TP back to normal mode
    tpd_switch_normal_mode();    

	if(g_mATVCnt < 0)
		g_mATVCnt = 0;

	g_mI2CErrCnt = 0;
    up(&g_mATVLock);
    return 0;
}
//ting.kang
static int nmi5625_ioctl(struct file *file,
		    unsigned int cmd, unsigned long arg)
{
	struct nmi_5625_dev *d = file->private_data;
	long ret = 0;
	

	
	#ifdef NMI_USE_MTK_I2C_DMA
		U8 *pReadData = 0;
		U8 *pWriteData = 0;
		U8 *pa_addr = 0;
		int *user_data_addr;
	#else
		U8 *kbuf = &i2cBuf[0];
	#endif
	
    U16 len;
	
	switch ((cmd&0xffff0000)) {
        case NM5625_PWR_2P8_CTL:
		printk("NM5625_PWR_2P8_CTL, power11 %s\n",(arg==1)?"on":"off");

		if (arg == 1) {	/* on */
			// mt_set_gpio_out(u32 pin,u32 output)(NMI_POWER_VDDIO_PIN, 1);
			if (0 != cust_matv_power_on()) {
				goto _fail_;
			}
			mt_set_gpio_out(NMI_FM_ANT_PIN, GPIO_OUT_ONE);
			mt_set_gpio_out(NMI_ATV_ANT_PIN, GPIO_OUT_ZERO);
		} else{
			// mt_set_gpio_out(NMI_POWER_VDDIO_PIN, 0);
			if (0 != cust_matv_power_off()) {
				goto _fail_;
			}
			mt_set_gpio_out(NMI_FM_ANT_PIN, GPIO_OUT_ZERO);
			mt_set_gpio_out(NMI_ATV_ANT_PIN, GPIO_OUT_ONE);
		}
		break;
		
	case NM5625_PWR_1P2_CTL:
		printk("NM5625_PWR_1P2_CTL, power %s\n",(arg==1)?"on":"off");
		
		if (arg == 1) {	/* on */
#if 0
			if(TRUE != hwPowerOn(CAMERA_POWER_VCAM_A, VOL_2800, "nmitv")) {
				goto _fail_;
			}
			mt_set_gpio_mode(GPIO_CAMERA_CMRST1_PIN,GPIO_CAMERA_CMRST1_PIN_M_GPIO);
			mt_set_gpio_dir(GPIO_CAMERA_CMRST1_PIN,GPIO_DIR_OUT);
			mt_set_gpio_out(GPIO_CAMERA_CMRST1_PIN,GPIO_OUT_ZERO);
			mt_set_gpio_mode(GPIO_CAMERA_CMPDN1_PIN,GPIO_CAMERA_CMPDN1_PIN_M_GPIO);
			mt_set_gpio_dir(GPIO_CAMERA_CMPDN1_PIN,GPIO_DIR_OUT);
			mt_set_gpio_out(GPIO_CAMERA_CMPDN1_PIN,GPIO_OUT_ONE);
			///
			if(TRUE != hwPowerOn(MT6323_POWER_LDO_VCAM_IO, VOL_1800, "nmitv")) {
				goto _fail_;
			}
			///
#endif
			mt_set_gpio_out(NMI_POWER_VCORE_PIN, GPIO_OUT_ONE);
			g_bIsAtvStart  = true;   			
		}else {
#if 0
			mt_set_gpio_mode(GPIO_CAMERA_CMRST1_PIN,GPIO_MODE_00);
			mt_set_gpio_dir(GPIO_CAMERA_CMRST1_PIN,GPIO_DIR_OUT);
			mt_set_gpio_out(GPIO_CAMERA_CMRST1_PIN,GPIO_OUT_ZERO);
			mt_set_gpio_mode(GPIO_CAMERA_CMPDN1_PIN,GPIO_MODE_00);
			mt_set_gpio_dir(GPIO_CAMERA_CMPDN1_PIN,GPIO_DIR_OUT);
			mt_set_gpio_out(GPIO_CAMERA_CMPDN1_PIN,GPIO_OUT_ZERO);
			if(TRUE != hwPowerDown(CAMERA_POWER_VCAM_A, "nmitv")) {
				goto _fail_;
			}
			if(TRUE != hwPowerDown(MT6323_POWER_LDO_VCAM_IO, "nmitv")) {
				goto _fail_;
			}
			///
#endif
			mt_set_gpio_out(NMI_POWER_VCORE_PIN, GPIO_OUT_ZERO);
			g_bIsAtvStart = false;
			///
			mt_set_gpio_out(NMI_FM_ANT_PIN, GPIO_OUT_ZERO);
			mt_set_gpio_out(NMI_ATV_ANT_PIN, GPIO_OUT_ONE);
		}	
		break;	
	case NM5625_ATV_RESET_CTL:
		printk("NM5625_ATV_RESET_CTL, power %s\n",(arg==1)?"on":"off");
       	if (arg == 1) {
			mt_set_gpio_out(NMI_RESET_PIN, GPIO_OUT_ONE);			
		} 
		else {
			mt_set_gpio_out(NMI_RESET_PIN, GPIO_OUT_ZERO);			
		}
		break;
				
	case NM5625_ATV_I2C_READ:			

			len = cmd&0xffff;	/* Note: I used the lower 16 bits for size */	
			
			dPrint(N_INFO,"NM5625_ATV_I2C_READ , len is (%d)\n" , len );
			mutex_lock(&d->mu);
			
			#ifdef NMI_HW_I2C
				#ifdef NMI_USE_MTK_I2C_DMA
				
					user_data_addr = (int *)arg;
					
					pReadData = gpDMABuf_va;
					pa_addr   = gpDMABuf_pa;
					
					if(!pReadData){
						printk("[Error] dma_alloc_coherent failed!\n");
						mutex_unlock(&d->mu);
						goto _fail_;
					}
					ret = nmi5625_dma_read_m_byte(pReadData, pa_addr, len);    
					if (ret < 0) {
						//dPrint(N_ERR, "nmi: failed i2c read...(%d)\n", ret);
						mutex_unlock(&d->mu);
						goto _fail_;
					}
										
					if (copy_to_user(user_data_addr, pReadData, len) ) {
						dPrint(N_ERR, "nmi: failed copy to user...\n");
						ret = -EFAULT;
						mutex_unlock(&d->mu);
						goto _fail_;
					}
				#else
					if ( len > 8 )
					{
						dPrint(N_ERR, "nmi: failed receive 8 more data from i2s bus , please use dma way to instead.\n");
						ret = -EFAULT;
						mutex_unlock(&d->mu);
						goto _fail_;
					}
					ret = i2c_master_recv(d->i2c_client_atv, kbuf, len);
					
					if (ret < 0) {
						dPrint(N_ERR, "nmi: failed i2c read...(%d)\n", ret);
						mutex_unlock(&d->mu);
						goto _fail_;
					}

					if (copy_to_user(arg, i2cBuf, len) ) {
						dPrint(N_ERR, "nmi: failed copy to user...\n");
						ret = -EFAULT;
						mutex_unlock(&d->mu);
						goto _fail_;
					}
				#endif //end for #ifdef NMI_USE_MTK_I2C_DMA
			#else
				ret = nmi_i2c_read(0x60,kbuf,len);
				
				//dPrint(N_TRACE,"kernel:nmi_i2c_read buf is (%x), length is (%d)\n",kbuf,len);

				if (copy_to_user(arg, i2cBuf, len) ) {
					dPrint(N_ERR, "nmi: failed copy to user...\n");
					ret = -EFAULT;
					mutex_unlock(&d->mu);
					goto _fail_;
				}
			#endif
			
			mutex_unlock(&d->mu);

            break;	
			
	case NM5625_ATV_I2C_WRITE:			

			len = cmd&0xffff;	/* Note: I used the lower 16 bits for size */	
			
			dPrint(N_INFO,"NM5625_ATV_I2C_WRITE , len is (%d)\n" , len );
			mutex_lock(&d->mu);
			
			#ifdef NMI_HW_I2C
				#ifdef NMI_USE_MTK_I2C_DMA
				
					user_data_addr = (int *)arg;
					
					pWriteData = gpDMABuf_va;
					pa_addr    = gpDMABuf_pa;
					if(!pWriteData){
						printk("[Error] dma_alloc_coherent failed!\n");
						mutex_unlock(&d->mu);
						goto _fail_;
					}
					ret = copy_from_user(pWriteData, user_data_addr, len);
					if ( ret < 0 ) {
						dPrint(N_ERR, "nmi: failed copy from user...\n");
						ret = -EFAULT;
						mutex_unlock(&d->mu);
						goto _fail_;
					}
					ret = nmi5625_dma_write_m_byte(pWriteData, pa_addr, len); 

					if (ret < 0) {
						//dPrint(N_ERR, "nmi: failed i2c read...(%d)\n", ret);
						mutex_unlock(&d->mu);
						goto _fail_;
					}
					
				#else
					if ( len > 8 )
					{
						dPrint(N_ERR, "nmi: failed to send 8 more data to i2s bus , please use dma way to instead.\n");
						ret = -EFAULT;
						mutex_unlock(&d->mu);
						goto _fail_;
					}
						
					if (copy_from_user(kbuf, arg, len)) {					
						dPrint(N_ERR, "nmi: failed copy from user...\n");
						ret = -EFAULT;
						goto _fail_;
					}
					
					ret = i2c_master_send(d->i2c_client_atv, kbuf, len);
						
					if (ret < 0) {
						dPrint(N_ERR, "nmi: failed i2c write...(%d)\n", ret);
						mutex_unlock(&d->mu);
						goto _fail_;
					}
				
				#endif //end for #ifdef NMI_USE_MTK_I2C_DMA
			#else
				if (copy_from_user(kbuf, arg, len)) {					
					dPrint(N_ERR, "nmi: failed copy from user...\n");
					ret = -EFAULT;
					goto _fail_;
				}
					
				ret = nmi_i2c_write(0x60,kbuf,len);
				dPrint(N_TRACE,"kernel:nmi_i2c_write buf is (%x), length is (%d)\n",kbuf,len);
			#endif
			
			mutex_unlock(&d->mu);
			
            break;
        
        default:
            break;
    }
_fail_:
	//func_exit();
	//dPrint(N_TRACE, "nmi_ioctl return value...(%d)\n", ret);
	return ret; 
}