1
2
3
4
5
6
7
8
9
10
11
12#include <linux/clk.h>
13#include <linux/clkdev.h>
14#include <linux/clk-provider.h>
15#include <linux/delay.h>
16#include <linux/interrupt.h>
17#include <linux/math64.h>
18#include <linux/module.h>
19#include <linux/of.h>
20#include <linux/of_graph.h>
21#include <linux/platform_device.h>
22#include <linux/pm_runtime.h>
23#include <linux/regmap.h>
24#include <linux/videodev2.h>
25#include <linux/atmel-isc-media.h>
26
27#include <media/v4l2-ctrls.h>
28#include <media/v4l2-device.h>
29#include <media/v4l2-event.h>
30#include <media/v4l2-image-sizes.h>
31#include <media/v4l2-ioctl.h>
32#include <media/v4l2-fwnode.h>
33#include <media/v4l2-subdev.h>
34#include <media/videobuf2-dma-contig.h>
35
36#include "atmel-isc-regs.h"
37#include "atmel-isc.h"
38
39static unsigned int debug;
40module_param(debug, int, 0644);
41MODULE_PARM_DESC(debug, "debug level (0-2)");
42
43static unsigned int sensor_preferred = 1;
44module_param(sensor_preferred, uint, 0644);
45MODULE_PARM_DESC(sensor_preferred,
46 "Sensor is preferred to output the specified format (1-on 0-off), default 1");
47
48#define ISC_IS_FORMAT_RAW(mbus_code) \
49 (((mbus_code) & 0xf000) == 0x3000)
50
51#define ISC_IS_FORMAT_GREY(mbus_code) \
52 (((mbus_code) == MEDIA_BUS_FMT_Y10_1X10) | \
53 (((mbus_code) == MEDIA_BUS_FMT_Y8_1X8)))
54
55static inline void isc_update_v4l2_ctrls(struct isc_device *isc)
56{
57 struct isc_ctrls *ctrls = &isc->ctrls;
58
59
60 v4l2_ctrl_s_ctrl(isc->r_gain_ctrl, ctrls->gain[ISC_HIS_CFG_MODE_R]);
61 v4l2_ctrl_s_ctrl(isc->b_gain_ctrl, ctrls->gain[ISC_HIS_CFG_MODE_B]);
62 v4l2_ctrl_s_ctrl(isc->gr_gain_ctrl, ctrls->gain[ISC_HIS_CFG_MODE_GR]);
63 v4l2_ctrl_s_ctrl(isc->gb_gain_ctrl, ctrls->gain[ISC_HIS_CFG_MODE_GB]);
64
65 v4l2_ctrl_s_ctrl(isc->r_off_ctrl, ctrls->offset[ISC_HIS_CFG_MODE_R]);
66 v4l2_ctrl_s_ctrl(isc->b_off_ctrl, ctrls->offset[ISC_HIS_CFG_MODE_B]);
67 v4l2_ctrl_s_ctrl(isc->gr_off_ctrl, ctrls->offset[ISC_HIS_CFG_MODE_GR]);
68 v4l2_ctrl_s_ctrl(isc->gb_off_ctrl, ctrls->offset[ISC_HIS_CFG_MODE_GB]);
69}
70
71static inline void isc_update_awb_ctrls(struct isc_device *isc)
72{
73 struct isc_ctrls *ctrls = &isc->ctrls;
74
75
76
77 regmap_write(isc->regmap, ISC_WB_O_RGR,
78 ((ctrls->offset[ISC_HIS_CFG_MODE_R])) |
79 ((ctrls->offset[ISC_HIS_CFG_MODE_GR]) << 16));
80 regmap_write(isc->regmap, ISC_WB_O_BGB,
81 ((ctrls->offset[ISC_HIS_CFG_MODE_B])) |
82 ((ctrls->offset[ISC_HIS_CFG_MODE_GB]) << 16));
83 regmap_write(isc->regmap, ISC_WB_G_RGR,
84 ctrls->gain[ISC_HIS_CFG_MODE_R] |
85 (ctrls->gain[ISC_HIS_CFG_MODE_GR] << 16));
86 regmap_write(isc->regmap, ISC_WB_G_BGB,
87 ctrls->gain[ISC_HIS_CFG_MODE_B] |
88 (ctrls->gain[ISC_HIS_CFG_MODE_GB] << 16));
89}
90
91static inline void isc_reset_awb_ctrls(struct isc_device *isc)
92{
93 unsigned int c;
94
95 for (c = ISC_HIS_CFG_MODE_GR; c <= ISC_HIS_CFG_MODE_B; c++) {
96
97 isc->ctrls.gain[c] = 1 << 9;
98
99 isc->ctrls.offset[c] = 0;
100 }
101}
102
103static int isc_wait_clk_stable(struct clk_hw *hw)
104{
105 struct isc_clk *isc_clk = to_isc_clk(hw);
106 struct regmap *regmap = isc_clk->regmap;
107 unsigned long timeout = jiffies + usecs_to_jiffies(1000);
108 unsigned int status;
109
110 while (time_before(jiffies, timeout)) {
111 regmap_read(regmap, ISC_CLKSR, &status);
112 if (!(status & ISC_CLKSR_SIP))
113 return 0;
114
115 usleep_range(10, 250);
116 }
117
118 return -ETIMEDOUT;
119}
120
121static int isc_clk_prepare(struct clk_hw *hw)
122{
123 struct isc_clk *isc_clk = to_isc_clk(hw);
124 int ret;
125
126 if (isc_clk->id == ISC_ISPCK) {
127 ret = pm_runtime_resume_and_get(isc_clk->dev);
128 if (ret < 0)
129 return ret;
130 }
131
132 return isc_wait_clk_stable(hw);
133}
134
135static void isc_clk_unprepare(struct clk_hw *hw)
136{
137 struct isc_clk *isc_clk = to_isc_clk(hw);
138
139 isc_wait_clk_stable(hw);
140
141 if (isc_clk->id == ISC_ISPCK)
142 pm_runtime_put_sync(isc_clk->dev);
143}
144
145static int isc_clk_enable(struct clk_hw *hw)
146{
147 struct isc_clk *isc_clk = to_isc_clk(hw);
148 u32 id = isc_clk->id;
149 struct regmap *regmap = isc_clk->regmap;
150 unsigned long flags;
151 unsigned int status;
152
153 dev_dbg(isc_clk->dev, "ISC CLK: %s, id = %d, div = %d, parent id = %d\n",
154 __func__, id, isc_clk->div, isc_clk->parent_id);
155
156 spin_lock_irqsave(&isc_clk->lock, flags);
157 regmap_update_bits(regmap, ISC_CLKCFG,
158 ISC_CLKCFG_DIV_MASK(id) | ISC_CLKCFG_SEL_MASK(id),
159 (isc_clk->div << ISC_CLKCFG_DIV_SHIFT(id)) |
160 (isc_clk->parent_id << ISC_CLKCFG_SEL_SHIFT(id)));
161
162 regmap_write(regmap, ISC_CLKEN, ISC_CLK(id));
163 spin_unlock_irqrestore(&isc_clk->lock, flags);
164
165 regmap_read(regmap, ISC_CLKSR, &status);
166 if (status & ISC_CLK(id))
167 return 0;
168 else
169 return -EINVAL;
170}
171
172static void isc_clk_disable(struct clk_hw *hw)
173{
174 struct isc_clk *isc_clk = to_isc_clk(hw);
175 u32 id = isc_clk->id;
176 unsigned long flags;
177
178 spin_lock_irqsave(&isc_clk->lock, flags);
179 regmap_write(isc_clk->regmap, ISC_CLKDIS, ISC_CLK(id));
180 spin_unlock_irqrestore(&isc_clk->lock, flags);
181}
182
183static int isc_clk_is_enabled(struct clk_hw *hw)
184{
185 struct isc_clk *isc_clk = to_isc_clk(hw);
186 u32 status;
187 int ret;
188
189 if (isc_clk->id == ISC_ISPCK) {
190 ret = pm_runtime_resume_and_get(isc_clk->dev);
191 if (ret < 0)
192 return 0;
193 }
194
195 regmap_read(isc_clk->regmap, ISC_CLKSR, &status);
196
197 if (isc_clk->id == ISC_ISPCK)
198 pm_runtime_put_sync(isc_clk->dev);
199
200 return status & ISC_CLK(isc_clk->id) ? 1 : 0;
201}
202
203static unsigned long
204isc_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
205{
206 struct isc_clk *isc_clk = to_isc_clk(hw);
207
208 return DIV_ROUND_CLOSEST(parent_rate, isc_clk->div + 1);
209}
210
211static int isc_clk_determine_rate(struct clk_hw *hw,
212 struct clk_rate_request *req)
213{
214 struct isc_clk *isc_clk = to_isc_clk(hw);
215 long best_rate = -EINVAL;
216 int best_diff = -1;
217 unsigned int i, div;
218
219 for (i = 0; i < clk_hw_get_num_parents(hw); i++) {
220 struct clk_hw *parent;
221 unsigned long parent_rate;
222
223 parent = clk_hw_get_parent_by_index(hw, i);
224 if (!parent)
225 continue;
226
227 parent_rate = clk_hw_get_rate(parent);
228 if (!parent_rate)
229 continue;
230
231 for (div = 1; div < ISC_CLK_MAX_DIV + 2; div++) {
232 unsigned long rate;
233 int diff;
234
235 rate = DIV_ROUND_CLOSEST(parent_rate, div);
236 diff = abs(req->rate - rate);
237
238 if (best_diff < 0 || best_diff > diff) {
239 best_rate = rate;
240 best_diff = diff;
241 req->best_parent_rate = parent_rate;
242 req->best_parent_hw = parent;
243 }
244
245 if (!best_diff || rate < req->rate)
246 break;
247 }
248
249 if (!best_diff)
250 break;
251 }
252
253 dev_dbg(isc_clk->dev,
254 "ISC CLK: %s, best_rate = %ld, parent clk: %s @ %ld\n",
255 __func__, best_rate,
256 __clk_get_name((req->best_parent_hw)->clk),
257 req->best_parent_rate);
258
259 if (best_rate < 0)
260 return best_rate;
261
262 req->rate = best_rate;
263
264 return 0;
265}
266
267static int isc_clk_set_parent(struct clk_hw *hw, u8 index)
268{
269 struct isc_clk *isc_clk = to_isc_clk(hw);
270
271 if (index >= clk_hw_get_num_parents(hw))
272 return -EINVAL;
273
274 isc_clk->parent_id = index;
275
276 return 0;
277}
278
279static u8 isc_clk_get_parent(struct clk_hw *hw)
280{
281 struct isc_clk *isc_clk = to_isc_clk(hw);
282
283 return isc_clk->parent_id;
284}
285
286static int isc_clk_set_rate(struct clk_hw *hw,
287 unsigned long rate,
288 unsigned long parent_rate)
289{
290 struct isc_clk *isc_clk = to_isc_clk(hw);
291 u32 div;
292
293 if (!rate)
294 return -EINVAL;
295
296 div = DIV_ROUND_CLOSEST(parent_rate, rate);
297 if (div > (ISC_CLK_MAX_DIV + 1) || !div)
298 return -EINVAL;
299
300 isc_clk->div = div - 1;
301
302 return 0;
303}
304
305static const struct clk_ops isc_clk_ops = {
306 .prepare = isc_clk_prepare,
307 .unprepare = isc_clk_unprepare,
308 .enable = isc_clk_enable,
309 .disable = isc_clk_disable,
310 .is_enabled = isc_clk_is_enabled,
311 .recalc_rate = isc_clk_recalc_rate,
312 .determine_rate = isc_clk_determine_rate,
313 .set_parent = isc_clk_set_parent,
314 .get_parent = isc_clk_get_parent,
315 .set_rate = isc_clk_set_rate,
316};
317
318static int isc_clk_register(struct isc_device *isc, unsigned int id)
319{
320 struct regmap *regmap = isc->regmap;
321 struct device_node *np = isc->dev->of_node;
322 struct isc_clk *isc_clk;
323 struct clk_init_data init;
324 const char *clk_name = np->name;
325 const char *parent_names[3];
326 int num_parents;
327
328 num_parents = of_clk_get_parent_count(np);
329 if (num_parents < 1 || num_parents > 3)
330 return -EINVAL;
331
332 if (num_parents > 2 && id == ISC_ISPCK)
333 num_parents = 2;
334
335 of_clk_parent_fill(np, parent_names, num_parents);
336
337 if (id == ISC_MCK)
338 of_property_read_string(np, "clock-output-names", &clk_name);
339 else
340 clk_name = "isc-ispck";
341
342 init.parent_names = parent_names;
343 init.num_parents = num_parents;
344 init.name = clk_name;
345 init.ops = &isc_clk_ops;
346 init.flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE;
347
348 isc_clk = &isc->isc_clks[id];
349 isc_clk->hw.init = &init;
350 isc_clk->regmap = regmap;
351 isc_clk->id = id;
352 isc_clk->dev = isc->dev;
353 spin_lock_init(&isc_clk->lock);
354
355 isc_clk->clk = clk_register(isc->dev, &isc_clk->hw);
356 if (IS_ERR(isc_clk->clk)) {
357 dev_err(isc->dev, "%s: clock register fail\n", clk_name);
358 return PTR_ERR(isc_clk->clk);
359 } else if (id == ISC_MCK)
360 of_clk_add_provider(np, of_clk_src_simple_get, isc_clk->clk);
361
362 return 0;
363}
364
365int isc_clk_init(struct isc_device *isc)
366{
367 unsigned int i;
368 int ret;
369
370 for (i = 0; i < ARRAY_SIZE(isc->isc_clks); i++)
371 isc->isc_clks[i].clk = ERR_PTR(-EINVAL);
372
373 for (i = 0; i < ARRAY_SIZE(isc->isc_clks); i++) {
374 ret = isc_clk_register(isc, i);
375 if (ret)
376 return ret;
377 }
378
379 return 0;
380}
381EXPORT_SYMBOL_GPL(isc_clk_init);
382
383void isc_clk_cleanup(struct isc_device *isc)
384{
385 unsigned int i;
386
387 of_clk_del_provider(isc->dev->of_node);
388
389 for (i = 0; i < ARRAY_SIZE(isc->isc_clks); i++) {
390 struct isc_clk *isc_clk = &isc->isc_clks[i];
391
392 if (!IS_ERR(isc_clk->clk))
393 clk_unregister(isc_clk->clk);
394 }
395}
396EXPORT_SYMBOL_GPL(isc_clk_cleanup);
397
398static int isc_queue_setup(struct vb2_queue *vq,
399 unsigned int *nbuffers, unsigned int *nplanes,
400 unsigned int sizes[], struct device *alloc_devs[])
401{
402 struct isc_device *isc = vb2_get_drv_priv(vq);
403 unsigned int size = isc->fmt.fmt.pix.sizeimage;
404
405 if (*nplanes)
406 return sizes[0] < size ? -EINVAL : 0;
407
408 *nplanes = 1;
409 sizes[0] = size;
410
411 return 0;
412}
413
414static int isc_buffer_prepare(struct vb2_buffer *vb)
415{
416 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
417 struct isc_device *isc = vb2_get_drv_priv(vb->vb2_queue);
418 unsigned long size = isc->fmt.fmt.pix.sizeimage;
419
420 if (vb2_plane_size(vb, 0) < size) {
421 v4l2_err(&isc->v4l2_dev, "buffer too small (%lu < %lu)\n",
422 vb2_plane_size(vb, 0), size);
423 return -EINVAL;
424 }
425
426 vb2_set_plane_payload(vb, 0, size);
427
428 vbuf->field = isc->fmt.fmt.pix.field;
429
430 return 0;
431}
432
433static void isc_start_dma(struct isc_device *isc)
434{
435 struct regmap *regmap = isc->regmap;
436 u32 sizeimage = isc->fmt.fmt.pix.sizeimage;
437 u32 dctrl_dview;
438 dma_addr_t addr0;
439 u32 h, w;
440
441 h = isc->fmt.fmt.pix.height;
442 w = isc->fmt.fmt.pix.width;
443
444
445
446
447
448
449
450 if (!ISC_IS_FORMAT_RAW(isc->config.sd_format->mbus_code)) {
451 h <<= 1;
452 w <<= 1;
453 }
454
455
456
457
458
459
460
461
462 regmap_write(regmap, ISC_PFE_CFG1,
463 (ISC_PFE_CFG1_COLMIN(0) & ISC_PFE_CFG1_COLMIN_MASK) |
464 (ISC_PFE_CFG1_COLMAX(w - 1) & ISC_PFE_CFG1_COLMAX_MASK));
465
466 regmap_write(regmap, ISC_PFE_CFG2,
467 (ISC_PFE_CFG2_ROWMIN(0) & ISC_PFE_CFG2_ROWMIN_MASK) |
468 (ISC_PFE_CFG2_ROWMAX(h - 1) & ISC_PFE_CFG2_ROWMAX_MASK));
469
470 regmap_update_bits(regmap, ISC_PFE_CFG0,
471 ISC_PFE_CFG0_COLEN | ISC_PFE_CFG0_ROWEN,
472 ISC_PFE_CFG0_COLEN | ISC_PFE_CFG0_ROWEN);
473
474 addr0 = vb2_dma_contig_plane_dma_addr(&isc->cur_frm->vb.vb2_buf, 0);
475 regmap_write(regmap, ISC_DAD0 + isc->offsets.dma, addr0);
476
477 switch (isc->config.fourcc) {
478 case V4L2_PIX_FMT_YUV420:
479 regmap_write(regmap, ISC_DAD1 + isc->offsets.dma,
480 addr0 + (sizeimage * 2) / 3);
481 regmap_write(regmap, ISC_DAD2 + isc->offsets.dma,
482 addr0 + (sizeimage * 5) / 6);
483 break;
484 case V4L2_PIX_FMT_YUV422P:
485 regmap_write(regmap, ISC_DAD1 + isc->offsets.dma,
486 addr0 + sizeimage / 2);
487 regmap_write(regmap, ISC_DAD2 + isc->offsets.dma,
488 addr0 + (sizeimage * 3) / 4);
489 break;
490 default:
491 break;
492 }
493
494 dctrl_dview = isc->config.dctrl_dview;
495
496 regmap_write(regmap, ISC_DCTRL + isc->offsets.dma,
497 dctrl_dview | ISC_DCTRL_IE_IS);
498 spin_lock(&isc->awb_lock);
499 regmap_write(regmap, ISC_CTRLEN, ISC_CTRL_CAPTURE);
500 spin_unlock(&isc->awb_lock);
501}
502
503static void isc_set_pipeline(struct isc_device *isc, u32 pipeline)
504{
505 struct regmap *regmap = isc->regmap;
506 struct isc_ctrls *ctrls = &isc->ctrls;
507 u32 val, bay_cfg;
508 const u32 *gamma;
509 unsigned int i;
510
511
512 for (i = 0; i < ISC_PIPE_LINE_NODE_NUM; i++) {
513 val = pipeline & BIT(i) ? 1 : 0;
514 regmap_field_write(isc->pipeline[i], val);
515 }
516
517 if (!pipeline)
518 return;
519
520 bay_cfg = isc->config.sd_format->cfa_baycfg;
521
522 regmap_write(regmap, ISC_WB_CFG, bay_cfg);
523 isc_update_awb_ctrls(isc);
524 isc_update_v4l2_ctrls(isc);
525
526 regmap_write(regmap, ISC_CFA_CFG, bay_cfg | ISC_CFA_CFG_EITPOL);
527
528 gamma = &isc->gamma_table[ctrls->gamma_index][0];
529 regmap_bulk_write(regmap, ISC_GAM_BENTRY, gamma, GAMMA_ENTRIES);
530 regmap_bulk_write(regmap, ISC_GAM_GENTRY, gamma, GAMMA_ENTRIES);
531 regmap_bulk_write(regmap, ISC_GAM_RENTRY, gamma, GAMMA_ENTRIES);
532
533 isc->config_dpc(isc);
534 isc->config_csc(isc);
535 isc->config_cbc(isc);
536 isc->config_cc(isc);
537 isc->config_gam(isc);
538}
539
540static int isc_update_profile(struct isc_device *isc)
541{
542 struct regmap *regmap = isc->regmap;
543 u32 sr;
544 int counter = 100;
545
546 regmap_write(regmap, ISC_CTRLEN, ISC_CTRL_UPPRO);
547
548 regmap_read(regmap, ISC_CTRLSR, &sr);
549 while ((sr & ISC_CTRL_UPPRO) && counter--) {
550 usleep_range(1000, 2000);
551 regmap_read(regmap, ISC_CTRLSR, &sr);
552 }
553
554 if (counter < 0) {
555 v4l2_warn(&isc->v4l2_dev, "Time out to update profile\n");
556 return -ETIMEDOUT;
557 }
558
559 return 0;
560}
561
562static void isc_set_histogram(struct isc_device *isc, bool enable)
563{
564 struct regmap *regmap = isc->regmap;
565 struct isc_ctrls *ctrls = &isc->ctrls;
566
567 if (enable) {
568 regmap_write(regmap, ISC_HIS_CFG + isc->offsets.his,
569 ISC_HIS_CFG_MODE_GR |
570 (isc->config.sd_format->cfa_baycfg
571 << ISC_HIS_CFG_BAYSEL_SHIFT) |
572 ISC_HIS_CFG_RAR);
573 regmap_write(regmap, ISC_HIS_CTRL + isc->offsets.his,
574 ISC_HIS_CTRL_EN);
575 regmap_write(regmap, ISC_INTEN, ISC_INT_HISDONE);
576 ctrls->hist_id = ISC_HIS_CFG_MODE_GR;
577 isc_update_profile(isc);
578 regmap_write(regmap, ISC_CTRLEN, ISC_CTRL_HISREQ);
579
580 ctrls->hist_stat = HIST_ENABLED;
581 } else {
582 regmap_write(regmap, ISC_INTDIS, ISC_INT_HISDONE);
583 regmap_write(regmap, ISC_HIS_CTRL + isc->offsets.his,
584 ISC_HIS_CTRL_DIS);
585
586 ctrls->hist_stat = HIST_DISABLED;
587 }
588}
589
590static int isc_configure(struct isc_device *isc)
591{
592 struct regmap *regmap = isc->regmap;
593 u32 pfe_cfg0, dcfg, mask, pipeline;
594 struct isc_subdev_entity *subdev = isc->current_subdev;
595
596 pfe_cfg0 = isc->config.sd_format->pfe_cfg0_bps;
597 pipeline = isc->config.bits_pipeline;
598
599 dcfg = isc->config.dcfg_imode | isc->dcfg;
600
601 pfe_cfg0 |= subdev->pfe_cfg0 | ISC_PFE_CFG0_MODE_PROGRESSIVE;
602 mask = ISC_PFE_CFG0_BPS_MASK | ISC_PFE_CFG0_HPOL_LOW |
603 ISC_PFE_CFG0_VPOL_LOW | ISC_PFE_CFG0_PPOL_LOW |
604 ISC_PFE_CFG0_MODE_MASK | ISC_PFE_CFG0_CCIR_CRC |
605 ISC_PFE_CFG0_CCIR656 | ISC_PFE_CFG0_MIPI;
606
607 regmap_update_bits(regmap, ISC_PFE_CFG0, mask, pfe_cfg0);
608
609 isc->config_rlp(isc);
610
611 regmap_write(regmap, ISC_DCFG + isc->offsets.dma, dcfg);
612
613
614 isc_set_pipeline(isc, pipeline);
615
616
617
618
619
620 if (isc->ctrls.awb &&
621 ISC_IS_FORMAT_RAW(isc->config.sd_format->mbus_code))
622 isc_set_histogram(isc, true);
623 else
624 isc_set_histogram(isc, false);
625
626
627 return isc_update_profile(isc);
628}
629
630static int isc_start_streaming(struct vb2_queue *vq, unsigned int count)
631{
632 struct isc_device *isc = vb2_get_drv_priv(vq);
633 struct regmap *regmap = isc->regmap;
634 struct isc_buffer *buf;
635 unsigned long flags;
636 int ret;
637
638
639 ret = v4l2_subdev_call(isc->current_subdev->sd, video, s_stream, 1);
640 if (ret && ret != -ENOIOCTLCMD) {
641 v4l2_err(&isc->v4l2_dev, "stream on failed in subdev %d\n",
642 ret);
643 goto err_start_stream;
644 }
645
646 ret = pm_runtime_resume_and_get(isc->dev);
647 if (ret < 0) {
648 v4l2_err(&isc->v4l2_dev, "RPM resume failed in subdev %d\n",
649 ret);
650 goto err_pm_get;
651 }
652
653 ret = isc_configure(isc);
654 if (unlikely(ret))
655 goto err_configure;
656
657
658 regmap_write(regmap, ISC_INTEN, ISC_INT_DDONE);
659
660 spin_lock_irqsave(&isc->dma_queue_lock, flags);
661
662 isc->sequence = 0;
663 isc->stop = false;
664 reinit_completion(&isc->comp);
665
666 isc->cur_frm = list_first_entry(&isc->dma_queue,
667 struct isc_buffer, list);
668 list_del(&isc->cur_frm->list);
669
670 isc_start_dma(isc);
671
672 spin_unlock_irqrestore(&isc->dma_queue_lock, flags);
673
674
675 if (ISC_IS_FORMAT_RAW(isc->config.sd_format->mbus_code))
676 v4l2_ctrl_activate(isc->do_wb_ctrl, true);
677
678 return 0;
679
680err_configure:
681 pm_runtime_put_sync(isc->dev);
682err_pm_get:
683 v4l2_subdev_call(isc->current_subdev->sd, video, s_stream, 0);
684
685err_start_stream:
686 spin_lock_irqsave(&isc->dma_queue_lock, flags);
687 list_for_each_entry(buf, &isc->dma_queue, list)
688 vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_QUEUED);
689 INIT_LIST_HEAD(&isc->dma_queue);
690 spin_unlock_irqrestore(&isc->dma_queue_lock, flags);
691
692 return ret;
693}
694
695static void isc_stop_streaming(struct vb2_queue *vq)
696{
697 struct isc_device *isc = vb2_get_drv_priv(vq);
698 unsigned long flags;
699 struct isc_buffer *buf;
700 int ret;
701
702 v4l2_ctrl_activate(isc->do_wb_ctrl, false);
703
704 isc->stop = true;
705
706
707 if (isc->cur_frm && !wait_for_completion_timeout(&isc->comp, 5 * HZ))
708 v4l2_err(&isc->v4l2_dev,
709 "Timeout waiting for end of the capture\n");
710
711
712 regmap_write(isc->regmap, ISC_INTDIS, ISC_INT_DDONE);
713
714 pm_runtime_put_sync(isc->dev);
715
716
717 ret = v4l2_subdev_call(isc->current_subdev->sd, video, s_stream, 0);
718 if (ret && ret != -ENOIOCTLCMD)
719 v4l2_err(&isc->v4l2_dev, "stream off failed in subdev\n");
720
721
722 spin_lock_irqsave(&isc->dma_queue_lock, flags);
723 if (unlikely(isc->cur_frm)) {
724 vb2_buffer_done(&isc->cur_frm->vb.vb2_buf,
725 VB2_BUF_STATE_ERROR);
726 isc->cur_frm = NULL;
727 }
728 list_for_each_entry(buf, &isc->dma_queue, list)
729 vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
730 INIT_LIST_HEAD(&isc->dma_queue);
731 spin_unlock_irqrestore(&isc->dma_queue_lock, flags);
732}
733
734static void isc_buffer_queue(struct vb2_buffer *vb)
735{
736 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
737 struct isc_buffer *buf = container_of(vbuf, struct isc_buffer, vb);
738 struct isc_device *isc = vb2_get_drv_priv(vb->vb2_queue);
739 unsigned long flags;
740
741 spin_lock_irqsave(&isc->dma_queue_lock, flags);
742 if (!isc->cur_frm && list_empty(&isc->dma_queue) &&
743 vb2_is_streaming(vb->vb2_queue)) {
744 isc->cur_frm = buf;
745 isc_start_dma(isc);
746 } else
747 list_add_tail(&buf->list, &isc->dma_queue);
748 spin_unlock_irqrestore(&isc->dma_queue_lock, flags);
749}
750
751static struct isc_format *find_format_by_fourcc(struct isc_device *isc,
752 unsigned int fourcc)
753{
754 unsigned int num_formats = isc->num_user_formats;
755 struct isc_format *fmt;
756 unsigned int i;
757
758 for (i = 0; i < num_formats; i++) {
759 fmt = isc->user_formats[i];
760 if (fmt->fourcc == fourcc)
761 return fmt;
762 }
763
764 return NULL;
765}
766
767static const struct vb2_ops isc_vb2_ops = {
768 .queue_setup = isc_queue_setup,
769 .wait_prepare = vb2_ops_wait_prepare,
770 .wait_finish = vb2_ops_wait_finish,
771 .buf_prepare = isc_buffer_prepare,
772 .start_streaming = isc_start_streaming,
773 .stop_streaming = isc_stop_streaming,
774 .buf_queue = isc_buffer_queue,
775};
776
777static int isc_querycap(struct file *file, void *priv,
778 struct v4l2_capability *cap)
779{
780 struct isc_device *isc = video_drvdata(file);
781
782 strscpy(cap->driver, "microchip-isc", sizeof(cap->driver));
783 strscpy(cap->card, "Atmel Image Sensor Controller", sizeof(cap->card));
784 snprintf(cap->bus_info, sizeof(cap->bus_info),
785 "platform:%s", isc->v4l2_dev.name);
786
787 return 0;
788}
789
790static int isc_enum_fmt_vid_cap(struct file *file, void *priv,
791 struct v4l2_fmtdesc *f)
792{
793 struct isc_device *isc = video_drvdata(file);
794 u32 index = f->index;
795 u32 i, supported_index;
796
797 if (index < isc->controller_formats_size) {
798 f->pixelformat = isc->controller_formats[index].fourcc;
799 return 0;
800 }
801
802 index -= isc->controller_formats_size;
803
804 supported_index = 0;
805
806 for (i = 0; i < isc->formats_list_size; i++) {
807 if (!ISC_IS_FORMAT_RAW(isc->formats_list[i].mbus_code) ||
808 !isc->formats_list[i].sd_support)
809 continue;
810 if (supported_index == index) {
811 f->pixelformat = isc->formats_list[i].fourcc;
812 return 0;
813 }
814 supported_index++;
815 }
816
817 return -EINVAL;
818}
819
820static int isc_g_fmt_vid_cap(struct file *file, void *priv,
821 struct v4l2_format *fmt)
822{
823 struct isc_device *isc = video_drvdata(file);
824
825 *fmt = isc->fmt;
826
827 return 0;
828}
829
830
831
832
833
834static int isc_try_validate_formats(struct isc_device *isc)
835{
836 int ret;
837 bool bayer = false, yuv = false, rgb = false, grey = false;
838
839
840 switch (isc->try_config.fourcc) {
841 case V4L2_PIX_FMT_SBGGR8:
842 case V4L2_PIX_FMT_SGBRG8:
843 case V4L2_PIX_FMT_SGRBG8:
844 case V4L2_PIX_FMT_SRGGB8:
845 case V4L2_PIX_FMT_SBGGR10:
846 case V4L2_PIX_FMT_SGBRG10:
847 case V4L2_PIX_FMT_SGRBG10:
848 case V4L2_PIX_FMT_SRGGB10:
849 case V4L2_PIX_FMT_SBGGR12:
850 case V4L2_PIX_FMT_SGBRG12:
851 case V4L2_PIX_FMT_SGRBG12:
852 case V4L2_PIX_FMT_SRGGB12:
853 ret = 0;
854 bayer = true;
855 break;
856
857 case V4L2_PIX_FMT_YUV420:
858 case V4L2_PIX_FMT_YUV422P:
859 case V4L2_PIX_FMT_YUYV:
860 case V4L2_PIX_FMT_UYVY:
861 case V4L2_PIX_FMT_VYUY:
862 ret = 0;
863 yuv = true;
864 break;
865
866 case V4L2_PIX_FMT_RGB565:
867 case V4L2_PIX_FMT_ABGR32:
868 case V4L2_PIX_FMT_XBGR32:
869 case V4L2_PIX_FMT_ARGB444:
870 case V4L2_PIX_FMT_ARGB555:
871 ret = 0;
872 rgb = true;
873 break;
874 case V4L2_PIX_FMT_GREY:
875 case V4L2_PIX_FMT_Y10:
876 case V4L2_PIX_FMT_Y16:
877 ret = 0;
878 grey = true;
879 break;
880 default:
881
882 ret = -EINVAL;
883 }
884 v4l2_dbg(1, debug, &isc->v4l2_dev,
885 "Format validation, requested rgb=%u, yuv=%u, grey=%u, bayer=%u\n",
886 rgb, yuv, grey, bayer);
887
888
889 if ((bayer) && !ISC_IS_FORMAT_RAW(isc->try_config.sd_format->mbus_code))
890 return -EINVAL;
891
892
893 if (grey && !ISC_IS_FORMAT_RAW(isc->try_config.sd_format->mbus_code) &&
894 !ISC_IS_FORMAT_GREY(isc->try_config.sd_format->mbus_code))
895 return -EINVAL;
896
897 return ret;
898}
899
900
901
902
903
904
905static int isc_try_configure_rlp_dma(struct isc_device *isc, bool direct_dump)
906{
907 isc->try_config.rlp_cfg_mode = 0;
908
909 switch (isc->try_config.fourcc) {
910 case V4L2_PIX_FMT_SBGGR8:
911 case V4L2_PIX_FMT_SGBRG8:
912 case V4L2_PIX_FMT_SGRBG8:
913 case V4L2_PIX_FMT_SRGGB8:
914 isc->try_config.rlp_cfg_mode = ISC_RLP_CFG_MODE_DAT8;
915 isc->try_config.dcfg_imode = ISC_DCFG_IMODE_PACKED8;
916 isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PACKED;
917 isc->try_config.bpp = 8;
918 break;
919 case V4L2_PIX_FMT_SBGGR10:
920 case V4L2_PIX_FMT_SGBRG10:
921 case V4L2_PIX_FMT_SGRBG10:
922 case V4L2_PIX_FMT_SRGGB10:
923 isc->try_config.rlp_cfg_mode = ISC_RLP_CFG_MODE_DAT10;
924 isc->try_config.dcfg_imode = ISC_DCFG_IMODE_PACKED16;
925 isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PACKED;
926 isc->try_config.bpp = 16;
927 break;
928 case V4L2_PIX_FMT_SBGGR12:
929 case V4L2_PIX_FMT_SGBRG12:
930 case V4L2_PIX_FMT_SGRBG12:
931 case V4L2_PIX_FMT_SRGGB12:
932 isc->try_config.rlp_cfg_mode = ISC_RLP_CFG_MODE_DAT12;
933 isc->try_config.dcfg_imode = ISC_DCFG_IMODE_PACKED16;
934 isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PACKED;
935 isc->try_config.bpp = 16;
936 break;
937 case V4L2_PIX_FMT_RGB565:
938 isc->try_config.rlp_cfg_mode = ISC_RLP_CFG_MODE_RGB565;
939 isc->try_config.dcfg_imode = ISC_DCFG_IMODE_PACKED16;
940 isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PACKED;
941 isc->try_config.bpp = 16;
942 break;
943 case V4L2_PIX_FMT_ARGB444:
944 isc->try_config.rlp_cfg_mode = ISC_RLP_CFG_MODE_ARGB444;
945 isc->try_config.dcfg_imode = ISC_DCFG_IMODE_PACKED16;
946 isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PACKED;
947 isc->try_config.bpp = 16;
948 break;
949 case V4L2_PIX_FMT_ARGB555:
950 isc->try_config.rlp_cfg_mode = ISC_RLP_CFG_MODE_ARGB555;
951 isc->try_config.dcfg_imode = ISC_DCFG_IMODE_PACKED16;
952 isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PACKED;
953 isc->try_config.bpp = 16;
954 break;
955 case V4L2_PIX_FMT_ABGR32:
956 case V4L2_PIX_FMT_XBGR32:
957 isc->try_config.rlp_cfg_mode = ISC_RLP_CFG_MODE_ARGB32;
958 isc->try_config.dcfg_imode = ISC_DCFG_IMODE_PACKED32;
959 isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PACKED;
960 isc->try_config.bpp = 32;
961 break;
962 case V4L2_PIX_FMT_YUV420:
963 isc->try_config.rlp_cfg_mode = ISC_RLP_CFG_MODE_YYCC;
964 isc->try_config.dcfg_imode = ISC_DCFG_IMODE_YC420P;
965 isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PLANAR;
966 isc->try_config.bpp = 12;
967 break;
968 case V4L2_PIX_FMT_YUV422P:
969 isc->try_config.rlp_cfg_mode = ISC_RLP_CFG_MODE_YYCC;
970 isc->try_config.dcfg_imode = ISC_DCFG_IMODE_YC422P;
971 isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PLANAR;
972 isc->try_config.bpp = 16;
973 break;
974 case V4L2_PIX_FMT_YUYV:
975 isc->try_config.rlp_cfg_mode = ISC_RLP_CFG_MODE_YCYC | ISC_RLP_CFG_YMODE_YUYV;
976 isc->try_config.dcfg_imode = ISC_DCFG_IMODE_PACKED32;
977 isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PACKED;
978 isc->try_config.bpp = 16;
979 break;
980 case V4L2_PIX_FMT_UYVY:
981 isc->try_config.rlp_cfg_mode = ISC_RLP_CFG_MODE_YCYC | ISC_RLP_CFG_YMODE_UYVY;
982 isc->try_config.dcfg_imode = ISC_DCFG_IMODE_PACKED32;
983 isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PACKED;
984 isc->try_config.bpp = 16;
985 break;
986 case V4L2_PIX_FMT_VYUY:
987 isc->try_config.rlp_cfg_mode = ISC_RLP_CFG_MODE_YCYC | ISC_RLP_CFG_YMODE_VYUY;
988 isc->try_config.dcfg_imode = ISC_DCFG_IMODE_PACKED32;
989 isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PACKED;
990 isc->try_config.bpp = 16;
991 break;
992 case V4L2_PIX_FMT_GREY:
993 isc->try_config.rlp_cfg_mode = ISC_RLP_CFG_MODE_DATY8;
994 isc->try_config.dcfg_imode = ISC_DCFG_IMODE_PACKED8;
995 isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PACKED;
996 isc->try_config.bpp = 8;
997 break;
998 case V4L2_PIX_FMT_Y16:
999 isc->try_config.rlp_cfg_mode = ISC_RLP_CFG_MODE_DATY10 | ISC_RLP_CFG_LSH;
1000 fallthrough;
1001 case V4L2_PIX_FMT_Y10:
1002 isc->try_config.rlp_cfg_mode |= ISC_RLP_CFG_MODE_DATY10;
1003 isc->try_config.dcfg_imode = ISC_DCFG_IMODE_PACKED16;
1004 isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PACKED;
1005 isc->try_config.bpp = 16;
1006 break;
1007 default:
1008 return -EINVAL;
1009 }
1010
1011 if (direct_dump) {
1012 isc->try_config.rlp_cfg_mode = ISC_RLP_CFG_MODE_DAT8;
1013 isc->try_config.dcfg_imode = ISC_DCFG_IMODE_PACKED8;
1014 isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PACKED;
1015 return 0;
1016 }
1017
1018 return 0;
1019}
1020
1021
1022
1023
1024
1025static int isc_try_configure_pipeline(struct isc_device *isc)
1026{
1027 switch (isc->try_config.fourcc) {
1028 case V4L2_PIX_FMT_RGB565:
1029 case V4L2_PIX_FMT_ARGB555:
1030 case V4L2_PIX_FMT_ARGB444:
1031 case V4L2_PIX_FMT_ABGR32:
1032 case V4L2_PIX_FMT_XBGR32:
1033
1034 if (ISC_IS_FORMAT_RAW(isc->try_config.sd_format->mbus_code)) {
1035 isc->try_config.bits_pipeline = CFA_ENABLE |
1036 WB_ENABLE | GAM_ENABLES | DPC_BLCENABLE |
1037 CC_ENABLE;
1038 } else {
1039 isc->try_config.bits_pipeline = 0x0;
1040 }
1041 break;
1042 case V4L2_PIX_FMT_YUV420:
1043
1044 if (ISC_IS_FORMAT_RAW(isc->try_config.sd_format->mbus_code)) {
1045 isc->try_config.bits_pipeline = CFA_ENABLE |
1046 CSC_ENABLE | GAM_ENABLES | WB_ENABLE |
1047 SUB420_ENABLE | SUB422_ENABLE | CBC_ENABLE |
1048 DPC_BLCENABLE;
1049 } else {
1050 isc->try_config.bits_pipeline = 0x0;
1051 }
1052 break;
1053 case V4L2_PIX_FMT_YUV422P:
1054
1055 if (ISC_IS_FORMAT_RAW(isc->try_config.sd_format->mbus_code)) {
1056 isc->try_config.bits_pipeline = CFA_ENABLE |
1057 CSC_ENABLE | WB_ENABLE | GAM_ENABLES |
1058 SUB422_ENABLE | CBC_ENABLE | DPC_BLCENABLE;
1059 } else {
1060 isc->try_config.bits_pipeline = 0x0;
1061 }
1062 break;
1063 case V4L2_PIX_FMT_YUYV:
1064 case V4L2_PIX_FMT_UYVY:
1065 case V4L2_PIX_FMT_VYUY:
1066
1067 if (ISC_IS_FORMAT_RAW(isc->try_config.sd_format->mbus_code)) {
1068 isc->try_config.bits_pipeline = CFA_ENABLE |
1069 CSC_ENABLE | WB_ENABLE | GAM_ENABLES |
1070 SUB422_ENABLE | CBC_ENABLE | DPC_BLCENABLE;
1071 } else {
1072 isc->try_config.bits_pipeline = 0x0;
1073 }
1074 break;
1075 case V4L2_PIX_FMT_GREY:
1076 case V4L2_PIX_FMT_Y16:
1077
1078 if (ISC_IS_FORMAT_RAW(isc->try_config.sd_format->mbus_code)) {
1079 isc->try_config.bits_pipeline = CFA_ENABLE |
1080 CSC_ENABLE | WB_ENABLE | GAM_ENABLES |
1081 CBC_ENABLE | DPC_BLCENABLE;
1082 } else {
1083 isc->try_config.bits_pipeline = 0x0;
1084 }
1085 break;
1086 default:
1087 if (ISC_IS_FORMAT_RAW(isc->try_config.sd_format->mbus_code))
1088 isc->try_config.bits_pipeline = WB_ENABLE | DPC_BLCENABLE;
1089 else
1090 isc->try_config.bits_pipeline = 0x0;
1091 }
1092
1093
1094 isc->adapt_pipeline(isc);
1095
1096 return 0;
1097}
1098
1099static void isc_try_fse(struct isc_device *isc,
1100 struct v4l2_subdev_state *sd_state)
1101{
1102 int ret;
1103 struct v4l2_subdev_frame_size_enum fse = {};
1104
1105
1106
1107
1108
1109 if (!isc->try_config.sd_format)
1110 return;
1111
1112 fse.code = isc->try_config.sd_format->mbus_code;
1113 fse.which = V4L2_SUBDEV_FORMAT_TRY;
1114
1115 ret = v4l2_subdev_call(isc->current_subdev->sd, pad, enum_frame_size,
1116 sd_state, &fse);
1117
1118
1119
1120
1121 if (ret) {
1122 sd_state->pads->try_crop.width = isc->max_width;
1123 sd_state->pads->try_crop.height = isc->max_height;
1124 } else {
1125 sd_state->pads->try_crop.width = fse.max_width;
1126 sd_state->pads->try_crop.height = fse.max_height;
1127 }
1128}
1129
1130static int isc_try_fmt(struct isc_device *isc, struct v4l2_format *f,
1131 u32 *code)
1132{
1133 int i;
1134 struct isc_format *sd_fmt = NULL, *direct_fmt = NULL;
1135 struct v4l2_pix_format *pixfmt = &f->fmt.pix;
1136 struct v4l2_subdev_pad_config pad_cfg = {};
1137 struct v4l2_subdev_state pad_state = {
1138 .pads = &pad_cfg
1139 };
1140 struct v4l2_subdev_format format = {
1141 .which = V4L2_SUBDEV_FORMAT_TRY,
1142 };
1143 u32 mbus_code;
1144 int ret;
1145 bool rlp_dma_direct_dump = false;
1146
1147 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1148 return -EINVAL;
1149
1150
1151 for (i = 0; i < isc->num_user_formats; i++) {
1152 if (ISC_IS_FORMAT_RAW(isc->user_formats[i]->mbus_code)) {
1153 sd_fmt = isc->user_formats[i];
1154 break;
1155 }
1156 }
1157
1158
1159
1160 direct_fmt = find_format_by_fourcc(isc, pixfmt->pixelformat);
1161
1162
1163
1164
1165 if (direct_fmt && sd_fmt && sensor_preferred)
1166 sd_fmt = direct_fmt;
1167
1168
1169 if (direct_fmt && !sd_fmt)
1170 sd_fmt = direct_fmt;
1171
1172
1173
1174
1175 if (sd_fmt == direct_fmt)
1176 rlp_dma_direct_dump = true;
1177
1178
1179
1180
1181
1182 if (!sd_fmt && !direct_fmt) {
1183 sd_fmt = isc->user_formats[isc->num_user_formats - 1];
1184 v4l2_dbg(1, debug, &isc->v4l2_dev,
1185 "Sensor not supporting %.4s, using %.4s\n",
1186 (char *)&pixfmt->pixelformat, (char *)&sd_fmt->fourcc);
1187 }
1188
1189 if (!sd_fmt) {
1190 ret = -EINVAL;
1191 goto isc_try_fmt_err;
1192 }
1193
1194
1195 v4l2_dbg(1, debug, &isc->v4l2_dev,
1196 "Preferring to have sensor using format %.4s\n",
1197 (char *)&sd_fmt->fourcc);
1198
1199
1200 isc->try_config.sd_format = sd_fmt;
1201
1202
1203 if (pixfmt->width > isc->max_width)
1204 pixfmt->width = isc->max_width;
1205 if (pixfmt->height > isc->max_height)
1206 pixfmt->height = isc->max_height;
1207
1208
1209
1210
1211
1212 mbus_code = sd_fmt->mbus_code;
1213
1214
1215
1216
1217
1218 isc->try_config.fourcc = pixfmt->pixelformat;
1219
1220 if (isc_try_validate_formats(isc)) {
1221 pixfmt->pixelformat = isc->try_config.fourcc = sd_fmt->fourcc;
1222
1223 ret = isc_try_validate_formats(isc);
1224 if (ret)
1225 goto isc_try_fmt_err;
1226 }
1227
1228 ret = isc_try_configure_rlp_dma(isc, rlp_dma_direct_dump);
1229 if (ret)
1230 goto isc_try_fmt_err;
1231
1232 ret = isc_try_configure_pipeline(isc);
1233 if (ret)
1234 goto isc_try_fmt_err;
1235
1236
1237 isc_try_fse(isc, &pad_state);
1238
1239 v4l2_fill_mbus_format(&format.format, pixfmt, mbus_code);
1240 ret = v4l2_subdev_call(isc->current_subdev->sd, pad, set_fmt,
1241 &pad_state, &format);
1242 if (ret < 0)
1243 goto isc_try_fmt_subdev_err;
1244
1245 v4l2_fill_pix_format(pixfmt, &format.format);
1246
1247
1248 if (pixfmt->width > isc->max_width)
1249 pixfmt->width = isc->max_width;
1250 if (pixfmt->height > isc->max_height)
1251 pixfmt->height = isc->max_height;
1252
1253 pixfmt->field = V4L2_FIELD_NONE;
1254 pixfmt->bytesperline = (pixfmt->width * isc->try_config.bpp) >> 3;
1255 pixfmt->sizeimage = pixfmt->bytesperline * pixfmt->height;
1256
1257 if (code)
1258 *code = mbus_code;
1259
1260 return 0;
1261
1262isc_try_fmt_err:
1263 v4l2_err(&isc->v4l2_dev, "Could not find any possible format for a working pipeline\n");
1264isc_try_fmt_subdev_err:
1265 memset(&isc->try_config, 0, sizeof(isc->try_config));
1266
1267 return ret;
1268}
1269
1270static int isc_set_fmt(struct isc_device *isc, struct v4l2_format *f)
1271{
1272 struct v4l2_subdev_format format = {
1273 .which = V4L2_SUBDEV_FORMAT_ACTIVE,
1274 };
1275 u32 mbus_code = 0;
1276 int ret;
1277
1278 ret = isc_try_fmt(isc, f, &mbus_code);
1279 if (ret)
1280 return ret;
1281
1282 v4l2_fill_mbus_format(&format.format, &f->fmt.pix, mbus_code);
1283 ret = v4l2_subdev_call(isc->current_subdev->sd, pad,
1284 set_fmt, NULL, &format);
1285 if (ret < 0)
1286 return ret;
1287
1288
1289 if (f->fmt.pix.width > isc->max_width)
1290 f->fmt.pix.width = isc->max_width;
1291 if (f->fmt.pix.height > isc->max_height)
1292 f->fmt.pix.height = isc->max_height;
1293
1294 isc->fmt = *f;
1295
1296 if (isc->try_config.sd_format && isc->config.sd_format &&
1297 isc->try_config.sd_format != isc->config.sd_format) {
1298 isc->ctrls.hist_stat = HIST_INIT;
1299 isc_reset_awb_ctrls(isc);
1300 isc_update_v4l2_ctrls(isc);
1301 }
1302
1303 isc->config = isc->try_config;
1304
1305 v4l2_dbg(1, debug, &isc->v4l2_dev, "New ISC configuration in place\n");
1306
1307 return 0;
1308}
1309
1310static int isc_s_fmt_vid_cap(struct file *file, void *priv,
1311 struct v4l2_format *f)
1312{
1313 struct isc_device *isc = video_drvdata(file);
1314
1315 if (vb2_is_streaming(&isc->vb2_vidq))
1316 return -EBUSY;
1317
1318 return isc_set_fmt(isc, f);
1319}
1320
1321static int isc_try_fmt_vid_cap(struct file *file, void *priv,
1322 struct v4l2_format *f)
1323{
1324 struct isc_device *isc = video_drvdata(file);
1325
1326 return isc_try_fmt(isc, f, NULL);
1327}
1328
1329static int isc_enum_input(struct file *file, void *priv,
1330 struct v4l2_input *inp)
1331{
1332 if (inp->index != 0)
1333 return -EINVAL;
1334
1335 inp->type = V4L2_INPUT_TYPE_CAMERA;
1336 inp->std = 0;
1337 strscpy(inp->name, "Camera", sizeof(inp->name));
1338
1339 return 0;
1340}
1341
1342static int isc_g_input(struct file *file, void *priv, unsigned int *i)
1343{
1344 *i = 0;
1345
1346 return 0;
1347}
1348
1349static int isc_s_input(struct file *file, void *priv, unsigned int i)
1350{
1351 if (i > 0)
1352 return -EINVAL;
1353
1354 return 0;
1355}
1356
1357static int isc_g_parm(struct file *file, void *fh, struct v4l2_streamparm *a)
1358{
1359 struct isc_device *isc = video_drvdata(file);
1360
1361 return v4l2_g_parm_cap(video_devdata(file), isc->current_subdev->sd, a);
1362}
1363
1364static int isc_s_parm(struct file *file, void *fh, struct v4l2_streamparm *a)
1365{
1366 struct isc_device *isc = video_drvdata(file);
1367
1368 return v4l2_s_parm_cap(video_devdata(file), isc->current_subdev->sd, a);
1369}
1370
1371static int isc_enum_framesizes(struct file *file, void *fh,
1372 struct v4l2_frmsizeenum *fsize)
1373{
1374 struct isc_device *isc = video_drvdata(file);
1375 struct v4l2_subdev_frame_size_enum fse = {
1376 .code = isc->config.sd_format->mbus_code,
1377 .index = fsize->index,
1378 .which = V4L2_SUBDEV_FORMAT_ACTIVE,
1379 };
1380 int ret = -EINVAL;
1381 int i;
1382
1383 for (i = 0; i < isc->num_user_formats; i++)
1384 if (isc->user_formats[i]->fourcc == fsize->pixel_format)
1385 ret = 0;
1386
1387 for (i = 0; i < isc->controller_formats_size; i++)
1388 if (isc->controller_formats[i].fourcc == fsize->pixel_format)
1389 ret = 0;
1390
1391 if (ret)
1392 return ret;
1393
1394 ret = v4l2_subdev_call(isc->current_subdev->sd, pad, enum_frame_size,
1395 NULL, &fse);
1396 if (ret)
1397 return ret;
1398
1399 fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
1400 fsize->discrete.width = fse.max_width;
1401 fsize->discrete.height = fse.max_height;
1402
1403 return 0;
1404}
1405
1406static int isc_enum_frameintervals(struct file *file, void *fh,
1407 struct v4l2_frmivalenum *fival)
1408{
1409 struct isc_device *isc = video_drvdata(file);
1410 struct v4l2_subdev_frame_interval_enum fie = {
1411 .code = isc->config.sd_format->mbus_code,
1412 .index = fival->index,
1413 .width = fival->width,
1414 .height = fival->height,
1415 .which = V4L2_SUBDEV_FORMAT_ACTIVE,
1416 };
1417 int ret = -EINVAL;
1418 unsigned int i;
1419
1420 for (i = 0; i < isc->num_user_formats; i++)
1421 if (isc->user_formats[i]->fourcc == fival->pixel_format)
1422 ret = 0;
1423
1424 for (i = 0; i < isc->controller_formats_size; i++)
1425 if (isc->controller_formats[i].fourcc == fival->pixel_format)
1426 ret = 0;
1427
1428 if (ret)
1429 return ret;
1430
1431 ret = v4l2_subdev_call(isc->current_subdev->sd, pad,
1432 enum_frame_interval, NULL, &fie);
1433 if (ret)
1434 return ret;
1435
1436 fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
1437 fival->discrete = fie.interval;
1438
1439 return 0;
1440}
1441
1442static const struct v4l2_ioctl_ops isc_ioctl_ops = {
1443 .vidioc_querycap = isc_querycap,
1444 .vidioc_enum_fmt_vid_cap = isc_enum_fmt_vid_cap,
1445 .vidioc_g_fmt_vid_cap = isc_g_fmt_vid_cap,
1446 .vidioc_s_fmt_vid_cap = isc_s_fmt_vid_cap,
1447 .vidioc_try_fmt_vid_cap = isc_try_fmt_vid_cap,
1448
1449 .vidioc_enum_input = isc_enum_input,
1450 .vidioc_g_input = isc_g_input,
1451 .vidioc_s_input = isc_s_input,
1452
1453 .vidioc_reqbufs = vb2_ioctl_reqbufs,
1454 .vidioc_querybuf = vb2_ioctl_querybuf,
1455 .vidioc_qbuf = vb2_ioctl_qbuf,
1456 .vidioc_expbuf = vb2_ioctl_expbuf,
1457 .vidioc_dqbuf = vb2_ioctl_dqbuf,
1458 .vidioc_create_bufs = vb2_ioctl_create_bufs,
1459 .vidioc_prepare_buf = vb2_ioctl_prepare_buf,
1460 .vidioc_streamon = vb2_ioctl_streamon,
1461 .vidioc_streamoff = vb2_ioctl_streamoff,
1462
1463 .vidioc_g_parm = isc_g_parm,
1464 .vidioc_s_parm = isc_s_parm,
1465 .vidioc_enum_framesizes = isc_enum_framesizes,
1466 .vidioc_enum_frameintervals = isc_enum_frameintervals,
1467
1468 .vidioc_log_status = v4l2_ctrl_log_status,
1469 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
1470 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
1471};
1472
1473static int isc_open(struct file *file)
1474{
1475 struct isc_device *isc = video_drvdata(file);
1476 struct v4l2_subdev *sd = isc->current_subdev->sd;
1477 int ret;
1478
1479 if (mutex_lock_interruptible(&isc->lock))
1480 return -ERESTARTSYS;
1481
1482 ret = v4l2_fh_open(file);
1483 if (ret < 0)
1484 goto unlock;
1485
1486 if (!v4l2_fh_is_singular_file(file))
1487 goto unlock;
1488
1489 ret = v4l2_subdev_call(sd, core, s_power, 1);
1490 if (ret < 0 && ret != -ENOIOCTLCMD) {
1491 v4l2_fh_release(file);
1492 goto unlock;
1493 }
1494
1495 ret = isc_set_fmt(isc, &isc->fmt);
1496 if (ret) {
1497 v4l2_subdev_call(sd, core, s_power, 0);
1498 v4l2_fh_release(file);
1499 }
1500
1501unlock:
1502 mutex_unlock(&isc->lock);
1503 return ret;
1504}
1505
1506static int isc_release(struct file *file)
1507{
1508 struct isc_device *isc = video_drvdata(file);
1509 struct v4l2_subdev *sd = isc->current_subdev->sd;
1510 bool fh_singular;
1511 int ret;
1512
1513 mutex_lock(&isc->lock);
1514
1515 fh_singular = v4l2_fh_is_singular_file(file);
1516
1517 ret = _vb2_fop_release(file, NULL);
1518
1519 if (fh_singular)
1520 v4l2_subdev_call(sd, core, s_power, 0);
1521
1522 mutex_unlock(&isc->lock);
1523
1524 return ret;
1525}
1526
1527static const struct v4l2_file_operations isc_fops = {
1528 .owner = THIS_MODULE,
1529 .open = isc_open,
1530 .release = isc_release,
1531 .unlocked_ioctl = video_ioctl2,
1532 .read = vb2_fop_read,
1533 .mmap = vb2_fop_mmap,
1534 .poll = vb2_fop_poll,
1535};
1536
1537irqreturn_t isc_interrupt(int irq, void *dev_id)
1538{
1539 struct isc_device *isc = (struct isc_device *)dev_id;
1540 struct regmap *regmap = isc->regmap;
1541 u32 isc_intsr, isc_intmask, pending;
1542 irqreturn_t ret = IRQ_NONE;
1543
1544 regmap_read(regmap, ISC_INTSR, &isc_intsr);
1545 regmap_read(regmap, ISC_INTMASK, &isc_intmask);
1546
1547 pending = isc_intsr & isc_intmask;
1548
1549 if (likely(pending & ISC_INT_DDONE)) {
1550 spin_lock(&isc->dma_queue_lock);
1551 if (isc->cur_frm) {
1552 struct vb2_v4l2_buffer *vbuf = &isc->cur_frm->vb;
1553 struct vb2_buffer *vb = &vbuf->vb2_buf;
1554
1555 vb->timestamp = ktime_get_ns();
1556 vbuf->sequence = isc->sequence++;
1557 vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
1558 isc->cur_frm = NULL;
1559 }
1560
1561 if (!list_empty(&isc->dma_queue) && !isc->stop) {
1562 isc->cur_frm = list_first_entry(&isc->dma_queue,
1563 struct isc_buffer, list);
1564 list_del(&isc->cur_frm->list);
1565
1566 isc_start_dma(isc);
1567 }
1568
1569 if (isc->stop)
1570 complete(&isc->comp);
1571
1572 ret = IRQ_HANDLED;
1573 spin_unlock(&isc->dma_queue_lock);
1574 }
1575
1576 if (pending & ISC_INT_HISDONE) {
1577 schedule_work(&isc->awb_work);
1578 ret = IRQ_HANDLED;
1579 }
1580
1581 return ret;
1582}
1583EXPORT_SYMBOL_GPL(isc_interrupt);
1584
1585static void isc_hist_count(struct isc_device *isc, u32 *min, u32 *max)
1586{
1587 struct regmap *regmap = isc->regmap;
1588 struct isc_ctrls *ctrls = &isc->ctrls;
1589 u32 *hist_count = &ctrls->hist_count[ctrls->hist_id];
1590 u32 *hist_entry = &ctrls->hist_entry[0];
1591 u32 i;
1592
1593 *min = 0;
1594 *max = HIST_ENTRIES;
1595
1596 regmap_bulk_read(regmap, ISC_HIS_ENTRY + isc->offsets.his_entry,
1597 hist_entry, HIST_ENTRIES);
1598
1599 *hist_count = 0;
1600
1601
1602
1603
1604 for (i = 1; i < HIST_ENTRIES; i++) {
1605 if (*hist_entry && !*min)
1606 *min = i;
1607 if (*hist_entry)
1608 *max = i;
1609 *hist_count += i * (*hist_entry++);
1610 }
1611
1612 if (!*min)
1613 *min = 1;
1614}
1615
1616static void isc_wb_update(struct isc_ctrls *ctrls)
1617{
1618 u32 *hist_count = &ctrls->hist_count[0];
1619 u32 c, offset[4];
1620 u64 avg = 0;
1621
1622 u32 s_gain[4], gw_gain[4];
1623
1624
1625
1626
1627
1628
1629
1630 avg = (u64)hist_count[ISC_HIS_CFG_MODE_GR] +
1631 (u64)hist_count[ISC_HIS_CFG_MODE_GB];
1632 avg >>= 1;
1633
1634
1635 if (!avg)
1636 return;
1637
1638 for (c = ISC_HIS_CFG_MODE_GR; c <= ISC_HIS_CFG_MODE_B; c++) {
1639
1640
1641
1642
1643
1644 offset[c] = ctrls->hist_minmax[c][HIST_MIN_INDEX];
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654 ctrls->offset[c] = (offset[c] - 1) << 3;
1655
1656
1657
1658
1659
1660
1661 ctrls->offset[c] = -ctrls->offset[c];
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671 s_gain[c] = (HIST_ENTRIES << 9) /
1672 (ctrls->hist_minmax[c][HIST_MAX_INDEX] -
1673 ctrls->hist_minmax[c][HIST_MIN_INDEX] + 1);
1674
1675
1676
1677
1678
1679
1680
1681 if (hist_count[c])
1682 gw_gain[c] = div_u64(avg << 9, hist_count[c]);
1683 else
1684 gw_gain[c] = 1 << 9;
1685
1686
1687 ctrls->gain[c] = s_gain[c] * gw_gain[c];
1688 ctrls->gain[c] >>= 9;
1689 }
1690}
1691
1692static void isc_awb_work(struct work_struct *w)
1693{
1694 struct isc_device *isc =
1695 container_of(w, struct isc_device, awb_work);
1696 struct regmap *regmap = isc->regmap;
1697 struct isc_ctrls *ctrls = &isc->ctrls;
1698 u32 hist_id = ctrls->hist_id;
1699 u32 baysel;
1700 unsigned long flags;
1701 u32 min, max;
1702 int ret;
1703
1704
1705 if (isc->stop)
1706 return;
1707
1708 if (ctrls->hist_stat != HIST_ENABLED)
1709 return;
1710
1711 isc_hist_count(isc, &min, &max);
1712 ctrls->hist_minmax[hist_id][HIST_MIN_INDEX] = min;
1713 ctrls->hist_minmax[hist_id][HIST_MAX_INDEX] = max;
1714
1715 if (hist_id != ISC_HIS_CFG_MODE_B) {
1716 hist_id++;
1717 } else {
1718 isc_wb_update(ctrls);
1719 hist_id = ISC_HIS_CFG_MODE_GR;
1720 }
1721
1722 ctrls->hist_id = hist_id;
1723 baysel = isc->config.sd_format->cfa_baycfg << ISC_HIS_CFG_BAYSEL_SHIFT;
1724
1725 ret = pm_runtime_resume_and_get(isc->dev);
1726 if (ret < 0)
1727 return;
1728
1729
1730
1731
1732
1733 if (hist_id == ISC_HIS_CFG_MODE_GR || ctrls->awb == ISC_WB_NONE) {
1734
1735
1736
1737
1738
1739
1740 spin_lock_irqsave(&isc->awb_lock, flags);
1741 isc_update_awb_ctrls(isc);
1742 spin_unlock_irqrestore(&isc->awb_lock, flags);
1743
1744
1745
1746
1747
1748 if (ctrls->awb == ISC_WB_ONETIME) {
1749 v4l2_info(&isc->v4l2_dev,
1750 "Completed one time white-balance adjustment.\n");
1751
1752 isc_update_v4l2_ctrls(isc);
1753 ctrls->awb = ISC_WB_NONE;
1754 }
1755 }
1756 regmap_write(regmap, ISC_HIS_CFG + isc->offsets.his,
1757 hist_id | baysel | ISC_HIS_CFG_RAR);
1758 isc_update_profile(isc);
1759
1760 if (ctrls->awb)
1761 regmap_write(regmap, ISC_CTRLEN, ISC_CTRL_HISREQ);
1762
1763 pm_runtime_put_sync(isc->dev);
1764}
1765
1766static int isc_s_ctrl(struct v4l2_ctrl *ctrl)
1767{
1768 struct isc_device *isc = container_of(ctrl->handler,
1769 struct isc_device, ctrls.handler);
1770 struct isc_ctrls *ctrls = &isc->ctrls;
1771
1772 if (ctrl->flags & V4L2_CTRL_FLAG_INACTIVE)
1773 return 0;
1774
1775 switch (ctrl->id) {
1776 case V4L2_CID_BRIGHTNESS:
1777 ctrls->brightness = ctrl->val & ISC_CBC_BRIGHT_MASK;
1778 break;
1779 case V4L2_CID_CONTRAST:
1780 ctrls->contrast = ctrl->val & ISC_CBC_CONTRAST_MASK;
1781 break;
1782 case V4L2_CID_GAMMA:
1783 ctrls->gamma_index = ctrl->val;
1784 break;
1785 default:
1786 return -EINVAL;
1787 }
1788
1789 return 0;
1790}
1791
1792static const struct v4l2_ctrl_ops isc_ctrl_ops = {
1793 .s_ctrl = isc_s_ctrl,
1794};
1795
1796static int isc_s_awb_ctrl(struct v4l2_ctrl *ctrl)
1797{
1798 struct isc_device *isc = container_of(ctrl->handler,
1799 struct isc_device, ctrls.handler);
1800 struct isc_ctrls *ctrls = &isc->ctrls;
1801
1802 if (ctrl->flags & V4L2_CTRL_FLAG_INACTIVE)
1803 return 0;
1804
1805 switch (ctrl->id) {
1806 case V4L2_CID_AUTO_WHITE_BALANCE:
1807 if (ctrl->val == 1)
1808 ctrls->awb = ISC_WB_AUTO;
1809 else
1810 ctrls->awb = ISC_WB_NONE;
1811
1812
1813 if (!isc->config.sd_format)
1814 break;
1815
1816
1817 if (ctrl->cluster[ISC_CTRL_R_GAIN]->is_new)
1818 ctrls->gain[ISC_HIS_CFG_MODE_R] = isc->r_gain_ctrl->val;
1819 if (ctrl->cluster[ISC_CTRL_B_GAIN]->is_new)
1820 ctrls->gain[ISC_HIS_CFG_MODE_B] = isc->b_gain_ctrl->val;
1821 if (ctrl->cluster[ISC_CTRL_GR_GAIN]->is_new)
1822 ctrls->gain[ISC_HIS_CFG_MODE_GR] = isc->gr_gain_ctrl->val;
1823 if (ctrl->cluster[ISC_CTRL_GB_GAIN]->is_new)
1824 ctrls->gain[ISC_HIS_CFG_MODE_GB] = isc->gb_gain_ctrl->val;
1825
1826 if (ctrl->cluster[ISC_CTRL_R_OFF]->is_new)
1827 ctrls->offset[ISC_HIS_CFG_MODE_R] = isc->r_off_ctrl->val;
1828 if (ctrl->cluster[ISC_CTRL_B_OFF]->is_new)
1829 ctrls->offset[ISC_HIS_CFG_MODE_B] = isc->b_off_ctrl->val;
1830 if (ctrl->cluster[ISC_CTRL_GR_OFF]->is_new)
1831 ctrls->offset[ISC_HIS_CFG_MODE_GR] = isc->gr_off_ctrl->val;
1832 if (ctrl->cluster[ISC_CTRL_GB_OFF]->is_new)
1833 ctrls->offset[ISC_HIS_CFG_MODE_GB] = isc->gb_off_ctrl->val;
1834
1835 isc_update_awb_ctrls(isc);
1836
1837 if (vb2_is_streaming(&isc->vb2_vidq)) {
1838
1839
1840
1841
1842 isc_update_profile(isc);
1843 } else {
1844
1845
1846
1847
1848
1849 v4l2_ctrl_activate(isc->do_wb_ctrl, false);
1850 }
1851
1852
1853 if (ctrls->awb == ISC_WB_AUTO &&
1854 vb2_is_streaming(&isc->vb2_vidq) &&
1855 ISC_IS_FORMAT_RAW(isc->config.sd_format->mbus_code))
1856 isc_set_histogram(isc, true);
1857
1858
1859
1860
1861
1862 if (ctrls->awb == ISC_WB_NONE &&
1863 ctrl->cluster[ISC_CTRL_DO_WB]->is_new &&
1864 !(ctrl->cluster[ISC_CTRL_DO_WB]->flags &
1865 V4L2_CTRL_FLAG_INACTIVE)) {
1866 ctrls->awb = ISC_WB_ONETIME;
1867 isc_set_histogram(isc, true);
1868 v4l2_dbg(1, debug, &isc->v4l2_dev,
1869 "One time white-balance started.\n");
1870 }
1871 return 0;
1872 }
1873 return 0;
1874}
1875
1876static int isc_g_volatile_awb_ctrl(struct v4l2_ctrl *ctrl)
1877{
1878 struct isc_device *isc = container_of(ctrl->handler,
1879 struct isc_device, ctrls.handler);
1880 struct isc_ctrls *ctrls = &isc->ctrls;
1881
1882 switch (ctrl->id) {
1883
1884 case V4L2_CID_AUTO_WHITE_BALANCE:
1885 ctrl->cluster[ISC_CTRL_R_GAIN]->val =
1886 ctrls->gain[ISC_HIS_CFG_MODE_R];
1887 ctrl->cluster[ISC_CTRL_B_GAIN]->val =
1888 ctrls->gain[ISC_HIS_CFG_MODE_B];
1889 ctrl->cluster[ISC_CTRL_GR_GAIN]->val =
1890 ctrls->gain[ISC_HIS_CFG_MODE_GR];
1891 ctrl->cluster[ISC_CTRL_GB_GAIN]->val =
1892 ctrls->gain[ISC_HIS_CFG_MODE_GB];
1893
1894 ctrl->cluster[ISC_CTRL_R_OFF]->val =
1895 ctrls->offset[ISC_HIS_CFG_MODE_R];
1896 ctrl->cluster[ISC_CTRL_B_OFF]->val =
1897 ctrls->offset[ISC_HIS_CFG_MODE_B];
1898 ctrl->cluster[ISC_CTRL_GR_OFF]->val =
1899 ctrls->offset[ISC_HIS_CFG_MODE_GR];
1900 ctrl->cluster[ISC_CTRL_GB_OFF]->val =
1901 ctrls->offset[ISC_HIS_CFG_MODE_GB];
1902 break;
1903 }
1904 return 0;
1905}
1906
1907static const struct v4l2_ctrl_ops isc_awb_ops = {
1908 .s_ctrl = isc_s_awb_ctrl,
1909 .g_volatile_ctrl = isc_g_volatile_awb_ctrl,
1910};
1911
1912#define ISC_CTRL_OFF(_name, _id, _name_str) \
1913 static const struct v4l2_ctrl_config _name = { \
1914 .ops = &isc_awb_ops, \
1915 .id = _id, \
1916 .name = _name_str, \
1917 .type = V4L2_CTRL_TYPE_INTEGER, \
1918 .flags = V4L2_CTRL_FLAG_SLIDER, \
1919 .min = -4095, \
1920 .max = 4095, \
1921 .step = 1, \
1922 .def = 0, \
1923 }
1924
1925ISC_CTRL_OFF(isc_r_off_ctrl, ISC_CID_R_OFFSET, "Red Component Offset");
1926ISC_CTRL_OFF(isc_b_off_ctrl, ISC_CID_B_OFFSET, "Blue Component Offset");
1927ISC_CTRL_OFF(isc_gr_off_ctrl, ISC_CID_GR_OFFSET, "Green Red Component Offset");
1928ISC_CTRL_OFF(isc_gb_off_ctrl, ISC_CID_GB_OFFSET, "Green Blue Component Offset");
1929
1930#define ISC_CTRL_GAIN(_name, _id, _name_str) \
1931 static const struct v4l2_ctrl_config _name = { \
1932 .ops = &isc_awb_ops, \
1933 .id = _id, \
1934 .name = _name_str, \
1935 .type = V4L2_CTRL_TYPE_INTEGER, \
1936 .flags = V4L2_CTRL_FLAG_SLIDER, \
1937 .min = 0, \
1938 .max = 8191, \
1939 .step = 1, \
1940 .def = 512, \
1941 }
1942
1943ISC_CTRL_GAIN(isc_r_gain_ctrl, ISC_CID_R_GAIN, "Red Component Gain");
1944ISC_CTRL_GAIN(isc_b_gain_ctrl, ISC_CID_B_GAIN, "Blue Component Gain");
1945ISC_CTRL_GAIN(isc_gr_gain_ctrl, ISC_CID_GR_GAIN, "Green Red Component Gain");
1946ISC_CTRL_GAIN(isc_gb_gain_ctrl, ISC_CID_GB_GAIN, "Green Blue Component Gain");
1947
1948static int isc_ctrl_init(struct isc_device *isc)
1949{
1950 const struct v4l2_ctrl_ops *ops = &isc_ctrl_ops;
1951 struct isc_ctrls *ctrls = &isc->ctrls;
1952 struct v4l2_ctrl_handler *hdl = &ctrls->handler;
1953 int ret;
1954
1955 ctrls->hist_stat = HIST_INIT;
1956 isc_reset_awb_ctrls(isc);
1957
1958 ret = v4l2_ctrl_handler_init(hdl, 13);
1959 if (ret < 0)
1960 return ret;
1961
1962
1963 isc->config_ctrls(isc, ops);
1964
1965 ctrls->brightness = 0;
1966
1967 v4l2_ctrl_new_std(hdl, ops, V4L2_CID_BRIGHTNESS, -1024, 1023, 1, 0);
1968 v4l2_ctrl_new_std(hdl, ops, V4L2_CID_GAMMA, 0, isc->gamma_max, 1,
1969 isc->gamma_max);
1970 isc->awb_ctrl = v4l2_ctrl_new_std(hdl, &isc_awb_ops,
1971 V4L2_CID_AUTO_WHITE_BALANCE,
1972 0, 1, 1, 1);
1973
1974
1975 isc->do_wb_ctrl = v4l2_ctrl_new_std(hdl, &isc_awb_ops,
1976 V4L2_CID_DO_WHITE_BALANCE,
1977 0, 0, 0, 0);
1978
1979 if (!isc->do_wb_ctrl) {
1980 ret = hdl->error;
1981 v4l2_ctrl_handler_free(hdl);
1982 return ret;
1983 }
1984
1985 v4l2_ctrl_activate(isc->do_wb_ctrl, false);
1986
1987 isc->r_gain_ctrl = v4l2_ctrl_new_custom(hdl, &isc_r_gain_ctrl, NULL);
1988 isc->b_gain_ctrl = v4l2_ctrl_new_custom(hdl, &isc_b_gain_ctrl, NULL);
1989 isc->gr_gain_ctrl = v4l2_ctrl_new_custom(hdl, &isc_gr_gain_ctrl, NULL);
1990 isc->gb_gain_ctrl = v4l2_ctrl_new_custom(hdl, &isc_gb_gain_ctrl, NULL);
1991 isc->r_off_ctrl = v4l2_ctrl_new_custom(hdl, &isc_r_off_ctrl, NULL);
1992 isc->b_off_ctrl = v4l2_ctrl_new_custom(hdl, &isc_b_off_ctrl, NULL);
1993 isc->gr_off_ctrl = v4l2_ctrl_new_custom(hdl, &isc_gr_off_ctrl, NULL);
1994 isc->gb_off_ctrl = v4l2_ctrl_new_custom(hdl, &isc_gb_off_ctrl, NULL);
1995
1996
1997
1998
1999
2000 v4l2_ctrl_auto_cluster(10, &isc->awb_ctrl, 0, true);
2001
2002 v4l2_ctrl_handler_setup(hdl);
2003
2004 return 0;
2005}
2006
2007static int isc_async_bound(struct v4l2_async_notifier *notifier,
2008 struct v4l2_subdev *subdev,
2009 struct v4l2_async_subdev *asd)
2010{
2011 struct isc_device *isc = container_of(notifier->v4l2_dev,
2012 struct isc_device, v4l2_dev);
2013 struct isc_subdev_entity *subdev_entity =
2014 container_of(notifier, struct isc_subdev_entity, notifier);
2015
2016 if (video_is_registered(&isc->video_dev)) {
2017 v4l2_err(&isc->v4l2_dev, "only supports one sub-device.\n");
2018 return -EBUSY;
2019 }
2020
2021 subdev_entity->sd = subdev;
2022
2023 return 0;
2024}
2025
2026static void isc_async_unbind(struct v4l2_async_notifier *notifier,
2027 struct v4l2_subdev *subdev,
2028 struct v4l2_async_subdev *asd)
2029{
2030 struct isc_device *isc = container_of(notifier->v4l2_dev,
2031 struct isc_device, v4l2_dev);
2032 cancel_work_sync(&isc->awb_work);
2033 video_unregister_device(&isc->video_dev);
2034 v4l2_ctrl_handler_free(&isc->ctrls.handler);
2035}
2036
2037static struct isc_format *find_format_by_code(struct isc_device *isc,
2038 unsigned int code, int *index)
2039{
2040 struct isc_format *fmt = &isc->formats_list[0];
2041 unsigned int i;
2042
2043 for (i = 0; i < isc->formats_list_size; i++) {
2044 if (fmt->mbus_code == code) {
2045 *index = i;
2046 return fmt;
2047 }
2048
2049 fmt++;
2050 }
2051
2052 return NULL;
2053}
2054
2055static int isc_formats_init(struct isc_device *isc)
2056{
2057 struct isc_format *fmt;
2058 struct v4l2_subdev *subdev = isc->current_subdev->sd;
2059 unsigned int num_fmts, i, j;
2060 u32 list_size = isc->formats_list_size;
2061 struct v4l2_subdev_mbus_code_enum mbus_code = {
2062 .which = V4L2_SUBDEV_FORMAT_ACTIVE,
2063 };
2064
2065 num_fmts = 0;
2066 while (!v4l2_subdev_call(subdev, pad, enum_mbus_code,
2067 NULL, &mbus_code)) {
2068 mbus_code.index++;
2069
2070 fmt = find_format_by_code(isc, mbus_code.code, &i);
2071 if (!fmt) {
2072 v4l2_warn(&isc->v4l2_dev, "Mbus code %x not supported\n",
2073 mbus_code.code);
2074 continue;
2075 }
2076
2077 fmt->sd_support = true;
2078 num_fmts++;
2079 }
2080
2081 if (!num_fmts)
2082 return -ENXIO;
2083
2084 isc->num_user_formats = num_fmts;
2085 isc->user_formats = devm_kcalloc(isc->dev,
2086 num_fmts, sizeof(*isc->user_formats),
2087 GFP_KERNEL);
2088 if (!isc->user_formats)
2089 return -ENOMEM;
2090
2091 fmt = &isc->formats_list[0];
2092 for (i = 0, j = 0; i < list_size; i++) {
2093 if (fmt->sd_support)
2094 isc->user_formats[j++] = fmt;
2095 fmt++;
2096 }
2097
2098 return 0;
2099}
2100
2101static int isc_set_default_fmt(struct isc_device *isc)
2102{
2103 struct v4l2_format f = {
2104 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
2105 .fmt.pix = {
2106 .width = VGA_WIDTH,
2107 .height = VGA_HEIGHT,
2108 .field = V4L2_FIELD_NONE,
2109 .pixelformat = isc->user_formats[0]->fourcc,
2110 },
2111 };
2112 int ret;
2113
2114 ret = isc_try_fmt(isc, &f, NULL);
2115 if (ret)
2116 return ret;
2117
2118 isc->fmt = f;
2119 return 0;
2120}
2121
2122static int isc_async_complete(struct v4l2_async_notifier *notifier)
2123{
2124 struct isc_device *isc = container_of(notifier->v4l2_dev,
2125 struct isc_device, v4l2_dev);
2126 struct video_device *vdev = &isc->video_dev;
2127 struct vb2_queue *q = &isc->vb2_vidq;
2128 int ret = 0;
2129
2130 INIT_WORK(&isc->awb_work, isc_awb_work);
2131
2132 ret = v4l2_device_register_subdev_nodes(&isc->v4l2_dev);
2133 if (ret < 0) {
2134 v4l2_err(&isc->v4l2_dev, "Failed to register subdev nodes\n");
2135 return ret;
2136 }
2137
2138 isc->current_subdev = container_of(notifier,
2139 struct isc_subdev_entity, notifier);
2140 mutex_init(&isc->lock);
2141 init_completion(&isc->comp);
2142
2143
2144 q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2145 q->io_modes = VB2_MMAP | VB2_DMABUF | VB2_READ;
2146 q->drv_priv = isc;
2147 q->buf_struct_size = sizeof(struct isc_buffer);
2148 q->ops = &isc_vb2_ops;
2149 q->mem_ops = &vb2_dma_contig_memops;
2150 q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
2151 q->lock = &isc->lock;
2152 q->min_buffers_needed = 1;
2153 q->dev = isc->dev;
2154
2155 ret = vb2_queue_init(q);
2156 if (ret < 0) {
2157 v4l2_err(&isc->v4l2_dev,
2158 "vb2_queue_init() failed: %d\n", ret);
2159 goto isc_async_complete_err;
2160 }
2161
2162
2163 INIT_LIST_HEAD(&isc->dma_queue);
2164 spin_lock_init(&isc->dma_queue_lock);
2165 spin_lock_init(&isc->awb_lock);
2166
2167 ret = isc_formats_init(isc);
2168 if (ret < 0) {
2169 v4l2_err(&isc->v4l2_dev,
2170 "Init format failed: %d\n", ret);
2171 goto isc_async_complete_err;
2172 }
2173
2174 ret = isc_set_default_fmt(isc);
2175 if (ret) {
2176 v4l2_err(&isc->v4l2_dev, "Could not set default format\n");
2177 goto isc_async_complete_err;
2178 }
2179
2180 ret = isc_ctrl_init(isc);
2181 if (ret) {
2182 v4l2_err(&isc->v4l2_dev, "Init isc ctrols failed: %d\n", ret);
2183 goto isc_async_complete_err;
2184 }
2185
2186
2187 strscpy(vdev->name, "microchip-isc", sizeof(vdev->name));
2188 vdev->release = video_device_release_empty;
2189 vdev->fops = &isc_fops;
2190 vdev->ioctl_ops = &isc_ioctl_ops;
2191 vdev->v4l2_dev = &isc->v4l2_dev;
2192 vdev->vfl_dir = VFL_DIR_RX;
2193 vdev->queue = q;
2194 vdev->lock = &isc->lock;
2195 vdev->ctrl_handler = &isc->ctrls.handler;
2196 vdev->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_CAPTURE;
2197 video_set_drvdata(vdev, isc);
2198
2199 ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1);
2200 if (ret < 0) {
2201 v4l2_err(&isc->v4l2_dev,
2202 "video_register_device failed: %d\n", ret);
2203 goto isc_async_complete_err;
2204 }
2205
2206 return 0;
2207
2208isc_async_complete_err:
2209 mutex_destroy(&isc->lock);
2210 return ret;
2211}
2212
2213const struct v4l2_async_notifier_operations isc_async_ops = {
2214 .bound = isc_async_bound,
2215 .unbind = isc_async_unbind,
2216 .complete = isc_async_complete,
2217};
2218EXPORT_SYMBOL_GPL(isc_async_ops);
2219
2220void isc_subdev_cleanup(struct isc_device *isc)
2221{
2222 struct isc_subdev_entity *subdev_entity;
2223
2224 list_for_each_entry(subdev_entity, &isc->subdev_entities, list) {
2225 v4l2_async_notifier_unregister(&subdev_entity->notifier);
2226 v4l2_async_notifier_cleanup(&subdev_entity->notifier);
2227 }
2228
2229 INIT_LIST_HEAD(&isc->subdev_entities);
2230}
2231EXPORT_SYMBOL_GPL(isc_subdev_cleanup);
2232
2233int isc_pipeline_init(struct isc_device *isc)
2234{
2235 struct device *dev = isc->dev;
2236 struct regmap *regmap = isc->regmap;
2237 struct regmap_field *regs;
2238 unsigned int i;
2239
2240
2241
2242
2243
2244 const struct reg_field regfields[ISC_PIPE_LINE_NODE_NUM] = {
2245 REG_FIELD(ISC_DPC_CTRL, 0, 0),
2246 REG_FIELD(ISC_DPC_CTRL, 1, 1),
2247 REG_FIELD(ISC_DPC_CTRL, 2, 2),
2248 REG_FIELD(ISC_WB_CTRL, 0, 0),
2249 REG_FIELD(ISC_CFA_CTRL, 0, 0),
2250 REG_FIELD(ISC_CC_CTRL, 0, 0),
2251 REG_FIELD(ISC_GAM_CTRL, 0, 0),
2252 REG_FIELD(ISC_GAM_CTRL, 1, 1),
2253 REG_FIELD(ISC_GAM_CTRL, 2, 2),
2254 REG_FIELD(ISC_GAM_CTRL, 3, 3),
2255 REG_FIELD(ISC_VHXS_CTRL, 0, 0),
2256 REG_FIELD(ISC_CSC_CTRL + isc->offsets.csc, 0, 0),
2257 REG_FIELD(ISC_CBC_CTRL + isc->offsets.cbc, 0, 0),
2258 REG_FIELD(ISC_SUB422_CTRL + isc->offsets.sub422, 0, 0),
2259 REG_FIELD(ISC_SUB420_CTRL + isc->offsets.sub420, 0, 0),
2260 };
2261
2262 for (i = 0; i < ISC_PIPE_LINE_NODE_NUM; i++) {
2263 regs = devm_regmap_field_alloc(dev, regmap, regfields[i]);
2264 if (IS_ERR(regs))
2265 return PTR_ERR(regs);
2266
2267 isc->pipeline[i] = regs;
2268 }
2269
2270 return 0;
2271}
2272EXPORT_SYMBOL_GPL(isc_pipeline_init);
2273
2274
2275#define ATMEL_ISC_REG_MAX 0xd5c
2276const struct regmap_config isc_regmap_config = {
2277 .reg_bits = 32,
2278 .reg_stride = 4,
2279 .val_bits = 32,
2280 .max_register = ATMEL_ISC_REG_MAX,
2281};
2282EXPORT_SYMBOL_GPL(isc_regmap_config);
2283
2284MODULE_AUTHOR("Songjun Wu");
2285MODULE_AUTHOR("Eugen Hristev");
2286MODULE_DESCRIPTION("Atmel ISC common code base");
2287MODULE_LICENSE("GPL v2");
2288