1
2 /*
3 * vin.c for all v4l2 subdev manage
4 *
5 * Copyright (c) 2017 by Allwinnertech Co., Ltd. http://www.allwinnertech.com
6 *
7 * Authors: Zhao Wei <zhaowei@allwinnertech.com>
8 * Yang Feng <yangfeng@allwinnertech.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */
14
15 #include <linux/module.h>
16 #include <linux/errno.h>
17 #include <linux/kernel.h>
18 #include <linux/init.h>
19 #include <linux/sched.h>
20 #include <linux/slab.h>
21 #include <linux/version.h>
22 #include <linux/mutex.h>
23 #include <linux/videodev2.h>
24 #include <linux/delay.h>
25 #include <linux/string.h>
26 #include <linux/freezer.h>
27 #include <linux/reset.h>
28
29 #include <linux/io.h>
30 #include <linux/platform_device.h>
31 #include <linux/interrupt.h>
32 #include <linux/i2c.h>
33 #include <linux/spi/spi.h>
34 #include <linux/moduleparam.h>
35 #include <media/v4l2-device.h>
36 #include <media/v4l2-ioctl.h>
37 #include <media/v4l2-common.h>
38 #include <media/v4l2-mediabus.h>
39 #include <media/v4l2-subdev.h>
40 #include <media/videobuf2-dma-contig.h>
41
42 #include <linux/regulator/consumer.h>
43
44 #include "vin-cci/cci_helper.h"
45 #include "utility/config.h"
46 #include "modules/sensor/camera_cfg.h"
47 #include "utility/vin_io.h"
48 #include "modules/sensor/sensor_helper.h"
49 #include "vin.h"
50 #include "modules/sensor-list/sensor_list.h"
51
52 #define VIN_MODULE_NAME "sunxi-vin-media"
53
54 static char ccm0[I2C_NAME_SIZE] = "";
55 uint i2c0_addr = 0xff;
56 static char ccm1[I2C_NAME_SIZE] = "";
57 uint i2c1_addr = 0xff;
58
59 char act_name[I2C_NAME_SIZE] = "";
60 uint act_slave = 0xff;
61 uint use_sensor_list = 0xff;
62 uint ptn_on_cnt;
63 extern uint ptn_frame_cnt;
64
65 module_param_string(ccm0, ccm0, sizeof(ccm0), S_IRUGO | S_IWUSR);
66 module_param_string(ccm1, ccm1, sizeof(ccm1), S_IRUGO | S_IWUSR);
67 module_param(i2c0_addr, uint, S_IRUGO | S_IWUSR);
68 module_param(i2c1_addr, uint, S_IRUGO | S_IWUSR);
69
70 module_param_string(act_name, act_name, sizeof(act_name), S_IRUGO | S_IWUSR);
71 module_param(act_slave, uint, S_IRUGO | S_IWUSR);
72 module_param(use_sensor_list, uint, S_IRUGO | S_IWUSR);
73
vin_md_prepare_pipeline(struct vin_pipeline * p,struct media_entity * me)74 static void vin_md_prepare_pipeline(struct vin_pipeline *p,
75 struct media_entity *me)
76 {
77 struct v4l2_subdev *sd;
78 int i;
79
80 for (i = 0; i < VIN_IND_ACTUATOR; i++)
81 p->sd[i] = NULL;
82
83 while (1) {
84 struct media_pad *pad = NULL;
85
86 /* Find remote source pad */
87 for (i = 0; i < me->num_pads; i++) {
88 struct media_pad *spad = &me->pads[i];
89
90 if (!(spad->flags & MEDIA_PAD_FL_SINK))
91 continue;
92 pad = media_entity_remote_pad(spad);
93 if (pad)
94 break;
95 }
96
97 if (pad == NULL)
98 break;
99
100 sd = media_entity_to_v4l2_subdev(pad->entity);
101 vin_log(VIN_LOG_MD, "%s entity is %s, group id is 0x%x\n",
102 __func__, pad->entity->name, sd->grp_id);
103
104 switch (sd->grp_id) {
105 case VIN_GRP_ID_SENSOR:
106 p->sd[VIN_IND_SENSOR] = sd;
107 break;
108 case VIN_GRP_ID_MIPI:
109 p->sd[VIN_IND_MIPI] = sd;
110 break;
111 case VIN_GRP_ID_CSI:
112 p->sd[VIN_IND_CSI] = sd;
113 break;
114 case VIN_GRP_ID_TDM_RX:
115 p->sd[VIN_IND_TDM_RX] = sd;
116 break;
117 case VIN_GRP_ID_ISP:
118 p->sd[VIN_IND_ISP] = sd;
119 break;
120 case VIN_GRP_ID_SCALER:
121 p->sd[VIN_IND_SCALER] = sd;
122 break;
123 case VIN_GRP_ID_CAPTURE:
124 p->sd[VIN_IND_CAPTURE] = sd;
125 break;
126 default:
127 break;
128 }
129 me = &sd->entity;
130 if (me->num_pads == 1)
131 break;
132 }
133 }
134
vin_mclk_pin_release(struct vin_md * vind)135 static int vin_mclk_pin_release(struct vin_md *vind)
136 {
137 #ifndef FPGA_VER
138 int i;
139
140 for (i = 0; i < VIN_MAX_CCI; i++) {
141 if (!IS_ERR_OR_NULL(vind->mclk[i].pin))
142 devm_pinctrl_put(vind->mclk[i].pin);
143 }
144 #endif
145 return 0;
146 }
147
vin_md_get_clocks(struct vin_md * vind)148 static int vin_md_get_clocks(struct vin_md *vind)
149 {
150 struct device_node *np = vind->pdev->dev.of_node;
151 unsigned int core_clk;
152 struct device *dev;
153 char clk_name[20];
154 int i;
155
156 dev = &vind->pdev->dev;
157 if (IS_ERR_OR_NULL(dev)) {
158 vin_err("dev is NULL!\n");
159 return -1;
160 }
161 /*get csi top clk*/
162 vind->clk[VIN_TOP_CLK].clock = devm_clk_get(dev, "csi_top");
163 if (IS_ERR(vind->clk[VIN_TOP_CLK].clock)) {
164 vin_err("get csi top clk fail\n");
165 return PTR_ERR(vind->clk[VIN_TOP_CLK].clock);
166 }
167 vind->clk[VIN_TOP_CLK_SRC].clock = devm_clk_get(dev, "csi_top_src");
168 if (IS_ERR(vind->clk[VIN_TOP_CLK_SRC].clock)) {
169 vin_err("get csi top clk src fail\n");
170 return PTR_ERR(vind->clk[VIN_TOP_CLK_SRC].clock);
171 }
172 /*get mclk*/
173 for (i = 0; i < VIN_MAX_CCI; i++) {
174 sprintf(clk_name, "csi_mclk%d", i);
175 vind->mclk[i].mclk = devm_clk_get(dev, clk_name);
176 if (IS_ERR(vind->mclk[i].mclk)) {
177 vin_err("get mclk%d clk fail\n", i);
178 return PTR_ERR(vind->mclk[i].mclk);
179 }
180 sprintf(clk_name, "csi_mclk%d_24m", i);
181 vind->mclk[i].clk_24m = devm_clk_get(dev, clk_name);
182 if (IS_ERR(vind->mclk[i].clk_24m)) {
183 vin_err("get mclk%d clk src 24m fail\n", i);
184 return PTR_ERR(vind->mclk[i].clk_24m);
185 }
186 sprintf(clk_name, "csi_mclk%d_pll", i);
187 vind->mclk[i].clk_pll = devm_clk_get(dev, clk_name);
188 if (IS_ERR(vind->mclk[i].clk_pll)) {
189 vin_err("get mclk%d clk src pll fail\n", i);
190 return PTR_ERR(vind->mclk[i].clk_pll);
191 }
192 }
193 /*get isp clk*/
194 vind->isp_clk[VIN_ISP_CLK].clock = devm_clk_get(dev, "csi_isp");
195 if (IS_ERR(vind->isp_clk[VIN_ISP_CLK].clock)) {
196 vind->isp_clk[VIN_ISP_CLK].clock = NULL;
197 vin_warn("get csi isp clk fail\n");
198 }
199 vind->isp_clk[VIN_ISP_CLK_SRC].clock = devm_clk_get(dev, "csi_isp_src");
200 if (IS_ERR(vind->isp_clk[VIN_ISP_CLK_SRC].clock)) {
201 vind->isp_clk[VIN_ISP_CLK].clock = NULL;
202 vin_warn("get csi isp src clk fail\n");
203 }
204 /*get mipi clk*/
205 vind->mipi_clk[VIN_MIPI_CLK].clock = devm_clk_get(dev, "csi_mipi");
206 if (IS_ERR(vind->mipi_clk[VIN_MIPI_CLK].clock)) {
207 vind->mipi_clk[VIN_MIPI_CLK].clock = NULL;
208 vin_warn("get csi mipi clk fail\n");
209 }
210 vind->mipi_clk[VIN_MIPI_CLK_SRC].clock = devm_clk_get(dev, "csi_mipi_src");
211 if (IS_ERR(vind->mipi_clk[VIN_MIPI_CLK_SRC].clock)) {
212 vind->mipi_clk[VIN_MIPI_CLK_SRC].clock = NULL;
213 vin_warn("get csi mipi src clk fail\n");
214 }
215 /*get bus clk*/
216 vind->bus_clk[VIN_CSI_BUS_CLK] = devm_clk_get(dev, "csi_bus");
217 if (IS_ERR_OR_NULL(vind->bus_clk[VIN_CSI_BUS_CLK])) {
218 vin_err("Get csi bus clk failed!\n");
219 return PTR_ERR(vind->bus_clk[VIN_CSI_BUS_CLK]);
220 }
221 vind->bus_clk[VIN_CSI_MBUS_CLK] = devm_clk_get(dev, "csi_mbus");
222 if (IS_ERR_OR_NULL(vind->bus_clk[VIN_CSI_MBUS_CLK])) {
223 vin_err("Get csi mbus clk failed!\n");
224 return PTR_ERR(vind->bus_clk[VIN_CSI_MBUS_CLK]);
225 }
226 vind->bus_clk[VIN_ISP_MBUS_CLK] = devm_clk_get(dev, "csi_isp_mbus");
227 if (IS_ERR(vind->bus_clk[VIN_ISP_MBUS_CLK])) {
228 vind->bus_clk[VIN_ISP_MBUS_CLK] = NULL;
229 vin_warn("get csi isp clk fail\n");
230 }
231 /*get csi/isp reset*/
232 vind->clk_reset[VIN_CSI_RET] = devm_reset_control_get(dev, "csi_ret");
233 if (IS_ERR(vind->clk_reset[VIN_CSI_RET])) {
234 vin_err("Get csi reset control fail\n");
235 return PTR_ERR(vind->clk_reset[VIN_CSI_RET]);
236 }
237 vind->clk_reset[VIN_ISP_RET] = devm_reset_control_get(dev, "isp_ret");
238 if (IS_ERR(vind->clk_reset[VIN_ISP_RET])) {
239 vin_warn("Get isp reset control fail\n");
240 vind->clk_reset[VIN_ISP_RET] = NULL;
241 }
242 /*get csi clk rate*/
243 if (clk_set_parent(vind->clk[VIN_TOP_CLK].clock, vind->clk[VIN_TOP_CLK_SRC].clock)) {
244 vin_err("vin top clock set parent failed\n");
245 return -1;
246 }
247 if (of_property_read_u32(np, "csi_top", &core_clk)) {
248 vin_err("vin failed to get core clk\n");
249 vind->clk[VIN_TOP_CLK].frequency = VIN_CLK_RATE;
250 } else {
251 vin_log(VIN_LOG_MD, "vin get core clk = %d\n", core_clk);
252 vind->clk[VIN_TOP_CLK].frequency = core_clk;
253 }
254 /*get isp clk rate*/
255 if (vind->isp_clk[VIN_ISP_CLK].clock && vind->isp_clk[VIN_ISP_CLK_SRC].clock) {
256 if (clk_set_parent(vind->isp_clk[VIN_ISP_CLK].clock,
257 vind->isp_clk[VIN_ISP_CLK_SRC].clock)) {
258 vin_err("isp clock set parent failed\n");
259 return -1;
260 }
261
262 if (of_property_read_u32(np, "csi_isp", &core_clk)) {
263 vin_err("vin failed to get isp clk rate\n");
264 vind->isp_clk[VIN_ISP_CLK].frequency = ISP_CLK_RATE;
265 } else {
266 vin_log(VIN_LOG_MD, "vin get isp clk rate = %d\n", core_clk);
267 vind->isp_clk[VIN_ISP_CLK].frequency = core_clk;
268 }
269 }
270 return 0;
271 }
272
vin_md_put_clocks(struct vin_md * vind)273 static void vin_md_put_clocks(struct vin_md *vind)
274 {
275 #ifndef FPGA_VER
276 int i;
277
278 for (i = 0; i < VIN_MAX_CLK; i++) {
279 if (vind->clk[i].clock)
280 clk_put(vind->clk[i].clock);
281 }
282
283 for (i = 0; i < VIN_MAX_CCI; i++) {
284 if (vind->mclk[i].mclk)
285 clk_put(vind->mclk[i].mclk);
286 if (vind->mclk[i].clk_24m)
287 clk_put(vind->mclk[i].clk_24m);
288 if (vind->mclk[i].clk_pll)
289 clk_put(vind->mclk[i].clk_pll);
290 }
291
292 if (vind->isp_clk[VIN_ISP_CLK].clock)
293 clk_put(vind->isp_clk[VIN_ISP_CLK].clock);
294 if (vind->isp_clk[VIN_ISP_CLK_SRC].clock)
295 clk_put(vind->isp_clk[VIN_ISP_CLK_SRC].clock);
296
297 for (i = 0; i < VIN_MIPI_MAX_CLK; i++) {
298 if (vind->mipi_clk[i].clock)
299 clk_put(vind->mipi_clk[i].clock);
300 }
301 if (vind->bus_clk[VIN_CSI_BUS_CLK])
302 clk_put(vind->bus_clk[VIN_ISP_CLK]);
303 if (vind->bus_clk[VIN_CSI_MBUS_CLK])
304 clk_put(vind->bus_clk[VIN_ISP_CLK]);
305 if (vind->bus_clk[VIN_ISP_MBUS_CLK])
306 clk_put(vind->bus_clk[VIN_ISP_CLK]);
307 #endif
308 }
309
__vin_set_top_clk_rate(struct vin_md * vind,unsigned int rate)310 static int __vin_set_top_clk_rate(struct vin_md *vind, unsigned int rate)
311 {
312 if (rate >= 300000000)
313 vind->clk[VIN_TOP_CLK_SRC].frequency = rate;
314 else if (rate >= 150000000)
315 vind->clk[VIN_TOP_CLK_SRC].frequency = rate * 2;
316 else if (rate >= 75000000)
317 vind->clk[VIN_TOP_CLK_SRC].frequency = rate * 4;
318 else
319 vind->clk[VIN_TOP_CLK_SRC].frequency = VIN_CLK_RATE;
320
321 #ifndef CONFIG_ARCH_SUN50IW3P1
322 if (clk_set_rate(vind->clk[VIN_TOP_CLK_SRC].clock,
323 vind->clk[VIN_TOP_CLK_SRC].frequency)) {
324 vin_err("set vin top clock source rate error\n");
325 return -1;
326 }
327 #endif
328
329 if (clk_set_rate(vind->clk[VIN_TOP_CLK].clock, rate)) {
330 vin_err("set vin top clock rate error\n");
331 return -1;
332 }
333 vin_log(VIN_LOG_POWER, "vin top clk get rate = %ld\n",
334 clk_get_rate(vind->clk[VIN_TOP_CLK].clock));
335
336 return 0;
337 }
338
__vin_set_isp_clk_rate(struct vin_md * vind,unsigned int rate)339 static int __vin_set_isp_clk_rate(struct vin_md *vind, unsigned int rate)
340 {
341 if (rate >= 300000000)
342 vind->isp_clk[VIN_ISP_CLK_SRC].frequency = rate;
343 else if (rate >= 150000000)
344 vind->isp_clk[VIN_ISP_CLK_SRC].frequency = rate * 2;
345 else if (rate >= 75000000)
346 vind->isp_clk[VIN_ISP_CLK_SRC].frequency = rate * 4;
347 else
348 vind->isp_clk[VIN_ISP_CLK_SRC].frequency = ISP_CLK_RATE;
349
350 #if defined CONFIG_ARCH_SUN8IW16P1
351 if (clk_set_rate(vind->isp_clk[VIN_ISP_CLK_SRC].clock,
352 vind->isp_clk[VIN_ISP_CLK_SRC].frequency)) {
353 vin_err("set vin isp clock source rate error\n");
354 return -1;
355 }
356 #endif
357 if (clk_set_rate(vind->isp_clk[VIN_ISP_CLK].clock, rate)) {
358 vin_err("set vin isp clock rate error\n");
359 return -1;
360 }
361 vin_log(VIN_LOG_POWER, "vin isp clk get rate = %ld\n",
362 clk_get_rate(vind->isp_clk[VIN_ISP_CLK].clock));
363
364 return 0;
365 }
366
vin_md_clk_enable(struct vin_md * vind)367 static int vin_md_clk_enable(struct vin_md *vind)
368 {
369 #ifndef FPGA_VER
370 int ret;
371
372 if (vind->clk[VIN_TOP_CLK].clock) {
373 __vin_set_top_clk_rate(vind, vind->clk[VIN_TOP_CLK].frequency);
374 ret = reset_control_deassert(vind->clk_reset[VIN_CSI_RET]);
375 if (ret) {
376 vin_err("reset deassert fail\n");
377 return ret;
378 }
379 ret = clk_prepare_enable(vind->bus_clk[VIN_CSI_BUS_CLK]);
380 if (ret) {
381 vin_err("csi bus clk prepare enable fail\n");
382 goto assert_reset_csi;
383 }
384 ret = clk_prepare_enable(vind->bus_clk[VIN_CSI_MBUS_CLK]);
385 if (ret) {
386 vin_err("csi mbus clk prepare enable fail\n");
387 goto enable_csi_bus;
388 }
389
390 ret = clk_prepare_enable(vind->clk[VIN_TOP_CLK].clock);
391 if (ret) {
392 vin_err("csi clk prepare enable fail\n");
393 goto enable_csi_mbus;
394 }
395 }
396
397 if (vind->isp_clk[VIN_ISP_CLK].clock) {
398 if (vind->isp_clk[VIN_ISP_CLK_SRC].clock)
399 __vin_set_isp_clk_rate(vind, vind->isp_clk[VIN_ISP_CLK].frequency);
400 ret = reset_control_deassert(vind->clk_reset[VIN_ISP_RET]);
401 if (ret) {
402 goto enable_csi_clk;
403 }
404 ret = clk_prepare_enable(vind->bus_clk[VIN_ISP_MBUS_CLK]);
405 if (ret) {
406 vin_err("csi mbus clk prepare enable fail\n");
407 goto assert_reset_isp;
408 }
409 ret = clk_prepare_enable(vind->isp_clk[VIN_ISP_CLK].clock);
410 if (ret)
411 goto enable_isp_mbus;
412
413 }
414
415 if (vind->mipi_clk[VIN_MIPI_CLK].clock)
416 clk_prepare_enable(vind->mipi_clk[VIN_MIPI_CLK].clock);
417
418 return 0;
419 enable_isp_mbus:
420 clk_disable_unprepare(vind->bus_clk[VIN_ISP_MBUS_CLK]);
421 assert_reset_isp:
422 reset_control_assert(vind->clk_reset[VIN_ISP_RET]);
423 enable_csi_clk:
424 clk_disable_unprepare(vind->clk[VIN_TOP_CLK].clock);
425 enable_csi_mbus:
426 clk_disable_unprepare(vind->bus_clk[VIN_CSI_MBUS_CLK]);
427 enable_csi_bus:
428 clk_disable_unprepare(vind->bus_clk[VIN_CSI_BUS_CLK]);
429 assert_reset_csi:
430 reset_control_assert(vind->clk_reset[VIN_CSI_RET]);
431
432 return ret;
433 #else
434 void __iomem *clk_base;
435 void __iomem *gpio_base;
436 int ret;
437
438 vin_log(VIN_LOG_MD, "directly write pin and clk config @ FPGA\n");
439 if (vind->clk[VIN_TOP_CLK].clock) {
440 ret = reset_control_deassert(vind->clk_reset[VIN_CSI_RET]);
441 if (ret) {
442 vin_err("reset deassert fail\n");
443 return ret;
444 }
445 ret = clk_prepare_enable(vind->bus_clk[VIN_CSI_BUS_CLK]);
446 if (ret) {
447 vin_err("csi bus clk prepare enable fail\n");
448 goto assert_reset_csi;
449 }
450 ret = clk_prepare_enable(vind->bus_clk[VIN_CSI_MBUS_CLK]);
451 if (ret) {
452 vin_err("csi mbus clk prepare enable fail\n");
453 goto enable_csi_bus;
454 }
455
456 ret = clk_prepare_enable(vind->clk[VIN_TOP_CLK].clock);
457 if (ret) {
458 vin_err("csi clk prepare enable fail\n");
459 goto enable_csi_mbus;
460 }
461 }
462
463 if (vind->isp_clk[VIN_ISP_CLK].clock) {
464 ret = reset_control_deassert(vind->clk_reset[VIN_ISP_RET]);
465 if (ret) {
466 goto enable_csi_clk;
467 }
468 ret = clk_prepare_enable(vind->bus_clk[VIN_ISP_MBUS_CLK]);
469 if (ret) {
470 vin_err("csi mbus clk prepare enable fail\n");
471 goto assert_reset_isp;
472 }
473 ret = clk_prepare_enable(vind->isp_clk[VIN_ISP_CLK].clock);
474 if (ret)
475 goto enable_isp_mbus;
476
477 }
478
479 if (vind->mipi_clk[VIN_MIPI_CLK].clock)
480 clk_prepare_enable(vind->mipi_clk[VIN_MIPI_CLK].clock);
481
482
483
484
485 gpio_base = ioremap(0x02001000, 0x1000);
486 if (!gpio_base) {
487 vin_print("csi clk ioremap failed\n");
488 return -EIO;
489 }
490 writel(0x00010001, (gpio_base + 0xc1c)); /*CSI RET GATING*/
491 return 0;
492
493 enable_isp_mbus:
494 clk_disable_unprepare(vind->bus_clk[VIN_ISP_MBUS_CLK]);
495 assert_reset_isp:
496 reset_control_assert(vind->clk_reset[VIN_ISP_RET]);
497 enable_csi_clk:
498 clk_disable_unprepare(vind->clk[VIN_TOP_CLK].clock);
499 enable_csi_mbus:
500 clk_disable_unprepare(vind->bus_clk[VIN_CSI_MBUS_CLK]);
501 enable_csi_bus:
502 clk_disable_unprepare(vind->bus_clk[VIN_CSI_BUS_CLK]);
503 assert_reset_csi:
504 reset_control_assert(vind->clk_reset[VIN_CSI_RET]);
505
506 return ret;
507 #endif
508 }
509
vin_md_clk_disable(struct vin_md * vind)510 static void vin_md_clk_disable(struct vin_md *vind)
511 {
512 #ifndef FPGA_VER
513 if (vind->clk[VIN_TOP_CLK].clock) {
514 clk_disable_unprepare(vind->clk[VIN_TOP_CLK].clock);
515 clk_disable_unprepare(vind->bus_clk[VIN_CSI_MBUS_CLK]);
516 clk_disable_unprepare(vind->bus_clk[VIN_CSI_BUS_CLK]);
517 reset_control_assert(vind->clk_reset[VIN_CSI_RET]);
518 }
519
520 if (vind->isp_clk[VIN_ISP_CLK].clock) {
521 clk_disable_unprepare(vind->isp_clk[VIN_ISP_CLK].clock);
522 clk_disable_unprepare(vind->bus_clk[VIN_ISP_MBUS_CLK]);
523 reset_control_assert(vind->clk_reset[VIN_ISP_RET]);
524
525 }
526
527 if (vind->mipi_clk[VIN_MIPI_CLK].clock)
528 clk_disable_unprepare(vind->mipi_clk[VIN_MIPI_CLK].clock);
529 #endif
530 }
531
532 #if !defined NO_SUPPROT_CCU_PLATDORM
vin_ccu_clk_gating_en(unsigned int en)533 static void vin_ccu_clk_gating_en(unsigned int en)
534 {
535 if (en) {
536 csic_ccu_clk_gating_enable();
537 csic_ccu_mcsi_clk_mode(1);
538 csic_ccu_mcsi_post_clk_enable(0);
539 csic_ccu_mcsi_post_clk_enable(1);
540 } else {
541 csic_ccu_mcsi_post_clk_disable(1);
542 csic_ccu_mcsi_post_clk_disable(0);
543 csic_ccu_mcsi_clk_mode(0);
544 csic_ccu_clk_gating_disable();
545 }
546 }
547
vin_subdev_ccu_en(struct v4l2_subdev * sd,unsigned int en)548 static void vin_subdev_ccu_en(struct v4l2_subdev *sd, unsigned int en)
549 {
550 __maybe_unused struct mipi_dev *mipi = NULL;
551 __maybe_unused struct csi_dev *csi = NULL;
552 __maybe_unused struct isp_dev *isp = NULL;
553 struct scaler_dev *scaler = NULL;
554 struct vin_core *vinc = NULL;
555 void *dev = v4l2_get_subdevdata(sd);
556
557 if (dev == NULL) {
558 vin_err("%s subdev is NULL, cannot set ccu\n", sd->name);
559 return;
560 }
561
562 switch (sd->grp_id) {
563 #if !defined (CONFIG_ARCH_SUN50IW10)
564 case VIN_GRP_ID_MIPI:
565 mipi = (struct mipi_dev *)dev;
566 #if defined (CONFIG_ARCH_SUN8IW16P1)
567 csic_ccu_mcsi_combo_clk_en(mipi->id, en);
568 #else
569 csic_ccu_mcsi_mipi_clk_en(mipi->id, en);
570 #endif
571 break;
572 #endif
573 #ifndef SUPPORT_ISP_TDM
574 case VIN_GRP_ID_CSI:
575 csi = (struct csi_dev *)dev;
576 csic_ccu_mcsi_parser_clk_en(csi->id, en);
577 break;
578 case VIN_GRP_ID_ISP:
579 isp = (struct isp_dev *)dev;
580 csic_ccu_misp_isp_clk_en(isp->id, en);
581 break;
582 #endif
583 case VIN_GRP_ID_SCALER:
584 scaler = (struct scaler_dev *)dev;
585 csic_ccu_vipp_clk_en(scaler->id, en);
586 break;
587 case VIN_GRP_ID_CAPTURE:
588 vinc = (struct vin_core *)dev;
589 csic_ccu_bk_clk_en(vinc->vipp_sel, en);
590 break;
591 default:
592 break;
593 }
594 }
595 #endif
596
vin_md_set_power(struct vin_md * vind,int on)597 static void vin_md_set_power(struct vin_md *vind, int on)
598 {
599 __maybe_unused int i;
600
601 if (on && (vind->use_count)++ > 0)
602 return;
603 else if (!on && (vind->use_count == 0 || --(vind->use_count) > 0))
604 return;
605
606 if (on) {
607 vin_md_clk_enable(vind);
608 usleep_range(100, 120);
609 #if !defined NO_SUPPROT_CCU_PLATDORM
610 vin_ccu_clk_gating_en(1);
611 csic_isp_bridge_enable(vind->id);
612 #endif
613 #if defined (CONFIG_ARCH_SUN50IW10)
614 csic_ccu_mcsi_combo_clk_en(0, 1);
615 #endif
616 #ifdef SUPPORT_ISP_TDM
617 for (i = 0; i < VIN_MAX_CSI; i++)
618 csic_ccu_mcsi_parser_clk_en(i, 1);
619 for (i = 0; i < VIN_MAX_ISP; i++)
620 csic_ccu_misp_isp_clk_en(i, 1);
621 #endif
622 csic_top_enable(vind->id);
623 csic_top_version_read_en(vind->id, 1);
624 csic_feature_list_get(vind->id, &vind->csic_fl);
625 csic_version_get(vind->id, &vind->csic_ver);
626 csic_top_version_read_en(vind->id, 0);
627 csic_mbus_req_mex_set(vind->id, 0xf);
628 #ifdef CONFIG_MULTI_FRAME
629 csic_mulp_mode_en(vind->id, 1);
630 csic_mulp_dma_cs(vind->id, CSIC_MULF_DMA0_CS);
631 csic_mulp_int_enable(vind->id, MULF_DONE | MULF_ERR);
632 #endif
633
634 #if defined (CONFIG_ARCH_SUN50IW10)
635 cmb_phy_top_enable();
636 #endif
637 } else {
638 #if defined (CONFIG_ARCH_SUN50IW10)
639 cmb_phy_top_disable();
640 #endif
641
642 #ifdef CONFIG_MULTI_FRAME
643 csic_mulp_int_disable(vind->id, MULF_ALL);
644 csic_mulp_mode_en(vind->id, 0);
645 #endif
646 csic_top_disable(vind->id);
647 #if !defined NO_SUPPROT_CCU_PLATDORM
648 csic_isp_bridge_disable(vind->id);
649 vin_ccu_clk_gating_en(0);
650 #endif
651 vin_md_clk_disable(vind);
652 }
653 }
654
vin_set_cci_power(struct vin_md * vind,int on)655 static void vin_set_cci_power(struct vin_md *vind, int on)
656 {
657 #if defined (CONFIG_ARCH_SUN50IW9P1)
658 int i;
659
660 if (on) {
661 vin_md_set_power(vind, on);
662 for (i = 0; i < VIN_MAX_CSI; i++)
663 csic_ccu_mcsi_parser_clk_en(i, on);
664 } else {
665 for (i = 0; i < VIN_MAX_CSI; i++)
666 csic_ccu_mcsi_parser_clk_en(i, on);
667 vin_md_set_power(vind, on);
668 }
669 #endif
670 }
671
vin_gpio_request(struct vin_md * vind)672 static int vin_gpio_request(struct vin_md *vind)
673 {
674 #ifndef FPGA_VER
675 unsigned int i, num;
676 struct sensor_list *sl = NULL;
677 int *gpio = NULL;
678
679 for (num = 0; num < VIN_MAX_DEV; num++) {
680 sl = &vind->modules[num].sensors;
681
682 for (i = 0; i < MAX_GPIO_NUM; i++) {
683 gpio = &sl->gpio[i];
684 if (gpio != NULL && *gpio >= 0) {
685 if (gpio_request(*gpio, NULL) < 0) {
686 vin_log(VIN_LOG_MD, "gpio%d request failed!\n", *gpio);
687 continue;
688 }
689 vin_log(VIN_LOG_MD, "gpio%d request success!\n", *gpio);
690 }
691
692 }
693 }
694 #endif
695 return 0;
696 }
697
vin_gpio_release(struct vin_md * vind)698 static void vin_gpio_release(struct vin_md *vind)
699 {
700 #ifndef FPGA_VER
701 unsigned int i, num;
702 struct sensor_list *sl = NULL;
703 int *gpio = NULL;
704
705 for (num = 0; num < VIN_MAX_DEV; num++) {
706 sl = &vind->modules[num].sensors;
707
708 for (i = 0; i < MAX_GPIO_NUM; i++) {
709 gpio = &sl->gpio[i];
710 if (gpio != NULL && *gpio >= 0)
711 gpio_free(*gpio);
712 }
713 }
714 #endif
715 }
716
__vin_pattern_config(struct vin_md * vind,struct vin_core * vinc,int on)717 static void __vin_pattern_config(struct vin_md *vind, struct vin_core *vinc, int on)
718 {
719 #ifdef SUPPORT_PTN
720 int port_sel = 2;
721
722 if (vinc->ptn_cfg.ptn_en && on) {
723 if (vinc->csi_sel == 1)
724 port_sel = 2;
725 else
726 port_sel = vinc->csi_sel + 2;
727 csic_ptn_control(vind->id, vinc->ptn_cfg.ptn_mode, vinc->ptn_cfg.ptn_dw, port_sel);
728 csic_ptn_length(vind->id, vinc->ptn_cfg.ptn_buf.size);
729 csic_ptn_addr(vind->id, (unsigned long)vinc->ptn_cfg.ptn_buf.dma_addr);
730 csic_ptn_size(vind->id, vinc->ptn_cfg.ptn_w, vinc->ptn_cfg.ptn_h);
731 } else {
732 csic_ptn_generation_en(vind->id, 0);
733 }
734 #endif
735 }
736
__vin_pattern_onoff(struct vin_md * vind,struct vin_core * vinc,int on)737 static void __vin_pattern_onoff(struct vin_md *vind, struct vin_core *vinc, int on)
738 {
739 #ifdef SUPPORT_PTN
740 if (vinc->ptn_cfg.ptn_en) {
741 if (vinc->ptn_cfg.ptn_type > 0) {
742 ptn_on_cnt++;
743 if (ptn_on_cnt%vinc->ptn_cfg.ptn_type == 0) {
744 ptn_on_cnt = 0;
745 ptn_frame_cnt = 0;
746 csic_ptn_generation_en(vind->id, on);
747 }
748 } else {
749 csic_ptn_generation_en(vind->id, on);
750 }
751 }
752 #endif
753 }
754
__vin_subdev_set_power(struct v4l2_subdev * sd,unsigned int idx,int on)755 static int __vin_subdev_set_power(struct v4l2_subdev *sd, unsigned int idx, int on)
756 {
757 int *use_count;
758 int ret;
759
760 if (sd == NULL)
761 return -ENXIO;
762
763 use_count = &sd->entity.use_count;
764 if (on && (*use_count)++ > 0)
765 return 0;
766 else if (!on && (*use_count == 0 || --(*use_count) > 0))
767 return 0;
768
769 #if defined SENSOR_POER_BEFORE_VIN
770 if (idx == VIN_IND_SENSOR)
771 return 0;
772 #endif
773
774 #if !defined NO_SUPPROT_CCU_PLATDORM
775 if (on)
776 vin_subdev_ccu_en(sd, on);
777 #endif
778 ret = v4l2_subdev_call(sd, core, s_power, on);
779 #if !defined NO_SUPPROT_CCU_PLATDORM
780 if (!on)
781 vin_subdev_ccu_en(sd, on);
782 #endif
783
784 #if 0
785 if (ret == 0 || ret == -ENOIOCTLCMD) {
786 if (on || sd->grp_id != VIN_GRP_ID_SENSOR)
787 ret = v4l2_subdev_call(sd, core, init, on);
788 }
789 #endif
790 return ret != -ENOIOCTLCMD ? ret : 0;
791 }
792
vin_pipeline_s_power(struct vin_pipeline * p,bool on)793 static int vin_pipeline_s_power(struct vin_pipeline *p, bool on)
794 {
795 static const u8 seq[2][VIN_IND_MAX] = {
796 { VIN_IND_ISP, VIN_IND_SENSOR, VIN_IND_CSI, VIN_IND_MIPI,
797 VIN_IND_SCALER, VIN_IND_CAPTURE },
798 { VIN_IND_CAPTURE, VIN_IND_MIPI, VIN_IND_CSI, VIN_IND_SENSOR,
799 VIN_IND_ISP, VIN_IND_SCALER},
800 };
801 int i, ret = 0;
802
803 for (i = 0; i < VIN_IND_TDM_RX; i++) {
804 unsigned int idx = seq[on][i];
805 if (!p->sd[idx] || !p->sd[idx]->entity.graph_obj.mdev)
806 continue;
807 ret = __vin_subdev_set_power(p->sd[idx], idx, on);
808 if (ret < 0 && ret != -ENXIO)
809 goto error;
810 }
811 return 0;
812 error:
813 for (; i >= 0; i--) {
814 unsigned int idx = seq[on][i];
815 if (!p->sd[idx] || !p->sd[idx]->entity.graph_obj.mdev)
816 continue;
817 __vin_subdev_set_power(p->sd[idx], idx, !on);
818 }
819 return ret;
820 }
821
__vin_pipeline_open(struct vin_pipeline * p,struct media_entity * me,bool prepare)822 static int __vin_pipeline_open(struct vin_pipeline *p,
823 struct media_entity *me, bool prepare)
824 {
825 struct vin_md *vind;
826 int ret;
827
828 if (WARN_ON(p == NULL || me == NULL))
829 return -EINVAL;
830
831 if (prepare)
832 vin_md_prepare_pipeline(p, me);
833
834 vind = entity_to_vin_mdev(me);
835 if (vind)
836 vin_md_set_power(vind, 1);
837
838 ret = vin_pipeline_s_power(p, 1);
839 if (!ret)
840 return 0;
841 return ret;
842 }
843
__vin_pipeline_close(struct vin_pipeline * p)844 static int __vin_pipeline_close(struct vin_pipeline *p)
845 {
846 struct v4l2_subdev *sd = p ? p->sd[VIN_IND_SENSOR] : NULL;
847 struct vin_md *vind;
848 int ret = 0;
849
850 if (WARN_ON(sd == NULL))
851 return -EINVAL;
852
853 if (p->sd[VIN_IND_SENSOR])
854 ret = vin_pipeline_s_power(p, 0);
855
856 vind = entity_to_vin_mdev(&sd->entity);
857 if (vind)
858 vin_md_set_power(vind, 0);
859
860 return ret == -ENXIO ? 0 : ret;
861 }
862
__vin_subdev_set_stream(struct v4l2_subdev * sd,unsigned int idx,int on)863 static int __vin_subdev_set_stream(struct v4l2_subdev *sd, unsigned int idx, int on)
864 {
865 __maybe_unused struct isp_dev *isp = NULL;
866 int *stream_count;
867 int ret;
868
869 if (sd == NULL)
870 return -ENODEV;
871
872 stream_count = &sd->entity.stream_count;
873 if (on && (*stream_count)++ > 0)
874 return 0;
875 else if (!on && (*stream_count == 0 || --(*stream_count) > 0))
876 return 0;
877
878 #if defined ISP0_BRIDGE_VALID
879 if (!on && idx == VIN_IND_ISP) {
880 isp = v4l2_get_subdevdata(sd);
881 if (isp->id == 0)
882 csic_isp_bridge_disable(0);
883 }
884 #endif
885 ret = v4l2_subdev_call(sd, video, s_stream, on);
886 #if defined ISP0_BRIDGE_VALID
887 if (on && idx == VIN_IND_ISP) {
888 isp = v4l2_get_subdevdata(sd);
889 if (isp->id == 0)
890 csic_isp_bridge_enable(0);
891 }
892 #endif
893
894 return ret != -ENOIOCTLCMD ? ret : 0;
895 }
896
__vin_pipeline_s_stream(struct vin_pipeline * p,int on_idx)897 static int __vin_pipeline_s_stream(struct vin_pipeline *p, int on_idx)
898 {
899 static const u8 seq[3][VIN_IND_MAX] = {
900 { VIN_IND_CAPTURE, VIN_IND_ISP, VIN_IND_SENSOR, VIN_IND_CSI, VIN_IND_MIPI,
901 VIN_IND_SCALER, VIN_IND_TDM_RX },
902 { VIN_IND_TDM_RX, VIN_IND_SENSOR, VIN_IND_MIPI, VIN_IND_ISP,
903 VIN_IND_SCALER, VIN_IND_CAPTURE, VIN_IND_CSI},
904 { VIN_IND_TDM_RX, VIN_IND_MIPI, VIN_IND_SENSOR, VIN_IND_ISP,
905 VIN_IND_SCALER, VIN_IND_CAPTURE, VIN_IND_CSI},
906 };
907 struct v4l2_mbus_config mcfg;
908 struct vin_core *vinc = NULL;
909 struct vin_md *vind = NULL;
910 int i, on, ret = 0;
911
912 if (p == NULL) {
913 vin_err("pipeline is NULL, cannot s_stream\n");
914 return -ENODEV;
915 }
916
917 if (WARN_ON(p->sd[VIN_IND_SENSOR] == NULL))
918 return -ENODEV;
919
920 vind = entity_to_vin_mdev(&p->sd[VIN_IND_SENSOR]->entity);
921 if (vind == NULL) {
922 vin_err("vin media is NULL, cannot s_stream\n");
923 return -ENODEV;
924 }
925
926 vinc = v4l2_get_subdevdata(p->sd[VIN_IND_CAPTURE]);
927 if (vinc == NULL) {
928 vin_err("vin video is NULL, cannot s_stream\n");
929 return -ENODEV;
930 }
931
932 if (on_idx) {
933 v4l2_subdev_call(p->sd[VIN_IND_SENSOR], pad, get_mbus_config, 0, &mcfg);
934 #if defined CONFIG_ARCH_SUN8IW16P1
935 ret = sensor_get_clk(p->sd[VIN_IND_SENSOR], &mcfg, &vind->clk[VIN_TOP_CLK].frequency,
936 &vind->isp_clk[VIN_ISP_CLK].frequency);
937 if (!ret) {
938 __vin_set_top_clk_rate(vind, vind->clk[VIN_TOP_CLK].frequency);
939 if (vind->isp_clk[VIN_ISP_CLK_SRC].clock)
940 __vin_set_isp_clk_rate(vind, vind->isp_clk[VIN_ISP_CLK].frequency);
941 }
942 #endif
943 /*vin change top clk rate*/
944 if (vinc->vin_clk && (vinc->vin_clk != vind->clk[VIN_TOP_CLK].frequency)) {
945 __vin_set_top_clk_rate(vind, vinc->vin_clk);
946 vind->clk[VIN_TOP_CLK].frequency = vinc->vin_clk;
947 }
948
949 #if defined (CONFIG_ARCH_SUN50IW9P1)
950 csic_dma_input_select(vind->id, vinc->vipp_sel, vinc->csi_sel, vinc->isp_tx_ch);
951 #else
952 for (i = 0; i < vinc->total_rx_ch; i++)
953 csic_isp_input_select(vind->id, vinc->isp_sel, i, vinc->csi_sel, i);
954 csic_vipp_input_select(vind->id, vinc->vipp_sel, vinc->isp_sel, vinc->isp_tx_ch);
955 #endif
956 }
957
958 on = on_idx ? 1 : 0;
959
960 __vin_pattern_config(vind, vinc, on);
961
962 for (i = 0; i < VIN_IND_ACTUATOR; i++) {
963 unsigned int idx = seq[on_idx][i];
964 if (!p->sd[idx] || !p->sd[idx]->entity.graph_obj.mdev)
965 continue;
966 if (vinc->ptn_cfg.ptn_en && (idx <= VIN_IND_MIPI))
967 continue;
968 ret = __vin_subdev_set_stream(p->sd[idx], idx, on);
969 if (ret < 0 && ret != -ENODEV) {
970 vin_err("%s error!\n", __func__);
971 goto error;
972 }
973 usleep_range(100, 120);
974 }
975
976 __vin_pattern_onoff(vind, vinc, on);
977
978 return 0;
979 error:
980 for (; i >= 0; i--) {
981 unsigned int idx = seq[on_idx][i];
982 if (!p->sd[idx] || !p->sd[idx]->entity.graph_obj.mdev)
983 continue;
984 if (vinc->ptn_cfg.ptn_en && (idx <= VIN_IND_MIPI))
985 continue;
986 __vin_subdev_set_stream(p->sd[idx], idx, !on);
987 }
988 return ret;
989 }
990
991 static const struct vin_pipeline_ops vin_pipe_ops = {
992 .open = __vin_pipeline_open,
993 .close = __vin_pipeline_close,
994 .set_stream = __vin_pipeline_s_stream,
995 };
996
__vin_subdev_register(struct vin_md * vind,char * name,u8 addr,enum module_type type,int bus_sel)997 static struct v4l2_subdev *__vin_subdev_register(struct vin_md *vind,
998 char *name, u8 addr, enum module_type type, int bus_sel)
999 {
1000 struct v4l2_device *v4l2_dev = &vind->v4l2_dev;
1001 struct v4l2_subdev *sd = NULL;
1002
1003 if (type == VIN_MODULE_TYPE_CCI) {
1004 sd = cci_bus_match(name, bus_sel, addr);
1005 if (IS_ERR_OR_NULL(sd)) {
1006 vin_err("registering %s, No such device!\n", name);
1007 return NULL;
1008 } else {
1009 if (v4l2_device_register_subdev(v4l2_dev, sd)) {
1010 struct cci_driver *cd = v4l2_get_subdevdata(sd);
1011
1012 cci_bus_match_cancel(cd);
1013 vin_log(VIN_LOG_MD, "%s register failed!\n", name);
1014 return NULL;
1015 }
1016 vin_log(VIN_LOG_MD, "%s register OK!\n", name);
1017 }
1018 } else if (type == VIN_MODULE_TYPE_I2C) {
1019 struct i2c_adapter *adapter = i2c_get_adapter(bus_sel);
1020
1021 if (adapter == NULL) {
1022 vin_err("%s request i2c%d adapter failed!\n", name, bus_sel);
1023 return NULL;
1024 }
1025 sd = v4l2_i2c_new_subdev(v4l2_dev, adapter, name, addr, NULL);
1026 if (IS_ERR_OR_NULL(sd)) {
1027 i2c_put_adapter(adapter);
1028 vin_err("registering %s, No such device!\n", name);
1029 return NULL;
1030 } else {
1031 vin_log(VIN_LOG_MD, "%s register OK!\n", name);
1032 }
1033 } else if (type == VIN_MODULE_TYPE_SPI) {
1034 #if defined(CONFIG_SPI)
1035 struct spi_master *master = spi_busnum_to_master(bus_sel);
1036 /*if use struct spi_board_info info diretly, maybe leadto stack overflow!*/
1037 struct spi_board_info *info = NULL;
1038
1039 if (master == NULL) {
1040 vin_err("%s request spi%d master failed!\n", name, bus_sel);
1041 return NULL;
1042 }
1043
1044 info = kzalloc(sizeof(struct spi_board_info), GFP_KERNEL);
1045 if (info == NULL)
1046 return NULL;
1047 strlcpy(info->modalias, name, sizeof(info->modalias));
1048 info->bus_num = bus_sel;
1049 info->chip_select = 0;
1050 info->max_speed_hz = 12000000;
1051 info->mode = 0x0b; /*0x08 (little end) | 0x03*/
1052 sd = v4l2_spi_new_subdev(v4l2_dev, master, info);
1053 kfree(info);
1054 if (IS_ERR_OR_NULL(sd)) {
1055 spi_master_put(master);
1056 vin_err("registering %s, No such device!\n", name);
1057 return NULL;
1058 } else {
1059 vin_log(VIN_LOG_MD, "%s register OK!\n", name);
1060 }
1061 #endif
1062 } else if (type == VIN_MODULE_TYPE_GPIO) {
1063 vin_log(VIN_LOG_MD, "Sensor type error, type = %d!\n", type);
1064 return NULL;
1065 } else {
1066 vin_log(VIN_LOG_MD, "Sensor type error, type = %d!\n", type);
1067 return NULL;
1068 }
1069
1070 return sd;
1071 }
1072
__vin_subdev_unregister(struct v4l2_subdev * sd,enum module_type type)1073 static int __vin_subdev_unregister(struct v4l2_subdev *sd,
1074 enum module_type type)
1075 {
1076 if (IS_ERR_OR_NULL(sd)) {
1077 vin_log(VIN_LOG_MD, "%s sd = NULL!\n", __func__);
1078 return -1;
1079 }
1080
1081 if (type == VIN_MODULE_TYPE_CCI) {
1082 struct cci_driver *cci_driv = v4l2_get_subdevdata(sd);
1083
1084 if (IS_ERR_OR_NULL(cci_driv))
1085 return -ENODEV;
1086 vin_log(VIN_LOG_MD, "vin sd %s unregister!\n", sd->name);
1087 v4l2_device_unregister_subdev(sd);
1088 cci_bus_match_cancel(cci_driv);
1089 } else if (type == VIN_MODULE_TYPE_I2C) {
1090 struct i2c_adapter *adapter;
1091 struct i2c_client *client = v4l2_get_subdevdata(sd);
1092
1093 if (!client)
1094 return -ENODEV;
1095 vin_log(VIN_LOG_MD, "vin sd %s unregister!\n", sd->name);
1096 v4l2_device_unregister_subdev(sd);
1097 adapter = client->adapter;
1098 i2c_unregister_device(client);
1099 if (adapter)
1100 i2c_put_adapter(adapter);
1101 } else if (type == VIN_MODULE_TYPE_SPI) {
1102 #if defined(CONFIG_SPI)
1103 struct spi_master *master;
1104 struct spi_device *spi = v4l2_get_subdevdata(sd);
1105
1106 if (!spi)
1107 return -ENODEV;
1108 vin_log(VIN_LOG_MD, "vin sd %s unregister!\n", sd->name);
1109 v4l2_device_unregister_subdev(sd);
1110 master = spi->master;
1111 spi_unregister_device(spi);
1112 if (master)
1113 spi_master_put(master);
1114 #endif
1115 } else if (type == VIN_MODULE_TYPE_GPIO) {
1116 vin_log(VIN_LOG_MD, "Sensor type error, type = %d!\n", type);
1117 return -EFAULT;
1118 } else {
1119 vin_log(VIN_LOG_MD, "Sensor type error, type = %d!\n", type);
1120 return -EFAULT;
1121 }
1122
1123 return 0;
1124 }
1125
__vin_handle_sensor_info(struct sensor_instance * inst)1126 static int __vin_handle_sensor_info(struct sensor_instance *inst)
1127 {
1128 if (inst->cam_type == SENSOR_RAW) {
1129 inst->is_bayer_raw = 1;
1130 inst->is_isp_used = 1;
1131 } else if (inst->cam_type == SENSOR_YUV) {
1132 inst->is_bayer_raw = 0;
1133 inst->is_isp_used = 0;
1134 } else {
1135 inst->is_bayer_raw = 0;
1136 inst->is_isp_used = 0;
1137 }
1138 return 0;
1139 }
1140
__vin_register_module(struct vin_md * vind,struct modules_config * module,int i)1141 static struct v4l2_subdev *__vin_register_module(struct vin_md *vind,
1142 struct modules_config *module, int i)
1143 {
1144 struct sensor_instance *inst = &module->sensors.inst[i];
1145 struct vin_module_info *modules = &module->modules;
1146
1147 if (!strcmp(inst->cam_name, "")) {
1148 vin_err("Sensor name is NULL!\n");
1149 modules->sensor[i].sd = NULL;
1150 return modules->sensor[i].sd;
1151 }
1152
1153 /*camera sensor register. */
1154 modules->sensor[i].sd = __vin_subdev_register(vind, inst->cam_name,
1155 inst->cam_addr >> 1,
1156 modules->sensor[i].type,
1157 module->sensors.sensor_bus_sel);
1158 if (module->sensors.use_sensor_list == 1)
1159 module->act_used = inst->act_used;
1160
1161 if (!module->act_used || !modules->sensor[i].sd) {
1162 modules->act[i].sd = NULL;
1163 return modules->sensor[i].sd;
1164 }
1165 /*camera act register. */
1166 modules->act[i].sd = __vin_subdev_register(vind, inst->act_name,
1167 inst->act_addr >> 1,
1168 modules->act[i].type,
1169 module->sensors.act_bus_sel);
1170 return modules->sensor[i].sd;
1171 }
1172
__vin_unregister_module(struct modules_config * module,int i)1173 static void __vin_unregister_module(struct modules_config *module, int i)
1174 {
1175 struct vin_module_info *modules = &module->modules;
1176
1177 /*camera subdev unregister */
1178 __vin_subdev_unregister(modules->sensor[i].sd,
1179 modules->sensor[i].type);
1180 __vin_subdev_unregister(modules->act[i].sd,
1181 modules->act[i].type);
1182 vin_log(VIN_LOG_MD, "%s!\n", __func__);
1183 modules->sensor[i].sd = NULL;
1184 modules->act[i].sd = NULL;
1185 }
1186
vin_md_link_notify(struct media_link * link,u32 flags,unsigned int notification)1187 static int vin_md_link_notify(struct media_link *link, u32 flags,
1188 unsigned int notification)
1189 {
1190 if (notification == MEDIA_DEV_NOTIFY_POST_LINK_CH)
1191 vin_log(VIN_LOG_MD, "%s: source %s, sink %s, flag %d\n", __func__,
1192 link->source->entity->name,
1193 link->sink->entity->name, flags);
1194 return 0;
1195 }
1196
1197 const struct media_device_ops media_device_ops = {
1198 .link_notify = vin_md_link_notify,
1199 };
1200
vin_md_sysfs_show(struct device * dev,struct device_attribute * attr,char * buf)1201 static ssize_t vin_md_sysfs_show(struct device *dev,
1202 struct device_attribute *attr, char *buf)
1203 {
1204 struct platform_device *pdev = to_platform_device(dev);
1205 struct vin_md *vind = platform_get_drvdata(pdev);
1206
1207 if (vind->user_subdev_api)
1208 return strlcpy(buf, "Sub-device API (sub-dev)\n", PAGE_SIZE);
1209
1210 return strlcpy(buf, "V4L2 video node only API (vid-dev)\n", PAGE_SIZE);
1211 }
1212
vin_md_sysfs_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)1213 static ssize_t vin_md_sysfs_store(struct device *dev,
1214 struct device_attribute *attr,
1215 const char *buf, size_t count)
1216 {
1217 struct platform_device *pdev = to_platform_device(dev);
1218 struct vin_md *vind = platform_get_drvdata(pdev);
1219 bool subdev_api;
1220 int i;
1221
1222 if (!strcmp(buf, "vid-dev\n"))
1223 subdev_api = false;
1224 else if (!strcmp(buf, "sub-dev\n"))
1225 subdev_api = true;
1226 else
1227 return count;
1228
1229 vind->user_subdev_api = subdev_api;
1230 for (i = 0; i < VIN_MAX_DEV; i++)
1231 if (vind->vinc[i])
1232 vind->vinc[i]->vid_cap.user_subdev_api = subdev_api;
1233 return count;
1234 }
1235
1236 static DEVICE_ATTR(subdev_api, S_IWUSR | S_IRUGO,
1237 vin_md_sysfs_show, vin_md_sysfs_store);
1238
vin_md_register_core_entity(struct vin_md * vind,struct vin_core * vinc)1239 static int vin_md_register_core_entity(struct vin_md *vind,
1240 struct vin_core *vinc)
1241 {
1242 struct v4l2_subdev *sd;
1243 int ret;
1244
1245 if (WARN_ON(vinc->id >= VIN_MAX_DEV))
1246 return -EBUSY;
1247
1248 sd = &vinc->vid_cap.subdev;
1249 v4l2_set_subdev_hostdata(sd, (void *)&vin_pipe_ops);
1250
1251 ret = v4l2_device_register_subdev(&vind->v4l2_dev, sd);
1252 if (!ret) {
1253 vind->vinc[vinc->id] = vinc;
1254 vinc->vid_cap.user_subdev_api = vind->user_subdev_api;
1255 } else {
1256 vin_err("Failed to register vin_cap.%d (%d)\n",
1257 vinc->id, ret);
1258 }
1259 return ret;
1260 }
1261
vin_md_register_entities(struct vin_md * vind,struct device_node * parent)1262 static int vin_md_register_entities(struct vin_md *vind,
1263 struct device_node *parent)
1264 {
1265 int i, j, ret;
1266
1267 vin_log(VIN_LOG_MD, "%s\n", __func__);
1268
1269 for (i = 0; i < VIN_MAX_DEV; i++) {
1270 struct modules_config *module = NULL;
1271 struct sensor_list *sensors = NULL;
1272
1273 module = &vind->modules[i];
1274 sensors = &vind->modules[i].sensors;
1275
1276 sensors->valid_idx = NO_VALID_SENSOR;
1277 for (j = 0; j < sensors->detect_num; j++) {
1278 if (sensors->use_sensor_list == 1)
1279 __vin_handle_sensor_info(&sensors->inst[j]);
1280
1281 if (__vin_register_module(vind, module, j)) {
1282 sensors->valid_idx = j;
1283 break;
1284 }
1285 }
1286 vin_log(VIN_LOG_MD, "list%d valid sensor index %d\n",
1287 i, sensors->valid_idx);
1288
1289 if (sensors->valid_idx == NO_VALID_SENSOR || !module->flash_used)
1290 continue;
1291
1292 /*flash subdev register */
1293 module->modules.flash.sd = sunxi_flash_get_subdev(
1294 module->modules.flash.id);
1295
1296 ret = v4l2_device_register_subdev(&vind->v4l2_dev,
1297 module->modules.flash.sd);
1298 if (ret < 0)
1299 vin_log(VIN_LOG_MD, "flash%d register fail!\n",
1300 module->modules.flash.id);
1301 }
1302
1303 for (i = 0; i < VIN_MAX_DEV; i++) {
1304 struct modules_config *module = NULL;
1305
1306 /*video device register */
1307 vind->vinc[i] = sunxi_vin_core_get_dev(i);
1308 if (vind->vinc[i] == NULL) {
1309 vin_print("vinc%d is null\n", i);
1310 continue;
1311
1312 }
1313
1314 vind->vinc[i]->v4l2_dev = &vind->v4l2_dev;
1315
1316 module = &vind->modules[vind->vinc[i]->rear_sensor];
1317
1318 if (module->sensors.valid_idx == NO_VALID_SENSOR) {
1319 vind->vinc[i] = NULL;
1320 continue;
1321 }
1322 vin_md_register_core_entity(vind, vind->vinc[i]);
1323 }
1324
1325 for (i = 0; i < VIN_MAX_CSI; i++) {
1326 /*Register CSI subdev */
1327 vind->csi[i].id = i;
1328 vind->csi[i].sd = sunxi_csi_get_subdev(i);
1329 ret = v4l2_device_register_subdev(&vind->v4l2_dev,
1330 vind->csi[i].sd);
1331 if (ret < 0)
1332 vin_log(VIN_LOG_MD, "csi%d register fail!\n", i);
1333 }
1334
1335 #ifdef SUPPORT_ISP_TDM
1336 for (i = 0; i < VIN_MAX_TDM; i++) {
1337 /*Register TDM subdev */
1338 vind->tdm[i].id = i;
1339 for (j = 0; j < TDM_RX_NUM; j++) {
1340 vind->tdm[i].tdm_rx[j].sd = sunxi_tdm_get_subdev(i, j);
1341 ret = v4l2_device_register_subdev(&vind->v4l2_dev,
1342 vind->tdm[i].tdm_rx[j].sd);
1343 if (ret < 0)
1344 vin_log(VIN_LOG_MD, "the tdx%d of tdx_rx%d register fail!\n", i, j);
1345 }
1346 }
1347 #endif
1348 for (i = 0; i < VIN_MAX_MIPI; i++) {
1349 /*Register MIPI subdev */
1350 vind->mipi[i].id = i;
1351 vind->mipi[i].sd = sunxi_mipi_get_subdev(i);
1352 ret = v4l2_device_register_subdev(&vind->v4l2_dev,
1353 vind->mipi[i].sd);
1354 if (ret < 0)
1355 vin_log(VIN_LOG_MD, "mipi%d register fail!\n", i);
1356 }
1357
1358 for (i = 0; i < VIN_MAX_ISP; i++) {
1359 /*Register ISP subdev */
1360 vind->isp[i].id = i;
1361 vind->isp[i].sd = sunxi_isp_get_subdev(i);
1362 ret = v4l2_device_register_subdev(&vind->v4l2_dev,
1363 vind->isp[i].sd);
1364 if (ret < 0)
1365 vin_log(VIN_LOG_MD, "isp%d register fail!\n", i);
1366 /*Register STATISTIC BUF subdev */
1367 vind->stat[i].id = i;
1368 vind->stat[i].sd = sunxi_stat_get_subdev(i);
1369 ret = v4l2_device_register_subdev(&vind->v4l2_dev,
1370 vind->stat[i].sd);
1371 if (ret < 0)
1372 vin_log(VIN_LOG_MD, "stat%d register fail!\n", i);
1373 }
1374
1375 for (i = 0; i < VIN_MAX_SCALER; i++) {
1376 /*Register SCALER subdev */
1377 vind->scaler[i].id = i;
1378 vind->scaler[i].sd = sunxi_scaler_get_subdev(i);
1379 ret = v4l2_device_register_subdev(&vind->v4l2_dev,
1380 vind->scaler[i].sd);
1381 if (ret < 0)
1382 vin_log(VIN_LOG_MD, "scaler%d register fail!\n", i);
1383 }
1384
1385 return 0;
1386 }
1387
vin_md_unregister_entities(struct vin_md * vind)1388 static void vin_md_unregister_entities(struct vin_md *vind)
1389 {
1390 int i;
1391 __maybe_unused int j;
1392
1393 for (i = 0; i < VIN_MAX_DEV; i++) {
1394 struct vin_module_info *modules = NULL;
1395 struct sensor_list *sensors = NULL;
1396
1397 sensors = &vind->modules[i].sensors;
1398 if (sensors->valid_idx != NO_VALID_SENSOR) {
1399 __vin_unregister_module(&vind->modules[i],
1400 sensors->valid_idx);
1401
1402 modules = &vind->modules[i].modules;
1403 v4l2_device_unregister_subdev(modules->flash.sd);
1404 modules->flash.sd = NULL;
1405 }
1406
1407 if (vind->vinc[i] == NULL)
1408 continue;
1409 v4l2_device_unregister_subdev(&vind->vinc[i]->vid_cap.subdev);
1410 vind->vinc[i]->pipeline_ops = NULL;
1411 vind->vinc[i] = NULL;
1412 }
1413
1414 for (i = 0; i < VIN_MAX_CSI; i++) {
1415 v4l2_device_unregister_subdev(vind->csi[i].sd);
1416 vind->cci[i].sd = NULL;
1417 }
1418
1419 #ifdef SUPPORT_ISP_TDM
1420 for (i = 0; i < VIN_MAX_TDM; i++) {
1421 for (j = 0; j < TDM_RX_NUM; j++) {
1422 v4l2_device_unregister_subdev(vind->tdm[i].tdm_rx[j].sd);
1423 vind->tdm[i].tdm_rx[j].sd = NULL;
1424 }
1425 }
1426 #endif
1427
1428 for (i = 0; i < VIN_MAX_MIPI; i++) {
1429 v4l2_device_unregister_subdev(vind->mipi[i].sd);
1430 vind->mipi[i].sd = NULL;
1431 }
1432
1433 for (i = 0; i < VIN_MAX_ISP; i++) {
1434 v4l2_device_unregister_subdev(vind->isp[i].sd);
1435 vind->isp[i].sd = NULL;
1436 v4l2_device_unregister_subdev(vind->stat[i].sd);
1437 vind->stat[i].sd = NULL;
1438 }
1439
1440 for (i = 0; i < VIN_MAX_SCALER; i++) {
1441 v4l2_device_unregister_subdev(vind->scaler[i].sd);
1442 vind->scaler[i].sd = NULL;
1443 }
1444
1445 vin_log(VIN_LOG_MD, "%s\n", __func__);
1446 }
1447
sensor_link_to_mipi_csi(struct modules_config * module,struct v4l2_subdev * to)1448 static int sensor_link_to_mipi_csi(struct modules_config *module,
1449 struct v4l2_subdev *to)
1450 {
1451 struct v4l2_subdev *sensor = NULL;
1452 struct media_entity *source, *sink;
1453 int ret = 0;
1454
1455 if (module->sensors.valid_idx == NO_VALID_SENSOR) {
1456 vin_warn("Pipe line %s sensor subdev is NULL!\n",
1457 module->sensors.sensor_pos);
1458 return -1;
1459 }
1460
1461 sensor = module->modules.sensor[module->sensors.valid_idx].sd;
1462 source = &sensor->entity;
1463 sink = &to->entity;
1464 ret = media_create_pad_link(source, SENSOR_PAD_SOURCE, sink, 0, 0);
1465
1466 vin_log(VIN_LOG_MD, "created link [%s] %c> [%s]\n",
1467 source->name, '-', sink->name);
1468 return ret;
1469 }
vin_create_media_links(struct vin_md * vind)1470 static int vin_create_media_links(struct vin_md *vind)
1471 {
1472 struct v4l2_subdev *mipi, *csi, *isp, *stat, *scaler, *cap_sd;
1473 struct media_entity *source, *sink;
1474 struct modules_config *module;
1475 int i, j, ret = 0;
1476 __maybe_unused struct v4l2_subdev *tdm_rx;
1477
1478 for (i = 0; i < VIN_MAX_DEV; i++) {
1479 struct vin_core *vinc = NULL;
1480
1481 vinc = vind->vinc[i];
1482
1483 if (vinc == NULL)
1484 continue;
1485
1486 /*MIPI*/
1487 if (vinc->mipi_sel == 0xff)
1488 mipi = NULL;
1489 else
1490 mipi = vind->mipi[vinc->mipi_sel].sd;
1491 /*CSI*/
1492 if (vinc->csi_sel == 0xff)
1493 csi = NULL;
1494 else
1495 csi = vind->csi[vinc->csi_sel].sd;
1496
1497 if (mipi != NULL) {
1498 /*link MIPI sensor*/
1499 module = &vind->modules[vinc->rear_sensor];
1500 sensor_link_to_mipi_csi(module, mipi);
1501 if (vinc->rear_sensor != vinc->front_sensor) {
1502 module = &vind->modules[vinc->front_sensor];
1503 sensor_link_to_mipi_csi(module, mipi);
1504 }
1505
1506 if (csi == NULL) {
1507 vin_err("MIPI Pipe line csi subdev is NULL, "
1508 "DevID is %d\n", i);
1509 continue;
1510 }
1511 source = &mipi->entity;
1512 sink = &csi->entity;
1513 ret = media_create_pad_link(source, MIPI_PAD_SOURCE,
1514 sink, CSI_PAD_SINK,
1515 MEDIA_LNK_FL_ENABLED);
1516 } else {
1517 /*link Bt.601 sensor*/
1518 if (csi == NULL) {
1519 vin_err("Bt.601 Pipeline csi subdev is NULL, "
1520 "DevID is %d\n", i);
1521 continue;
1522 }
1523 module = &vind->modules[vinc->rear_sensor];
1524 sensor_link_to_mipi_csi(module, csi);
1525 if (vinc->rear_sensor != vinc->front_sensor) {
1526 module = &vind->modules[vinc->front_sensor];
1527 sensor_link_to_mipi_csi(module, csi);
1528 }
1529 }
1530
1531 #ifdef SUPPORT_ISP_TDM
1532 /*tdm*/
1533 if (vinc->tdm_rx_sel == 0xff)
1534 tdm_rx = NULL;
1535 else
1536 tdm_rx = vind->tdm[vinc->tdm_rx_sel/2].tdm_rx[vinc->tdm_rx_sel].sd;
1537 /*isp*/
1538 if (vinc->isp_sel == 0xff)
1539 isp = NULL;
1540 else
1541 isp = vind->isp[vinc->isp_sel].sd;
1542
1543 if (tdm_rx != NULL) {
1544 source = &csi->entity;
1545 sink = &tdm_rx->entity;
1546 ret = media_create_pad_link(source, SCALER_PAD_SOURCE,
1547 sink, VIN_SD_PAD_SINK,
1548 MEDIA_LNK_FL_ENABLED);
1549 vin_log(VIN_LOG_MD, "created link [%s] %c> [%s]\n",
1550 source->name, '=', sink->name);
1551
1552 source = &tdm_rx->entity;
1553 sink = &isp->entity;
1554 ret = media_create_pad_link(source, SCALER_PAD_SOURCE,
1555 sink, VIN_SD_PAD_SINK,
1556 MEDIA_LNK_FL_ENABLED);
1557 vin_log(VIN_LOG_MD, "created link [%s] %c> [%s]\n",
1558 source->name, '=', sink->name);
1559 } else {
1560 source = &csi->entity;
1561 sink = &isp->entity;
1562 ret = media_create_pad_link(source, SCALER_PAD_SOURCE,
1563 sink, VIN_SD_PAD_SINK,
1564 MEDIA_LNK_FL_ENABLED);
1565 vin_log(VIN_LOG_MD, "created link [%s] %c> [%s]\n",
1566 source->name, '=', sink->name);
1567 }
1568 #endif
1569 cap_sd = &vinc->vid_cap.subdev;
1570
1571 /* SCALER */
1572 scaler = vind->scaler[i].sd;
1573 if (scaler == NULL)
1574 continue;
1575 /*Link Vin Core*/
1576 source = &scaler->entity;
1577 sink = &cap_sd->entity;
1578 ret = media_create_pad_link(source, SCALER_PAD_SOURCE,
1579 sink, VIN_SD_PAD_SINK,
1580 MEDIA_LNK_FL_ENABLED);
1581 if (ret)
1582 break;
1583
1584 /* Notify vin core subdev entity */
1585 ret = media_entity_call(sink, link_setup, &sink->pads[0],
1586 &source->pads[SCALER_PAD_SOURCE],
1587 MEDIA_LNK_FL_ENABLED);
1588 if (ret)
1589 break;
1590
1591 vin_log(VIN_LOG_MD, "created link [%s] %c> [%s]\n",
1592 source->name, '=', sink->name);
1593
1594 source = &cap_sd->entity;
1595 sink = &vinc->vid_cap.vdev.entity;
1596 ret = media_create_pad_link(source, VIN_SD_PAD_SOURCE,
1597 sink, 0, MEDIA_LNK_FL_ENABLED);
1598 if (ret)
1599 break;
1600 vin_log(VIN_LOG_MD, "created link [%s] %c> [%s]\n",
1601 source->name, '=', sink->name);
1602 }
1603
1604 #ifndef SUPPORT_ISP_TDM
1605 for (i = 0; i < VIN_MAX_CSI; i++) {
1606 csi = vind->csi[i].sd;
1607 if (csi == NULL)
1608 continue;
1609 source = &csi->entity;
1610 for (j = 0; j < VIN_MAX_ISP; j++) {
1611 isp = vind->isp[j].sd;
1612 if (isp == NULL)
1613 continue;
1614 sink = &isp->entity;
1615 ret = media_create_pad_link(source, CSI_PAD_SOURCE,
1616 sink, ISP_PAD_SINK, 0);
1617 vin_log(VIN_LOG_MD, "created link [%s] %c> [%s]\n",
1618 source->name, '-', sink->name);
1619 }
1620 }
1621 #endif
1622
1623 for (i = 0; i < VIN_MAX_ISP; i++) {
1624 isp = vind->isp[i].sd;
1625 if (isp == NULL)
1626 continue;
1627 source = &isp->entity;
1628 stat = vind->stat[i].sd;
1629 sink = &stat->entity;
1630 ret = media_create_pad_link(source, ISP_PAD_SOURCE_ST,
1631 sink, 0,
1632 MEDIA_LNK_FL_IMMUTABLE |
1633 MEDIA_LNK_FL_ENABLED);
1634 vin_log(VIN_LOG_MD, "created link [%s] %c> [%s]\n",
1635 source->name, '=', sink->name);
1636
1637 for (j = 0; j < VIN_MAX_SCALER; j++) {
1638 scaler = vind->scaler[j].sd;
1639 if (scaler == NULL)
1640 continue;
1641 sink = &scaler->entity;
1642 ret = media_create_pad_link(source, ISP_PAD_SOURCE,
1643 sink, SCALER_PAD_SINK, 0);
1644 vin_log(VIN_LOG_MD, "created link [%s] %c> [%s]\n",
1645 source->name, '-', sink->name);
1646 }
1647 }
1648 return ret;
1649 }
1650
vin_setup_default_links(struct vin_md * vind)1651 static int vin_setup_default_links(struct vin_md *vind)
1652 {
1653 struct v4l2_subdev *isp, *scaler;
1654 int i, ret = 0;
1655
1656 for (i = 0; i < VIN_MAX_DEV; i++) {
1657 struct vin_core *vinc = NULL;
1658 struct media_link *link = NULL;
1659 struct vin_pipeline *p = NULL;
1660
1661 vinc = vind->vinc[i];
1662 if (vinc == NULL)
1663 continue;
1664
1665 /*ISP*/
1666 if (vinc->isp_sel == 0xff)
1667 isp = NULL;
1668 else
1669 isp = vind->isp[vinc->isp_sel].sd;
1670
1671 /*SCALER*/
1672 if (vinc->vipp_sel == 0xff)
1673 scaler = NULL;
1674 else
1675 scaler = vind->scaler[vinc->vipp_sel].sd;
1676 if (isp && scaler)
1677 link = media_entity_find_link(&isp->entity.pads[ISP_PAD_SOURCE],
1678 &scaler->entity.pads[SCALER_PAD_SINK]);
1679
1680 if (link) {
1681 vin_log(VIN_LOG_MD, "link: source %s sink %s\n",
1682 link->source->entity->name,
1683 link->sink->entity->name);
1684 ret = media_entity_setup_link(link, MEDIA_LNK_FL_ENABLED);
1685 if (ret)
1686 vin_err("media_entity_setup_link error\n");
1687 } else {
1688 vin_err("media_entity_find_link null\n");
1689 continue;
1690 }
1691
1692 p = &vinc->vid_cap.pipe;
1693 vin_md_prepare_pipeline(p, &vinc->vid_cap.vdev.entity);
1694 }
1695
1696 return ret;
1697 }
1698
1699 #if IS_ENABLED(CONFIG_MULTI_FRAME)
vin_top_isr(int irq,void * priv)1700 static irqreturn_t vin_top_isr(int irq, void *priv)
1701 {
1702 struct vin_md *vind = (struct vin_md *)priv;
1703 struct cisc_mulp_int_status status;
1704 unsigned long flags;
1705
1706 csic_mulp_int_get_status(vind->id, &status);
1707
1708 spin_lock_irqsave(&vind->slock, flags);
1709
1710 if (status.mulf_done) {
1711 csic_mulp_int_clear_status(vind->id, MULF_DONE);
1712 vin_print("MULF_DONE come\n");
1713 }
1714
1715 if (status.mulf_err) {
1716 csic_mulp_int_clear_status(vind->id, MULF_ERR);
1717 vin_print("MULF_ERR come\n");
1718 }
1719
1720 spin_unlock_irqrestore(&vind->slock, flags);
1721
1722 return IRQ_HANDLED;
1723 }
1724
vind_irq_request(struct vin_md * vind,int i)1725 static int vind_irq_request(struct vin_md *vind, int i)
1726 {
1727 int ret;
1728 struct device_node *np = vind->pdev->dev.of_node;
1729 /*get irq resource */
1730 vind->irq = irq_of_parse_and_map(np, i);
1731 if (vind->irq <= 0) {
1732 vin_warn("Failing to get CSI TOP IRQ resource!\n");
1733 return -ENXIO;
1734 }
1735
1736 ret = request_irq(vind->irq, vin_top_isr, IRQF_SHARED,
1737 vind->pdev->name, vind);
1738
1739 if (ret) {
1740 vin_err("Failing to install CSI TOP irq (%d)!\n", ret);
1741 return -ENXIO;
1742 }
1743 return 0;
1744 }
1745 #endif
1746
vin_probe(struct platform_device * pdev)1747 static int vin_probe(struct platform_device *pdev)
1748 {
1749 struct device *dev = &pdev->dev;
1750 struct device_node *np = pdev->dev.of_node;
1751 struct v4l2_device *v4l2_dev;
1752 struct vin_md *vind;
1753 enum module_type sensor_type, act_type;
1754 int ret, i, num;
1755
1756 vind = devm_kzalloc(dev, sizeof(*vind), GFP_KERNEL);
1757 if (!vind)
1758 return -ENOMEM;
1759
1760 spin_lock_init(&vind->slock);
1761
1762 of_property_read_u32(np, "device_id", &pdev->id);
1763 if (pdev->id < 0) {
1764 vin_err("vin media failed to get device id\n");
1765 pdev->id = 0;
1766 }
1767
1768 vind->id = pdev->id;
1769 vind->pdev = pdev;
1770
1771 vind->base = of_iomap(np, 0);
1772 if (!vind->base) {
1773 vind->is_empty = 1;
1774 vind->base = kzalloc(0x400, GFP_KERNEL);
1775 if (!vind->base) {
1776 ret = -EIO;
1777 goto freedev;
1778 }
1779 }
1780 csic_top_set_base_addr(vind->id, (unsigned long)vind->base);
1781
1782 vind->ccu_base = of_iomap(np, 1);
1783 if (!vind->ccu_base)
1784 vin_warn("vin failed to get ccu base register!\n");
1785 else
1786 csic_ccu_set_base_addr((unsigned long)vind->ccu_base);
1787
1788 #if defined CONFIG_ARCH_SUN50IW10
1789 vind->cmb_top_base = of_iomap(np, 2);
1790 if (!vind->cmb_top_base)
1791 vin_warn("vin failed to get cmb top base register!\n");
1792 else
1793 cmb_csi_set_top_base_addr((unsigned long)vind->cmb_top_base);
1794 #endif
1795
1796 #ifdef CONFIG_MULTI_FRAME
1797 vind_irq_request(vind, 0);
1798 #endif
1799
1800 #if 1
1801 for (num = 0; num < VIN_MAX_DEV; num++) {
1802 #ifdef CONFIG_FLASH_MODULE
1803 vind->modules[num].modules.flash.type = VIN_MODULE_TYPE_GPIO;
1804 #endif
1805 vind->modules[num].sensors.inst[0].cam_addr = i2c0_addr;
1806 strcpy(vind->modules[num].sensors.inst[0].cam_name, ccm0);
1807 vind->modules[num].sensors.inst[0].act_addr = act_slave;
1808 strcpy(vind->modules[num].sensors.inst[0].act_name, act_name);
1809 vind->modules[num].sensors.use_sensor_list = use_sensor_list;
1810 for (i = 0; i < MAX_GPIO_NUM; i++)
1811 vind->modules[num].sensors.gpio[i] = -1;
1812 }
1813 #endif
1814
1815 parse_modules_from_device_tree(vind);
1816
1817 for (num = 0; num < VIN_MAX_DEV; num++) {
1818 sensor_type = vind->modules[num].sensors.sensor_bus_type;
1819 act_type = vind->modules[num].sensors.act_bus_type;
1820
1821 #if defined(CONFIG_CCI_MODULE) || defined(CONFIG_CCI)
1822 sensor_type = VIN_MODULE_TYPE_CCI;
1823 act_type = VIN_MODULE_TYPE_CCI;
1824 #endif
1825 for (i = 0; i < MAX_DETECT_NUM; i++) {
1826 vind->modules[num].modules.sensor[i].type = sensor_type;
1827 vind->modules[num].modules.act[i].type = act_type;
1828 }
1829 }
1830
1831 vin_gpio_request(vind);
1832
1833 strlcpy(vind->media_dev.model, "Allwinner Vin",
1834 sizeof(vind->media_dev.model));
1835
1836 vind->media_dev.ops = &media_device_ops;
1837 vind->media_dev.dev = dev;
1838
1839 v4l2_dev = &vind->v4l2_dev;
1840 v4l2_dev->mdev = &vind->media_dev;
1841 strlcpy(v4l2_dev->name, "sunxi-vin", sizeof(v4l2_dev->name));
1842
1843 ret = v4l2_device_register(dev, &vind->v4l2_dev);
1844 if (ret < 0) {
1845 vin_err("Failed to register v4l2_device: %d\n", ret);
1846 goto unmap;
1847 }
1848 media_device_init(&vind->media_dev);
1849 ret = media_device_register(&vind->media_dev);
1850 if (ret < 0) {
1851 vin_err("Failed to register media device: %d\n",
1852 ret);
1853 goto err_md;
1854 }
1855
1856 platform_set_drvdata(pdev, vind);
1857
1858 ret = vin_md_get_clocks(vind);
1859 if (ret)
1860 goto err_clk;
1861
1862 vind->user_subdev_api = 0;
1863
1864 #ifdef CONFIG_PM
1865 pm_runtime_enable(&pdev->dev);
1866 #endif
1867
1868 vin_md_clk_enable(vind);
1869 vin_set_cci_power(vind, 1);
1870
1871 if (dev->of_node) {
1872 ret = vin_md_register_entities(vind, dev->of_node);
1873 } else {
1874 vin_err("Device tree of_node is NULL!\n");
1875 ret = -ENOSYS;
1876 goto err_clk;
1877 }
1878
1879 vin_set_cci_power(vind, 0);
1880 vin_md_clk_disable(vind);
1881
1882 mutex_lock(&vind->media_dev.graph_mutex);
1883 ret = vin_create_media_links(vind);
1884 mutex_unlock(&vind->media_dev.graph_mutex);
1885 if (ret) {
1886 vin_err("vin_create_media_links error\n");
1887 goto err_clk;
1888 }
1889
1890 /*
1891 * when use media_entity_setup_link we should
1892 * pay attention to graph_mutex dead lock.
1893 */
1894 ret = vin_setup_default_links(vind);
1895 if (ret) {
1896 vin_err("vin_setup_default_links error\n");
1897 goto err_clk;
1898 }
1899
1900 ret = v4l2_device_register_subdev_nodes(&vind->v4l2_dev);
1901 if (ret)
1902 goto err_clk;
1903
1904 ret = device_create_file(&pdev->dev, &dev_attr_subdev_api);
1905 if (ret)
1906 goto err_clk;
1907
1908
1909 vin_log(VIN_LOG_MD, "%s ok!\n", __func__);
1910 return 0;
1911
1912 err_clk:
1913 vin_md_put_clocks(vind);
1914 vin_md_unregister_entities(vind);
1915 media_device_unregister(&vind->media_dev);
1916 err_md:
1917 v4l2_device_unregister(&vind->v4l2_dev);
1918 unmap:
1919 if (!vind->is_empty)
1920 iounmap(vind->base);
1921 else
1922 kfree(vind->base);
1923 freedev:
1924 devm_kfree(dev, vind);
1925 return ret;
1926 }
1927
vin_remove(struct platform_device * pdev)1928 static int vin_remove(struct platform_device *pdev)
1929 {
1930 struct vin_md *vind = (struct vin_md *)dev_get_drvdata(&pdev->dev);
1931
1932 device_remove_file(&pdev->dev, &dev_attr_subdev_api);
1933 vin_md_put_clocks(vind);
1934 vin_mclk_pin_release(vind);
1935 vin_gpio_release(vind);
1936 vin_md_unregister_entities(vind);
1937 v4l2_device_unregister(&vind->v4l2_dev);
1938 media_device_unregister(&vind->media_dev);
1939 media_device_cleanup(&vind->media_dev);
1940 #ifdef CONFIG_PM
1941 pm_runtime_disable(&pdev->dev);
1942 #endif
1943 if (vind->base) {
1944 if (!vind->is_empty)
1945 iounmap(vind->base);
1946 else
1947 kfree(vind->base);
1948 }
1949
1950 devm_kfree(&pdev->dev, vind);
1951 vin_log(VIN_LOG_MD, "%s ok!\n", __func__);
1952 return 0;
1953 }
1954
vin_shutdown(struct platform_device * pdev)1955 static void vin_shutdown(struct platform_device *pdev)
1956 {
1957 vin_log(VIN_LOG_MD, "%s!\n", __func__);
1958 }
1959
1960 #ifdef CONFIG_PM
1961
vin_runtime_suspend(struct device * d)1962 int vin_runtime_suspend(struct device *d)
1963 {
1964 return 0;
1965 }
vin_runtime_resume(struct device * d)1966 int vin_runtime_resume(struct device *d)
1967 {
1968 return 0;
1969 }
1970
vin_runtime_idle(struct device * d)1971 int vin_runtime_idle(struct device *d)
1972 {
1973 return 0;
1974 }
1975
1976 #endif
1977
vin_suspend(struct device * d)1978 int vin_suspend(struct device *d)
1979 {
1980 return 0;
1981 }
1982
vin_resume(struct device * d)1983 int vin_resume(struct device *d)
1984 {
1985 return 0;
1986 }
1987
1988 static const struct dev_pm_ops vin_runtime_pm_ops = {
1989 SET_SYSTEM_SLEEP_PM_OPS(vin_suspend, vin_resume)
1990 SET_RUNTIME_PM_OPS(vin_runtime_suspend, vin_runtime_resume,
1991 vin_runtime_idle)
1992 };
1993
1994 static const struct of_device_id sunxi_vin_match[] = {
1995 {.compatible = "allwinner,sunxi-vin-media",},
1996 {},
1997 };
1998
1999 static struct platform_driver vin_driver = {
2000 .probe = vin_probe,
2001 .remove = vin_remove,
2002 .shutdown = vin_shutdown,
2003 .driver = {
2004 .name = VIN_MODULE_NAME,
2005 .owner = THIS_MODULE,
2006 .of_match_table = sunxi_vin_match,
2007 .pm = &vin_runtime_pm_ops,
2008 }
2009 };
vin_init(void)2010 static int __init vin_init(void)
2011 {
2012 int ret;
2013
2014 vin_log(VIN_LOG_MD, "Welcome to Video Input driver\n");
2015 ret = sunxi_csi_platform_register();
2016 if (ret) {
2017 vin_err("Sunxi csi driver register failed\n");
2018 return ret;
2019 }
2020
2021 #ifdef SUPPORT_ISP_TDM
2022 ret = sunxi_tdm_platform_register();
2023 if (ret) {
2024 vin_err("Sunxi tdm driver register failed\n");
2025 return ret;
2026 }
2027 #endif
2028
2029 ret = sunxi_isp_platform_register();
2030 if (ret) {
2031 vin_err("Sunxi isp driver register failed\n");
2032 return ret;
2033 }
2034
2035 ret = sunxi_mipi_platform_register();
2036 if (ret) {
2037 vin_err("Sunxi mipi driver register failed\n");
2038 return ret;
2039 }
2040
2041 ret = sunxi_flash_platform_register();
2042 if (ret) {
2043 vin_err("Sunxi flash driver register failed\n");
2044 return ret;
2045 }
2046
2047 ret = sunxi_scaler_platform_register();
2048 if (ret) {
2049 vin_err("Sunxi scaler driver register failed\n");
2050 return ret;
2051 }
2052
2053 ret = sunxi_vin_core_register_driver();
2054 if (ret) {
2055 vin_err("Sunxi vin register driver failed!\n");
2056 return ret;
2057 }
2058
2059 ret = platform_driver_register(&vin_driver);
2060 if (ret) {
2061 vin_err("Sunxi vin register driver failed!\n");
2062 return ret;
2063 }
2064
2065 ret = sunxi_vin_debug_register_driver();
2066 if (ret) {
2067 vin_err("Sunxi vin debug register driver failed!\n");
2068 return ret;
2069 }
2070
2071 vin_log(VIN_LOG_MD, "vin init end\n");
2072 return ret;
2073 }
2074
vin_exit(void)2075 static void __exit vin_exit(void)
2076 {
2077 vin_log(VIN_LOG_MD, "vin_exit\n");
2078 platform_driver_unregister(&vin_driver);
2079 sunxi_vin_debug_unregister_driver();
2080 sunxi_vin_core_unregister_driver();
2081 sunxi_csi_platform_unregister();
2082 #ifdef SUPPORT_ISP_TDM
2083 sunxi_tdm_platform_unregister();
2084 #endif
2085 sunxi_isp_platform_unregister();
2086 sunxi_mipi_platform_unregister();
2087 sunxi_flash_platform_unregister();
2088 sunxi_scaler_platform_unregister();
2089 vin_log(VIN_LOG_MD, "vin_exit end\n");
2090 }
2091
2092 module_init(vin_init);
2093 module_exit(vin_exit);
2094
2095 MODULE_AUTHOR("yangfeng");
2096 MODULE_LICENSE("Dual BSD/GPL");
2097 MODULE_DESCRIPTION("Video Input Module for Allwinner");
2098
2099