#define IEP_IOC_MAGIC 'i'
-#define IEP_SET_PARAMETER_REQ _IOW(IEP_IOC_MAGIC, 1, unsigned long)
-#define IEP_SET_PARAMETER_DEINTERLACE _IOW(IEP_IOC_MAGIC, 2, unsigned long)
-#define IEP_SET_PARAMETER_ENHANCE _IOW(IEP_IOC_MAGIC, 3, unsigned long)
-#define IEP_SET_PARAMETER_CONVERT _IOW(IEP_IOC_MAGIC, 4, unsigned long)
-#define IEP_SET_PARAMETER_SCALE _IOW(IEP_IOC_MAGIC, 5, unsigned long)
-#define IEP_GET_RESULT_SYNC _IOW(IEP_IOC_MAGIC, 6, unsigned long)
-#define IEP_GET_RESULT_ASYNC _IOW(IEP_IOC_MAGIC, 7, unsigned long)
-#define IEP_SET_PARAMETER _IOW(IEP_IOC_MAGIC, 8, unsigned long)
-#define IEP_RELEASE_CURRENT_TASK _IOW(IEP_IOC_MAGIC, 9, unsigned long)
+#define IEP_SET_PARAMETER_REQ _IOW(IEP_IOC_MAGIC, 1, unsigned long)
+#define IEP_SET_PARAMETER_DEINTERLACE _IOW(IEP_IOC_MAGIC, 2, unsigned long)
+#define IEP_SET_PARAMETER_ENHANCE _IOW(IEP_IOC_MAGIC, 3, unsigned long)
+#define IEP_SET_PARAMETER_CONVERT _IOW(IEP_IOC_MAGIC, 4, unsigned long)
+#define IEP_SET_PARAMETER_SCALE _IOW(IEP_IOC_MAGIC, 5, unsigned long)
+#define IEP_GET_RESULT_SYNC _IOW(IEP_IOC_MAGIC, 6, unsigned long)
+#define IEP_GET_RESULT_ASYNC _IOW(IEP_IOC_MAGIC, 7, unsigned long)
+#define IEP_SET_PARAMETER _IOW(IEP_IOC_MAGIC, 8, unsigned long)
+#define IEP_RELEASE_CURRENT_TASK _IOW(IEP_IOC_MAGIC, 9, unsigned long)
+
+#ifdef CONFIG_COMPAT
+#define COMPAT_IEP_SET_PARAMETER_REQ _IOW(IEP_IOC_MAGIC, 1, u32)
+#define COMPAT_IEP_SET_PARAMETER_DEINTERLACE _IOW(IEP_IOC_MAGIC, 2, u32)
+#define COMPAT_IEP_SET_PARAMETER_ENHANCE _IOW(IEP_IOC_MAGIC, 3, u32)
+#define COMPAT_IEP_SET_PARAMETER_CONVERT _IOW(IEP_IOC_MAGIC, 4, u32)
+#define COMPAT_IEP_SET_PARAMETER_SCALE _IOW(IEP_IOC_MAGIC, 5, u32)
+#define COMPAT_IEP_GET_RESULT_SYNC _IOW(IEP_IOC_MAGIC, 6, u32)
+#define COMPAT_IEP_GET_RESULT_ASYNC _IOW(IEP_IOC_MAGIC, 7, u32)
+#define COMPAT_IEP_SET_PARAMETER _IOW(IEP_IOC_MAGIC, 8, u32)
+#define COMPAT_IEP_RELEASE_CURRENT_TASK _IOW(IEP_IOC_MAGIC, 9, u32)
+#endif
/* Driver information */
#define DRIVER_DESC "IEP Device Driver"
#define DRIVER_NAME "iep"
+#define DEBUG
+#ifdef DEBUG
+#define iep_debug(level, fmt, args...) \
+ do { \
+ if (debug >= level) \
+ pr_info("%s:%d: " fmt, \
+ __func__, __LINE__, ##args); \
+ } while (0)
+#else
+#define iep_debug(level, fmt, args...)
+#endif
+
+#define iep_debug_enter() vpu_debug(4, "enter\n")
+#define iep_debug_leave() vpu_debug(4, "leave\n")
+
+#define iep_err(fmt, args...) \
+ pr_err("%s:%d: " fmt, __func__, __LINE__, ##args)
+
/* Logging */
#define IEP_DEBUG 0
#if IEP_DEBUG
struct iep_img
{
- unsigned short act_w; // act_width
- unsigned short act_h; // act_height
- signed short x_off; // x offset for the vir,word unit
- signed short y_off; // y offset for the vir,word unit
-
- unsigned short vir_w; //unit :pix
- unsigned short vir_h; //unit :pix
- unsigned int format;
- unsigned int *mem_addr;
- unsigned int *uv_addr;
- unsigned int *v_addr;
-
- unsigned char rb_swap;//not be used
- unsigned char uv_swap;//not be used
-
- unsigned char alpha_swap;//not be used
+ u16 act_w; /* act_width */
+ u16 act_h; /* act_height */
+ s16 x_off; /* x offset for the vir,word unit */
+ s16 y_off; /* y offset for the vir,word unit */
+
+ u16 vir_w; /* unit :pix */
+ u16 vir_h; /* unit :pix */
+ u32 format;
+ u32 mem_addr;
+ u32 uv_addr;
+ u32 v_addr;
+
+ u8 rb_swap; /* not be used */
+ u8 uv_swap; /* not be used */
+
+ u8 alpha_swap; /* not be used */
};
u8 yuv2rgb_clip_en;
u8 lcdc_path_en;
- int off_x;
- int off_y;
- int width;
- int height;
- int layer;
+ s32 off_x;
+ s32 off_y;
+ s32 width;
+ s32 height;
+ s32 layer;
u8 yuv_3D_denoise_en;
/* yuv color enhance */
u8 yuv_enhance_en;
- int sat_con_int;
- int contrast_int;
- int cos_hue_int;
- int sin_hue_int;
+ s32 sat_con_int;
+ s32 contrast_int;
+ s32 cos_hue_int;
+ s32 sin_hue_int;
s8 yuv_enh_brightness; /*-32<brightness<31*/
u8 video_mode; /*0-3*/
u8 color_bar_y; /*0-127*/
u8 rgb_enhance_en;/*i don't konw what is used*/
u8 rgb_color_enhance_en;/*sw_rgb_color_enh_en*/
- unsigned int rgb_enh_coe;
+ u32 rgb_enh_coe;
u8 rgb_enhance_mode;/*sw_rgb_enh_sel,dde sel*/
u8 rgb_cg_en;/*sw_rgb_con_gam_en*/
- unsigned int cg_tab[192];
+ u32 cg_tab[192];
/*sw_con_gam_order;0 cg prior to dde,1 dde prior to cg*/
u8 rgb_contrast_enhance_mode;
- int enh_threshold;
- int enh_alpha;
- int enh_radius;
+ s32 enh_threshold;
+ s32 enh_alpha;
+ s32 enh_radius;
u8 scale_up_mode;
#define IEP_MAJOR 255
#define IEP_CLK_ENABLE
-//#define IEP_TEST_CASE
+/*#define IEP_TEST_CASE*/
-//#undef dmac_flush_range
-//#define dmac_flush_range dma_cache_wback_inv
+static int debug;
+module_param(debug, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(debug,
+ "Debug level - higher value produces more verbose messages");
#define RK_IEP_SIZE 0x1000
#define IEP_TIMEOUT_DELAY 2*HZ
/* iep_soft_rst(iep_drvdata1->iep_base); */
#ifdef IEP_CLK_ENABLE
- clk_prepare_enable(iep_drvdata1->pd_iep);
+ if (iep_drvdata1->pd_iep)
+ clk_prepare_enable(iep_drvdata1->pd_iep);
clk_prepare_enable(iep_drvdata1->aclk_iep);
clk_prepare_enable(iep_drvdata1->hclk_iep);
#endif
#ifdef IEP_CLK_ENABLE
clk_disable_unprepare(iep_drvdata1->aclk_iep);
clk_disable_unprepare(iep_drvdata1->hclk_iep);
- clk_disable_unprepare(iep_drvdata1->pd_iep);
+ if (iep_drvdata1->pd_iep)
+ clk_disable_unprepare(iep_drvdata1->pd_iep);
#endif
wake_unlock(&iep_drvdata1->wake_lock);
return ret;
}
+#ifdef CONFIG_COMPAT
+static long compat_iep_ioctl(struct file *filp, uint32_t cmd,
+ unsigned long arg)
+{
+ int ret = 0;
+ iep_session *session = (iep_session *)filp->private_data;
+
+ if (NULL == session) {
+ IEP_ERR("%s [%d] iep thread session is null\n",
+ __func__, __LINE__);
+ return -EINVAL;
+ }
+
+ mutex_lock(&iep_service.mutex);
+
+ switch (cmd) {
+ case COMPAT_IEP_SET_PARAMETER:
+ {
+ struct IEP_MSG *msg;
+
+ msg = kzalloc(sizeof(*msg), GFP_KERNEL);
+
+ if (msg) {
+ if (copy_from_user
+ (msg, compat_ptr((compat_uptr_t)arg),
+ sizeof(struct IEP_MSG))) {
+ IEP_ERR("copy_from_user failure\n");
+ ret = -EFAULT;
+ }
+ }
+
+ if (ret == 0) {
+ if (atomic_read(&iep_service.waitcnt) < 10) {
+#if defined(CONFIG_IEP_IOMMU)
+ iep_power_on();
+#endif
+ iep_config(session, msg);
+ atomic_inc(&iep_service.waitcnt);
+ } else {
+ IEP_ERR("iep task queue full\n");
+ ret = -EFAULT;
+ }
+ }
+
+ /** REGISTER CONFIG must accord to Timing When DPI mode
+ * enable */
+ if (!iep_drvdata1->dpi_mode)
+ iep_try_set_reg();
+ kfree(msg);
+ }
+ break;
+ case COMPAT_IEP_GET_RESULT_SYNC:
+ if (0 > iep_get_result_sync(session))
+ ret = -ETIMEDOUT;
+ break;
+ case COMPAT_IEP_GET_RESULT_ASYNC:
+ iep_get_result_async(session);
+ break;
+ case COMPAT_IEP_RELEASE_CURRENT_TASK:
+ iep_del_running_list_timeout();
+ iep_try_set_reg();
+ iep_try_start_frm();
+ break;
+ default:
+ IEP_ERR("unknown ioctl cmd!\n");
+ ret = -EINVAL;
+ }
+ mutex_unlock(&iep_service.mutex);
+
+ return ret;
+}
+#endif
+
struct file_operations iep_fops = {
.owner = THIS_MODULE,
.open = iep_open,
.release = iep_release,
.poll = iep_poll,
.unlocked_ioctl = iep_ioctl,
+#ifdef CONFIG_COMPAT
+ .compat_ioctl = compat_iep_ioctl,
+#endif
};
static struct miscdevice iep_dev = {
data->pd_iep = devm_clk_get(&pdev->dev, "pd_iep");
if (IS_ERR(data->pd_iep)) {
IEP_ERR("failed to find iep power down clock source.\n");
- goto err_clock;
+ data->pd_iep = NULL;
}
data->aclk_iep = devm_clk_get(&pdev->dev, "aclk_iep");
}
err_ioremap:
wake_lock_destroy(&data->wake_lock);
+#ifdef IEP_CLK_ENABLE
err_clock:
+#endif
return ret;
}