1*238c84f7SMauro Carvalho Chehab /* SPDX-License-Identifier: GPL-2.0-only */ 2*238c84f7SMauro Carvalho Chehab /* 3*238c84f7SMauro Carvalho Chehab * Samsung EXYNOS4x12 FIMC-IS (Imaging Subsystem) driver 4*238c84f7SMauro Carvalho Chehab * 5*238c84f7SMauro Carvalho Chehab * Copyright (C) 2013 Samsung Electronics Co., Ltd. 6*238c84f7SMauro Carvalho Chehab * 7*238c84f7SMauro Carvalho Chehab * Authors: Sylwester Nawrocki <s.nawrocki@samsung.com> 8*238c84f7SMauro Carvalho Chehab * Younghwan Joo <yhwan.joo@samsung.com> 9*238c84f7SMauro Carvalho Chehab */ 10*238c84f7SMauro Carvalho Chehab #ifndef FIMC_ISP_H_ 11*238c84f7SMauro Carvalho Chehab #define FIMC_ISP_H_ 12*238c84f7SMauro Carvalho Chehab 13*238c84f7SMauro Carvalho Chehab #include <linux/io.h> 14*238c84f7SMauro Carvalho Chehab #include <linux/platform_device.h> 15*238c84f7SMauro Carvalho Chehab #include <linux/sched.h> 16*238c84f7SMauro Carvalho Chehab #include <linux/spinlock.h> 17*238c84f7SMauro Carvalho Chehab #include <linux/types.h> 18*238c84f7SMauro Carvalho Chehab #include <linux/videodev2.h> 19*238c84f7SMauro Carvalho Chehab 20*238c84f7SMauro Carvalho Chehab #include <media/media-entity.h> 21*238c84f7SMauro Carvalho Chehab #include <media/videobuf2-v4l2.h> 22*238c84f7SMauro Carvalho Chehab #include <media/v4l2-device.h> 23*238c84f7SMauro Carvalho Chehab #include <media/v4l2-mediabus.h> 24*238c84f7SMauro Carvalho Chehab #include <media/drv-intf/exynos-fimc.h> 25*238c84f7SMauro Carvalho Chehab 26*238c84f7SMauro Carvalho Chehab extern int fimc_isp_debug; 27*238c84f7SMauro Carvalho Chehab 28*238c84f7SMauro Carvalho Chehab #define isp_dbg(level, dev, fmt, arg...) \ 29*238c84f7SMauro Carvalho Chehab v4l2_dbg(level, fimc_isp_debug, dev, fmt, ## arg) 30*238c84f7SMauro Carvalho Chehab 31*238c84f7SMauro Carvalho Chehab /* FIXME: revisit these constraints */ 32*238c84f7SMauro Carvalho Chehab #define FIMC_ISP_SINK_WIDTH_MIN (16 + 8) 33*238c84f7SMauro Carvalho Chehab #define FIMC_ISP_SINK_HEIGHT_MIN (12 + 8) 34*238c84f7SMauro Carvalho Chehab #define FIMC_ISP_SOURCE_WIDTH_MIN 8 35*238c84f7SMauro Carvalho Chehab #define FIMC_ISP_SOURCE_HEIGHT_MIN 8 36*238c84f7SMauro Carvalho Chehab #define FIMC_ISP_CAC_MARGIN_WIDTH 16 37*238c84f7SMauro Carvalho Chehab #define FIMC_ISP_CAC_MARGIN_HEIGHT 12 38*238c84f7SMauro Carvalho Chehab 39*238c84f7SMauro Carvalho Chehab #define FIMC_ISP_SINK_WIDTH_MAX (4000 - 16) 40*238c84f7SMauro Carvalho Chehab #define FIMC_ISP_SINK_HEIGHT_MAX (4000 + 12) 41*238c84f7SMauro Carvalho Chehab #define FIMC_ISP_SOURCE_WIDTH_MAX 4000 42*238c84f7SMauro Carvalho Chehab #define FIMC_ISP_SOURCE_HEIGHT_MAX 4000 43*238c84f7SMauro Carvalho Chehab 44*238c84f7SMauro Carvalho Chehab #define FIMC_ISP_NUM_FORMATS 3 45*238c84f7SMauro Carvalho Chehab #define FIMC_ISP_REQ_BUFS_MIN 2 46*238c84f7SMauro Carvalho Chehab #define FIMC_ISP_REQ_BUFS_MAX 32 47*238c84f7SMauro Carvalho Chehab 48*238c84f7SMauro Carvalho Chehab #define FIMC_ISP_SD_PAD_SINK 0 49*238c84f7SMauro Carvalho Chehab #define FIMC_ISP_SD_PAD_SRC_FIFO 1 50*238c84f7SMauro Carvalho Chehab #define FIMC_ISP_SD_PAD_SRC_DMA 2 51*238c84f7SMauro Carvalho Chehab #define FIMC_ISP_SD_PADS_NUM 3 52*238c84f7SMauro Carvalho Chehab #define FIMC_ISP_MAX_PLANES 1 53*238c84f7SMauro Carvalho Chehab 54*238c84f7SMauro Carvalho Chehab /** 55*238c84f7SMauro Carvalho Chehab * struct fimc_isp_frame - source/target frame properties 56*238c84f7SMauro Carvalho Chehab * @width: full image width 57*238c84f7SMauro Carvalho Chehab * @height: full image height 58*238c84f7SMauro Carvalho Chehab * @rect: crop/composition rectangle 59*238c84f7SMauro Carvalho Chehab */ 60*238c84f7SMauro Carvalho Chehab struct fimc_isp_frame { 61*238c84f7SMauro Carvalho Chehab u16 width; 62*238c84f7SMauro Carvalho Chehab u16 height; 63*238c84f7SMauro Carvalho Chehab struct v4l2_rect rect; 64*238c84f7SMauro Carvalho Chehab }; 65*238c84f7SMauro Carvalho Chehab 66*238c84f7SMauro Carvalho Chehab struct fimc_isp_ctrls { 67*238c84f7SMauro Carvalho Chehab struct v4l2_ctrl_handler handler; 68*238c84f7SMauro Carvalho Chehab 69*238c84f7SMauro Carvalho Chehab /* Auto white balance */ 70*238c84f7SMauro Carvalho Chehab struct v4l2_ctrl *auto_wb; 71*238c84f7SMauro Carvalho Chehab /* Auto ISO control cluster */ 72*238c84f7SMauro Carvalho Chehab struct { 73*238c84f7SMauro Carvalho Chehab struct v4l2_ctrl *auto_iso; 74*238c84f7SMauro Carvalho Chehab struct v4l2_ctrl *iso; 75*238c84f7SMauro Carvalho Chehab }; 76*238c84f7SMauro Carvalho Chehab /* Adjust - contrast */ 77*238c84f7SMauro Carvalho Chehab struct v4l2_ctrl *contrast; 78*238c84f7SMauro Carvalho Chehab /* Adjust - saturation */ 79*238c84f7SMauro Carvalho Chehab struct v4l2_ctrl *saturation; 80*238c84f7SMauro Carvalho Chehab /* Adjust - sharpness */ 81*238c84f7SMauro Carvalho Chehab struct v4l2_ctrl *sharpness; 82*238c84f7SMauro Carvalho Chehab /* Adjust - brightness */ 83*238c84f7SMauro Carvalho Chehab struct v4l2_ctrl *brightness; 84*238c84f7SMauro Carvalho Chehab /* Adjust - hue */ 85*238c84f7SMauro Carvalho Chehab struct v4l2_ctrl *hue; 86*238c84f7SMauro Carvalho Chehab 87*238c84f7SMauro Carvalho Chehab /* Auto/manual exposure */ 88*238c84f7SMauro Carvalho Chehab struct v4l2_ctrl *auto_exp; 89*238c84f7SMauro Carvalho Chehab /* Manual exposure value */ 90*238c84f7SMauro Carvalho Chehab struct v4l2_ctrl *exposure; 91*238c84f7SMauro Carvalho Chehab /* AE/AWB lock/unlock */ 92*238c84f7SMauro Carvalho Chehab struct v4l2_ctrl *aewb_lock; 93*238c84f7SMauro Carvalho Chehab /* Exposure metering mode */ 94*238c84f7SMauro Carvalho Chehab struct v4l2_ctrl *exp_metering; 95*238c84f7SMauro Carvalho Chehab /* AFC */ 96*238c84f7SMauro Carvalho Chehab struct v4l2_ctrl *afc; 97*238c84f7SMauro Carvalho Chehab /* ISP image effect */ 98*238c84f7SMauro Carvalho Chehab struct v4l2_ctrl *colorfx; 99*238c84f7SMauro Carvalho Chehab }; 100*238c84f7SMauro Carvalho Chehab 101*238c84f7SMauro Carvalho Chehab struct isp_video_buf { 102*238c84f7SMauro Carvalho Chehab struct vb2_v4l2_buffer vb; 103*238c84f7SMauro Carvalho Chehab dma_addr_t dma_addr[FIMC_ISP_MAX_PLANES]; 104*238c84f7SMauro Carvalho Chehab unsigned int index; 105*238c84f7SMauro Carvalho Chehab }; 106*238c84f7SMauro Carvalho Chehab 107*238c84f7SMauro Carvalho Chehab #define to_isp_video_buf(_b) container_of(_b, struct isp_video_buf, vb) 108*238c84f7SMauro Carvalho Chehab 109*238c84f7SMauro Carvalho Chehab #define FIMC_ISP_MAX_BUFS 4 110*238c84f7SMauro Carvalho Chehab 111*238c84f7SMauro Carvalho Chehab /** 112*238c84f7SMauro Carvalho Chehab * struct fimc_is_video - fimc-is video device structure 113*238c84f7SMauro Carvalho Chehab * @ve: video_device structure and media pipeline 114*238c84f7SMauro Carvalho Chehab * @type: video device type (CAPTURE/OUTPUT) 115*238c84f7SMauro Carvalho Chehab * @pad: video device media (sink) pad 116*238c84f7SMauro Carvalho Chehab * @pending_buf_q: pending buffers queue head 117*238c84f7SMauro Carvalho Chehab * @active_buf_q: a queue head of buffers scheduled in hardware 118*238c84f7SMauro Carvalho Chehab * @vb_queue: vb2 buffer queue 119*238c84f7SMauro Carvalho Chehab * @reqbufs_count: the number of buffers requested in REQBUFS ioctl 120*238c84f7SMauro Carvalho Chehab * @buf_count: number of video buffers scheduled in hardware 121*238c84f7SMauro Carvalho Chehab * @buf_mask: bitmask of the queued video buffer indices 122*238c84f7SMauro Carvalho Chehab * @frame_count: counter of frames dequeued to user space 123*238c84f7SMauro Carvalho Chehab * @streaming: is streaming in progress? 124*238c84f7SMauro Carvalho Chehab * @buffers: buffer info 125*238c84f7SMauro Carvalho Chehab * @format: current fimc pixel format 126*238c84f7SMauro Carvalho Chehab * @pixfmt: current pixel format 127*238c84f7SMauro Carvalho Chehab */ 128*238c84f7SMauro Carvalho Chehab struct fimc_is_video { 129*238c84f7SMauro Carvalho Chehab struct exynos_video_entity ve; 130*238c84f7SMauro Carvalho Chehab enum v4l2_buf_type type; 131*238c84f7SMauro Carvalho Chehab struct media_pad pad; 132*238c84f7SMauro Carvalho Chehab struct list_head pending_buf_q; 133*238c84f7SMauro Carvalho Chehab struct list_head active_buf_q; 134*238c84f7SMauro Carvalho Chehab struct vb2_queue vb_queue; 135*238c84f7SMauro Carvalho Chehab unsigned int reqbufs_count; 136*238c84f7SMauro Carvalho Chehab unsigned int buf_count; 137*238c84f7SMauro Carvalho Chehab unsigned int buf_mask; 138*238c84f7SMauro Carvalho Chehab unsigned int frame_count; 139*238c84f7SMauro Carvalho Chehab int streaming; 140*238c84f7SMauro Carvalho Chehab struct isp_video_buf *buffers[FIMC_ISP_MAX_BUFS]; 141*238c84f7SMauro Carvalho Chehab const struct fimc_fmt *format; 142*238c84f7SMauro Carvalho Chehab struct v4l2_pix_format_mplane pixfmt; 143*238c84f7SMauro Carvalho Chehab }; 144*238c84f7SMauro Carvalho Chehab 145*238c84f7SMauro Carvalho Chehab /* struct fimc_isp:state bit definitions */ 146*238c84f7SMauro Carvalho Chehab #define ST_ISP_VID_CAP_BUF_PREP 0 147*238c84f7SMauro Carvalho Chehab #define ST_ISP_VID_CAP_STREAMING 1 148*238c84f7SMauro Carvalho Chehab 149*238c84f7SMauro Carvalho Chehab /** 150*238c84f7SMauro Carvalho Chehab * struct fimc_isp - FIMC-IS ISP data structure 151*238c84f7SMauro Carvalho Chehab * @pdev: pointer to FIMC-IS platform device 152*238c84f7SMauro Carvalho Chehab * @subdev: ISP v4l2_subdev 153*238c84f7SMauro Carvalho Chehab * @subdev_pads: the ISP subdev media pads 154*238c84f7SMauro Carvalho Chehab * @src_fmt: source mediabus format 155*238c84f7SMauro Carvalho Chehab * @sink_fmt: sink mediabus format 156*238c84f7SMauro Carvalho Chehab * @test_pattern: test pattern controls 157*238c84f7SMauro Carvalho Chehab * @ctrls: v4l2 controls structure 158*238c84f7SMauro Carvalho Chehab * @video_lock: mutex serializing video device operations 159*238c84f7SMauro Carvalho Chehab * @subdev_lock: mutex serializing subdev operations 160*238c84f7SMauro Carvalho Chehab * @cac_margin_x: horizontal CAC margin in pixels 161*238c84f7SMauro Carvalho Chehab * @cac_margin_y: vertical CAC margin in pixels 162*238c84f7SMauro Carvalho Chehab * @state: driver state flags 163*238c84f7SMauro Carvalho Chehab * @video_capture: the ISP block video capture device 164*238c84f7SMauro Carvalho Chehab */ 165*238c84f7SMauro Carvalho Chehab struct fimc_isp { 166*238c84f7SMauro Carvalho Chehab struct platform_device *pdev; 167*238c84f7SMauro Carvalho Chehab struct v4l2_subdev subdev; 168*238c84f7SMauro Carvalho Chehab struct media_pad subdev_pads[FIMC_ISP_SD_PADS_NUM]; 169*238c84f7SMauro Carvalho Chehab struct v4l2_mbus_framefmt src_fmt; 170*238c84f7SMauro Carvalho Chehab struct v4l2_mbus_framefmt sink_fmt; 171*238c84f7SMauro Carvalho Chehab struct v4l2_ctrl *test_pattern; 172*238c84f7SMauro Carvalho Chehab struct fimc_isp_ctrls ctrls; 173*238c84f7SMauro Carvalho Chehab 174*238c84f7SMauro Carvalho Chehab struct mutex video_lock; 175*238c84f7SMauro Carvalho Chehab struct mutex subdev_lock; 176*238c84f7SMauro Carvalho Chehab 177*238c84f7SMauro Carvalho Chehab unsigned int cac_margin_x; 178*238c84f7SMauro Carvalho Chehab unsigned int cac_margin_y; 179*238c84f7SMauro Carvalho Chehab 180*238c84f7SMauro Carvalho Chehab unsigned long state; 181*238c84f7SMauro Carvalho Chehab 182*238c84f7SMauro Carvalho Chehab struct fimc_is_video video_capture; 183*238c84f7SMauro Carvalho Chehab }; 184*238c84f7SMauro Carvalho Chehab 185*238c84f7SMauro Carvalho Chehab #define ctrl_to_fimc_isp(_ctrl) \ 186*238c84f7SMauro Carvalho Chehab container_of(ctrl->handler, struct fimc_isp, ctrls.handler) 187*238c84f7SMauro Carvalho Chehab 188*238c84f7SMauro Carvalho Chehab struct fimc_is; 189*238c84f7SMauro Carvalho Chehab 190*238c84f7SMauro Carvalho Chehab int fimc_isp_subdev_create(struct fimc_isp *isp); 191*238c84f7SMauro Carvalho Chehab void fimc_isp_subdev_destroy(struct fimc_isp *isp); 192*238c84f7SMauro Carvalho Chehab void fimc_isp_irq_handler(struct fimc_is *is); 193*238c84f7SMauro Carvalho Chehab int fimc_is_create_controls(struct fimc_isp *isp); 194*238c84f7SMauro Carvalho Chehab int fimc_is_delete_controls(struct fimc_isp *isp); 195*238c84f7SMauro Carvalho Chehab const struct fimc_fmt *fimc_isp_find_format(const u32 *pixelformat, 196*238c84f7SMauro Carvalho Chehab const u32 *mbus_code, int index); 197*238c84f7SMauro Carvalho Chehab #endif /* FIMC_ISP_H_ */ 198