Merge tag 'csky-for-linus-4.20-fixup-dtb' of https://github.com/c-sky/csky-linux
[linux-block.git] / drivers / media / platform / atmel / atmel-isc.c
CommitLineData
10626744
SW
1/*
2 * Atmel Image Sensor Controller (ISC) driver
3 *
4 * Copyright (C) 2016 Atmel
5 *
6 * Author: Songjun Wu <songjun.wu@microchip.com>
7 *
8 * This program is free software; you may redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; version 2 of the License.
11 *
12 * Sensor-->PFE-->WB-->CFA-->CC-->GAM-->CSC-->CBC-->SUB-->RLP-->DMA
13 *
14 * ISC video pipeline integrates the following submodules:
15 * PFE: Parallel Front End to sample the camera sensor input stream
16 * WB: Programmable white balance in the Bayer domain
17 * CFA: Color filter array interpolation module
18 * CC: Programmable color correction
19 * GAM: Gamma correction
20 * CSC: Programmable color space conversion
21 * CBC: Contrast and Brightness control
22 * SUB: This module performs YCbCr444 to YCbCr420 chrominance subsampling
23 * RLP: This module performs rounding, range limiting
24 * and packing of the incoming data
25 */
26
27#include <linux/clk.h>
28#include <linux/clkdev.h>
29#include <linux/clk-provider.h>
30#include <linux/delay.h>
31#include <linux/interrupt.h>
93d4a26c 32#include <linux/math64.h>
10626744
SW
33#include <linux/module.h>
34#include <linux/of.h>
859969b3 35#include <linux/of_graph.h>
10626744
SW
36#include <linux/platform_device.h>
37#include <linux/pm_runtime.h>
38#include <linux/regmap.h>
39#include <linux/videodev2.h>
40
93d4a26c 41#include <media/v4l2-ctrls.h>
10626744 42#include <media/v4l2-device.h>
93d4a26c 43#include <media/v4l2-event.h>
10626744
SW
44#include <media/v4l2-image-sizes.h>
45#include <media/v4l2-ioctl.h>
859969b3 46#include <media/v4l2-fwnode.h>
10626744
SW
47#include <media/v4l2-subdev.h>
48#include <media/videobuf2-dma-contig.h>
49
50#include "atmel-isc-regs.h"
51
52#define ATMEL_ISC_NAME "atmel_isc"
53
54#define ISC_MAX_SUPPORT_WIDTH 2592
55#define ISC_MAX_SUPPORT_HEIGHT 1944
56
57#define ISC_CLK_MAX_DIV 255
58
59enum isc_clk_id {
60 ISC_ISPCK = 0,
61 ISC_MCK = 1,
62};
63
64struct isc_clk {
65 struct clk_hw hw;
66 struct clk *clk;
67 struct regmap *regmap;
cab1dea3 68 spinlock_t lock;
10626744
SW
69 u8 id;
70 u8 parent_id;
71 u32 div;
72 struct device *dev;
73};
74
75#define to_isc_clk(hw) container_of(hw, struct isc_clk, hw)
76
77struct isc_buffer {
78 struct vb2_v4l2_buffer vb;
79 struct list_head list;
80};
81
82struct isc_subdev_entity {
83 struct v4l2_subdev *sd;
84 struct v4l2_async_subdev *asd;
85 struct v4l2_async_notifier notifier;
10626744
SW
86
87 u32 pfe_cfg0;
88
89 struct list_head list;
90};
91
f103ea11
WY
92/* Indicate the format is generated by the sensor */
93#define FMT_FLAG_FROM_SENSOR BIT(0)
94/* Indicate the format is produced by ISC itself */
95#define FMT_FLAG_FROM_CONTROLLER BIT(1)
96/* Indicate a Raw Bayer format */
97#define FMT_FLAG_RAW_FORMAT BIT(2)
98
99#define FMT_FLAG_RAW_FROM_SENSOR (FMT_FLAG_FROM_SENSOR | \
100 FMT_FLAG_RAW_FORMAT)
101
10626744
SW
102/*
103 * struct isc_format - ISC media bus format information
104 * @fourcc: Fourcc code for this format
105 * @mbus_code: V4L2 media bus format code.
f103ea11 106 * flags: Indicate format from sensor or converted by controller
93d4a26c 107 * @bpp: Bits per pixel (when stored in memory)
10626744 108 * (when transferred over a bus)
93d4a26c
SW
109 * @sd_support: Subdev supports this format
110 * @isc_support: ISC can convert raw format to this format
10626744 111 */
f103ea11 112
10626744
SW
113struct isc_format {
114 u32 fourcc;
115 u32 mbus_code;
f103ea11 116 u32 flags;
10626744
SW
117 u8 bpp;
118
93d4a26c
SW
119 bool sd_support;
120 bool isc_support;
121};
122
f103ea11
WY
123/* Pipeline bitmap */
124#define WB_ENABLE BIT(0)
125#define CFA_ENABLE BIT(1)
126#define CC_ENABLE BIT(2)
127#define GAM_ENABLE BIT(3)
128#define GAM_BENABLE BIT(4)
129#define GAM_GENABLE BIT(5)
130#define GAM_RENABLE BIT(6)
131#define CSC_ENABLE BIT(7)
132#define CBC_ENABLE BIT(8)
133#define SUB422_ENABLE BIT(9)
134#define SUB420_ENABLE BIT(10)
135
136#define GAM_ENABLES (GAM_RENABLE | GAM_GENABLE | GAM_BENABLE | GAM_ENABLE)
137
138struct fmt_config {
139 u32 fourcc;
140
141 u32 pfe_cfg0_bps;
142 u32 cfa_baycfg;
143 u32 rlp_cfg_mode;
144 u32 dcfg_imode;
145 u32 dctrl_dview;
146
147 u32 bits_pipeline;
148};
93d4a26c
SW
149
150#define HIST_ENTRIES 512
151#define HIST_BAYER (ISC_HIS_CFG_MODE_B + 1)
152
153enum{
154 HIST_INIT = 0,
155 HIST_ENABLED,
156 HIST_DISABLED,
157};
158
159struct isc_ctrls {
160 struct v4l2_ctrl_handler handler;
161
162 u32 brightness;
163 u32 contrast;
164 u8 gamma_index;
165 u8 awb;
166
167 u32 r_gain;
168 u32 b_gain;
169
170 u32 hist_entry[HIST_ENTRIES];
171 u32 hist_count[HIST_BAYER];
172 u8 hist_id;
173 u8 hist_stat;
10626744
SW
174};
175
176#define ISC_PIPE_LINE_NODE_NUM 11
177
178struct isc_device {
179 struct regmap *regmap;
180 struct clk *hclock;
181 struct clk *ispck;
182 struct isc_clk isc_clks[2];
183
184 struct device *dev;
185 struct v4l2_device v4l2_dev;
186 struct video_device video_dev;
187
188 struct vb2_queue vb2_vidq;
189 spinlock_t dma_queue_lock;
190 struct list_head dma_queue;
191 struct isc_buffer *cur_frm;
192 unsigned int sequence;
193 bool stop;
194 struct completion comp;
195
196 struct v4l2_format fmt;
197 struct isc_format **user_formats;
198 unsigned int num_user_formats;
199 const struct isc_format *current_fmt;
93d4a26c
SW
200 const struct isc_format *raw_fmt;
201
202 struct isc_ctrls ctrls;
203 struct work_struct awb_work;
10626744
SW
204
205 struct mutex lock;
206
207 struct regmap_field *pipeline[ISC_PIPE_LINE_NODE_NUM];
208
209 struct isc_subdev_entity *current_subdev;
210 struct list_head subdev_entities;
211};
212
f103ea11
WY
213static struct isc_format formats_list[] = {
214 {
215 .fourcc = V4L2_PIX_FMT_SBGGR8,
216 .mbus_code = MEDIA_BUS_FMT_SBGGR8_1X8,
217 .flags = FMT_FLAG_RAW_FROM_SENSOR,
218 .bpp = 8,
219 },
220 {
221 .fourcc = V4L2_PIX_FMT_SGBRG8,
222 .mbus_code = MEDIA_BUS_FMT_SGBRG8_1X8,
223 .flags = FMT_FLAG_RAW_FROM_SENSOR,
224 .bpp = 8,
225 },
226 {
227 .fourcc = V4L2_PIX_FMT_SGRBG8,
228 .mbus_code = MEDIA_BUS_FMT_SGRBG8_1X8,
229 .flags = FMT_FLAG_RAW_FROM_SENSOR,
230 .bpp = 8,
231 },
232 {
233 .fourcc = V4L2_PIX_FMT_SRGGB8,
234 .mbus_code = MEDIA_BUS_FMT_SRGGB8_1X8,
235 .flags = FMT_FLAG_RAW_FROM_SENSOR,
236 .bpp = 8,
237 },
238 {
239 .fourcc = V4L2_PIX_FMT_SBGGR10,
240 .mbus_code = MEDIA_BUS_FMT_SBGGR10_1X10,
241 .flags = FMT_FLAG_RAW_FROM_SENSOR,
242 .bpp = 16,
243 },
244 {
245 .fourcc = V4L2_PIX_FMT_SGBRG10,
246 .mbus_code = MEDIA_BUS_FMT_SGBRG10_1X10,
247 .flags = FMT_FLAG_RAW_FROM_SENSOR,
248 .bpp = 16,
249 },
250 {
251 .fourcc = V4L2_PIX_FMT_SGRBG10,
252 .mbus_code = MEDIA_BUS_FMT_SGRBG10_1X10,
253 .flags = FMT_FLAG_RAW_FROM_SENSOR,
254 .bpp = 16,
255 },
256 {
257 .fourcc = V4L2_PIX_FMT_SRGGB10,
258 .mbus_code = MEDIA_BUS_FMT_SRGGB10_1X10,
259 .flags = FMT_FLAG_RAW_FROM_SENSOR,
260 .bpp = 16,
261 },
262 {
263 .fourcc = V4L2_PIX_FMT_SBGGR12,
264 .mbus_code = MEDIA_BUS_FMT_SBGGR12_1X12,
265 .flags = FMT_FLAG_RAW_FROM_SENSOR,
266 .bpp = 16,
267 },
268 {
269 .fourcc = V4L2_PIX_FMT_SGBRG12,
270 .mbus_code = MEDIA_BUS_FMT_SGBRG12_1X12,
271 .flags = FMT_FLAG_RAW_FROM_SENSOR,
272 .bpp = 16,
273 },
274 {
275 .fourcc = V4L2_PIX_FMT_SGRBG12,
276 .mbus_code = MEDIA_BUS_FMT_SGRBG12_1X12,
277 .flags = FMT_FLAG_RAW_FROM_SENSOR,
278 .bpp = 16,
279 },
280 {
281 .fourcc = V4L2_PIX_FMT_SRGGB12,
282 .mbus_code = MEDIA_BUS_FMT_SRGGB12_1X12,
283 .flags = FMT_FLAG_RAW_FROM_SENSOR,
284 .bpp = 16,
285 },
286 {
287 .fourcc = V4L2_PIX_FMT_YUV420,
288 .mbus_code = 0x0,
289 .flags = FMT_FLAG_FROM_CONTROLLER,
290 .bpp = 12,
291 },
292 {
293 .fourcc = V4L2_PIX_FMT_YUV422P,
294 .mbus_code = 0x0,
295 .flags = FMT_FLAG_FROM_CONTROLLER,
296 .bpp = 16,
297 },
298 {
299 .fourcc = V4L2_PIX_FMT_GREY,
300 .mbus_code = MEDIA_BUS_FMT_Y8_1X8,
301 .flags = FMT_FLAG_FROM_CONTROLLER |
302 FMT_FLAG_FROM_SENSOR,
303 .bpp = 8,
304 },
305 {
306 .fourcc = V4L2_PIX_FMT_ARGB444,
307 .mbus_code = MEDIA_BUS_FMT_RGB444_2X8_PADHI_LE,
308 .flags = FMT_FLAG_FROM_CONTROLLER,
309 .bpp = 16,
310 },
311 {
312 .fourcc = V4L2_PIX_FMT_ARGB555,
313 .mbus_code = MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE,
314 .flags = FMT_FLAG_FROM_CONTROLLER,
315 .bpp = 16,
316 },
317 {
318 .fourcc = V4L2_PIX_FMT_RGB565,
319 .mbus_code = MEDIA_BUS_FMT_RGB565_2X8_LE,
320 .flags = FMT_FLAG_FROM_CONTROLLER,
321 .bpp = 16,
322 },
323 {
324 .fourcc = V4L2_PIX_FMT_ARGB32,
325 .mbus_code = MEDIA_BUS_FMT_ARGB8888_1X32,
326 .flags = FMT_FLAG_FROM_CONTROLLER,
327 .bpp = 32,
328 },
329 {
330 .fourcc = V4L2_PIX_FMT_YUYV,
331 .mbus_code = MEDIA_BUS_FMT_YUYV8_2X8,
332 .flags = FMT_FLAG_FROM_CONTROLLER |
333 FMT_FLAG_FROM_SENSOR,
334 .bpp = 16,
335 },
336};
337
c7b7187b 338static struct fmt_config fmt_configs_list[] = {
f103ea11
WY
339 {
340 .fourcc = V4L2_PIX_FMT_SBGGR8,
341 .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT,
342 .cfa_baycfg = ISC_BAY_CFG_BGBG,
343 .rlp_cfg_mode = ISC_RLP_CFG_MODE_DAT8,
344 .dcfg_imode = ISC_DCFG_IMODE_PACKED8,
345 .dctrl_dview = ISC_DCTRL_DVIEW_PACKED,
346 .bits_pipeline = 0x0,
347 },
348 {
349 .fourcc = V4L2_PIX_FMT_SGBRG8,
350 .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT,
351 .cfa_baycfg = ISC_BAY_CFG_GBGB,
352 .rlp_cfg_mode = ISC_RLP_CFG_MODE_DAT8,
353 .dcfg_imode = ISC_DCFG_IMODE_PACKED8,
354 .dctrl_dview = ISC_DCTRL_DVIEW_PACKED,
355 .bits_pipeline = 0x0,
356 },
357 {
358 .fourcc = V4L2_PIX_FMT_SGRBG8,
359 .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT,
360 .cfa_baycfg = ISC_BAY_CFG_GRGR,
361 .rlp_cfg_mode = ISC_RLP_CFG_MODE_DAT8,
362 .dcfg_imode = ISC_DCFG_IMODE_PACKED8,
363 .dctrl_dview = ISC_DCTRL_DVIEW_PACKED,
364 .bits_pipeline = 0x0,
365 },
366 {
367 .fourcc = V4L2_PIX_FMT_SRGGB8,
368 .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT,
369 .cfa_baycfg = ISC_BAY_CFG_RGRG,
370 .rlp_cfg_mode = ISC_RLP_CFG_MODE_DAT8,
371 .dcfg_imode = ISC_DCFG_IMODE_PACKED8,
372 .dctrl_dview = ISC_DCTRL_DVIEW_PACKED,
373 .bits_pipeline = 0x0,
374 },
375 {
376 .fourcc = V4L2_PIX_FMT_SBGGR10,
377 .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TEN,
378 .cfa_baycfg = ISC_BAY_CFG_BGBG,
379 .rlp_cfg_mode = ISC_RLP_CFG_MODE_DAT10,
380 .dcfg_imode = ISC_DCFG_IMODE_PACKED16,
381 .dctrl_dview = ISC_DCTRL_DVIEW_PACKED,
382 .bits_pipeline = 0x0,
383 },
384 {
385 .fourcc = V4L2_PIX_FMT_SGBRG10,
386 .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TEN,
387 .cfa_baycfg = ISC_BAY_CFG_GBGB,
388 .rlp_cfg_mode = ISC_RLP_CFG_MODE_DAT10,
389 .dcfg_imode = ISC_DCFG_IMODE_PACKED16,
390 .dctrl_dview = ISC_DCTRL_DVIEW_PACKED,
391 .bits_pipeline = 0x0,
392 },
393 {
394 .fourcc = V4L2_PIX_FMT_SGRBG10,
395 .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TEN,
396 .cfa_baycfg = ISC_BAY_CFG_GRGR,
397 .rlp_cfg_mode = ISC_RLP_CFG_MODE_DAT10,
398 .dcfg_imode = ISC_DCFG_IMODE_PACKED16,
399 .dctrl_dview = ISC_DCTRL_DVIEW_PACKED,
400 .bits_pipeline = 0x0,
401 },
402 {
403 .fourcc = V4L2_PIX_FMT_SRGGB10,
404 .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TEN,
405 .cfa_baycfg = ISC_BAY_CFG_RGRG,
406 .rlp_cfg_mode = ISC_RLP_CFG_MODE_DAT10,
407 .dcfg_imode = ISC_DCFG_IMODE_PACKED16,
408 .dctrl_dview = ISC_DCTRL_DVIEW_PACKED,
409 .bits_pipeline = 0x0,
410 },
411 {
412 .fourcc = V4L2_PIX_FMT_SBGGR12,
413 .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TWELVE,
414 .cfa_baycfg = ISC_BAY_CFG_BGBG,
415 .rlp_cfg_mode = ISC_RLP_CFG_MODE_DAT12,
416 .dcfg_imode = ISC_DCFG_IMODE_PACKED16,
417 .dctrl_dview = ISC_DCTRL_DVIEW_PACKED,
418 .bits_pipeline = 0x0,
419 },
420 {
421 .fourcc = V4L2_PIX_FMT_SGBRG12,
422 .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TWELVE,
423 .cfa_baycfg = ISC_BAY_CFG_GBGB,
424 .rlp_cfg_mode = ISC_RLP_CFG_MODE_DAT12,
425 .dcfg_imode = ISC_DCFG_IMODE_PACKED16,
426 .dctrl_dview = ISC_DCTRL_DVIEW_PACKED,
427 .bits_pipeline = 0x0
428 },
429 {
430 .fourcc = V4L2_PIX_FMT_SGRBG12,
431 .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TWELVE,
432 .cfa_baycfg = ISC_BAY_CFG_GRGR,
433 .rlp_cfg_mode = ISC_RLP_CFG_MODE_DAT12,
434 .dcfg_imode = ISC_DCFG_IMODE_PACKED16,
435 .dctrl_dview = ISC_DCTRL_DVIEW_PACKED,
436 .bits_pipeline = 0x0,
437 },
438 {
439 .fourcc = V4L2_PIX_FMT_SRGGB12,
440 .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TWELVE,
441 .cfa_baycfg = ISC_BAY_CFG_RGRG,
442 .rlp_cfg_mode = ISC_RLP_CFG_MODE_DAT12,
443 .dcfg_imode = ISC_DCFG_IMODE_PACKED16,
444 .dctrl_dview = ISC_DCTRL_DVIEW_PACKED,
445 .bits_pipeline = 0x0,
446 },
447 {
448 .fourcc = V4L2_PIX_FMT_YUV420,
449 .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT,
450 .cfa_baycfg = ISC_BAY_CFG_BGBG,
451 .rlp_cfg_mode = ISC_RLP_CFG_MODE_YYCC,
452 .dcfg_imode = ISC_DCFG_IMODE_YC420P,
453 .dctrl_dview = ISC_DCTRL_DVIEW_PLANAR,
454 .bits_pipeline = SUB420_ENABLE | SUB422_ENABLE |
455 CBC_ENABLE | CSC_ENABLE |
456 GAM_ENABLES |
457 CFA_ENABLE | WB_ENABLE,
458 },
459 {
460 .fourcc = V4L2_PIX_FMT_YUV422P,
461 .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT,
462 .cfa_baycfg = ISC_BAY_CFG_BGBG,
463 .rlp_cfg_mode = ISC_RLP_CFG_MODE_YYCC,
464 .dcfg_imode = ISC_DCFG_IMODE_YC422P,
465 .dctrl_dview = ISC_DCTRL_DVIEW_PLANAR,
466 .bits_pipeline = SUB422_ENABLE |
467 CBC_ENABLE | CSC_ENABLE |
468 GAM_ENABLES |
469 CFA_ENABLE | WB_ENABLE,
470 },
471 {
472 .fourcc = V4L2_PIX_FMT_GREY,
473 .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT,
474 .cfa_baycfg = ISC_BAY_CFG_BGBG,
475 .rlp_cfg_mode = ISC_RLP_CFG_MODE_DATY8,
476 .dcfg_imode = ISC_DCFG_IMODE_PACKED8,
477 .dctrl_dview = ISC_DCTRL_DVIEW_PACKED,
478 .bits_pipeline = CBC_ENABLE | CSC_ENABLE |
479 GAM_ENABLES |
480 CFA_ENABLE | WB_ENABLE,
481 },
482 {
483 .fourcc = V4L2_PIX_FMT_ARGB444,
484 .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT,
485 .cfa_baycfg = ISC_BAY_CFG_BGBG,
486 .rlp_cfg_mode = ISC_RLP_CFG_MODE_ARGB444,
487 .dcfg_imode = ISC_DCFG_IMODE_PACKED16,
488 .dctrl_dview = ISC_DCTRL_DVIEW_PACKED,
489 .bits_pipeline = GAM_ENABLES | CFA_ENABLE | WB_ENABLE,
490 },
491 {
492 .fourcc = V4L2_PIX_FMT_ARGB555,
493 .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT,
494 .cfa_baycfg = ISC_BAY_CFG_BGBG,
495 .rlp_cfg_mode = ISC_RLP_CFG_MODE_ARGB555,
496 .dcfg_imode = ISC_DCFG_IMODE_PACKED16,
497 .dctrl_dview = ISC_DCTRL_DVIEW_PACKED,
498 .bits_pipeline = GAM_ENABLES | CFA_ENABLE | WB_ENABLE,
499 },
500 {
501 .fourcc = V4L2_PIX_FMT_RGB565,
502 .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT,
503 .cfa_baycfg = ISC_BAY_CFG_BGBG,
504 .rlp_cfg_mode = ISC_RLP_CFG_MODE_RGB565,
505 .dcfg_imode = ISC_DCFG_IMODE_PACKED16,
506 .dctrl_dview = ISC_DCTRL_DVIEW_PACKED,
507 .bits_pipeline = GAM_ENABLES | CFA_ENABLE | WB_ENABLE,
508 },
509 {
510 .fourcc = V4L2_PIX_FMT_ARGB32,
511 .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT,
512 .cfa_baycfg = ISC_BAY_CFG_BGBG,
513 .rlp_cfg_mode = ISC_RLP_CFG_MODE_ARGB32,
514 .dcfg_imode = ISC_DCFG_IMODE_PACKED32,
515 .dctrl_dview = ISC_DCTRL_DVIEW_PACKED,
516 .bits_pipeline = GAM_ENABLES | CFA_ENABLE | WB_ENABLE,
517 },
518 {
519 .fourcc = V4L2_PIX_FMT_YUYV,
520 .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT,
521 .cfa_baycfg = ISC_BAY_CFG_BGBG,
522 .rlp_cfg_mode = ISC_RLP_CFG_MODE_DAT8,
523 .dcfg_imode = ISC_DCFG_IMODE_PACKED8,
524 .dctrl_dview = ISC_DCTRL_DVIEW_PACKED,
525 .bits_pipeline = 0x0
526 },
93d4a26c
SW
527};
528
529#define GAMMA_MAX 2
530#define GAMMA_ENTRIES 64
531
532/* Gamma table with gamma 1/2.2 */
533static const u32 isc_gamma_table[GAMMA_MAX + 1][GAMMA_ENTRIES] = {
534 /* 0 --> gamma 1/1.8 */
535 { 0x65, 0x66002F, 0x950025, 0xBB0020, 0xDB001D, 0xF8001A,
536 0x1130018, 0x12B0017, 0x1420016, 0x1580014, 0x16D0013, 0x1810012,
537 0x1940012, 0x1A60012, 0x1B80011, 0x1C90010, 0x1DA0010, 0x1EA000F,
538 0x1FA000F, 0x209000F, 0x218000F, 0x227000E, 0x235000E, 0x243000E,
539 0x251000E, 0x25F000D, 0x26C000D, 0x279000D, 0x286000D, 0x293000C,
540 0x2A0000C, 0x2AC000C, 0x2B8000C, 0x2C4000C, 0x2D0000B, 0x2DC000B,
541 0x2E7000B, 0x2F3000B, 0x2FE000B, 0x309000B, 0x314000B, 0x31F000A,
542 0x32A000A, 0x334000B, 0x33F000A, 0x349000A, 0x354000A, 0x35E000A,
543 0x368000A, 0x372000A, 0x37C000A, 0x386000A, 0x3900009, 0x399000A,
544 0x3A30009, 0x3AD0009, 0x3B60009, 0x3BF000A, 0x3C90009, 0x3D20009,
545 0x3DB0009, 0x3E40009, 0x3ED0009, 0x3F60009 },
546
547 /* 1 --> gamma 1/2 */
548 { 0x7F, 0x800034, 0xB50028, 0xDE0021, 0x100001E, 0x11E001B,
549 0x1390019, 0x1520017, 0x16A0015, 0x1800014, 0x1940014, 0x1A80013,
550 0x1BB0012, 0x1CD0011, 0x1DF0010, 0x1EF0010, 0x200000F, 0x20F000F,
551 0x21F000E, 0x22D000F, 0x23C000E, 0x24A000E, 0x258000D, 0x265000D,
552 0x273000C, 0x27F000D, 0x28C000C, 0x299000C, 0x2A5000C, 0x2B1000B,
553 0x2BC000C, 0x2C8000B, 0x2D3000C, 0x2DF000B, 0x2EA000A, 0x2F5000A,
554 0x2FF000B, 0x30A000A, 0x314000B, 0x31F000A, 0x329000A, 0x333000A,
555 0x33D0009, 0x3470009, 0x350000A, 0x35A0009, 0x363000A, 0x36D0009,
556 0x3760009, 0x37F0009, 0x3880009, 0x3910009, 0x39A0009, 0x3A30009,
557 0x3AC0008, 0x3B40009, 0x3BD0008, 0x3C60008, 0x3CE0008, 0x3D60009,
558 0x3DF0008, 0x3E70008, 0x3EF0008, 0x3F70008 },
559
560 /* 2 --> gamma 1/2.2 */
561 { 0x99, 0x9B0038, 0xD4002A, 0xFF0023, 0x122001F, 0x141001B,
562 0x15D0019, 0x1760017, 0x18E0015, 0x1A30015, 0x1B80013, 0x1CC0012,
563 0x1DE0011, 0x1F00010, 0x2010010, 0x2110010, 0x221000F, 0x230000F,
564 0x23F000E, 0x24D000E, 0x25B000D, 0x269000C, 0x276000C, 0x283000C,
565 0x28F000C, 0x29B000C, 0x2A7000C, 0x2B3000B, 0x2BF000B, 0x2CA000B,
566 0x2D5000B, 0x2E0000A, 0x2EB000A, 0x2F5000A, 0x2FF000A, 0x30A000A,
567 0x3140009, 0x31E0009, 0x327000A, 0x3310009, 0x33A0009, 0x3440009,
568 0x34D0009, 0x3560009, 0x35F0009, 0x3680008, 0x3710008, 0x3790009,
569 0x3820008, 0x38A0008, 0x3930008, 0x39B0008, 0x3A30008, 0x3AB0008,
570 0x3B30008, 0x3BB0008, 0x3C30008, 0x3CB0007, 0x3D20008, 0x3DA0007,
571 0x3E20007, 0x3E90007, 0x3F00008, 0x3F80007 },
10626744
SW
572};
573
93d4a26c
SW
574static unsigned int sensor_preferred = 1;
575module_param(sensor_preferred, uint, 0644);
576MODULE_PARM_DESC(sensor_preferred,
577 "Sensor is preferred to output the specified format (1-on 0-off), default 1");
578
64f6306a
WY
579static int isc_wait_clk_stable(struct clk_hw *hw)
580{
581 struct isc_clk *isc_clk = to_isc_clk(hw);
582 struct regmap *regmap = isc_clk->regmap;
583 unsigned long timeout = jiffies + usecs_to_jiffies(1000);
584 unsigned int status;
585
586 while (time_before(jiffies, timeout)) {
587 regmap_read(regmap, ISC_CLKSR, &status);
588 if (!(status & ISC_CLKSR_SIP))
589 return 0;
590
591 usleep_range(10, 250);
592 }
593
594 return -ETIMEDOUT;
595}
596
597static int isc_clk_prepare(struct clk_hw *hw)
598{
599 struct isc_clk *isc_clk = to_isc_clk(hw);
600
d7ca1c9c 601 if (isc_clk->id == ISC_ISPCK)
64f6306a
WY
602 pm_runtime_get_sync(isc_clk->dev);
603
604 return isc_wait_clk_stable(hw);
605}
606
607static void isc_clk_unprepare(struct clk_hw *hw)
608{
609 struct isc_clk *isc_clk = to_isc_clk(hw);
610
611 isc_wait_clk_stable(hw);
612
d7ca1c9c 613 if (isc_clk->id == ISC_ISPCK)
64f6306a
WY
614 pm_runtime_put_sync(isc_clk->dev);
615}
616
10626744
SW
617static int isc_clk_enable(struct clk_hw *hw)
618{
619 struct isc_clk *isc_clk = to_isc_clk(hw);
620 u32 id = isc_clk->id;
621 struct regmap *regmap = isc_clk->regmap;
cab1dea3
WY
622 unsigned long flags;
623 unsigned int status;
10626744
SW
624
625 dev_dbg(isc_clk->dev, "ISC CLK: %s, div = %d, parent id = %d\n",
626 __func__, isc_clk->div, isc_clk->parent_id);
627
cab1dea3 628 spin_lock_irqsave(&isc_clk->lock, flags);
10626744
SW
629 regmap_update_bits(regmap, ISC_CLKCFG,
630 ISC_CLKCFG_DIV_MASK(id) | ISC_CLKCFG_SEL_MASK(id),
631 (isc_clk->div << ISC_CLKCFG_DIV_SHIFT(id)) |
632 (isc_clk->parent_id << ISC_CLKCFG_SEL_SHIFT(id)));
633
634 regmap_write(regmap, ISC_CLKEN, ISC_CLK(id));
cab1dea3 635 spin_unlock_irqrestore(&isc_clk->lock, flags);
10626744 636
cab1dea3
WY
637 regmap_read(regmap, ISC_CLKSR, &status);
638 if (status & ISC_CLK(id))
639 return 0;
640 else
641 return -EINVAL;
10626744
SW
642}
643
644static void isc_clk_disable(struct clk_hw *hw)
645{
646 struct isc_clk *isc_clk = to_isc_clk(hw);
647 u32 id = isc_clk->id;
cab1dea3 648 unsigned long flags;
10626744 649
cab1dea3 650 spin_lock_irqsave(&isc_clk->lock, flags);
10626744 651 regmap_write(isc_clk->regmap, ISC_CLKDIS, ISC_CLK(id));
cab1dea3 652 spin_unlock_irqrestore(&isc_clk->lock, flags);
10626744
SW
653}
654
655static int isc_clk_is_enabled(struct clk_hw *hw)
656{
657 struct isc_clk *isc_clk = to_isc_clk(hw);
658 u32 status;
659
d7ca1c9c 660 if (isc_clk->id == ISC_ISPCK)
01192aa1
WY
661 pm_runtime_get_sync(isc_clk->dev);
662
10626744
SW
663 regmap_read(isc_clk->regmap, ISC_CLKSR, &status);
664
d7ca1c9c 665 if (isc_clk->id == ISC_ISPCK)
01192aa1
WY
666 pm_runtime_put_sync(isc_clk->dev);
667
10626744
SW
668 return status & ISC_CLK(isc_clk->id) ? 1 : 0;
669}
670
671static unsigned long
672isc_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
673{
674 struct isc_clk *isc_clk = to_isc_clk(hw);
675
676 return DIV_ROUND_CLOSEST(parent_rate, isc_clk->div + 1);
677}
678
679static int isc_clk_determine_rate(struct clk_hw *hw,
680 struct clk_rate_request *req)
681{
682 struct isc_clk *isc_clk = to_isc_clk(hw);
683 long best_rate = -EINVAL;
684 int best_diff = -1;
685 unsigned int i, div;
686
687 for (i = 0; i < clk_hw_get_num_parents(hw); i++) {
688 struct clk_hw *parent;
689 unsigned long parent_rate;
690
691 parent = clk_hw_get_parent_by_index(hw, i);
692 if (!parent)
693 continue;
694
695 parent_rate = clk_hw_get_rate(parent);
696 if (!parent_rate)
697 continue;
698
699 for (div = 1; div < ISC_CLK_MAX_DIV + 2; div++) {
700 unsigned long rate;
701 int diff;
702
703 rate = DIV_ROUND_CLOSEST(parent_rate, div);
704 diff = abs(req->rate - rate);
705
706 if (best_diff < 0 || best_diff > diff) {
707 best_rate = rate;
708 best_diff = diff;
709 req->best_parent_rate = parent_rate;
710 req->best_parent_hw = parent;
711 }
712
713 if (!best_diff || rate < req->rate)
714 break;
715 }
716
717 if (!best_diff)
718 break;
719 }
720
721 dev_dbg(isc_clk->dev,
722 "ISC CLK: %s, best_rate = %ld, parent clk: %s @ %ld\n",
723 __func__, best_rate,
724 __clk_get_name((req->best_parent_hw)->clk),
725 req->best_parent_rate);
726
727 if (best_rate < 0)
728 return best_rate;
729
730 req->rate = best_rate;
731
732 return 0;
733}
734
735static int isc_clk_set_parent(struct clk_hw *hw, u8 index)
736{
737 struct isc_clk *isc_clk = to_isc_clk(hw);
738
739 if (index >= clk_hw_get_num_parents(hw))
740 return -EINVAL;
741
742 isc_clk->parent_id = index;
743
744 return 0;
745}
746
747static u8 isc_clk_get_parent(struct clk_hw *hw)
748{
749 struct isc_clk *isc_clk = to_isc_clk(hw);
750
751 return isc_clk->parent_id;
752}
753
754static int isc_clk_set_rate(struct clk_hw *hw,
755 unsigned long rate,
756 unsigned long parent_rate)
757{
758 struct isc_clk *isc_clk = to_isc_clk(hw);
759 u32 div;
760
761 if (!rate)
762 return -EINVAL;
763
764 div = DIV_ROUND_CLOSEST(parent_rate, rate);
765 if (div > (ISC_CLK_MAX_DIV + 1) || !div)
766 return -EINVAL;
767
768 isc_clk->div = div - 1;
769
770 return 0;
771}
772
773static const struct clk_ops isc_clk_ops = {
64f6306a
WY
774 .prepare = isc_clk_prepare,
775 .unprepare = isc_clk_unprepare,
10626744
SW
776 .enable = isc_clk_enable,
777 .disable = isc_clk_disable,
778 .is_enabled = isc_clk_is_enabled,
779 .recalc_rate = isc_clk_recalc_rate,
780 .determine_rate = isc_clk_determine_rate,
781 .set_parent = isc_clk_set_parent,
782 .get_parent = isc_clk_get_parent,
783 .set_rate = isc_clk_set_rate,
784};
785
786static int isc_clk_register(struct isc_device *isc, unsigned int id)
787{
788 struct regmap *regmap = isc->regmap;
789 struct device_node *np = isc->dev->of_node;
790 struct isc_clk *isc_clk;
791 struct clk_init_data init;
792 const char *clk_name = np->name;
793 const char *parent_names[3];
794 int num_parents;
795
796 num_parents = of_clk_get_parent_count(np);
797 if (num_parents < 1 || num_parents > 3)
798 return -EINVAL;
799
800 if (num_parents > 2 && id == ISC_ISPCK)
801 num_parents = 2;
802
803 of_clk_parent_fill(np, parent_names, num_parents);
804
805 if (id == ISC_MCK)
806 of_property_read_string(np, "clock-output-names", &clk_name);
807 else
808 clk_name = "isc-ispck";
809
810 init.parent_names = parent_names;
811 init.num_parents = num_parents;
812 init.name = clk_name;
813 init.ops = &isc_clk_ops;
814 init.flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE;
815
816 isc_clk = &isc->isc_clks[id];
817 isc_clk->hw.init = &init;
818 isc_clk->regmap = regmap;
819 isc_clk->id = id;
820 isc_clk->dev = isc->dev;
cab1dea3 821 spin_lock_init(&isc_clk->lock);
10626744
SW
822
823 isc_clk->clk = clk_register(isc->dev, &isc_clk->hw);
824 if (IS_ERR(isc_clk->clk)) {
825 dev_err(isc->dev, "%s: clock register fail\n", clk_name);
826 return PTR_ERR(isc_clk->clk);
827 } else if (id == ISC_MCK)
828 of_clk_add_provider(np, of_clk_src_simple_get, isc_clk->clk);
829
830 return 0;
831}
832
833static int isc_clk_init(struct isc_device *isc)
834{
835 unsigned int i;
836 int ret;
837
838 for (i = 0; i < ARRAY_SIZE(isc->isc_clks); i++)
839 isc->isc_clks[i].clk = ERR_PTR(-EINVAL);
840
841 for (i = 0; i < ARRAY_SIZE(isc->isc_clks); i++) {
842 ret = isc_clk_register(isc, i);
843 if (ret)
844 return ret;
845 }
846
847 return 0;
848}
849
850static void isc_clk_cleanup(struct isc_device *isc)
851{
852 unsigned int i;
853
854 of_clk_del_provider(isc->dev->of_node);
855
856 for (i = 0; i < ARRAY_SIZE(isc->isc_clks); i++) {
857 struct isc_clk *isc_clk = &isc->isc_clks[i];
858
859 if (!IS_ERR(isc_clk->clk))
860 clk_unregister(isc_clk->clk);
861 }
862}
863
864static int isc_queue_setup(struct vb2_queue *vq,
865 unsigned int *nbuffers, unsigned int *nplanes,
866 unsigned int sizes[], struct device *alloc_devs[])
867{
868 struct isc_device *isc = vb2_get_drv_priv(vq);
869 unsigned int size = isc->fmt.fmt.pix.sizeimage;
870
871 if (*nplanes)
872 return sizes[0] < size ? -EINVAL : 0;
873
874 *nplanes = 1;
875 sizes[0] = size;
876
877 return 0;
878}
879
880static int isc_buffer_prepare(struct vb2_buffer *vb)
881{
882 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
883 struct isc_device *isc = vb2_get_drv_priv(vb->vb2_queue);
884 unsigned long size = isc->fmt.fmt.pix.sizeimage;
885
886 if (vb2_plane_size(vb, 0) < size) {
887 v4l2_err(&isc->v4l2_dev, "buffer too small (%lu < %lu)\n",
888 vb2_plane_size(vb, 0), size);
889 return -EINVAL;
890 }
891
892 vb2_set_plane_payload(vb, 0, size);
893
894 vbuf->field = isc->fmt.fmt.pix.field;
895
896 return 0;
897}
898
93d4a26c 899static inline bool sensor_is_preferred(const struct isc_format *isc_fmt)
10626744 900{
93d4a26c
SW
901 return (sensor_preferred && isc_fmt->sd_support) ||
902 !isc_fmt->isc_support;
903}
10626744 904
f103ea11
WY
905static struct fmt_config *get_fmt_config(u32 fourcc)
906{
907 struct fmt_config *config;
908 int i;
909
910 config = &fmt_configs_list[0];
911 for (i = 0; i < ARRAY_SIZE(fmt_configs_list); i++) {
912 if (config->fourcc == fourcc)
913 return config;
914
915 config++;
916 }
917 return NULL;
918}
919
93d4a26c
SW
920static void isc_start_dma(struct isc_device *isc)
921{
922 struct regmap *regmap = isc->regmap;
923 struct v4l2_pix_format *pixfmt = &isc->fmt.fmt.pix;
924 u32 sizeimage = pixfmt->sizeimage;
f103ea11 925 struct fmt_config *config = get_fmt_config(isc->current_fmt->fourcc);
93d4a26c
SW
926 u32 dctrl_dview;
927 dma_addr_t addr0;
928
929 addr0 = vb2_dma_contig_plane_dma_addr(&isc->cur_frm->vb.vb2_buf, 0);
930 regmap_write(regmap, ISC_DAD0, addr0);
931
932 switch (pixfmt->pixelformat) {
933 case V4L2_PIX_FMT_YUV420:
934 regmap_write(regmap, ISC_DAD1, addr0 + (sizeimage * 2) / 3);
935 regmap_write(regmap, ISC_DAD2, addr0 + (sizeimage * 5) / 6);
936 break;
937 case V4L2_PIX_FMT_YUV422P:
938 regmap_write(regmap, ISC_DAD1, addr0 + sizeimage / 2);
939 regmap_write(regmap, ISC_DAD2, addr0 + (sizeimage * 3) / 4);
940 break;
941 default:
942 break;
943 }
944
945 if (sensor_is_preferred(isc->current_fmt))
946 dctrl_dview = ISC_DCTRL_DVIEW_PACKED;
947 else
f103ea11 948 dctrl_dview = config->dctrl_dview;
10626744 949
93d4a26c 950 regmap_write(regmap, ISC_DCTRL, dctrl_dview | ISC_DCTRL_IE_IS);
10626744
SW
951 regmap_write(regmap, ISC_CTRLEN, ISC_CTRL_CAPTURE);
952}
953
954static void isc_set_pipeline(struct isc_device *isc, u32 pipeline)
955{
93d4a26c
SW
956 struct regmap *regmap = isc->regmap;
957 struct isc_ctrls *ctrls = &isc->ctrls;
f103ea11 958 struct fmt_config *config = get_fmt_config(isc->raw_fmt->fourcc);
93d4a26c
SW
959 u32 val, bay_cfg;
960 const u32 *gamma;
10626744
SW
961 unsigned int i;
962
93d4a26c 963 /* WB-->CFA-->CC-->GAM-->CSC-->CBC-->SUB422-->SUB420 */
10626744
SW
964 for (i = 0; i < ISC_PIPE_LINE_NODE_NUM; i++) {
965 val = pipeline & BIT(i) ? 1 : 0;
966 regmap_field_write(isc->pipeline[i], val);
967 }
93d4a26c
SW
968
969 if (!pipeline)
970 return;
971
f103ea11 972 bay_cfg = config->cfa_baycfg;
93d4a26c
SW
973
974 regmap_write(regmap, ISC_WB_CFG, bay_cfg);
975 regmap_write(regmap, ISC_WB_O_RGR, 0x0);
976 regmap_write(regmap, ISC_WB_O_BGR, 0x0);
977 regmap_write(regmap, ISC_WB_G_RGR, ctrls->r_gain | (0x1 << 25));
978 regmap_write(regmap, ISC_WB_G_BGR, ctrls->b_gain | (0x1 << 25));
979
980 regmap_write(regmap, ISC_CFA_CFG, bay_cfg | ISC_CFA_CFG_EITPOL);
981
982 gamma = &isc_gamma_table[ctrls->gamma_index][0];
983 regmap_bulk_write(regmap, ISC_GAM_BENTRY, gamma, GAMMA_ENTRIES);
984 regmap_bulk_write(regmap, ISC_GAM_GENTRY, gamma, GAMMA_ENTRIES);
985 regmap_bulk_write(regmap, ISC_GAM_RENTRY, gamma, GAMMA_ENTRIES);
986
987 /* Convert RGB to YUV */
988 regmap_write(regmap, ISC_CSC_YR_YG, 0x42 | (0x81 << 16));
989 regmap_write(regmap, ISC_CSC_YB_OY, 0x19 | (0x10 << 16));
990 regmap_write(regmap, ISC_CSC_CBR_CBG, 0xFDA | (0xFB6 << 16));
991 regmap_write(regmap, ISC_CSC_CBB_OCB, 0x70 | (0x80 << 16));
992 regmap_write(regmap, ISC_CSC_CRR_CRG, 0x70 | (0xFA2 << 16));
993 regmap_write(regmap, ISC_CSC_CRB_OCR, 0xFEE | (0x80 << 16));
994
995 regmap_write(regmap, ISC_CBC_BRIGHT, ctrls->brightness);
996 regmap_write(regmap, ISC_CBC_CONTRAST, ctrls->contrast);
997}
998
999static int isc_update_profile(struct isc_device *isc)
1000{
1001 struct regmap *regmap = isc->regmap;
1002 u32 sr;
1003 int counter = 100;
1004
1005 regmap_write(regmap, ISC_CTRLEN, ISC_CTRL_UPPRO);
1006
1007 regmap_read(regmap, ISC_CTRLSR, &sr);
1008 while ((sr & ISC_CTRL_UPPRO) && counter--) {
1009 usleep_range(1000, 2000);
1010 regmap_read(regmap, ISC_CTRLSR, &sr);
1011 }
1012
1013 if (counter < 0) {
1014 v4l2_warn(&isc->v4l2_dev, "Time out to update profie\n");
1015 return -ETIMEDOUT;
1016 }
1017
1018 return 0;
1019}
1020
1021static void isc_set_histogram(struct isc_device *isc)
1022{
1023 struct regmap *regmap = isc->regmap;
1024 struct isc_ctrls *ctrls = &isc->ctrls;
f103ea11 1025 struct fmt_config *config = get_fmt_config(isc->raw_fmt->fourcc);
93d4a26c
SW
1026
1027 if (ctrls->awb && (ctrls->hist_stat != HIST_ENABLED)) {
f103ea11
WY
1028 regmap_write(regmap, ISC_HIS_CFG,
1029 ISC_HIS_CFG_MODE_R |
1030 (config->cfa_baycfg << ISC_HIS_CFG_BAYSEL_SHIFT) |
1031 ISC_HIS_CFG_RAR);
93d4a26c
SW
1032 regmap_write(regmap, ISC_HIS_CTRL, ISC_HIS_CTRL_EN);
1033 regmap_write(regmap, ISC_INTEN, ISC_INT_HISDONE);
1034 ctrls->hist_id = ISC_HIS_CFG_MODE_R;
1035 isc_update_profile(isc);
1036 regmap_write(regmap, ISC_CTRLEN, ISC_CTRL_HISREQ);
1037
1038 ctrls->hist_stat = HIST_ENABLED;
1039 } else if (!ctrls->awb && (ctrls->hist_stat != HIST_DISABLED)) {
1040 regmap_write(regmap, ISC_INTDIS, ISC_INT_HISDONE);
1041 regmap_write(regmap, ISC_HIS_CTRL, ISC_HIS_CTRL_DIS);
1042
1043 ctrls->hist_stat = HIST_DISABLED;
1044 }
1045}
1046
1047static inline void isc_get_param(const struct isc_format *fmt,
f103ea11 1048 u32 *rlp_mode, u32 *dcfg)
93d4a26c 1049{
f103ea11
WY
1050 struct fmt_config *config = get_fmt_config(fmt->fourcc);
1051
682559d9
SW
1052 *dcfg = ISC_DCFG_YMBSIZE_BEATS8;
1053
93d4a26c
SW
1054 switch (fmt->fourcc) {
1055 case V4L2_PIX_FMT_SBGGR10:
1056 case V4L2_PIX_FMT_SGBRG10:
1057 case V4L2_PIX_FMT_SGRBG10:
1058 case V4L2_PIX_FMT_SRGGB10:
1059 case V4L2_PIX_FMT_SBGGR12:
1060 case V4L2_PIX_FMT_SGBRG12:
1061 case V4L2_PIX_FMT_SGRBG12:
1062 case V4L2_PIX_FMT_SRGGB12:
f103ea11
WY
1063 *rlp_mode = config->rlp_cfg_mode;
1064 *dcfg |= config->dcfg_imode;
93d4a26c
SW
1065 break;
1066 default:
1067 *rlp_mode = ISC_RLP_CFG_MODE_DAT8;
682559d9 1068 *dcfg |= ISC_DCFG_IMODE_PACKED8;
93d4a26c
SW
1069 break;
1070 }
10626744
SW
1071}
1072
1073static int isc_configure(struct isc_device *isc)
1074{
1075 struct regmap *regmap = isc->regmap;
1076 const struct isc_format *current_fmt = isc->current_fmt;
f103ea11
WY
1077 struct fmt_config *curfmt_config = get_fmt_config(current_fmt->fourcc);
1078 struct fmt_config *rawfmt_config = get_fmt_config(isc->raw_fmt->fourcc);
10626744 1079 struct isc_subdev_entity *subdev = isc->current_subdev;
682559d9 1080 u32 pfe_cfg0, rlp_mode, dcfg, mask, pipeline;
93d4a26c
SW
1081
1082 if (sensor_is_preferred(current_fmt)) {
f103ea11 1083 pfe_cfg0 = curfmt_config->pfe_cfg0_bps;
93d4a26c 1084 pipeline = 0x0;
682559d9 1085 isc_get_param(current_fmt, &rlp_mode, &dcfg);
93d4a26c
SW
1086 isc->ctrls.hist_stat = HIST_INIT;
1087 } else {
f103ea11
WY
1088 pfe_cfg0 = rawfmt_config->pfe_cfg0_bps;
1089 pipeline = curfmt_config->bits_pipeline;
1090 rlp_mode = curfmt_config->rlp_cfg_mode;
1091 dcfg = curfmt_config->dcfg_imode |
1092 ISC_DCFG_YMBSIZE_BEATS8 | ISC_DCFG_CMBSIZE_BEATS8;
93d4a26c 1093 }
10626744 1094
93d4a26c 1095 pfe_cfg0 |= subdev->pfe_cfg0 | ISC_PFE_CFG0_MODE_PROGRESSIVE;
10626744
SW
1096 mask = ISC_PFE_CFG0_BPS_MASK | ISC_PFE_CFG0_HPOL_LOW |
1097 ISC_PFE_CFG0_VPOL_LOW | ISC_PFE_CFG0_PPOL_LOW |
1098 ISC_PFE_CFG0_MODE_MASK;
1099
93d4a26c 1100 regmap_update_bits(regmap, ISC_PFE_CFG0, mask, pfe_cfg0);
10626744
SW
1101
1102 regmap_update_bits(regmap, ISC_RLP_CFG, ISC_RLP_CFG_MODE_MASK,
93d4a26c 1103 rlp_mode);
10626744 1104
682559d9 1105 regmap_write(regmap, ISC_DCFG, dcfg);
10626744 1106
93d4a26c
SW
1107 /* Set the pipeline */
1108 isc_set_pipeline(isc, pipeline);
10626744 1109
93d4a26c
SW
1110 if (pipeline)
1111 isc_set_histogram(isc);
10626744 1112
93d4a26c
SW
1113 /* Update profile */
1114 return isc_update_profile(isc);
10626744
SW
1115}
1116
1117static int isc_start_streaming(struct vb2_queue *vq, unsigned int count)
1118{
1119 struct isc_device *isc = vb2_get_drv_priv(vq);
1120 struct regmap *regmap = isc->regmap;
1121 struct isc_buffer *buf;
1122 unsigned long flags;
1123 int ret;
10626744
SW
1124
1125 /* Enable stream on the sub device */
1126 ret = v4l2_subdev_call(isc->current_subdev->sd, video, s_stream, 1);
1127 if (ret && ret != -ENOIOCTLCMD) {
1128 v4l2_err(&isc->v4l2_dev, "stream on failed in subdev\n");
1129 goto err_start_stream;
1130 }
1131
1132 pm_runtime_get_sync(isc->dev);
1133
10626744
SW
1134 ret = isc_configure(isc);
1135 if (unlikely(ret))
1136 goto err_configure;
1137
1138 /* Enable DMA interrupt */
1139 regmap_write(regmap, ISC_INTEN, ISC_INT_DDONE);
1140
1141 spin_lock_irqsave(&isc->dma_queue_lock, flags);
1142
1143 isc->sequence = 0;
1144 isc->stop = false;
1145 reinit_completion(&isc->comp);
1146
1147 isc->cur_frm = list_first_entry(&isc->dma_queue,
1148 struct isc_buffer, list);
1149 list_del(&isc->cur_frm->list);
1150
93d4a26c 1151 isc_start_dma(isc);
10626744
SW
1152
1153 spin_unlock_irqrestore(&isc->dma_queue_lock, flags);
1154
1155 return 0;
1156
1157err_configure:
1158 pm_runtime_put_sync(isc->dev);
1159
1160 v4l2_subdev_call(isc->current_subdev->sd, video, s_stream, 0);
1161
1162err_start_stream:
1163 spin_lock_irqsave(&isc->dma_queue_lock, flags);
1164 list_for_each_entry(buf, &isc->dma_queue, list)
1165 vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_QUEUED);
1166 INIT_LIST_HEAD(&isc->dma_queue);
1167 spin_unlock_irqrestore(&isc->dma_queue_lock, flags);
1168
1169 return ret;
1170}
1171
1172static void isc_stop_streaming(struct vb2_queue *vq)
1173{
1174 struct isc_device *isc = vb2_get_drv_priv(vq);
1175 unsigned long flags;
1176 struct isc_buffer *buf;
1177 int ret;
1178
1179 isc->stop = true;
1180
1181 /* Wait until the end of the current frame */
1182 if (isc->cur_frm && !wait_for_completion_timeout(&isc->comp, 5 * HZ))
1183 v4l2_err(&isc->v4l2_dev,
1184 "Timeout waiting for end of the capture\n");
1185
1186 /* Disable DMA interrupt */
1187 regmap_write(isc->regmap, ISC_INTDIS, ISC_INT_DDONE);
1188
1189 pm_runtime_put_sync(isc->dev);
1190
1191 /* Disable stream on the sub device */
1192 ret = v4l2_subdev_call(isc->current_subdev->sd, video, s_stream, 0);
1193 if (ret && ret != -ENOIOCTLCMD)
1194 v4l2_err(&isc->v4l2_dev, "stream off failed in subdev\n");
1195
1196 /* Release all active buffers */
1197 spin_lock_irqsave(&isc->dma_queue_lock, flags);
1198 if (unlikely(isc->cur_frm)) {
1199 vb2_buffer_done(&isc->cur_frm->vb.vb2_buf,
1200 VB2_BUF_STATE_ERROR);
1201 isc->cur_frm = NULL;
1202 }
1203 list_for_each_entry(buf, &isc->dma_queue, list)
1204 vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
1205 INIT_LIST_HEAD(&isc->dma_queue);
1206 spin_unlock_irqrestore(&isc->dma_queue_lock, flags);
1207}
1208
1209static void isc_buffer_queue(struct vb2_buffer *vb)
1210{
1211 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
1212 struct isc_buffer *buf = container_of(vbuf, struct isc_buffer, vb);
1213 struct isc_device *isc = vb2_get_drv_priv(vb->vb2_queue);
1214 unsigned long flags;
1215
1216 spin_lock_irqsave(&isc->dma_queue_lock, flags);
fa8bbe0a
SW
1217 if (!isc->cur_frm && list_empty(&isc->dma_queue) &&
1218 vb2_is_streaming(vb->vb2_queue)) {
1219 isc->cur_frm = buf;
93d4a26c 1220 isc_start_dma(isc);
fa8bbe0a
SW
1221 } else
1222 list_add_tail(&buf->list, &isc->dma_queue);
10626744
SW
1223 spin_unlock_irqrestore(&isc->dma_queue_lock, flags);
1224}
1225
62c11a54 1226static const struct vb2_ops isc_vb2_ops = {
10626744
SW
1227 .queue_setup = isc_queue_setup,
1228 .wait_prepare = vb2_ops_wait_prepare,
1229 .wait_finish = vb2_ops_wait_finish,
1230 .buf_prepare = isc_buffer_prepare,
1231 .start_streaming = isc_start_streaming,
1232 .stop_streaming = isc_stop_streaming,
1233 .buf_queue = isc_buffer_queue,
1234};
1235
1236static int isc_querycap(struct file *file, void *priv,
1237 struct v4l2_capability *cap)
1238{
1239 struct isc_device *isc = video_drvdata(file);
1240
cc1e6315
MCC
1241 strscpy(cap->driver, ATMEL_ISC_NAME, sizeof(cap->driver));
1242 strscpy(cap->card, "Atmel Image Sensor Controller", sizeof(cap->card));
10626744
SW
1243 snprintf(cap->bus_info, sizeof(cap->bus_info),
1244 "platform:%s", isc->v4l2_dev.name);
1245
1246 return 0;
1247}
1248
1249static int isc_enum_fmt_vid_cap(struct file *file, void *priv,
1250 struct v4l2_fmtdesc *f)
1251{
1252 struct isc_device *isc = video_drvdata(file);
1253 u32 index = f->index;
1254
1255 if (index >= isc->num_user_formats)
1256 return -EINVAL;
1257
1258 f->pixelformat = isc->user_formats[index]->fourcc;
1259
1260 return 0;
1261}
1262
1263static int isc_g_fmt_vid_cap(struct file *file, void *priv,
1264 struct v4l2_format *fmt)
1265{
1266 struct isc_device *isc = video_drvdata(file);
1267
1268 *fmt = isc->fmt;
1269
1270 return 0;
1271}
1272
1273static struct isc_format *find_format_by_fourcc(struct isc_device *isc,
1274 unsigned int fourcc)
1275{
1276 unsigned int num_formats = isc->num_user_formats;
1277 struct isc_format *fmt;
1278 unsigned int i;
1279
1280 for (i = 0; i < num_formats; i++) {
1281 fmt = isc->user_formats[i];
1282 if (fmt->fourcc == fourcc)
1283 return fmt;
1284 }
1285
1286 return NULL;
1287}
1288
1289static int isc_try_fmt(struct isc_device *isc, struct v4l2_format *f,
93d4a26c 1290 struct isc_format **current_fmt, u32 *code)
10626744
SW
1291{
1292 struct isc_format *isc_fmt;
1293 struct v4l2_pix_format *pixfmt = &f->fmt.pix;
b0ea17c5 1294 struct v4l2_subdev_pad_config pad_cfg;
10626744
SW
1295 struct v4l2_subdev_format format = {
1296 .which = V4L2_SUBDEV_FORMAT_TRY,
1297 };
93d4a26c 1298 u32 mbus_code;
10626744
SW
1299 int ret;
1300
1301 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1302 return -EINVAL;
1303
1304 isc_fmt = find_format_by_fourcc(isc, pixfmt->pixelformat);
1305 if (!isc_fmt) {
1306 v4l2_warn(&isc->v4l2_dev, "Format 0x%x not found\n",
1307 pixfmt->pixelformat);
1308 isc_fmt = isc->user_formats[isc->num_user_formats - 1];
1309 pixfmt->pixelformat = isc_fmt->fourcc;
1310 }
1311
1312 /* Limit to Atmel ISC hardware capabilities */
1313 if (pixfmt->width > ISC_MAX_SUPPORT_WIDTH)
1314 pixfmt->width = ISC_MAX_SUPPORT_WIDTH;
1315 if (pixfmt->height > ISC_MAX_SUPPORT_HEIGHT)
1316 pixfmt->height = ISC_MAX_SUPPORT_HEIGHT;
1317
93d4a26c
SW
1318 if (sensor_is_preferred(isc_fmt))
1319 mbus_code = isc_fmt->mbus_code;
1320 else
1321 mbus_code = isc->raw_fmt->mbus_code;
1322
1323 v4l2_fill_mbus_format(&format.format, pixfmt, mbus_code);
10626744 1324 ret = v4l2_subdev_call(isc->current_subdev->sd, pad, set_fmt,
b0ea17c5 1325 &pad_cfg, &format);
10626744
SW
1326 if (ret < 0)
1327 return ret;
1328
1329 v4l2_fill_pix_format(pixfmt, &format.format);
1330
1331 pixfmt->field = V4L2_FIELD_NONE;
93d4a26c 1332 pixfmt->bytesperline = (pixfmt->width * isc_fmt->bpp) >> 3;
10626744
SW
1333 pixfmt->sizeimage = pixfmt->bytesperline * pixfmt->height;
1334
1335 if (current_fmt)
1336 *current_fmt = isc_fmt;
1337
93d4a26c
SW
1338 if (code)
1339 *code = mbus_code;
1340
10626744
SW
1341 return 0;
1342}
1343
1344static int isc_set_fmt(struct isc_device *isc, struct v4l2_format *f)
1345{
1346 struct v4l2_subdev_format format = {
1347 .which = V4L2_SUBDEV_FORMAT_ACTIVE,
1348 };
1349 struct isc_format *current_fmt;
93d4a26c 1350 u32 mbus_code;
10626744
SW
1351 int ret;
1352
93d4a26c 1353 ret = isc_try_fmt(isc, f, &current_fmt, &mbus_code);
10626744
SW
1354 if (ret)
1355 return ret;
1356
93d4a26c 1357 v4l2_fill_mbus_format(&format.format, &f->fmt.pix, mbus_code);
10626744
SW
1358 ret = v4l2_subdev_call(isc->current_subdev->sd, pad,
1359 set_fmt, NULL, &format);
1360 if (ret < 0)
1361 return ret;
1362
1363 isc->fmt = *f;
1364 isc->current_fmt = current_fmt;
1365
1366 return 0;
1367}
1368
1369static int isc_s_fmt_vid_cap(struct file *file, void *priv,
1370 struct v4l2_format *f)
1371{
1372 struct isc_device *isc = video_drvdata(file);
1373
1374 if (vb2_is_streaming(&isc->vb2_vidq))
1375 return -EBUSY;
1376
1377 return isc_set_fmt(isc, f);
1378}
1379
1380static int isc_try_fmt_vid_cap(struct file *file, void *priv,
1381 struct v4l2_format *f)
1382{
1383 struct isc_device *isc = video_drvdata(file);
1384
93d4a26c 1385 return isc_try_fmt(isc, f, NULL, NULL);
10626744
SW
1386}
1387
1388static int isc_enum_input(struct file *file, void *priv,
1389 struct v4l2_input *inp)
1390{
1391 if (inp->index != 0)
1392 return -EINVAL;
1393
1394 inp->type = V4L2_INPUT_TYPE_CAMERA;
1395 inp->std = 0;
cc1e6315 1396 strscpy(inp->name, "Camera", sizeof(inp->name));
10626744
SW
1397
1398 return 0;
1399}
1400
1401static int isc_g_input(struct file *file, void *priv, unsigned int *i)
1402{
1403 *i = 0;
1404
1405 return 0;
1406}
1407
1408static int isc_s_input(struct file *file, void *priv, unsigned int i)
1409{
1410 if (i > 0)
1411 return -EINVAL;
1412
1413 return 0;
1414}
1415
1416static int isc_g_parm(struct file *file, void *fh, struct v4l2_streamparm *a)
1417{
1418 struct isc_device *isc = video_drvdata(file);
1419
4471109e 1420 return v4l2_g_parm_cap(video_devdata(file), isc->current_subdev->sd, a);
10626744
SW
1421}
1422
1423static int isc_s_parm(struct file *file, void *fh, struct v4l2_streamparm *a)
1424{
1425 struct isc_device *isc = video_drvdata(file);
1426
4471109e 1427 return v4l2_s_parm_cap(video_devdata(file), isc->current_subdev->sd, a);
10626744
SW
1428}
1429
1430static int isc_enum_framesizes(struct file *file, void *fh,
1431 struct v4l2_frmsizeenum *fsize)
1432{
1433 struct isc_device *isc = video_drvdata(file);
1434 const struct isc_format *isc_fmt;
1435 struct v4l2_subdev_frame_size_enum fse = {
1436 .index = fsize->index,
1437 .which = V4L2_SUBDEV_FORMAT_ACTIVE,
1438 };
1439 int ret;
1440
1441 isc_fmt = find_format_by_fourcc(isc, fsize->pixel_format);
1442 if (!isc_fmt)
1443 return -EINVAL;
1444
93d4a26c
SW
1445 if (sensor_is_preferred(isc_fmt))
1446 fse.code = isc_fmt->mbus_code;
1447 else
1448 fse.code = isc->raw_fmt->mbus_code;
10626744
SW
1449
1450 ret = v4l2_subdev_call(isc->current_subdev->sd, pad, enum_frame_size,
1451 NULL, &fse);
1452 if (ret)
1453 return ret;
1454
1455 fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
1456 fsize->discrete.width = fse.max_width;
1457 fsize->discrete.height = fse.max_height;
1458
1459 return 0;
1460}
1461
1462static int isc_enum_frameintervals(struct file *file, void *fh,
1463 struct v4l2_frmivalenum *fival)
1464{
1465 struct isc_device *isc = video_drvdata(file);
1466 const struct isc_format *isc_fmt;
1467 struct v4l2_subdev_frame_interval_enum fie = {
1468 .index = fival->index,
1469 .width = fival->width,
1470 .height = fival->height,
1471 .which = V4L2_SUBDEV_FORMAT_ACTIVE,
1472 };
1473 int ret;
1474
1475 isc_fmt = find_format_by_fourcc(isc, fival->pixel_format);
1476 if (!isc_fmt)
1477 return -EINVAL;
1478
93d4a26c
SW
1479 if (sensor_is_preferred(isc_fmt))
1480 fie.code = isc_fmt->mbus_code;
1481 else
1482 fie.code = isc->raw_fmt->mbus_code;
10626744
SW
1483
1484 ret = v4l2_subdev_call(isc->current_subdev->sd, pad,
1485 enum_frame_interval, NULL, &fie);
1486 if (ret)
1487 return ret;
1488
1489 fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
1490 fival->discrete = fie.interval;
1491
1492 return 0;
1493}
1494
1495static const struct v4l2_ioctl_ops isc_ioctl_ops = {
1496 .vidioc_querycap = isc_querycap,
1497 .vidioc_enum_fmt_vid_cap = isc_enum_fmt_vid_cap,
1498 .vidioc_g_fmt_vid_cap = isc_g_fmt_vid_cap,
1499 .vidioc_s_fmt_vid_cap = isc_s_fmt_vid_cap,
1500 .vidioc_try_fmt_vid_cap = isc_try_fmt_vid_cap,
1501
1502 .vidioc_enum_input = isc_enum_input,
1503 .vidioc_g_input = isc_g_input,
1504 .vidioc_s_input = isc_s_input,
1505
1506 .vidioc_reqbufs = vb2_ioctl_reqbufs,
1507 .vidioc_querybuf = vb2_ioctl_querybuf,
1508 .vidioc_qbuf = vb2_ioctl_qbuf,
1509 .vidioc_expbuf = vb2_ioctl_expbuf,
1510 .vidioc_dqbuf = vb2_ioctl_dqbuf,
1511 .vidioc_create_bufs = vb2_ioctl_create_bufs,
1512 .vidioc_prepare_buf = vb2_ioctl_prepare_buf,
1513 .vidioc_streamon = vb2_ioctl_streamon,
1514 .vidioc_streamoff = vb2_ioctl_streamoff,
1515
1516 .vidioc_g_parm = isc_g_parm,
1517 .vidioc_s_parm = isc_s_parm,
1518 .vidioc_enum_framesizes = isc_enum_framesizes,
1519 .vidioc_enum_frameintervals = isc_enum_frameintervals,
93d4a26c
SW
1520
1521 .vidioc_log_status = v4l2_ctrl_log_status,
1522 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
1523 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
10626744
SW
1524};
1525
1526static int isc_open(struct file *file)
1527{
1528 struct isc_device *isc = video_drvdata(file);
1529 struct v4l2_subdev *sd = isc->current_subdev->sd;
1530 int ret;
1531
1532 if (mutex_lock_interruptible(&isc->lock))
1533 return -ERESTARTSYS;
1534
1535 ret = v4l2_fh_open(file);
1536 if (ret < 0)
1537 goto unlock;
1538
1539 if (!v4l2_fh_is_singular_file(file))
1540 goto unlock;
1541
1542 ret = v4l2_subdev_call(sd, core, s_power, 1);
4540e0ad 1543 if (ret < 0 && ret != -ENOIOCTLCMD) {
10626744 1544 v4l2_fh_release(file);
4540e0ad
SW
1545 goto unlock;
1546 }
1547
1548 ret = isc_set_fmt(isc, &isc->fmt);
1549 if (ret) {
1550 v4l2_subdev_call(sd, core, s_power, 0);
1551 v4l2_fh_release(file);
1552 }
10626744
SW
1553
1554unlock:
1555 mutex_unlock(&isc->lock);
1556 return ret;
1557}
1558
1559static int isc_release(struct file *file)
1560{
1561 struct isc_device *isc = video_drvdata(file);
1562 struct v4l2_subdev *sd = isc->current_subdev->sd;
1563 bool fh_singular;
1564 int ret;
1565
1566 mutex_lock(&isc->lock);
1567
1568 fh_singular = v4l2_fh_is_singular_file(file);
1569
1570 ret = _vb2_fop_release(file, NULL);
1571
1572 if (fh_singular)
1573 v4l2_subdev_call(sd, core, s_power, 0);
1574
1575 mutex_unlock(&isc->lock);
1576
1577 return ret;
1578}
1579
1580static const struct v4l2_file_operations isc_fops = {
1581 .owner = THIS_MODULE,
1582 .open = isc_open,
1583 .release = isc_release,
1584 .unlocked_ioctl = video_ioctl2,
1585 .read = vb2_fop_read,
1586 .mmap = vb2_fop_mmap,
1587 .poll = vb2_fop_poll,
1588};
1589
1590static irqreturn_t isc_interrupt(int irq, void *dev_id)
1591{
1592 struct isc_device *isc = (struct isc_device *)dev_id;
1593 struct regmap *regmap = isc->regmap;
1594 u32 isc_intsr, isc_intmask, pending;
1595 irqreturn_t ret = IRQ_NONE;
1596
10626744
SW
1597 regmap_read(regmap, ISC_INTSR, &isc_intsr);
1598 regmap_read(regmap, ISC_INTMASK, &isc_intmask);
1599
1600 pending = isc_intsr & isc_intmask;
1601
1602 if (likely(pending & ISC_INT_DDONE)) {
93d4a26c 1603 spin_lock(&isc->dma_queue_lock);
10626744
SW
1604 if (isc->cur_frm) {
1605 struct vb2_v4l2_buffer *vbuf = &isc->cur_frm->vb;
1606 struct vb2_buffer *vb = &vbuf->vb2_buf;
1607
1608 vb->timestamp = ktime_get_ns();
1609 vbuf->sequence = isc->sequence++;
1610 vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
1611 isc->cur_frm = NULL;
1612 }
1613
1614 if (!list_empty(&isc->dma_queue) && !isc->stop) {
1615 isc->cur_frm = list_first_entry(&isc->dma_queue,
1616 struct isc_buffer, list);
1617 list_del(&isc->cur_frm->list);
1618
93d4a26c 1619 isc_start_dma(isc);
10626744
SW
1620 }
1621
1622 if (isc->stop)
1623 complete(&isc->comp);
1624
1625 ret = IRQ_HANDLED;
93d4a26c 1626 spin_unlock(&isc->dma_queue_lock);
10626744
SW
1627 }
1628
93d4a26c
SW
1629 if (pending & ISC_INT_HISDONE) {
1630 schedule_work(&isc->awb_work);
1631 ret = IRQ_HANDLED;
1632 }
10626744
SW
1633
1634 return ret;
1635}
1636
93d4a26c
SW
1637static void isc_hist_count(struct isc_device *isc)
1638{
1639 struct regmap *regmap = isc->regmap;
1640 struct isc_ctrls *ctrls = &isc->ctrls;
1641 u32 *hist_count = &ctrls->hist_count[ctrls->hist_id];
1642 u32 *hist_entry = &ctrls->hist_entry[0];
1643 u32 i;
1644
1645 regmap_bulk_read(regmap, ISC_HIS_ENTRY, hist_entry, HIST_ENTRIES);
1646
1647 *hist_count = 0;
6ea87867 1648 for (i = 0; i < HIST_ENTRIES; i++)
93d4a26c
SW
1649 *hist_count += i * (*hist_entry++);
1650}
1651
1652static void isc_wb_update(struct isc_ctrls *ctrls)
1653{
1654 u32 *hist_count = &ctrls->hist_count[0];
1655 u64 g_count = (u64)hist_count[ISC_HIS_CFG_MODE_GB] << 9;
1656 u32 hist_r = hist_count[ISC_HIS_CFG_MODE_R];
1657 u32 hist_b = hist_count[ISC_HIS_CFG_MODE_B];
1658
1659 if (hist_r)
1660 ctrls->r_gain = div_u64(g_count, hist_r);
1661
1662 if (hist_b)
1663 ctrls->b_gain = div_u64(g_count, hist_b);
1664}
1665
1666static void isc_awb_work(struct work_struct *w)
1667{
1668 struct isc_device *isc =
1669 container_of(w, struct isc_device, awb_work);
1670 struct regmap *regmap = isc->regmap;
f103ea11 1671 struct fmt_config *config = get_fmt_config(isc->raw_fmt->fourcc);
93d4a26c
SW
1672 struct isc_ctrls *ctrls = &isc->ctrls;
1673 u32 hist_id = ctrls->hist_id;
1674 u32 baysel;
1675
1676 if (ctrls->hist_stat != HIST_ENABLED)
1677 return;
1678
1679 isc_hist_count(isc);
1680
1681 if (hist_id != ISC_HIS_CFG_MODE_B) {
1682 hist_id++;
1683 } else {
1684 isc_wb_update(ctrls);
1685 hist_id = ISC_HIS_CFG_MODE_R;
1686 }
1687
1688 ctrls->hist_id = hist_id;
f103ea11 1689 baysel = config->cfa_baycfg << ISC_HIS_CFG_BAYSEL_SHIFT;
93d4a26c
SW
1690
1691 pm_runtime_get_sync(isc->dev);
1692
1693 regmap_write(regmap, ISC_HIS_CFG, hist_id | baysel | ISC_HIS_CFG_RAR);
1694 isc_update_profile(isc);
1695 regmap_write(regmap, ISC_CTRLEN, ISC_CTRL_HISREQ);
1696
1697 pm_runtime_put_sync(isc->dev);
1698}
1699
1700static int isc_s_ctrl(struct v4l2_ctrl *ctrl)
1701{
1702 struct isc_device *isc = container_of(ctrl->handler,
1703 struct isc_device, ctrls.handler);
1704 struct isc_ctrls *ctrls = &isc->ctrls;
1705
1706 switch (ctrl->id) {
1707 case V4L2_CID_BRIGHTNESS:
1708 ctrls->brightness = ctrl->val & ISC_CBC_BRIGHT_MASK;
1709 break;
1710 case V4L2_CID_CONTRAST:
1711 ctrls->contrast = ctrl->val & ISC_CBC_CONTRAST_MASK;
1712 break;
1713 case V4L2_CID_GAMMA:
1714 ctrls->gamma_index = ctrl->val;
1715 break;
1716 case V4L2_CID_AUTO_WHITE_BALANCE:
1717 ctrls->awb = ctrl->val;
1718 if (ctrls->hist_stat != HIST_ENABLED) {
1719 ctrls->r_gain = 0x1 << 9;
1720 ctrls->b_gain = 0x1 << 9;
1721 }
1722 break;
1723 default:
1724 return -EINVAL;
1725 }
1726
1727 return 0;
1728}
1729
1730static const struct v4l2_ctrl_ops isc_ctrl_ops = {
1731 .s_ctrl = isc_s_ctrl,
1732};
1733
1734static int isc_ctrl_init(struct isc_device *isc)
1735{
1736 const struct v4l2_ctrl_ops *ops = &isc_ctrl_ops;
1737 struct isc_ctrls *ctrls = &isc->ctrls;
1738 struct v4l2_ctrl_handler *hdl = &ctrls->handler;
1739 int ret;
1740
1741 ctrls->hist_stat = HIST_INIT;
1742
1743 ret = v4l2_ctrl_handler_init(hdl, 4);
1744 if (ret < 0)
1745 return ret;
1746
1747 v4l2_ctrl_new_std(hdl, ops, V4L2_CID_BRIGHTNESS, -1024, 1023, 1, 0);
1748 v4l2_ctrl_new_std(hdl, ops, V4L2_CID_CONTRAST, -2048, 2047, 1, 256);
1749 v4l2_ctrl_new_std(hdl, ops, V4L2_CID_GAMMA, 0, GAMMA_MAX, 1, 2);
1750 v4l2_ctrl_new_std(hdl, ops, V4L2_CID_AUTO_WHITE_BALANCE, 0, 1, 1, 1);
1751
1752 v4l2_ctrl_handler_setup(hdl);
1753
1754 return 0;
1755}
1756
1757
10626744
SW
1758static int isc_async_bound(struct v4l2_async_notifier *notifier,
1759 struct v4l2_subdev *subdev,
1760 struct v4l2_async_subdev *asd)
1761{
1762 struct isc_device *isc = container_of(notifier->v4l2_dev,
1763 struct isc_device, v4l2_dev);
1764 struct isc_subdev_entity *subdev_entity =
1765 container_of(notifier, struct isc_subdev_entity, notifier);
1766
1767 if (video_is_registered(&isc->video_dev)) {
1768 v4l2_err(&isc->v4l2_dev, "only supports one sub-device.\n");
1769 return -EBUSY;
1770 }
1771
1772 subdev_entity->sd = subdev;
1773
1774 return 0;
1775}
1776
1777static void isc_async_unbind(struct v4l2_async_notifier *notifier,
1778 struct v4l2_subdev *subdev,
1779 struct v4l2_async_subdev *asd)
1780{
1781 struct isc_device *isc = container_of(notifier->v4l2_dev,
1782 struct isc_device, v4l2_dev);
93d4a26c 1783 cancel_work_sync(&isc->awb_work);
10626744 1784 video_unregister_device(&isc->video_dev);
93d4a26c 1785 v4l2_ctrl_handler_free(&isc->ctrls.handler);
10626744
SW
1786}
1787
1788static struct isc_format *find_format_by_code(unsigned int code, int *index)
1789{
f103ea11 1790 struct isc_format *fmt = &formats_list[0];
10626744
SW
1791 unsigned int i;
1792
f103ea11 1793 for (i = 0; i < ARRAY_SIZE(formats_list); i++) {
10626744
SW
1794 if (fmt->mbus_code == code) {
1795 *index = i;
1796 return fmt;
1797 }
1798
1799 fmt++;
1800 }
1801
1802 return NULL;
1803}
1804
1805static int isc_formats_init(struct isc_device *isc)
1806{
1807 struct isc_format *fmt;
1808 struct v4l2_subdev *subdev = isc->current_subdev->sd;
93d4a26c 1809 unsigned int num_fmts, i, j;
f103ea11 1810 u32 list_size = ARRAY_SIZE(formats_list);
10626744
SW
1811 struct v4l2_subdev_mbus_code_enum mbus_code = {
1812 .which = V4L2_SUBDEV_FORMAT_ACTIVE,
1813 };
1814
10626744
SW
1815 while (!v4l2_subdev_call(subdev, pad, enum_mbus_code,
1816 NULL, &mbus_code)) {
1817 mbus_code.index++;
f103ea11 1818
10626744 1819 fmt = find_format_by_code(mbus_code.code, &i);
f103ea11 1820 if ((!fmt) || (!(fmt->flags & FMT_FLAG_FROM_SENSOR)))
10626744
SW
1821 continue;
1822
93d4a26c
SW
1823 fmt->sd_support = true;
1824
f103ea11 1825 if (fmt->flags & FMT_FLAG_RAW_FORMAT)
93d4a26c 1826 isc->raw_fmt = fmt;
93d4a26c
SW
1827 }
1828
f103ea11
WY
1829 fmt = &formats_list[0];
1830 for (i = 0; i < list_size; i++) {
1831 if (fmt->flags & FMT_FLAG_FROM_CONTROLLER)
1832 fmt->isc_support = true;
1833
1834 fmt++;
1835 }
1836
1837 fmt = &formats_list[0];
1838 num_fmts = 0;
1839 for (i = 0; i < list_size; i++) {
93d4a26c
SW
1840 if (fmt->isc_support || fmt->sd_support)
1841 num_fmts++;
1842
1843 fmt++;
10626744
SW
1844 }
1845
1846 if (!num_fmts)
1847 return -ENXIO;
1848
1849 isc->num_user_formats = num_fmts;
1850 isc->user_formats = devm_kcalloc(isc->dev,
2d3da59f 1851 num_fmts, sizeof(*isc->user_formats),
10626744 1852 GFP_KERNEL);
c38e8657 1853 if (!isc->user_formats)
10626744 1854 return -ENOMEM;
10626744 1855
f103ea11
WY
1856 fmt = &formats_list[0];
1857 for (i = 0, j = 0; i < list_size; i++) {
93d4a26c 1858 if (fmt->isc_support || fmt->sd_support)
10626744
SW
1859 isc->user_formats[j++] = fmt;
1860
1861 fmt++;
1862 }
1863
1864 return 0;
1865}
1866
1867static int isc_set_default_fmt(struct isc_device *isc)
1868{
1869 struct v4l2_format f = {
1870 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
1871 .fmt.pix = {
1872 .width = VGA_WIDTH,
1873 .height = VGA_HEIGHT,
1874 .field = V4L2_FIELD_NONE,
1875 .pixelformat = isc->user_formats[0]->fourcc,
1876 },
1877 };
4540e0ad 1878 int ret;
10626744 1879
93d4a26c 1880 ret = isc_try_fmt(isc, &f, NULL, NULL);
4540e0ad
SW
1881 if (ret)
1882 return ret;
1883
1884 isc->current_fmt = isc->user_formats[0];
1885 isc->fmt = f;
1886
1887 return 0;
10626744
SW
1888}
1889
1890static int isc_async_complete(struct v4l2_async_notifier *notifier)
1891{
1892 struct isc_device *isc = container_of(notifier->v4l2_dev,
1893 struct isc_device, v4l2_dev);
10626744
SW
1894 struct video_device *vdev = &isc->video_dev;
1895 struct vb2_queue *q = &isc->vb2_vidq;
1896 int ret;
1897
93d4a26c
SW
1898 ret = v4l2_device_register_subdev_nodes(&isc->v4l2_dev);
1899 if (ret < 0) {
1900 v4l2_err(&isc->v4l2_dev, "Failed to register subdev nodes\n");
1901 return ret;
1902 }
1903
10626744
SW
1904 isc->current_subdev = container_of(notifier,
1905 struct isc_subdev_entity, notifier);
10626744
SW
1906 mutex_init(&isc->lock);
1907 init_completion(&isc->comp);
1908
1909 /* Initialize videobuf2 queue */
1910 q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1911 q->io_modes = VB2_MMAP | VB2_DMABUF | VB2_READ;
1912 q->drv_priv = isc;
1913 q->buf_struct_size = sizeof(struct isc_buffer);
1914 q->ops = &isc_vb2_ops;
1915 q->mem_ops = &vb2_dma_contig_memops;
1916 q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
1917 q->lock = &isc->lock;
1918 q->min_buffers_needed = 1;
1919 q->dev = isc->dev;
1920
1921 ret = vb2_queue_init(q);
1922 if (ret < 0) {
1923 v4l2_err(&isc->v4l2_dev,
1924 "vb2_queue_init() failed: %d\n", ret);
1925 return ret;
1926 }
1927
1928 /* Init video dma queues */
1929 INIT_LIST_HEAD(&isc->dma_queue);
1930 spin_lock_init(&isc->dma_queue_lock);
1931
10626744
SW
1932 ret = isc_formats_init(isc);
1933 if (ret < 0) {
1934 v4l2_err(&isc->v4l2_dev,
1935 "Init format failed: %d\n", ret);
1936 return ret;
1937 }
1938
10626744
SW
1939 ret = isc_set_default_fmt(isc);
1940 if (ret) {
1941 v4l2_err(&isc->v4l2_dev, "Could not set default format\n");
1942 return ret;
1943 }
1944
93d4a26c
SW
1945 ret = isc_ctrl_init(isc);
1946 if (ret) {
1947 v4l2_err(&isc->v4l2_dev, "Init isc ctrols failed: %d\n", ret);
1948 return ret;
1949 }
1950
1951 INIT_WORK(&isc->awb_work, isc_awb_work);
1952
10626744 1953 /* Register video device */
c0decac1 1954 strscpy(vdev->name, ATMEL_ISC_NAME, sizeof(vdev->name));
10626744
SW
1955 vdev->release = video_device_release_empty;
1956 vdev->fops = &isc_fops;
1957 vdev->ioctl_ops = &isc_ioctl_ops;
1958 vdev->v4l2_dev = &isc->v4l2_dev;
1959 vdev->vfl_dir = VFL_DIR_RX;
1960 vdev->queue = q;
1961 vdev->lock = &isc->lock;
93d4a26c 1962 vdev->ctrl_handler = &isc->ctrls.handler;
10626744
SW
1963 vdev->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_CAPTURE;
1964 video_set_drvdata(vdev, isc);
1965
1966 ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1);
1967 if (ret < 0) {
1968 v4l2_err(&isc->v4l2_dev,
1969 "video_register_device failed: %d\n", ret);
1970 return ret;
1971 }
1972
1973 return 0;
1974}
1975
b6ee3f0d
LP
1976static const struct v4l2_async_notifier_operations isc_async_ops = {
1977 .bound = isc_async_bound,
1978 .unbind = isc_async_unbind,
1979 .complete = isc_async_complete,
1980};
1981
10626744
SW
1982static void isc_subdev_cleanup(struct isc_device *isc)
1983{
1984 struct isc_subdev_entity *subdev_entity;
1985
d079f94c 1986 list_for_each_entry(subdev_entity, &isc->subdev_entities, list) {
10626744 1987 v4l2_async_notifier_unregister(&subdev_entity->notifier);
d079f94c
SL
1988 v4l2_async_notifier_cleanup(&subdev_entity->notifier);
1989 }
10626744
SW
1990
1991 INIT_LIST_HEAD(&isc->subdev_entities);
1992}
1993
1994static int isc_pipeline_init(struct isc_device *isc)
1995{
1996 struct device *dev = isc->dev;
1997 struct regmap *regmap = isc->regmap;
1998 struct regmap_field *regs;
1999 unsigned int i;
2000
2001 /* WB-->CFA-->CC-->GAM-->CSC-->CBC-->SUB422-->SUB420 */
2002 const struct reg_field regfields[ISC_PIPE_LINE_NODE_NUM] = {
2003 REG_FIELD(ISC_WB_CTRL, 0, 0),
2004 REG_FIELD(ISC_CFA_CTRL, 0, 0),
2005 REG_FIELD(ISC_CC_CTRL, 0, 0),
2006 REG_FIELD(ISC_GAM_CTRL, 0, 0),
2007 REG_FIELD(ISC_GAM_CTRL, 1, 1),
2008 REG_FIELD(ISC_GAM_CTRL, 2, 2),
2009 REG_FIELD(ISC_GAM_CTRL, 3, 3),
2010 REG_FIELD(ISC_CSC_CTRL, 0, 0),
2011 REG_FIELD(ISC_CBC_CTRL, 0, 0),
2012 REG_FIELD(ISC_SUB422_CTRL, 0, 0),
2013 REG_FIELD(ISC_SUB420_CTRL, 0, 0),
2014 };
2015
2016 for (i = 0; i < ISC_PIPE_LINE_NODE_NUM; i++) {
2017 regs = devm_regmap_field_alloc(dev, regmap, regfields[i]);
2018 if (IS_ERR(regs))
2019 return PTR_ERR(regs);
2020
2021 isc->pipeline[i] = regs;
2022 }
2023
2024 return 0;
2025}
2026
2027static int isc_parse_dt(struct device *dev, struct isc_device *isc)
2028{
2029 struct device_node *np = dev->of_node;
2030 struct device_node *epn = NULL, *rem;
10626744
SW
2031 struct isc_subdev_entity *subdev_entity;
2032 unsigned int flags;
2033 int ret;
2034
2035 INIT_LIST_HEAD(&isc->subdev_entities);
2036
79c5453d 2037 while (1) {
60359a28
SA
2038 struct v4l2_fwnode_endpoint v4l2_epn = { .bus_type = 0 };
2039
10626744
SW
2040 epn = of_graph_get_next_endpoint(np, epn);
2041 if (!epn)
79c5453d 2042 return 0;
10626744
SW
2043
2044 rem = of_graph_get_remote_port_parent(epn);
2045 if (!rem) {
68d9c47b
RH
2046 dev_notice(dev, "Remote device at %pOF not found\n",
2047 epn);
10626744
SW
2048 continue;
2049 }
2050
859969b3
SA
2051 ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(epn),
2052 &v4l2_epn);
10626744
SW
2053 if (ret) {
2054 of_node_put(rem);
2055 ret = -EINVAL;
2056 dev_err(dev, "Could not parse the endpoint\n");
2057 break;
2058 }
2059
2060 subdev_entity = devm_kzalloc(dev,
2061 sizeof(*subdev_entity), GFP_KERNEL);
af28c996 2062 if (!subdev_entity) {
10626744
SW
2063 of_node_put(rem);
2064 ret = -ENOMEM;
2065 break;
2066 }
2067
2068 subdev_entity->asd = devm_kzalloc(dev,
2069 sizeof(*subdev_entity->asd), GFP_KERNEL);
af28c996 2070 if (!subdev_entity->asd) {
10626744
SW
2071 of_node_put(rem);
2072 ret = -ENOMEM;
2073 break;
2074 }
2075
2076 flags = v4l2_epn.bus.parallel.flags;
2077
2078 if (flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)
2079 subdev_entity->pfe_cfg0 = ISC_PFE_CFG0_HPOL_LOW;
2080
2081 if (flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)
2082 subdev_entity->pfe_cfg0 |= ISC_PFE_CFG0_VPOL_LOW;
2083
2084 if (flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)
2085 subdev_entity->pfe_cfg0 |= ISC_PFE_CFG0_PPOL_LOW;
2086
859969b3 2087 subdev_entity->asd->match_type = V4L2_ASYNC_MATCH_FWNODE;
4e48afec 2088 subdev_entity->asd->match.fwnode =
859969b3 2089 of_fwnode_handle(rem);
10626744
SW
2090 list_add_tail(&subdev_entity->list, &isc->subdev_entities);
2091 }
2092
2093 of_node_put(epn);
2094 return ret;
2095}
2096
2097/* regmap configuration */
2098#define ATMEL_ISC_REG_MAX 0xbfc
2099static const struct regmap_config isc_regmap_config = {
2100 .reg_bits = 32,
2101 .reg_stride = 4,
2102 .val_bits = 32,
2103 .max_register = ATMEL_ISC_REG_MAX,
2104};
2105
2106static int atmel_isc_probe(struct platform_device *pdev)
2107{
2108 struct device *dev = &pdev->dev;
2109 struct isc_device *isc;
2110 struct resource *res;
2111 void __iomem *io_base;
2112 struct isc_subdev_entity *subdev_entity;
2113 int irq;
2114 int ret;
2115
2116 isc = devm_kzalloc(dev, sizeof(*isc), GFP_KERNEL);
2117 if (!isc)
2118 return -ENOMEM;
2119
2120 platform_set_drvdata(pdev, isc);
2121 isc->dev = dev;
2122
2123 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
2124 io_base = devm_ioremap_resource(dev, res);
2125 if (IS_ERR(io_base))
2126 return PTR_ERR(io_base);
2127
2128 isc->regmap = devm_regmap_init_mmio(dev, io_base, &isc_regmap_config);
2129 if (IS_ERR(isc->regmap)) {
2130 ret = PTR_ERR(isc->regmap);
2131 dev_err(dev, "failed to init register map: %d\n", ret);
2132 return ret;
2133 }
2134
2135 irq = platform_get_irq(pdev, 0);
846c4a7b 2136 if (irq < 0) {
10626744
SW
2137 ret = irq;
2138 dev_err(dev, "failed to get irq: %d\n", ret);
2139 return ret;
2140 }
2141
2142 ret = devm_request_irq(dev, irq, isc_interrupt, 0,
2143 ATMEL_ISC_NAME, isc);
2144 if (ret < 0) {
2145 dev_err(dev, "can't register ISR for IRQ %u (ret=%i)\n",
2146 irq, ret);
2147 return ret;
2148 }
2149
2150 ret = isc_pipeline_init(isc);
2151 if (ret)
2152 return ret;
2153
2154 isc->hclock = devm_clk_get(dev, "hclock");
2155 if (IS_ERR(isc->hclock)) {
2156 ret = PTR_ERR(isc->hclock);
2157 dev_err(dev, "failed to get hclock: %d\n", ret);
2158 return ret;
2159 }
2160
01192aa1
WY
2161 ret = clk_prepare_enable(isc->hclock);
2162 if (ret) {
2163 dev_err(dev, "failed to enable hclock: %d\n", ret);
2164 return ret;
2165 }
2166
10626744
SW
2167 ret = isc_clk_init(isc);
2168 if (ret) {
2169 dev_err(dev, "failed to init isc clock: %d\n", ret);
01192aa1 2170 goto unprepare_hclk;
10626744
SW
2171 }
2172
2173 isc->ispck = isc->isc_clks[ISC_ISPCK].clk;
2174
01192aa1
WY
2175 ret = clk_prepare_enable(isc->ispck);
2176 if (ret) {
2177 dev_err(dev, "failed to enable ispck: %d\n", ret);
2178 goto unprepare_hclk;
2179 }
2180
10626744
SW
2181 /* ispck should be greater or equal to hclock */
2182 ret = clk_set_rate(isc->ispck, clk_get_rate(isc->hclock));
2183 if (ret) {
2184 dev_err(dev, "failed to set ispck rate: %d\n", ret);
01192aa1 2185 goto unprepare_clk;
10626744
SW
2186 }
2187
2188 ret = v4l2_device_register(dev, &isc->v4l2_dev);
2189 if (ret) {
2190 dev_err(dev, "unable to register v4l2 device.\n");
01192aa1 2191 goto unprepare_clk;
10626744
SW
2192 }
2193
2194 ret = isc_parse_dt(dev, isc);
2195 if (ret) {
2196 dev_err(dev, "fail to parse device tree\n");
2197 goto unregister_v4l2_device;
2198 }
2199
2200 if (list_empty(&isc->subdev_entities)) {
2201 dev_err(dev, "no subdev found\n");
e04e5810 2202 ret = -ENODEV;
10626744
SW
2203 goto unregister_v4l2_device;
2204 }
2205
2206 list_for_each_entry(subdev_entity, &isc->subdev_entities, list) {
d079f94c
SL
2207 v4l2_async_notifier_init(&subdev_entity->notifier);
2208
2209 ret = v4l2_async_notifier_add_subdev(&subdev_entity->notifier,
2210 subdev_entity->asd);
2211 if (ret) {
2212 fwnode_handle_put(subdev_entity->asd->match.fwnode);
2213 goto cleanup_subdev;
2214 }
2215
b6ee3f0d 2216 subdev_entity->notifier.ops = &isc_async_ops;
10626744
SW
2217
2218 ret = v4l2_async_notifier_register(&isc->v4l2_dev,
2219 &subdev_entity->notifier);
2220 if (ret) {
2221 dev_err(dev, "fail to register async notifier\n");
2222 goto cleanup_subdev;
2223 }
2224
2225 if (video_is_registered(&isc->video_dev))
2226 break;
2227 }
2228
01192aa1 2229 pm_runtime_set_active(dev);
10626744 2230 pm_runtime_enable(dev);
01192aa1 2231 pm_request_idle(dev);
10626744
SW
2232
2233 return 0;
2234
2235cleanup_subdev:
2236 isc_subdev_cleanup(isc);
2237
2238unregister_v4l2_device:
2239 v4l2_device_unregister(&isc->v4l2_dev);
2240
01192aa1
WY
2241unprepare_clk:
2242 clk_disable_unprepare(isc->ispck);
2243unprepare_hclk:
2244 clk_disable_unprepare(isc->hclock);
2245
10626744
SW
2246 isc_clk_cleanup(isc);
2247
2248 return ret;
2249}
2250
2251static int atmel_isc_remove(struct platform_device *pdev)
2252{
2253 struct isc_device *isc = platform_get_drvdata(pdev);
2254
2255 pm_runtime_disable(&pdev->dev);
01192aa1
WY
2256 clk_disable_unprepare(isc->ispck);
2257 clk_disable_unprepare(isc->hclock);
10626744
SW
2258
2259 isc_subdev_cleanup(isc);
2260
2261 v4l2_device_unregister(&isc->v4l2_dev);
2262
2263 isc_clk_cleanup(isc);
2264
2265 return 0;
2266}
2267
b7e50635 2268static int __maybe_unused isc_runtime_suspend(struct device *dev)
10626744
SW
2269{
2270 struct isc_device *isc = dev_get_drvdata(dev);
2271
2272 clk_disable_unprepare(isc->ispck);
2273 clk_disable_unprepare(isc->hclock);
2274
2275 return 0;
2276}
2277
b7e50635 2278static int __maybe_unused isc_runtime_resume(struct device *dev)
10626744
SW
2279{
2280 struct isc_device *isc = dev_get_drvdata(dev);
2281 int ret;
2282
2283 ret = clk_prepare_enable(isc->hclock);
2284 if (ret)
2285 return ret;
2286
2287 return clk_prepare_enable(isc->ispck);
2288}
2289
2290static const struct dev_pm_ops atmel_isc_dev_pm_ops = {
2291 SET_RUNTIME_PM_OPS(isc_runtime_suspend, isc_runtime_resume, NULL)
2292};
2293
2294static const struct of_device_id atmel_isc_of_match[] = {
2295 { .compatible = "atmel,sama5d2-isc" },
2296 { }
2297};
2298MODULE_DEVICE_TABLE(of, atmel_isc_of_match);
2299
2300static struct platform_driver atmel_isc_driver = {
2301 .probe = atmel_isc_probe,
2302 .remove = atmel_isc_remove,
2303 .driver = {
2304 .name = ATMEL_ISC_NAME,
2305 .pm = &atmel_isc_dev_pm_ops,
2306 .of_match_table = of_match_ptr(atmel_isc_of_match),
2307 },
2308};
2309
2310module_platform_driver(atmel_isc_driver);
2311
2312MODULE_AUTHOR("Songjun Wu <songjun.wu@microchip.com>");
2313MODULE_DESCRIPTION("The V4L2 driver for Atmel-ISC");
2314MODULE_LICENSE("GPL v2");
2315MODULE_SUPPORTED_DEVICE("video");