2 *************************************************************************
3 * Rockchip driver for CIF ISP 1.0
4 * (Based on Intel driver for sofiaxxx)
6 * Copyright (C) 2015 Intel Mobile Communications GmbH
7 * Copyright (C) 2016 Fuzhou Rockchip Electronics Co., Ltd.
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *************************************************************************
17 #include <linux/kernel.h>
18 #include <linux/i2c.h>
19 #include <media/v4l2-subdev.h>
20 #include <media/v4l2-common.h>
21 #include <media/v4l2-ioctl.h>
22 #include "cif_isp10.h"
23 #include <linux/platform_data/rk_isp10_platform.h>
24 #include <media/v4l2-controls_rockchip.h>
25 #include <linux/slab.h>
26 /* ===================== */
28 /* ===================== */
29 void *cif_isp10_img_src_v4l2_i2c_subdev_to_img_src(
31 struct pltfrm_soc_cfg *soc_cfg)
34 struct i2c_client *client;
35 struct v4l2_subdev *subdev;
37 client = i2c_verify_client(dev);
38 if (IS_ERR_OR_NULL(client)) {
39 cif_isp10_pltfrm_pr_err(dev,
40 "not an I2C device\n");
45 subdev = i2c_get_clientdata(client);
46 if (IS_ERR_OR_NULL(subdev))
49 ret = v4l2_subdev_call(subdev,
57 return (void *)subdev;
59 cif_isp10_pltfrm_pr_err(NULL, "failed with error %d\n", ret);
63 static enum cif_isp10_pix_fmt img_src_v4l2_subdev_pix_fmt2cif_isp10_pix_fmt(
66 switch (img_src_pix_fmt) {
67 case MEDIA_BUS_FMT_YUYV8_1_5X8:
68 case MEDIA_BUS_FMT_YUYV8_2X8:
69 case MEDIA_BUS_FMT_YUYV10_2X10:
70 case MEDIA_BUS_FMT_YUYV8_1X16:
71 case MEDIA_BUS_FMT_YUYV10_1X20:
73 case MEDIA_BUS_FMT_UYVY8_1_5X8:
74 case MEDIA_BUS_FMT_UYVY8_2X8:
75 case MEDIA_BUS_FMT_UYVY8_1X16:
77 case MEDIA_BUS_FMT_RGB565_2X8_BE:
78 case MEDIA_BUS_FMT_RGB565_2X8_LE:
80 case MEDIA_BUS_FMT_RGB666_1X18:
82 case MEDIA_BUS_FMT_RGB888_1X24:
83 case MEDIA_BUS_FMT_RGB888_2X12_BE:
84 case MEDIA_BUS_FMT_RGB888_2X12_LE:
86 case MEDIA_BUS_FMT_SBGGR8_1X8:
87 return CIF_BAYER_SBGGR8;
88 case MEDIA_BUS_FMT_SGBRG8_1X8:
89 return CIF_BAYER_SGBRG8;
90 case MEDIA_BUS_FMT_SGRBG8_1X8:
91 return CIF_BAYER_SGRBG8;
92 case MEDIA_BUS_FMT_SRGGB8_1X8:
93 return CIF_BAYER_SRGGB8;
94 case MEDIA_BUS_FMT_SBGGR10_ALAW8_1X8:
95 case MEDIA_BUS_FMT_SBGGR10_DPCM8_1X8:
96 case MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_BE:
97 case MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE:
98 case MEDIA_BUS_FMT_SBGGR10_2X8_PADLO_BE:
99 case MEDIA_BUS_FMT_SBGGR10_2X8_PADLO_LE:
100 case MEDIA_BUS_FMT_SBGGR10_1X10:
101 return CIF_BAYER_SBGGR10;
102 case MEDIA_BUS_FMT_SGBRG10_ALAW8_1X8:
103 case MEDIA_BUS_FMT_SGBRG10_DPCM8_1X8:
104 case MEDIA_BUS_FMT_SGBRG10_1X10:
105 return CIF_BAYER_SGBRG10;
106 case MEDIA_BUS_FMT_SGRBG10_ALAW8_1X8:
107 case MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8:
108 case MEDIA_BUS_FMT_SGRBG10_1X10:
109 return CIF_BAYER_SGRBG10;
110 case MEDIA_BUS_FMT_SRGGB10_ALAW8_1X8:
111 case MEDIA_BUS_FMT_SRGGB10_DPCM8_1X8:
112 case MEDIA_BUS_FMT_SRGGB10_1X10:
113 return CIF_BAYER_SRGGB10;
114 case MEDIA_BUS_FMT_SBGGR12_1X12:
115 return CIF_BAYER_SBGGR12;
116 case MEDIA_BUS_FMT_SGBRG12_1X12:
117 return CIF_BAYER_SGBRG12;
118 case MEDIA_BUS_FMT_SGRBG12_1X12:
119 return CIF_BAYER_SGRBG12;
120 case MEDIA_BUS_FMT_SRGGB12_1X12:
121 return CIF_BAYER_SRGGB12;
122 case MEDIA_BUS_FMT_JPEG_1X8:
125 return CIF_UNKNOWN_FORMAT;
129 static int cif_isp10_pix_fmt2img_src_v4l2_subdev_pix_fmt(
130 enum cif_isp10_pix_fmt cif_isp10_pix_fmt)
132 switch (cif_isp10_pix_fmt) {
134 return MEDIA_BUS_FMT_YUYV8_2X8;
136 return MEDIA_BUS_FMT_UYVY8_2X8;
138 return MEDIA_BUS_FMT_RGB565_2X8_LE;
140 return MEDIA_BUS_FMT_RGB666_1X18;
142 return MEDIA_BUS_FMT_RGB888_1X24;
143 case CIF_BAYER_SBGGR8:
144 return MEDIA_BUS_FMT_SBGGR8_1X8;
145 case CIF_BAYER_SGBRG8:
146 return MEDIA_BUS_FMT_SGBRG8_1X8;
147 case CIF_BAYER_SGRBG8:
148 return MEDIA_BUS_FMT_SGRBG8_1X8;
149 case CIF_BAYER_SRGGB8:
150 return MEDIA_BUS_FMT_SRGGB8_1X8;
151 case CIF_BAYER_SBGGR10:
152 return MEDIA_BUS_FMT_SBGGR10_1X10;
153 case CIF_BAYER_SGBRG10:
154 return MEDIA_BUS_FMT_SGBRG10_1X10;
155 case CIF_BAYER_SGRBG10:
156 return MEDIA_BUS_FMT_SGRBG10_1X10;
157 case CIF_BAYER_SRGGB10:
158 return MEDIA_BUS_FMT_SRGGB10_1X10;
159 case CIF_BAYER_SBGGR12:
160 return MEDIA_BUS_FMT_SBGGR12_1X12;
161 case CIF_BAYER_SGBRG12:
162 return MEDIA_BUS_FMT_SGBRG12_1X12;
163 case CIF_BAYER_SGRBG12:
164 return MEDIA_BUS_FMT_SGRBG12_1X12;
165 case CIF_BAYER_SRGGB12:
166 return MEDIA_BUS_FMT_SRGGB12_1X12;
168 return MEDIA_BUS_FMT_JPEG_1X8;
174 static int cif_isp10_v4l2_cid2v4l2_cid(u32 cif_isp10_cid)
176 switch (cif_isp10_cid) {
177 case CIF_ISP10_CID_FLASH_MODE:
178 return V4L2_CID_FLASH_LED_MODE;
179 case CIF_ISP10_CID_AUTO_GAIN:
180 return V4L2_CID_AUTOGAIN;
181 case CIF_ISP10_CID_AUTO_EXPOSURE:
182 return V4L2_EXPOSURE_AUTO;
183 case CIF_ISP10_CID_AUTO_WHITE_BALANCE:
184 return V4L2_CID_AUTO_WHITE_BALANCE;
185 case CIF_ISP10_CID_BLACK_LEVEL:
186 return V4L2_CID_BLACK_LEVEL;
187 case CIF_ISP10_CID_WB_TEMPERATURE:
188 return V4L2_CID_WHITE_BALANCE_TEMPERATURE;
189 case CIF_ISP10_CID_EXPOSURE_TIME:
190 return V4L2_CID_EXPOSURE;
191 case CIF_ISP10_CID_ANALOG_GAIN:
192 return V4L2_CID_GAIN;
193 case CIF_ISP10_CID_FOCUS_ABSOLUTE:
194 return V4L2_CID_FOCUS_ABSOLUTE;
195 case CIF_ISP10_CID_AUTO_N_PRESET_WHITE_BALANCE:
196 return V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE;
197 case CIF_ISP10_CID_SCENE_MODE:
198 return V4L2_CID_SCENE_MODE;
199 case CIF_ISP10_CID_ISO_SENSITIVITY:
200 return V4L2_CID_ISO_SENSITIVITY;
201 case CIF_ISP10_CID_AUTO_FPS:
202 return RK_V4L2_CID_AUTO_FPS;
203 case CIF_ISP10_CID_VBLANKING:
204 return RK_V4L2_CID_VBLANKING;
205 case CIF_ISP10_CID_HFLIP:
206 return V4L2_CID_HFLIP;
207 case CIF_ISP10_CID_VFLIP:
208 return V4L2_CID_VFLIP;
210 cif_isp10_pltfrm_pr_err(NULL,
211 "unknown/unsupported CIF ISP20 ID %d\n",
218 int cif_isp10_img_src_v4l2_subdev_s_streaming(
222 struct v4l2_subdev *subdev = img_src;
225 return v4l2_subdev_call(subdev, video, s_stream, 1);
227 return v4l2_subdev_call(subdev, video, s_stream, 0);
230 int cif_isp10_img_src_v4l2_subdev_s_power(
234 struct v4l2_subdev *subdev = img_src;
237 return v4l2_subdev_call(subdev, core, s_power, 1);
239 return v4l2_subdev_call(subdev, core, s_power, 0);
242 int cif_isp10_img_src_v4l2_subdev_enum_strm_fmts(
245 struct cif_isp10_strm_fmt_desc *strm_fmt_desc)
248 struct v4l2_subdev *subdev = img_src;
249 struct v4l2_subdev_frame_interval_enum fie = {.index = index};
250 struct pltfrm_cam_defrect defrect;
253 ret = v4l2_subdev_call(subdev, video, querystd, &std);
254 if (!IS_ERR_VALUE(ret))
255 strm_fmt_desc->std_id = std;
257 strm_fmt_desc->std_id = 0;
259 ret = v4l2_subdev_call(subdev, pad,
260 enum_frame_interval, NULL, &fie);
261 if (!IS_ERR_VALUE(ret)) {
262 strm_fmt_desc->discrete_intrvl = true;
263 strm_fmt_desc->min_intrvl.numerator =
264 fie.interval.numerator;
265 strm_fmt_desc->min_intrvl.denominator =
266 fie.interval.denominator;
267 strm_fmt_desc->discrete_frmsize = true;
268 strm_fmt_desc->min_frmsize.width = fie.width;
269 strm_fmt_desc->min_frmsize.height = fie.height;
270 strm_fmt_desc->pix_fmt =
271 img_src_v4l2_subdev_pix_fmt2cif_isp10_pix_fmt(
274 defrect.width = fie.width;
275 defrect.height = fie.height;
276 memset(&defrect, 0x00, sizeof(struct v4l2_rect));
277 v4l2_subdev_call(subdev,
280 PLTFRM_CIFCAM_G_DEFRECT,
282 if ((defrect.defrect.width == 0) ||
283 (defrect.defrect.height == 0)) {
284 strm_fmt_desc->defrect.left = 0;
285 strm_fmt_desc->defrect.top = 0;
286 strm_fmt_desc->defrect.width = fie.width;
287 strm_fmt_desc->defrect.height = fie.height;
289 strm_fmt_desc->defrect = defrect.defrect;
296 int cif_isp10_img_src_v4l2_subdev_s_strm_fmt(
298 struct cif_isp10_strm_fmt *strm_fmt)
301 struct v4l2_subdev *subdev = img_src;
302 struct v4l2_subdev_format format;
303 struct v4l2_subdev_frame_interval intrvl;
305 format.which = V4L2_SUBDEV_FORMAT_ACTIVE;
306 format.format.code = cif_isp10_pix_fmt2img_src_v4l2_subdev_pix_fmt(
307 strm_fmt->frm_fmt.pix_fmt);
308 format.format.width = strm_fmt->frm_fmt.width;
309 format.format.height = strm_fmt->frm_fmt.height;
310 ret = v4l2_subdev_call(subdev, pad, set_fmt, NULL, &format);
311 if (IS_ERR_VALUE(ret))
313 intrvl.interval.numerator = strm_fmt->frm_intrvl.numerator;
314 intrvl.interval.denominator = strm_fmt->frm_intrvl.denominator;
315 ret = v4l2_subdev_call(subdev, video, s_frame_interval, &intrvl);
316 if (IS_ERR_VALUE(ret))
320 pr_err("img_src.%s ERR: failed with error %d\n", __func__, ret);
324 int cif_isp10_img_src_v4l2_subdev_g_ctrl(
329 struct v4l2_control ctrl;
331 struct v4l2_subdev *subdev = img_src;
333 ctrl.id = cif_isp10_v4l2_cid2v4l2_cid(id);
335 if (IS_ERR_VALUE(ctrl.id))
338 ret = v4l2_subdev_call(subdev, core, g_ctrl, &ctrl);
339 if (!IS_ERR_VALUE(ret)) {
340 if (id == CIF_ISP10_CID_FLASH_MODE) {
341 if (ctrl.value == V4L2_FLASH_LED_MODE_NONE) {
342 ctrl.value = CIF_ISP10_FLASH_MODE_OFF;
343 } else if (ctrl.value == V4L2_FLASH_LED_MODE_FLASH) {
344 ctrl.value = CIF_ISP10_FLASH_MODE_FLASH;
345 } else if (ctrl.value == V4L2_FLASH_LED_MODE_TORCH) {
346 ctrl.value = CIF_ISP10_FLASH_MODE_TORCH;
348 cif_isp10_pltfrm_pr_err(NULL,
349 "unknown/unsupported value %d for control ID 0x%x\n",
359 int cif_isp10_img_src_v4l2_subdev_s_ctrl(
364 struct v4l2_control ctrl;
365 struct v4l2_subdev *subdev = img_src;
368 ctrl.id = cif_isp10_v4l2_cid2v4l2_cid(id);
370 if (IS_ERR_VALUE(ctrl.id)) {
372 } else if (id == CIF_ISP10_CID_FLASH_MODE) {
373 if (val == CIF_ISP10_FLASH_MODE_OFF) {
374 ctrl.value = V4L2_FLASH_LED_MODE_NONE;
375 } else if (val == CIF_ISP10_FLASH_MODE_FLASH) {
376 ctrl.value = V4L2_FLASH_LED_MODE_FLASH;
377 } else if (val == CIF_ISP10_FLASH_MODE_TORCH) {
378 ctrl.value = V4L2_FLASH_LED_MODE_TORCH;
380 cif_isp10_pltfrm_pr_err(NULL,
381 "unknown/unsupported value %d for control ID %d\n",
386 return v4l2_subdev_call(subdev, core, s_ctrl, &ctrl);
389 const char *cif_isp10_img_src_v4l2_subdev_g_name(
392 struct v4l2_subdev *subdev = img_src;
394 return dev_driver_string(subdev->dev);
397 int cif_isp10_img_src_v4l2_subdev_s_ext_ctrls(
399 struct cif_isp10_img_src_ext_ctrl *ctrl)
401 struct v4l2_ext_controls ctrls;
402 struct v4l2_ext_control *controls;
405 struct v4l2_subdev *subdev = img_src;
410 controls = kmalloc_array(ctrl->cnt, sizeof(struct v4l2_ext_control),
416 for (i = 0; i < ctrl->cnt; i++) {
417 controls[i].id = ctrl->ctrls[i].id;
418 controls[i].value = ctrl->ctrls[i].val;
421 ctrls.count = ctrl->cnt;
422 ctrls.controls = controls;
424 * current kernel version don't define
425 * this member for struct v4l2_ext_control.
427 /* ctrls.ctrl_class = ctrl->class; */
428 ctrls.reserved[0] = 0;
429 ctrls.reserved[1] = 0;
431 ret = v4l2_subdev_call(subdev,
432 core, s_ext_ctrls, &ctrls);
439 long cif_isp10_img_src_v4l2_subdev_ioctl(
444 struct v4l2_subdev *subdev = img_src;
448 case RK_VIDIOC_SENSOR_MODE_DATA:
449 case RK_VIDIOC_CAMERA_MODULEINFO:
451 case PLTFRM_CIFCAM_G_ITF_CFG:
452 case PLTFRM_CIFCAM_G_DEFRECT:
453 case PLTFRM_CIFCAM_ATTACH:
454 ret = v4l2_subdev_call(subdev,
465 if (IS_ERR_VALUE(ret))
466 pr_err("img_src.%s subdev call(cmd: 0x%x) failed with error %ld\n",