isp10: rockchip: v0.1.6
[firefly-linux-kernel-4.4.55.git] / drivers / media / platform / rk-isp10 / cif_isp10_img_src_v4l2-subdev.c
1 /*
2  *************************************************************************
3  * Rockchip driver for CIF ISP 1.0
4  * (Based on Intel driver for sofiaxxx)
5  *
6  * Copyright (C) 2015 Intel Mobile Communications GmbH
7  * Copyright (C) 2016 Fuzhou Rockchip Electronics Co., Ltd.
8  *
9  *
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  *************************************************************************
15  */
16
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 /* ===================== */
27 /* Image Source */
28 /* ===================== */
29 void *cif_isp10_img_src_v4l2_i2c_subdev_to_img_src(
30         struct device *dev,
31         struct pltfrm_soc_cfg *soc_cfg)
32 {
33         int ret = 0;
34         struct i2c_client *client;
35         struct v4l2_subdev *subdev;
36
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");
41                 ret = -EINVAL;
42                 goto err;
43         }
44
45         subdev = i2c_get_clientdata(client);
46         if (IS_ERR_OR_NULL(subdev))
47                 return subdev;
48
49         ret = v4l2_subdev_call(subdev,
50                 core,
51                 ioctl,
52                 PLTFRM_CIFCAM_ATTACH,
53                 (void *)soc_cfg);
54         if (ret != 0)
55                 goto err;
56
57         return (void *)subdev;
58 err:
59         cif_isp10_pltfrm_pr_err(NULL, "failed with error %d\n", ret);
60         return ERR_PTR(ret);
61 }
62
63 static enum cif_isp10_pix_fmt img_src_v4l2_subdev_pix_fmt2cif_isp10_pix_fmt(
64         int img_src_pix_fmt)
65 {
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:
72                 return CIF_YUV422I;
73         case MEDIA_BUS_FMT_UYVY8_1_5X8:
74         case MEDIA_BUS_FMT_UYVY8_2X8:
75         case MEDIA_BUS_FMT_UYVY8_1X16:
76                 return CIF_UYV422I;
77         case MEDIA_BUS_FMT_RGB565_2X8_BE:
78         case MEDIA_BUS_FMT_RGB565_2X8_LE:
79                 return CIF_RGB565;
80         case MEDIA_BUS_FMT_RGB666_1X18:
81                 return CIF_RGB666;
82         case MEDIA_BUS_FMT_RGB888_1X24:
83         case MEDIA_BUS_FMT_RGB888_2X12_BE:
84         case MEDIA_BUS_FMT_RGB888_2X12_LE:
85                 return CIF_RGB888;
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:
123                 return CIF_JPEG;
124         default:
125                 return CIF_UNKNOWN_FORMAT;
126         }
127 }
128
129 static int cif_isp10_pix_fmt2img_src_v4l2_subdev_pix_fmt(
130         enum cif_isp10_pix_fmt cif_isp10_pix_fmt)
131 {
132         switch (cif_isp10_pix_fmt) {
133         case CIF_YUV422I:
134                 return MEDIA_BUS_FMT_YUYV8_2X8;
135         case CIF_UYV422I:
136                 return MEDIA_BUS_FMT_UYVY8_2X8;
137         case CIF_RGB565:
138                 return MEDIA_BUS_FMT_RGB565_2X8_LE;
139         case CIF_RGB666:
140                 return MEDIA_BUS_FMT_RGB666_1X18;
141         case CIF_RGB888:
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;
167         case CIF_JPEG:
168                 return MEDIA_BUS_FMT_JPEG_1X8;
169         default:
170                 return -EINVAL;
171         }
172 }
173
174 static int cif_isp10_v4l2_cid2v4l2_cid(u32 cif_isp10_cid)
175 {
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;
209         default:
210                 cif_isp10_pltfrm_pr_err(NULL,
211                         "unknown/unsupported CIF ISP20 ID %d\n",
212                         cif_isp10_cid);
213                 break;
214         }
215         return -EINVAL;
216 }
217
218 int cif_isp10_img_src_v4l2_subdev_s_streaming(
219         void *img_src,
220         bool enable)
221 {
222         struct v4l2_subdev *subdev = img_src;
223
224         if (enable)
225                 return v4l2_subdev_call(subdev, video, s_stream, 1);
226         else
227                 return v4l2_subdev_call(subdev, video, s_stream, 0);
228 }
229
230 int cif_isp10_img_src_v4l2_subdev_s_power(
231         void *img_src,
232         bool on)
233 {
234         struct v4l2_subdev *subdev = img_src;
235
236         if (on)
237                 return v4l2_subdev_call(subdev, core, s_power, 1);
238         else
239                 return v4l2_subdev_call(subdev, core, s_power, 0);
240 }
241
242 int cif_isp10_img_src_v4l2_subdev_enum_strm_fmts(
243         void *img_src,
244         u32 index,
245         struct cif_isp10_strm_fmt_desc *strm_fmt_desc)
246 {
247         int ret;
248         struct v4l2_subdev *subdev = img_src;
249         struct v4l2_subdev_frame_interval_enum fie = {.index = index};
250         struct pltfrm_cam_defrect defrect;
251         v4l2_std_id std;
252
253         ret = v4l2_subdev_call(subdev, video, querystd, &std);
254         if (!IS_ERR_VALUE(ret))
255                 strm_fmt_desc->std_id = std;
256         else
257                 strm_fmt_desc->std_id = 0;
258
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(
272                                 fie.code);
273
274                 defrect.width = fie.width;
275                 defrect.height = fie.height;
276                 memset(&defrect, 0x00, sizeof(struct v4l2_rect));
277                 v4l2_subdev_call(subdev,
278                         core,
279                         ioctl,
280                         PLTFRM_CIFCAM_G_DEFRECT,
281                         (void *)&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;
288                 } else {
289                         strm_fmt_desc->defrect = defrect.defrect;
290                 }
291         }
292
293         return ret;
294 }
295
296 int cif_isp10_img_src_v4l2_subdev_s_strm_fmt(
297         void *img_src,
298         struct cif_isp10_strm_fmt *strm_fmt)
299 {
300         int ret = 0;
301         struct v4l2_subdev *subdev = img_src;
302         struct v4l2_subdev_format format;
303         struct v4l2_subdev_frame_interval intrvl;
304
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))
312                 goto err;
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))
317                 goto err;
318         return 0;
319 err:
320         pr_err("img_src.%s ERR: failed with error %d\n", __func__, ret);
321         return ret;
322 }
323
324 int cif_isp10_img_src_v4l2_subdev_g_ctrl(
325         void *img_src,
326         int id,
327         int *val)
328 {
329         struct v4l2_control ctrl;
330         int ret;
331         struct v4l2_subdev *subdev = img_src;
332
333         ctrl.id = cif_isp10_v4l2_cid2v4l2_cid(id);
334
335         if (IS_ERR_VALUE(ctrl.id))
336                 return (int)ctrl.id;
337
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;
347                         } else {
348                                 cif_isp10_pltfrm_pr_err(NULL,
349                                         "unknown/unsupported value %d for control ID 0x%x\n",
350                                         ctrl.value, id);
351                                 return -EINVAL;
352                         }
353                 }
354                 *val = ctrl.value;
355         }
356         return ret;
357 }
358
359 int cif_isp10_img_src_v4l2_subdev_s_ctrl(
360         void *img_src,
361         int id,
362         int val)
363 {
364         struct v4l2_control ctrl;
365         struct v4l2_subdev *subdev = img_src;
366
367         ctrl.value = val;
368         ctrl.id = cif_isp10_v4l2_cid2v4l2_cid(id);
369
370         if (IS_ERR_VALUE(ctrl.id)) {
371                 return (int)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;
379                 } else {
380                         cif_isp10_pltfrm_pr_err(NULL,
381                                 "unknown/unsupported value %d for control ID %d\n",
382                                 val, id);
383                         return -EINVAL;
384                 }
385         }
386         return v4l2_subdev_call(subdev, core, s_ctrl, &ctrl);
387 }
388
389 const char *cif_isp10_img_src_v4l2_subdev_g_name(
390         void *img_src)
391 {
392         struct v4l2_subdev *subdev = img_src;
393
394         return dev_driver_string(subdev->dev);
395 }
396
397 int cif_isp10_img_src_v4l2_subdev_s_ext_ctrls(
398         void *img_src,
399         struct cif_isp10_img_src_ext_ctrl *ctrl)
400 {
401         struct v4l2_ext_controls ctrls;
402         struct v4l2_ext_control *controls;
403         int i;
404         int ret;
405         struct v4l2_subdev *subdev = img_src;
406
407         if (ctrl->cnt == 0)
408                 return -EINVAL;
409
410         controls = kmalloc_array(ctrl->cnt, sizeof(struct v4l2_ext_control),
411                 GFP_KERNEL);
412
413         if (!controls)
414                 return -ENOMEM;
415
416         for (i = 0; i < ctrl->cnt; i++) {
417                 controls[i].id = ctrl->ctrls[i].id;
418                 controls[i].value = ctrl->ctrls[i].val;
419         }
420
421         ctrls.count = ctrl->cnt;
422         ctrls.controls = controls;
423         /*
424          * current kernel version don't define
425          * this member for struct v4l2_ext_control.
426          */
427         /* ctrls.ctrl_class = ctrl->class; */
428         ctrls.reserved[0] = 0;
429         ctrls.reserved[1] = 0;
430
431         ret = v4l2_subdev_call(subdev,
432                 core, s_ext_ctrls, &ctrls);
433
434         kfree(controls);
435
436         return ret;
437 }
438
439 long cif_isp10_img_src_v4l2_subdev_ioctl(
440         void *img_src,
441         unsigned int cmd,
442         void *arg)
443 {
444         struct v4l2_subdev *subdev = img_src;
445         long ret = -EINVAL;
446
447         switch (cmd) {
448         case RK_VIDIOC_SENSOR_MODE_DATA:
449         case RK_VIDIOC_CAMERA_MODULEINFO:
450
451         case PLTFRM_CIFCAM_G_ITF_CFG:
452         case PLTFRM_CIFCAM_G_DEFRECT:
453         case PLTFRM_CIFCAM_ATTACH:
454                 ret = v4l2_subdev_call(subdev,
455                         core,
456                         ioctl,
457                         cmd,
458                         arg);
459
460                 break;
461         default:
462                 break;
463         }
464
465         if (IS_ERR_VALUE(ret))
466                 pr_err("img_src.%s subdev call(cmd: 0x%x) failed with error %ld\n",
467                 __func__, cmd, ret);
468
469         return ret;
470 }