kal_uint32 jpeg_drv_enc_ctrl_cfg( kal_uint32 exif_en, kal_uint32 quality, kal_uint32 restart_interval)
{
   
    jpeg_drv_enc_set_quality(quality);

    jpeg_drv_enc_set_restart_interval(restart_interval);

    jpeg_drv_enc_set_EncodeMode(exif_en);
    
    return 1;

    //if (0 != ctrl_cfg.gmc_disable)
    //    REG_JPEG_ENC_CTRL |= JPEG_ENC_CTRL_DIS_GMC_BIT;
    //
    //REG_JPEG_ENC_CTRL |= JPEG_ENC_EN_SELF_INIT;
}
static int jpeg_enc_ioctl(unsigned int cmd, unsigned long arg, struct file *file)
{
    int retValue;
    long timeout_jiff;
    unsigned int fileSize, encResult;
    JPEG_ENC_DRV_IN inParams;
    JPEG_ENC_DRV_OUT outParams;

    unsigned int *pStatus;

    pStatus = (unsigned int*)file->private_data;

    if(NULL == pStatus)
    {
        JPEG_WRN("Private data is null in flush operation. HOW COULD THIS HAPPEN ??\n");
        return -EFAULT;
    }
    
    switch(cmd)
    {       
        // initial and reset JPEG encoder
        case JPEG_ENC_IOCTL_INIT: 
            JPEG_MSG("JPEG Encoder Initial and Lock\n");
            
            retValue = jpeg_drv_enc_init();

            if(retValue == 0)
            {
                *pStatus = JPEG_ENC_PROCESS;
            }
            
            return retValue;   
     
            break;

        // Configure the register
        case JPEG_ENC_IOCTL_CONFIG:
            JPEG_MSG("JPEG Encoder Configure Hardware\n");
            if(*pStatus != JPEG_ENC_PROCESS)
            {
                JPEG_WRN("Permission Denied! This process can not access encoder");
                return -EFAULT;
            }

            if(enc_status == 0)
            {
                JPEG_WRN("Encoder status is available, HOW COULD THIS HAPPEN ??");
                *pStatus = 0;
                return -EFAULT;
            }
            
            // copy input parameters
            if(copy_from_user(&inParams, (void *)arg, sizeof(JPEG_ENC_DRV_IN)))
            {
                JPEG_WRN("JPEG Encoder : Copy from user error\n");
                return -EFAULT;
            }

            if(inParams.allocBuffer)
            {
                dstBufferSize = inParams.dstBufferSize;
                dstUserVA = inParams.dstBufferAddr;
                dstBufferVA = dma_alloc_coherent(0, dstBufferSize, &dstBufferPA, GFP_KERNEL);
            }
            else
            {
                dstBufferSize = 0;
                dstBufferPA = (unsigned int)inParams.dstBufferAddr;
            }

           
            JPEG_MSG("JPEG Encoder Buffer Address : %d\n", (unsigned int)inParams.dstBufferAddr);
            JPEG_MSG("JPEG Encoder Buffer Size : %d\n", inParams.dstBufferSize);
            JPEG_MSG("JPEG Encoder Buffer Width : %d\n", inParams.dstWidth);
            JPEG_MSG("JPEG Encoder Buffer Height : %d\n", inParams.dstHeight);
            JPEG_MSG("JPEG Encoder Buffer Format : %d\n", inParams.dstFormat);
            JPEG_MSG("JPEG Encoder Buffer Quality : %d\n", inParams.dstQuality);

            // 0. reset 
            jpeg_drv_enc_reset();

            // 1. set dst address
            jpeg_drv_enc_set_dst_buffer_info(dstBufferPA, inParams.dstBufferSize, 0);

            // 2. set file format
            jpeg_drv_enc_set_file_format(inParams.enableEXIF);

            // 3. set quality
            jpeg_drv_enc_set_quality(inParams.dstQuality);

            // 4. single run
            jpeg_drv_enc_set_mode(0, 0);

            // 5. set sampling factor
            if(jpeg_drv_enc_set_sample_format_related(inParams.dstWidth, inParams.dstHeight, inParams.dstFormat))
            {
                JPEG_WRN("JPEG Encoder : Unvalid YUV Format\n");
                jpeg_drv_enc_deinit();
                return -EINVAL;
            }

            // 6. set sync reset bit
            jpeg_drv_enc_set_sync_reset(inParams.enableSyncReset);
            
            break;

        case JPEG_ENC_IOCTL_START:
            JPEG_MSG("JPEG Encoder Start\n");
            if(*pStatus != JPEG_ENC_PROCESS)
            {
                JPEG_WRN("Permission Denied! This process can not access encoder");
                return -EFAULT;
            }

            if(enc_status == 0)
            {
                JPEG_WRN("Encoder status is available, HOW COULD THIS HAPPEN ??");
                *pStatus = 0;
                return -EFAULT;
            }
            //jpeg_reg_dump();
            jpeg_drv_enc_start();
            
            break;
            
        case JPEG_ENC_IOCTL_WAIT:
            if(*pStatus != JPEG_ENC_PROCESS)
            {
                JPEG_WRN("Permission Denied! This process can not access encoder");
                return -EFAULT;
            }

            if(enc_status == 0)
            {
                JPEG_WRN("Encoder status is available, HOW COULD THIS HAPPEN ??");
                *pStatus = 0;
                return -EFAULT;
            }
            if(copy_from_user(&outParams, (void *)arg, sizeof(JPEG_ENC_DRV_OUT)))
            {
                JPEG_WRN("JPEG Encoder : Copy from user error\n");
                return -EFAULT;
            }

#ifdef FPGA_VERSION
            JPEG_MSG("Polling JPEG Encoder Status");

            do
            {
                _jpeg_enc_int_status = REG_JPEG_ENC_INTERRUPT_STATUS;
            } while(_jpeg_enc_int_status == 0);
#else
            //set timeout
            timeout_jiff = outParams.timeout* HZ / 1000;
            JPEG_MSG("JPEG Encoder Time Jiffies : %ld\n", timeout_jiff);   
            wait_event_interruptible_timeout(enc_wait_queue, _jpeg_enc_int_status, timeout_jiff);
#endif
            encResult = jpeg_drv_enc_get_result(&fileSize);

            JPEG_MSG("Result : %d, Size : %u, addres : 0x%x\n", encResult, fileSize, ioread32(JPG_CODEC_BASE + 0x120));
            if(encResult != 0)
            {
                jpeg_reg_dump();
            }
            
            if(copy_to_user(outParams.fileSize, &fileSize, sizeof(unsigned int)))
            {
                JPEG_WRN("JPEG Encoder : Copy to user error (file size)\n");
                return -EFAULT;
            }
            
            if(copy_to_user(outParams.result, &encResult, sizeof(unsigned int)))
            {
                JPEG_WRN("JPEG Encoder : Copy to user error (result)\n");
                return -EFAULT;            
            }
            
            if(dstBufferSize != 0)
            {
                JPEG_MSG("Copy Data to User\n");
                if(copy_to_user(dstUserVA, dstBufferVA, fileSize))
                {
                    JPEG_WRN("JPEG Encoder : Copy to user error (dstbuffer)\n");
                    return -EFAULT; 
                }
                dma_free_coherent(0, dstBufferSize, dstBufferVA, dstBufferPA);
            }
            
            break;
            
        case JPEG_ENC_IOCTL_DEINIT:
            // copy input parameters
            if(*pStatus != JPEG_ENC_PROCESS)
            {
                JPEG_WRN("Permission Denied! This process can not access encoder");
                return -EFAULT;
            }

            if(enc_status == 0)
            {
                JPEG_WRN("Encoder status is available, HOW COULD THIS HAPPEN ??");
                *pStatus = 0;
                return -EFAULT;
            }
            jpeg_drv_enc_deinit();
            *pStatus = 0;

            return 0;
    }
    
    return 0;
}