diff options
-rw-r--r-- | Documentation/video4linux/fimc.txt | 30 | ||||
-rw-r--r-- | MAINTAINERS | 1 | ||||
-rw-r--r-- | drivers/media/platform/exynos4-is/Kconfig | 3 | ||||
-rw-r--r-- | drivers/media/platform/exynos4-is/common.c | 2 | ||||
-rw-r--r-- | drivers/media/platform/exynos4-is/fimc-core.h | 2 | ||||
-rw-r--r-- | drivers/media/platform/exynos4-is/fimc-isp-video.c | 2 | ||||
-rw-r--r-- | drivers/media/platform/exynos4-is/fimc-isp.h | 2 | ||||
-rw-r--r-- | drivers/media/platform/exynos4-is/fimc-lite-reg.c | 2 | ||||
-rw-r--r-- | drivers/media/platform/exynos4-is/fimc-lite.c | 2 | ||||
-rw-r--r-- | drivers/media/platform/exynos4-is/fimc-lite.h | 2 | ||||
-rw-r--r-- | drivers/media/platform/exynos4-is/fimc-reg.c | 2 | ||||
-rw-r--r-- | drivers/media/platform/exynos4-is/media-dev.c | 329 | ||||
-rw-r--r-- | drivers/media/platform/exynos4-is/media-dev.h | 6 | ||||
-rw-r--r-- | drivers/media/platform/exynos4-is/mipi-csis.c | 43 | ||||
-rw-r--r-- | include/linux/platform_data/mipi-csis.h | 28 | ||||
-rw-r--r-- | include/media/exynos-fimc.h (renamed from include/media/s5p_fimc.h) | 21 |
16 files changed, 50 insertions, 427 deletions
diff --git a/Documentation/video4linux/fimc.txt b/Documentation/video4linux/fimc.txt index 7d6e160724bd..e0c6b8bc4743 100644 --- a/Documentation/video4linux/fimc.txt +++ b/Documentation/video4linux/fimc.txt | |||
@@ -140,39 +140,9 @@ You can either grep through the kernel log to find relevant information, i.e. | |||
140 | or retrieve the information from /dev/media? with help of the media-ctl tool: | 140 | or retrieve the information from /dev/media? with help of the media-ctl tool: |
141 | # media-ctl -p | 141 | # media-ctl -p |
142 | 142 | ||
143 | 6. Platform support | ||
144 | =================== | ||
145 | |||
146 | The machine code (arch/arm/plat-samsung and arch/arm/mach-*) must select | ||
147 | following options: | ||
148 | |||
149 | CONFIG_S5P_DEV_FIMC0 mandatory | ||
150 | CONFIG_S5P_DEV_FIMC1 \ | ||
151 | CONFIG_S5P_DEV_FIMC2 | optional | ||
152 | CONFIG_S5P_DEV_FIMC3 | | ||
153 | CONFIG_S5P_SETUP_FIMC / | ||
154 | CONFIG_S5P_DEV_CSIS0 \ optional for MIPI-CSI interface | ||
155 | CONFIG_S5P_DEV_CSIS1 / | ||
156 | |||
157 | Except that, relevant s5p_device_fimc? should be registered in the machine code | ||
158 | in addition to a "s5p-fimc-md" platform device to which the media device driver | ||
159 | is bound. The "s5p-fimc-md" device instance is required even if only mem-to-mem | ||
160 | operation is used. | ||
161 | |||
162 | The description of sensor(s) attached to FIMC/MIPI-CSIS camera inputs should be | ||
163 | passed as the "s5p-fimc-md" device platform_data. The platform data structure | ||
164 | is defined in file include/media/s5p_fimc.h. | ||
165 | |||
166 | 7. Build | 143 | 7. Build |
167 | ======== | 144 | ======== |
168 | 145 | ||
169 | This driver depends on following config options: | ||
170 | PLAT_S5P, | ||
171 | PM_RUNTIME, | ||
172 | I2C, | ||
173 | REGULATOR, | ||
174 | VIDEO_V4L2_SUBDEV_API, | ||
175 | |||
176 | If the driver is built as a loadable kernel module (CONFIG_VIDEO_SAMSUNG_S5P_FIMC=m) | 146 | If the driver is built as a loadable kernel module (CONFIG_VIDEO_SAMSUNG_S5P_FIMC=m) |
177 | two modules are created (in addition to the core v4l2 modules): s5p-fimc.ko and | 147 | two modules are created (in addition to the core v4l2 modules): s5p-fimc.ko and |
178 | optional s5p-csis.ko (MIPI-CSI receiver subdev). | 148 | optional s5p-csis.ko (MIPI-CSI receiver subdev). |
diff --git a/MAINTAINERS b/MAINTAINERS index 129621ed165f..6b7c633a2e98 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -7654,7 +7654,6 @@ L: linux-media@vger.kernel.org | |||
7654 | Q: https://patchwork.linuxtv.org/project/linux-media/list/ | 7654 | Q: https://patchwork.linuxtv.org/project/linux-media/list/ |
7655 | S: Supported | 7655 | S: Supported |
7656 | F: drivers/media/platform/exynos4-is/ | 7656 | F: drivers/media/platform/exynos4-is/ |
7657 | F: include/media/s5p_fimc.h | ||
7658 | 7657 | ||
7659 | SAMSUNG S3C24XX/S3C64XX SOC SERIES CAMIF DRIVER | 7658 | SAMSUNG S3C24XX/S3C64XX SOC SERIES CAMIF DRIVER |
7660 | M: Sylwester Nawrocki <sylvester.nawrocki@gmail.com> | 7659 | M: Sylwester Nawrocki <sylvester.nawrocki@gmail.com> |
diff --git a/drivers/media/platform/exynos4-is/Kconfig b/drivers/media/platform/exynos4-is/Kconfig index e1b2ceba00c1..5dcaa0a80540 100644 --- a/drivers/media/platform/exynos4-is/Kconfig +++ b/drivers/media/platform/exynos4-is/Kconfig | |||
@@ -3,6 +3,7 @@ config VIDEO_SAMSUNG_EXYNOS4_IS | |||
3 | bool "Samsung S5P/EXYNOS4 SoC series Camera Subsystem driver" | 3 | bool "Samsung S5P/EXYNOS4 SoC series Camera Subsystem driver" |
4 | depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API | 4 | depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API |
5 | depends on (PLAT_S5P || ARCH_EXYNOS) | 5 | depends on (PLAT_S5P || ARCH_EXYNOS) |
6 | depends on OF && COMMON_CLK | ||
6 | help | 7 | help |
7 | Say Y here to enable camera host interface devices for | 8 | Say Y here to enable camera host interface devices for |
8 | Samsung S5P and EXYNOS SoC series. | 9 | Samsung S5P and EXYNOS SoC series. |
@@ -17,7 +18,7 @@ config VIDEO_S5P_FIMC | |||
17 | depends on I2C | 18 | depends on I2C |
18 | select VIDEOBUF2_DMA_CONTIG | 19 | select VIDEOBUF2_DMA_CONTIG |
19 | select V4L2_MEM2MEM_DEV | 20 | select V4L2_MEM2MEM_DEV |
20 | select MFD_SYSCON if OF | 21 | select MFD_SYSCON |
21 | select VIDEO_EXYNOS4_IS_COMMON | 22 | select VIDEO_EXYNOS4_IS_COMMON |
22 | help | 23 | help |
23 | This is a V4L2 driver for Samsung S5P and EXYNOS4 SoC camera host | 24 | This is a V4L2 driver for Samsung S5P and EXYNOS4 SoC camera host |
diff --git a/drivers/media/platform/exynos4-is/common.c b/drivers/media/platform/exynos4-is/common.c index 0ec210b4da1d..0eb34ecb8ee4 100644 --- a/drivers/media/platform/exynos4-is/common.c +++ b/drivers/media/platform/exynos4-is/common.c | |||
@@ -10,7 +10,7 @@ | |||
10 | */ | 10 | */ |
11 | 11 | ||
12 | #include <linux/module.h> | 12 | #include <linux/module.h> |
13 | #include <media/s5p_fimc.h> | 13 | #include <media/exynos-fimc.h> |
14 | #include "common.h" | 14 | #include "common.h" |
15 | 15 | ||
16 | /* Called with the media graph mutex held or entity->stream_count > 0. */ | 16 | /* Called with the media graph mutex held or entity->stream_count > 0. */ |
diff --git a/drivers/media/platform/exynos4-is/fimc-core.h b/drivers/media/platform/exynos4-is/fimc-core.h index 1790fb4e32ea..6c75c6ced1f7 100644 --- a/drivers/media/platform/exynos4-is/fimc-core.h +++ b/drivers/media/platform/exynos4-is/fimc-core.h | |||
@@ -27,7 +27,7 @@ | |||
27 | #include <media/v4l2-device.h> | 27 | #include <media/v4l2-device.h> |
28 | #include <media/v4l2-mem2mem.h> | 28 | #include <media/v4l2-mem2mem.h> |
29 | #include <media/v4l2-mediabus.h> | 29 | #include <media/v4l2-mediabus.h> |
30 | #include <media/s5p_fimc.h> | 30 | #include <media/exynos-fimc.h> |
31 | 31 | ||
32 | #define dbg(fmt, args...) \ | 32 | #define dbg(fmt, args...) \ |
33 | pr_debug("%s:%d: " fmt "\n", __func__, __LINE__, ##args) | 33 | pr_debug("%s:%d: " fmt "\n", __func__, __LINE__, ##args) |
diff --git a/drivers/media/platform/exynos4-is/fimc-isp-video.c b/drivers/media/platform/exynos4-is/fimc-isp-video.c index ced46600e343..93f9cf2ebcd6 100644 --- a/drivers/media/platform/exynos4-is/fimc-isp-video.c +++ b/drivers/media/platform/exynos4-is/fimc-isp-video.c | |||
@@ -30,7 +30,7 @@ | |||
30 | #include <media/v4l2-ioctl.h> | 30 | #include <media/v4l2-ioctl.h> |
31 | #include <media/videobuf2-core.h> | 31 | #include <media/videobuf2-core.h> |
32 | #include <media/videobuf2-dma-contig.h> | 32 | #include <media/videobuf2-dma-contig.h> |
33 | #include <media/s5p_fimc.h> | 33 | #include <media/exynos-fimc.h> |
34 | 34 | ||
35 | #include "common.h" | 35 | #include "common.h" |
36 | #include "media-dev.h" | 36 | #include "media-dev.h" |
diff --git a/drivers/media/platform/exynos4-is/fimc-isp.h b/drivers/media/platform/exynos4-is/fimc-isp.h index 4dc55a18d978..b99be09b49fc 100644 --- a/drivers/media/platform/exynos4-is/fimc-isp.h +++ b/drivers/media/platform/exynos4-is/fimc-isp.h | |||
@@ -24,7 +24,7 @@ | |||
24 | #include <media/videobuf2-core.h> | 24 | #include <media/videobuf2-core.h> |
25 | #include <media/v4l2-device.h> | 25 | #include <media/v4l2-device.h> |
26 | #include <media/v4l2-mediabus.h> | 26 | #include <media/v4l2-mediabus.h> |
27 | #include <media/s5p_fimc.h> | 27 | #include <media/exynos-fimc.h> |
28 | 28 | ||
29 | extern int fimc_isp_debug; | 29 | extern int fimc_isp_debug; |
30 | 30 | ||
diff --git a/drivers/media/platform/exynos4-is/fimc-lite-reg.c b/drivers/media/platform/exynos4-is/fimc-lite-reg.c index d0dc7ee04452..bc3ec7d25a32 100644 --- a/drivers/media/platform/exynos4-is/fimc-lite-reg.c +++ b/drivers/media/platform/exynos4-is/fimc-lite-reg.c | |||
@@ -12,7 +12,7 @@ | |||
12 | #include <linux/bitops.h> | 12 | #include <linux/bitops.h> |
13 | #include <linux/delay.h> | 13 | #include <linux/delay.h> |
14 | #include <linux/io.h> | 14 | #include <linux/io.h> |
15 | #include <media/s5p_fimc.h> | 15 | #include <media/exynos-fimc.h> |
16 | 16 | ||
17 | #include "fimc-lite-reg.h" | 17 | #include "fimc-lite-reg.h" |
18 | #include "fimc-lite.h" | 18 | #include "fimc-lite.h" |
diff --git a/drivers/media/platform/exynos4-is/fimc-lite.c b/drivers/media/platform/exynos4-is/fimc-lite.c index 630aef52dbb8..a97d2352f1d7 100644 --- a/drivers/media/platform/exynos4-is/fimc-lite.c +++ b/drivers/media/platform/exynos4-is/fimc-lite.c | |||
@@ -30,7 +30,7 @@ | |||
30 | #include <media/v4l2-mem2mem.h> | 30 | #include <media/v4l2-mem2mem.h> |
31 | #include <media/videobuf2-core.h> | 31 | #include <media/videobuf2-core.h> |
32 | #include <media/videobuf2-dma-contig.h> | 32 | #include <media/videobuf2-dma-contig.h> |
33 | #include <media/s5p_fimc.h> | 33 | #include <media/exynos-fimc.h> |
34 | 34 | ||
35 | #include "common.h" | 35 | #include "common.h" |
36 | #include "fimc-core.h" | 36 | #include "fimc-core.h" |
diff --git a/drivers/media/platform/exynos4-is/fimc-lite.h b/drivers/media/platform/exynos4-is/fimc-lite.h index 7428b2d22b52..ea19dc7be63e 100644 --- a/drivers/media/platform/exynos4-is/fimc-lite.h +++ b/drivers/media/platform/exynos4-is/fimc-lite.h | |||
@@ -23,7 +23,7 @@ | |||
23 | #include <media/v4l2-ctrls.h> | 23 | #include <media/v4l2-ctrls.h> |
24 | #include <media/v4l2-device.h> | 24 | #include <media/v4l2-device.h> |
25 | #include <media/v4l2-mediabus.h> | 25 | #include <media/v4l2-mediabus.h> |
26 | #include <media/s5p_fimc.h> | 26 | #include <media/exynos-fimc.h> |
27 | 27 | ||
28 | #define FIMC_LITE_DRV_NAME "exynos-fimc-lite" | 28 | #define FIMC_LITE_DRV_NAME "exynos-fimc-lite" |
29 | #define FLITE_CLK_NAME "flite" | 29 | #define FLITE_CLK_NAME "flite" |
diff --git a/drivers/media/platform/exynos4-is/fimc-reg.c b/drivers/media/platform/exynos4-is/fimc-reg.c index 1db8cb4c46ef..2d77fd8f440a 100644 --- a/drivers/media/platform/exynos4-is/fimc-reg.c +++ b/drivers/media/platform/exynos4-is/fimc-reg.c | |||
@@ -13,7 +13,7 @@ | |||
13 | #include <linux/io.h> | 13 | #include <linux/io.h> |
14 | #include <linux/regmap.h> | 14 | #include <linux/regmap.h> |
15 | 15 | ||
16 | #include <media/s5p_fimc.h> | 16 | #include <media/exynos-fimc.h> |
17 | #include "media-dev.h" | 17 | #include "media-dev.h" |
18 | 18 | ||
19 | #include "fimc-reg.h" | 19 | #include "fimc-reg.h" |
diff --git a/drivers/media/platform/exynos4-is/media-dev.c b/drivers/media/platform/exynos4-is/media-dev.c index 6e2d6042ade6..344718df5c62 100644 --- a/drivers/media/platform/exynos4-is/media-dev.c +++ b/drivers/media/platform/exynos4-is/media-dev.c | |||
@@ -31,7 +31,7 @@ | |||
31 | #include <media/v4l2-ctrls.h> | 31 | #include <media/v4l2-ctrls.h> |
32 | #include <media/v4l2-of.h> | 32 | #include <media/v4l2-of.h> |
33 | #include <media/media-device.h> | 33 | #include <media/media-device.h> |
34 | #include <media/s5p_fimc.h> | 34 | #include <media/exynos-fimc.h> |
35 | 35 | ||
36 | #include "media-dev.h" | 36 | #include "media-dev.h" |
37 | #include "fimc-core.h" | 37 | #include "fimc-core.h" |
@@ -39,10 +39,6 @@ | |||
39 | #include "fimc-lite.h" | 39 | #include "fimc-lite.h" |
40 | #include "mipi-csis.h" | 40 | #include "mipi-csis.h" |
41 | 41 | ||
42 | static int __fimc_md_set_camclk(struct fimc_md *fmd, | ||
43 | struct fimc_source_info *si, | ||
44 | bool on); | ||
45 | |||
46 | /* Set up image sensor subdev -> FIMC capture node notifications. */ | 42 | /* Set up image sensor subdev -> FIMC capture node notifications. */ |
47 | static void __setup_sensor_notification(struct fimc_md *fmd, | 43 | static void __setup_sensor_notification(struct fimc_md *fmd, |
48 | struct v4l2_subdev *sensor, | 44 | struct v4l2_subdev *sensor, |
@@ -223,17 +219,10 @@ static int __fimc_pipeline_open(struct exynos_media_pipeline *ep, | |||
223 | return ret; | 219 | return ret; |
224 | } | 220 | } |
225 | 221 | ||
226 | ret = fimc_md_set_camclk(sd, true); | ||
227 | if (ret < 0) | ||
228 | goto err_wbclk; | ||
229 | |||
230 | ret = fimc_pipeline_s_power(p, 1); | 222 | ret = fimc_pipeline_s_power(p, 1); |
231 | if (!ret) | 223 | if (!ret) |
232 | return 0; | 224 | return 0; |
233 | 225 | ||
234 | fimc_md_set_camclk(sd, false); | ||
235 | |||
236 | err_wbclk: | ||
237 | if (!IS_ERR(fmd->wbclk[CLK_IDX_WB_B]) && p->subdevs[IDX_IS_ISP]) | 226 | if (!IS_ERR(fmd->wbclk[CLK_IDX_WB_B]) && p->subdevs[IDX_IS_ISP]) |
238 | clk_disable_unprepare(fmd->wbclk[CLK_IDX_WB_B]); | 227 | clk_disable_unprepare(fmd->wbclk[CLK_IDX_WB_B]); |
239 | 228 | ||
@@ -259,7 +248,6 @@ static int __fimc_pipeline_close(struct exynos_media_pipeline *ep) | |||
259 | } | 248 | } |
260 | 249 | ||
261 | ret = fimc_pipeline_s_power(p, 0); | 250 | ret = fimc_pipeline_s_power(p, 0); |
262 | fimc_md_set_camclk(sd, false); | ||
263 | 251 | ||
264 | fmd = entity_to_fimc_mdev(&sd->entity); | 252 | fmd = entity_to_fimc_mdev(&sd->entity); |
265 | 253 | ||
@@ -337,75 +325,14 @@ static void fimc_md_pipelines_free(struct fimc_md *fmd) | |||
337 | } | 325 | } |
338 | } | 326 | } |
339 | 327 | ||
340 | /* | ||
341 | * Sensor subdevice helper functions | ||
342 | */ | ||
343 | static struct v4l2_subdev *fimc_md_register_sensor(struct fimc_md *fmd, | ||
344 | struct fimc_source_info *si) | ||
345 | { | ||
346 | struct i2c_adapter *adapter; | ||
347 | struct v4l2_subdev *sd = NULL; | ||
348 | |||
349 | if (!si || !fmd) | ||
350 | return NULL; | ||
351 | /* | ||
352 | * If FIMC bus type is not Writeback FIFO assume it is same | ||
353 | * as sensor_bus_type. | ||
354 | */ | ||
355 | si->fimc_bus_type = si->sensor_bus_type; | ||
356 | |||
357 | adapter = i2c_get_adapter(si->i2c_bus_num); | ||
358 | if (!adapter) { | ||
359 | v4l2_warn(&fmd->v4l2_dev, | ||
360 | "Failed to get I2C adapter %d, deferring probe\n", | ||
361 | si->i2c_bus_num); | ||
362 | return ERR_PTR(-EPROBE_DEFER); | ||
363 | } | ||
364 | sd = v4l2_i2c_new_subdev_board(&fmd->v4l2_dev, adapter, | ||
365 | si->board_info, NULL); | ||
366 | if (IS_ERR_OR_NULL(sd)) { | ||
367 | i2c_put_adapter(adapter); | ||
368 | v4l2_warn(&fmd->v4l2_dev, | ||
369 | "Failed to acquire subdev %s, deferring probe\n", | ||
370 | si->board_info->type); | ||
371 | return ERR_PTR(-EPROBE_DEFER); | ||
372 | } | ||
373 | v4l2_set_subdev_hostdata(sd, si); | ||
374 | sd->grp_id = GRP_ID_SENSOR; | ||
375 | |||
376 | v4l2_info(&fmd->v4l2_dev, "Registered sensor subdevice %s\n", | ||
377 | sd->name); | ||
378 | return sd; | ||
379 | } | ||
380 | |||
381 | static void fimc_md_unregister_sensor(struct v4l2_subdev *sd) | ||
382 | { | ||
383 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
384 | struct i2c_adapter *adapter; | ||
385 | |||
386 | if (!client || client->dev.of_node) | ||
387 | return; | ||
388 | |||
389 | v4l2_device_unregister_subdev(sd); | ||
390 | |||
391 | adapter = client->adapter; | ||
392 | i2c_unregister_device(client); | ||
393 | if (adapter) | ||
394 | i2c_put_adapter(adapter); | ||
395 | } | ||
396 | |||
397 | #ifdef CONFIG_OF | ||
398 | /* Parse port node and register as a sub-device any sensor specified there. */ | 328 | /* Parse port node and register as a sub-device any sensor specified there. */ |
399 | static int fimc_md_parse_port_node(struct fimc_md *fmd, | 329 | static int fimc_md_parse_port_node(struct fimc_md *fmd, |
400 | struct device_node *port, | 330 | struct device_node *port, |
401 | unsigned int index) | 331 | unsigned int index) |
402 | { | 332 | { |
333 | struct fimc_source_info *pd = &fmd->sensor[index].pdata; | ||
403 | struct device_node *rem, *ep, *np; | 334 | struct device_node *rem, *ep, *np; |
404 | struct fimc_source_info *pd; | ||
405 | struct v4l2_of_endpoint endpoint; | 335 | struct v4l2_of_endpoint endpoint; |
406 | u32 val; | ||
407 | |||
408 | pd = &fmd->sensor[index].pdata; | ||
409 | 336 | ||
410 | /* Assume here a port node can have only one endpoint node. */ | 337 | /* Assume here a port node can have only one endpoint node. */ |
411 | ep = of_get_next_child(port, NULL); | 338 | ep = of_get_next_child(port, NULL); |
@@ -425,20 +352,6 @@ static int fimc_md_parse_port_node(struct fimc_md *fmd, | |||
425 | ep->full_name); | 352 | ep->full_name); |
426 | return 0; | 353 | return 0; |
427 | } | 354 | } |
428 | if (!of_property_read_u32(rem, "samsung,camclk-out", &val)) | ||
429 | pd->clk_id = val; | ||
430 | |||
431 | if (!of_property_read_u32(rem, "clock-frequency", &val)) | ||
432 | pd->clk_frequency = val; | ||
433 | else | ||
434 | pd->clk_frequency = DEFAULT_SENSOR_CLK_FREQ; | ||
435 | |||
436 | if (pd->clk_frequency == 0) { | ||
437 | v4l2_err(&fmd->v4l2_dev, "Wrong clock frequency at node %s\n", | ||
438 | rem->full_name); | ||
439 | of_node_put(rem); | ||
440 | return -EINVAL; | ||
441 | } | ||
442 | 355 | ||
443 | if (fimc_input_is_parallel(endpoint.base.port)) { | 356 | if (fimc_input_is_parallel(endpoint.base.port)) { |
444 | if (endpoint.bus_type == V4L2_MBUS_PARALLEL) | 357 | if (endpoint.bus_type == V4L2_MBUS_PARALLEL) |
@@ -485,14 +398,26 @@ static int fimc_md_parse_port_node(struct fimc_md *fmd, | |||
485 | } | 398 | } |
486 | 399 | ||
487 | /* Register all SoC external sub-devices */ | 400 | /* Register all SoC external sub-devices */ |
488 | static int fimc_md_of_sensors_register(struct fimc_md *fmd, | 401 | static int fimc_md_register_sensor_entities(struct fimc_md *fmd) |
489 | struct device_node *np) | ||
490 | { | 402 | { |
491 | struct device_node *parent = fmd->pdev->dev.of_node; | 403 | struct device_node *parent = fmd->pdev->dev.of_node; |
492 | struct device_node *node, *ports; | 404 | struct device_node *node, *ports; |
493 | int index = 0; | 405 | int index = 0; |
494 | int ret; | 406 | int ret; |
495 | 407 | ||
408 | /* | ||
409 | * Runtime resume one of the FIMC entities to make sure | ||
410 | * the sclk_cam clocks are not globally disabled. | ||
411 | */ | ||
412 | if (!fmd->pmf) | ||
413 | return -ENXIO; | ||
414 | |||
415 | ret = pm_runtime_get_sync(fmd->pmf); | ||
416 | if (ret < 0) | ||
417 | return ret; | ||
418 | |||
419 | fmd->num_sensors = 0; | ||
420 | |||
496 | /* Attach sensors linked to MIPI CSI-2 receivers */ | 421 | /* Attach sensors linked to MIPI CSI-2 receivers */ |
497 | for_each_available_child_of_node(parent, node) { | 422 | for_each_available_child_of_node(parent, node) { |
498 | struct device_node *port; | 423 | struct device_node *port; |
@@ -506,14 +431,14 @@ static int fimc_md_of_sensors_register(struct fimc_md *fmd, | |||
506 | 431 | ||
507 | ret = fimc_md_parse_port_node(fmd, port, index); | 432 | ret = fimc_md_parse_port_node(fmd, port, index); |
508 | if (ret < 0) | 433 | if (ret < 0) |
509 | return ret; | 434 | goto rpm_put; |
510 | index++; | 435 | index++; |
511 | } | 436 | } |
512 | 437 | ||
513 | /* Attach sensors listed in the parallel-ports node */ | 438 | /* Attach sensors listed in the parallel-ports node */ |
514 | ports = of_get_child_by_name(parent, "parallel-ports"); | 439 | ports = of_get_child_by_name(parent, "parallel-ports"); |
515 | if (!ports) | 440 | if (!ports) |
516 | return 0; | 441 | goto rpm_put; |
517 | 442 | ||
518 | for_each_child_of_node(ports, node) { | 443 | for_each_child_of_node(ports, node) { |
519 | ret = fimc_md_parse_port_node(fmd, node, index); | 444 | ret = fimc_md_parse_port_node(fmd, node, index); |
@@ -521,8 +446,9 @@ static int fimc_md_of_sensors_register(struct fimc_md *fmd, | |||
521 | break; | 446 | break; |
522 | index++; | 447 | index++; |
523 | } | 448 | } |
524 | 449 | rpm_put: | |
525 | return 0; | 450 | pm_runtime_put(fmd->pmf); |
451 | return ret; | ||
526 | } | 452 | } |
527 | 453 | ||
528 | static int __of_get_csis_id(struct device_node *np) | 454 | static int __of_get_csis_id(struct device_node *np) |
@@ -535,68 +461,10 @@ static int __of_get_csis_id(struct device_node *np) | |||
535 | of_property_read_u32(np, "reg", ®); | 461 | of_property_read_u32(np, "reg", ®); |
536 | return reg - FIMC_INPUT_MIPI_CSI2_0; | 462 | return reg - FIMC_INPUT_MIPI_CSI2_0; |
537 | } | 463 | } |
538 | #else | ||
539 | #define fimc_md_of_sensors_register(fmd, np) (-ENOSYS) | ||
540 | #define __of_get_csis_id(np) (-ENOSYS) | ||
541 | #endif | ||
542 | |||
543 | static int fimc_md_register_sensor_entities(struct fimc_md *fmd) | ||
544 | { | ||
545 | struct s5p_platform_fimc *pdata = fmd->pdev->dev.platform_data; | ||
546 | struct device_node *of_node = fmd->pdev->dev.of_node; | ||
547 | int num_clients = 0; | ||
548 | int ret, i; | ||
549 | |||
550 | /* | ||
551 | * Runtime resume one of the FIMC entities to make sure | ||
552 | * the sclk_cam clocks are not globally disabled. | ||
553 | */ | ||
554 | if (!fmd->pmf) | ||
555 | return -ENXIO; | ||
556 | |||
557 | ret = pm_runtime_get_sync(fmd->pmf); | ||
558 | if (ret < 0) | ||
559 | return ret; | ||
560 | |||
561 | if (of_node) { | ||
562 | fmd->num_sensors = 0; | ||
563 | ret = fimc_md_of_sensors_register(fmd, of_node); | ||
564 | } else if (pdata) { | ||
565 | WARN_ON(pdata->num_clients > ARRAY_SIZE(fmd->sensor)); | ||
566 | num_clients = min_t(u32, pdata->num_clients, | ||
567 | ARRAY_SIZE(fmd->sensor)); | ||
568 | fmd->num_sensors = num_clients; | ||
569 | |||
570 | for (i = 0; i < num_clients; i++) { | ||
571 | struct fimc_sensor_info *si = &fmd->sensor[i]; | ||
572 | struct v4l2_subdev *sd; | ||
573 | |||
574 | si->pdata = pdata->source_info[i]; | ||
575 | ret = __fimc_md_set_camclk(fmd, &si->pdata, true); | ||
576 | if (ret) | ||
577 | break; | ||
578 | sd = fimc_md_register_sensor(fmd, &si->pdata); | ||
579 | ret = __fimc_md_set_camclk(fmd, &si->pdata, false); | ||
580 | |||
581 | if (IS_ERR(sd)) { | ||
582 | si->subdev = NULL; | ||
583 | ret = PTR_ERR(sd); | ||
584 | break; | ||
585 | } | ||
586 | si->subdev = sd; | ||
587 | if (ret) | ||
588 | break; | ||
589 | } | ||
590 | } | ||
591 | |||
592 | pm_runtime_put(fmd->pmf); | ||
593 | return ret; | ||
594 | } | ||
595 | 464 | ||
596 | /* | 465 | /* |
597 | * MIPI-CSIS, FIMC and FIMC-LITE platform devices registration. | 466 | * MIPI-CSIS, FIMC and FIMC-LITE platform devices registration. |
598 | */ | 467 | */ |
599 | |||
600 | static int register_fimc_lite_entity(struct fimc_md *fmd, | 468 | static int register_fimc_lite_entity(struct fimc_md *fmd, |
601 | struct fimc_lite *fimc_lite) | 469 | struct fimc_lite *fimc_lite) |
602 | { | 470 | { |
@@ -753,35 +621,9 @@ dev_unlock: | |||
753 | return ret; | 621 | return ret; |
754 | } | 622 | } |
755 | 623 | ||
756 | static int fimc_md_pdev_match(struct device *dev, void *data) | ||
757 | { | ||
758 | struct platform_device *pdev = to_platform_device(dev); | ||
759 | int plat_entity = -1; | ||
760 | int ret; | ||
761 | char *p; | ||
762 | |||
763 | if (!get_device(dev)) | ||
764 | return -ENODEV; | ||
765 | |||
766 | if (!strcmp(pdev->name, CSIS_DRIVER_NAME)) { | ||
767 | plat_entity = IDX_CSIS; | ||
768 | } else { | ||
769 | p = strstr(pdev->name, "fimc"); | ||
770 | if (p && *(p + 4) == 0) | ||
771 | plat_entity = IDX_FIMC; | ||
772 | } | ||
773 | |||
774 | if (plat_entity >= 0) | ||
775 | ret = fimc_md_register_platform_entity(data, pdev, | ||
776 | plat_entity); | ||
777 | put_device(dev); | ||
778 | return 0; | ||
779 | } | ||
780 | |||
781 | /* Register FIMC, FIMC-LITE and CSIS media entities */ | 624 | /* Register FIMC, FIMC-LITE and CSIS media entities */ |
782 | #ifdef CONFIG_OF | 625 | static int fimc_md_register_platform_entities(struct fimc_md *fmd, |
783 | static int fimc_md_register_of_platform_entities(struct fimc_md *fmd, | 626 | struct device_node *parent) |
784 | struct device_node *parent) | ||
785 | { | 627 | { |
786 | struct device_node *node; | 628 | struct device_node *node; |
787 | int ret = 0; | 629 | int ret = 0; |
@@ -815,9 +657,6 @@ static int fimc_md_register_of_platform_entities(struct fimc_md *fmd, | |||
815 | 657 | ||
816 | return ret; | 658 | return ret; |
817 | } | 659 | } |
818 | #else | ||
819 | #define fimc_md_register_of_platform_entities(fmd, node) (-ENOSYS) | ||
820 | #endif | ||
821 | 660 | ||
822 | static void fimc_md_unregister_entities(struct fimc_md *fmd) | 661 | static void fimc_md_unregister_entities(struct fimc_md *fmd) |
823 | { | 662 | { |
@@ -845,14 +684,6 @@ static void fimc_md_unregister_entities(struct fimc_md *fmd) | |||
845 | v4l2_device_unregister_subdev(fmd->csis[i].sd); | 684 | v4l2_device_unregister_subdev(fmd->csis[i].sd); |
846 | fmd->csis[i].sd = NULL; | 685 | fmd->csis[i].sd = NULL; |
847 | } | 686 | } |
848 | if (fmd->pdev->dev.of_node == NULL) { | ||
849 | for (i = 0; i < fmd->num_sensors; i++) { | ||
850 | if (fmd->sensor[i].subdev == NULL) | ||
851 | continue; | ||
852 | fimc_md_unregister_sensor(fmd->sensor[i].subdev); | ||
853 | fmd->sensor[i].subdev = NULL; | ||
854 | } | ||
855 | } | ||
856 | 687 | ||
857 | if (fmd->fimc_is) | 688 | if (fmd->fimc_is) |
858 | v4l2_device_unregister_subdev(&fmd->fimc_is->isp.subdev); | 689 | v4l2_device_unregister_subdev(&fmd->fimc_is->isp.subdev); |
@@ -1137,7 +968,7 @@ static void fimc_md_put_clocks(struct fimc_md *fmd) | |||
1137 | 968 | ||
1138 | static int fimc_md_get_clocks(struct fimc_md *fmd) | 969 | static int fimc_md_get_clocks(struct fimc_md *fmd) |
1139 | { | 970 | { |
1140 | struct device *dev = NULL; | 971 | struct device *dev = &fmd->pdev->dev; |
1141 | char clk_name[32]; | 972 | char clk_name[32]; |
1142 | struct clk *clock; | 973 | struct clk *clock; |
1143 | int i, ret = 0; | 974 | int i, ret = 0; |
@@ -1145,16 +976,12 @@ static int fimc_md_get_clocks(struct fimc_md *fmd) | |||
1145 | for (i = 0; i < FIMC_MAX_CAMCLKS; i++) | 976 | for (i = 0; i < FIMC_MAX_CAMCLKS; i++) |
1146 | fmd->camclk[i].clock = ERR_PTR(-EINVAL); | 977 | fmd->camclk[i].clock = ERR_PTR(-EINVAL); |
1147 | 978 | ||
1148 | if (fmd->pdev->dev.of_node) | ||
1149 | dev = &fmd->pdev->dev; | ||
1150 | |||
1151 | for (i = 0; i < FIMC_MAX_CAMCLKS; i++) { | 979 | for (i = 0; i < FIMC_MAX_CAMCLKS; i++) { |
1152 | snprintf(clk_name, sizeof(clk_name), "sclk_cam%u", i); | 980 | snprintf(clk_name, sizeof(clk_name), "sclk_cam%u", i); |
1153 | clock = clk_get(dev, clk_name); | 981 | clock = clk_get(dev, clk_name); |
1154 | 982 | ||
1155 | if (IS_ERR(clock)) { | 983 | if (IS_ERR(clock)) { |
1156 | dev_err(&fmd->pdev->dev, "Failed to get clock: %s\n", | 984 | dev_err(dev, "Failed to get clock: %s\n", clk_name); |
1157 | clk_name); | ||
1158 | ret = PTR_ERR(clock); | 985 | ret = PTR_ERR(clock); |
1159 | break; | 986 | break; |
1160 | } | 987 | } |
@@ -1188,86 +1015,6 @@ static int fimc_md_get_clocks(struct fimc_md *fmd) | |||
1188 | return ret; | 1015 | return ret; |
1189 | } | 1016 | } |
1190 | 1017 | ||
1191 | static int __fimc_md_set_camclk(struct fimc_md *fmd, | ||
1192 | struct fimc_source_info *si, | ||
1193 | bool on) | ||
1194 | { | ||
1195 | struct fimc_camclk_info *camclk; | ||
1196 | int ret = 0; | ||
1197 | |||
1198 | /* | ||
1199 | * When device tree is used the sensor drivers are supposed to | ||
1200 | * control the clock themselves. This whole function will be | ||
1201 | * removed once S5PV210 platform is converted to the device tree. | ||
1202 | */ | ||
1203 | if (fmd->pdev->dev.of_node) | ||
1204 | return 0; | ||
1205 | |||
1206 | if (WARN_ON(si->clk_id >= FIMC_MAX_CAMCLKS) || !fmd || !fmd->pmf) | ||
1207 | return -EINVAL; | ||
1208 | |||
1209 | camclk = &fmd->camclk[si->clk_id]; | ||
1210 | |||
1211 | dbg("camclk %d, f: %lu, use_count: %d, on: %d", | ||
1212 | si->clk_id, si->clk_frequency, camclk->use_count, on); | ||
1213 | |||
1214 | if (on) { | ||
1215 | if (camclk->use_count > 0 && | ||
1216 | camclk->frequency != si->clk_frequency) | ||
1217 | return -EINVAL; | ||
1218 | |||
1219 | if (camclk->use_count++ == 0) { | ||
1220 | clk_set_rate(camclk->clock, si->clk_frequency); | ||
1221 | camclk->frequency = si->clk_frequency; | ||
1222 | ret = pm_runtime_get_sync(fmd->pmf); | ||
1223 | if (ret < 0) | ||
1224 | return ret; | ||
1225 | ret = clk_prepare_enable(camclk->clock); | ||
1226 | dbg("Enabled camclk %d: f: %lu", si->clk_id, | ||
1227 | clk_get_rate(camclk->clock)); | ||
1228 | } | ||
1229 | return ret; | ||
1230 | } | ||
1231 | |||
1232 | if (WARN_ON(camclk->use_count == 0)) | ||
1233 | return 0; | ||
1234 | |||
1235 | if (--camclk->use_count == 0) { | ||
1236 | clk_disable_unprepare(camclk->clock); | ||
1237 | pm_runtime_put(fmd->pmf); | ||
1238 | dbg("Disabled camclk %d", si->clk_id); | ||
1239 | } | ||
1240 | return ret; | ||
1241 | } | ||
1242 | |||
1243 | /** | ||
1244 | * fimc_md_set_camclk - peripheral sensor clock setup | ||
1245 | * @sd: sensor subdev to configure sclk_cam clock for | ||
1246 | * @on: 1 to enable or 0 to disable the clock | ||
1247 | * | ||
1248 | * There are 2 separate clock outputs available in the SoC for external | ||
1249 | * image processors. These clocks are shared between all registered FIMC | ||
1250 | * devices to which sensors can be attached, either directly or through | ||
1251 | * the MIPI CSI receiver. The clock is allowed here to be used by | ||
1252 | * multiple sensors concurrently if they use same frequency. | ||
1253 | * This function should only be called when the graph mutex is held. | ||
1254 | */ | ||
1255 | int fimc_md_set_camclk(struct v4l2_subdev *sd, bool on) | ||
1256 | { | ||
1257 | struct fimc_source_info *si = v4l2_get_subdev_hostdata(sd); | ||
1258 | struct fimc_md *fmd = entity_to_fimc_mdev(&sd->entity); | ||
1259 | |||
1260 | /* | ||
1261 | * If there is a clock provider registered the sensors will | ||
1262 | * handle their clock themselves, no need to control it on | ||
1263 | * the host interface side. | ||
1264 | */ | ||
1265 | if (fmd->clk_provider.num_clocks > 0) | ||
1266 | return 0; | ||
1267 | |||
1268 | return __fimc_md_set_camclk(fmd, si, on); | ||
1269 | } | ||
1270 | |||
1271 | static int __fimc_md_modify_pipeline(struct media_entity *entity, bool enable) | 1018 | static int __fimc_md_modify_pipeline(struct media_entity *entity, bool enable) |
1272 | { | 1019 | { |
1273 | struct exynos_video_entity *ve; | 1020 | struct exynos_video_entity *ve; |
@@ -1426,7 +1173,6 @@ static int fimc_md_get_pinctrl(struct fimc_md *fmd) | |||
1426 | return 0; | 1173 | return 0; |
1427 | } | 1174 | } |
1428 | 1175 | ||
1429 | #ifdef CONFIG_OF | ||
1430 | static int cam_clk_prepare(struct clk_hw *hw) | 1176 | static int cam_clk_prepare(struct clk_hw *hw) |
1431 | { | 1177 | { |
1432 | struct cam_clk *camclk = to_cam_clk(hw); | 1178 | struct cam_clk *camclk = to_cam_clk(hw); |
@@ -1518,10 +1264,6 @@ err: | |||
1518 | fimc_md_unregister_clk_provider(fmd); | 1264 | fimc_md_unregister_clk_provider(fmd); |
1519 | return ret; | 1265 | return ret; |
1520 | } | 1266 | } |
1521 | #else | ||
1522 | #define fimc_md_register_clk_provider(fmd) (0) | ||
1523 | #define fimc_md_unregister_clk_provider(fmd) | ||
1524 | #endif | ||
1525 | 1267 | ||
1526 | static int subdev_notifier_bound(struct v4l2_async_notifier *notifier, | 1268 | static int subdev_notifier_bound(struct v4l2_async_notifier *notifier, |
1527 | struct v4l2_subdev *subdev, | 1269 | struct v4l2_subdev *subdev, |
@@ -1585,8 +1327,8 @@ static int fimc_md_probe(struct platform_device *pdev) | |||
1585 | return -ENOMEM; | 1327 | return -ENOMEM; |
1586 | 1328 | ||
1587 | spin_lock_init(&fmd->slock); | 1329 | spin_lock_init(&fmd->slock); |
1588 | fmd->pdev = pdev; | ||
1589 | INIT_LIST_HEAD(&fmd->pipelines); | 1330 | INIT_LIST_HEAD(&fmd->pipelines); |
1331 | fmd->pdev = pdev; | ||
1590 | 1332 | ||
1591 | strlcpy(fmd->media_dev.model, "SAMSUNG S5P FIMC", | 1333 | strlcpy(fmd->media_dev.model, "SAMSUNG S5P FIMC", |
1592 | sizeof(fmd->media_dev.model)); | 1334 | sizeof(fmd->media_dev.model)); |
@@ -1599,6 +1341,7 @@ static int fimc_md_probe(struct platform_device *pdev) | |||
1599 | strlcpy(v4l2_dev->name, "s5p-fimc-md", sizeof(v4l2_dev->name)); | 1341 | strlcpy(v4l2_dev->name, "s5p-fimc-md", sizeof(v4l2_dev->name)); |
1600 | 1342 | ||
1601 | fmd->use_isp = fimc_md_is_isp_available(dev->of_node); | 1343 | fmd->use_isp = fimc_md_is_isp_available(dev->of_node); |
1344 | fmd->user_subdev_api = true; | ||
1602 | 1345 | ||
1603 | ret = v4l2_device_register(dev, &fmd->v4l2_dev); | 1346 | ret = v4l2_device_register(dev, &fmd->v4l2_dev); |
1604 | if (ret < 0) { | 1347 | if (ret < 0) { |
@@ -1616,8 +1359,6 @@ static int fimc_md_probe(struct platform_device *pdev) | |||
1616 | if (ret) | 1359 | if (ret) |
1617 | goto err_md; | 1360 | goto err_md; |
1618 | 1361 | ||
1619 | fmd->user_subdev_api = (dev->of_node != NULL); | ||
1620 | |||
1621 | ret = fimc_md_get_pinctrl(fmd); | 1362 | ret = fimc_md_get_pinctrl(fmd); |
1622 | if (ret < 0) { | 1363 | if (ret < 0) { |
1623 | if (ret != EPROBE_DEFER) | 1364 | if (ret != EPROBE_DEFER) |
@@ -1630,22 +1371,16 @@ static int fimc_md_probe(struct platform_device *pdev) | |||
1630 | /* Protect the media graph while we're registering entities */ | 1371 | /* Protect the media graph while we're registering entities */ |
1631 | mutex_lock(&fmd->media_dev.graph_mutex); | 1372 | mutex_lock(&fmd->media_dev.graph_mutex); |
1632 | 1373 | ||
1633 | if (dev->of_node) | 1374 | ret = fimc_md_register_platform_entities(fmd, dev->of_node); |
1634 | ret = fimc_md_register_of_platform_entities(fmd, dev->of_node); | ||
1635 | else | ||
1636 | ret = bus_for_each_dev(&platform_bus_type, NULL, fmd, | ||
1637 | fimc_md_pdev_match); | ||
1638 | if (ret) { | 1375 | if (ret) { |
1639 | mutex_unlock(&fmd->media_dev.graph_mutex); | 1376 | mutex_unlock(&fmd->media_dev.graph_mutex); |
1640 | goto err_clk; | 1377 | goto err_clk; |
1641 | } | 1378 | } |
1642 | 1379 | ||
1643 | if (dev->platform_data || dev->of_node) { | 1380 | ret = fimc_md_register_sensor_entities(fmd); |
1644 | ret = fimc_md_register_sensor_entities(fmd); | 1381 | if (ret) { |
1645 | if (ret) { | 1382 | mutex_unlock(&fmd->media_dev.graph_mutex); |
1646 | mutex_unlock(&fmd->media_dev.graph_mutex); | 1383 | goto err_m_ent; |
1647 | goto err_m_ent; | ||
1648 | } | ||
1649 | } | 1384 | } |
1650 | 1385 | ||
1651 | mutex_unlock(&fmd->media_dev.graph_mutex); | 1386 | mutex_unlock(&fmd->media_dev.graph_mutex); |
diff --git a/drivers/media/platform/exynos4-is/media-dev.h b/drivers/media/platform/exynos4-is/media-dev.h index 58c49456b13f..03214541f149 100644 --- a/drivers/media/platform/exynos4-is/media-dev.h +++ b/drivers/media/platform/exynos4-is/media-dev.h | |||
@@ -19,7 +19,7 @@ | |||
19 | #include <media/media-entity.h> | 19 | #include <media/media-entity.h> |
20 | #include <media/v4l2-device.h> | 20 | #include <media/v4l2-device.h> |
21 | #include <media/v4l2-subdev.h> | 21 | #include <media/v4l2-subdev.h> |
22 | #include <media/s5p_fimc.h> | 22 | #include <media/exynos-fimc.h> |
23 | 23 | ||
24 | #include "fimc-core.h" | 24 | #include "fimc-core.h" |
25 | #include "fimc-lite.h" | 25 | #include "fimc-lite.h" |
@@ -94,9 +94,7 @@ struct fimc_sensor_info { | |||
94 | }; | 94 | }; |
95 | 95 | ||
96 | struct cam_clk { | 96 | struct cam_clk { |
97 | #ifdef CONFIG_COMMON_CLK | ||
98 | struct clk_hw hw; | 97 | struct clk_hw hw; |
99 | #endif | ||
100 | struct fimc_md *fmd; | 98 | struct fimc_md *fmd; |
101 | }; | 99 | }; |
102 | #define to_cam_clk(_hw) container_of(_hw, struct cam_clk, hw) | 100 | #define to_cam_clk(_hw) container_of(_hw, struct cam_clk, hw) |
@@ -144,9 +142,7 @@ struct fimc_md { | |||
144 | 142 | ||
145 | struct cam_clk_provider { | 143 | struct cam_clk_provider { |
146 | struct clk *clks[FIMC_MAX_CAMCLKS]; | 144 | struct clk *clks[FIMC_MAX_CAMCLKS]; |
147 | #ifdef CONFIG_COMMON_CLK | ||
148 | struct clk_onecell_data clk_data; | 145 | struct clk_onecell_data clk_data; |
149 | #endif | ||
150 | struct device_node *of_node; | 146 | struct device_node *of_node; |
151 | struct cam_clk camclk[FIMC_MAX_CAMCLKS]; | 147 | struct cam_clk camclk[FIMC_MAX_CAMCLKS]; |
152 | int num_clocks; | 148 | int num_clocks; |
diff --git a/drivers/media/platform/exynos4-is/mipi-csis.c b/drivers/media/platform/exynos4-is/mipi-csis.c index 3678ba59725c..ae54ef5f535d 100644 --- a/drivers/media/platform/exynos4-is/mipi-csis.c +++ b/drivers/media/platform/exynos4-is/mipi-csis.c | |||
@@ -22,14 +22,13 @@ | |||
22 | #include <linux/of.h> | 22 | #include <linux/of.h> |
23 | #include <linux/of_graph.h> | 23 | #include <linux/of_graph.h> |
24 | #include <linux/phy/phy.h> | 24 | #include <linux/phy/phy.h> |
25 | #include <linux/platform_data/mipi-csis.h> | ||
26 | #include <linux/platform_device.h> | 25 | #include <linux/platform_device.h> |
27 | #include <linux/pm_runtime.h> | 26 | #include <linux/pm_runtime.h> |
28 | #include <linux/regulator/consumer.h> | 27 | #include <linux/regulator/consumer.h> |
29 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
30 | #include <linux/spinlock.h> | 29 | #include <linux/spinlock.h> |
31 | #include <linux/videodev2.h> | 30 | #include <linux/videodev2.h> |
32 | #include <media/s5p_fimc.h> | 31 | #include <media/exynos-fimc.h> |
33 | #include <media/v4l2-of.h> | 32 | #include <media/v4l2-of.h> |
34 | #include <media/v4l2-subdev.h> | 33 | #include <media/v4l2-subdev.h> |
35 | 34 | ||
@@ -730,26 +729,6 @@ static irqreturn_t s5pcsis_irq_handler(int irq, void *dev_id) | |||
730 | return IRQ_HANDLED; | 729 | return IRQ_HANDLED; |
731 | } | 730 | } |
732 | 731 | ||
733 | static int s5pcsis_get_platform_data(struct platform_device *pdev, | ||
734 | struct csis_state *state) | ||
735 | { | ||
736 | struct s5p_platform_mipi_csis *pdata = pdev->dev.platform_data; | ||
737 | |||
738 | if (pdata == NULL) { | ||
739 | dev_err(&pdev->dev, "Platform data not specified\n"); | ||
740 | return -EINVAL; | ||
741 | } | ||
742 | |||
743 | state->clk_frequency = pdata->clk_rate; | ||
744 | state->num_lanes = pdata->lanes; | ||
745 | state->hs_settle = pdata->hs_settle; | ||
746 | state->index = max(0, pdev->id); | ||
747 | state->max_num_lanes = state->index ? CSIS1_MAX_LANES : | ||
748 | CSIS0_MAX_LANES; | ||
749 | return 0; | ||
750 | } | ||
751 | |||
752 | #ifdef CONFIG_OF | ||
753 | static int s5pcsis_parse_dt(struct platform_device *pdev, | 732 | static int s5pcsis_parse_dt(struct platform_device *pdev, |
754 | struct csis_state *state) | 733 | struct csis_state *state) |
755 | { | 734 | { |
@@ -787,9 +766,6 @@ static int s5pcsis_parse_dt(struct platform_device *pdev, | |||
787 | 766 | ||
788 | return 0; | 767 | return 0; |
789 | } | 768 | } |
790 | #else | ||
791 | #define s5pcsis_parse_dt(pdev, state) (-ENOSYS) | ||
792 | #endif | ||
793 | 769 | ||
794 | static int s5pcsis_pm_resume(struct device *dev, bool runtime); | 770 | static int s5pcsis_pm_resume(struct device *dev, bool runtime); |
795 | static const struct of_device_id s5pcsis_of_match[]; | 771 | static const struct of_device_id s5pcsis_of_match[]; |
@@ -812,19 +788,14 @@ static int s5pcsis_probe(struct platform_device *pdev) | |||
812 | spin_lock_init(&state->slock); | 788 | spin_lock_init(&state->slock); |
813 | state->pdev = pdev; | 789 | state->pdev = pdev; |
814 | 790 | ||
815 | if (dev->of_node) { | 791 | of_id = of_match_node(s5pcsis_of_match, dev->of_node); |
816 | of_id = of_match_node(s5pcsis_of_match, dev->of_node); | 792 | if (WARN_ON(of_id == NULL)) |
817 | if (WARN_ON(of_id == NULL)) | 793 | return -EINVAL; |
818 | return -EINVAL; | ||
819 | |||
820 | drv_data = of_id->data; | ||
821 | state->interrupt_mask = drv_data->interrupt_mask; | ||
822 | 794 | ||
823 | ret = s5pcsis_parse_dt(pdev, state); | 795 | drv_data = of_id->data; |
824 | } else { | 796 | state->interrupt_mask = drv_data->interrupt_mask; |
825 | ret = s5pcsis_get_platform_data(pdev, state); | ||
826 | } | ||
827 | 797 | ||
798 | ret = s5pcsis_parse_dt(pdev, state); | ||
828 | if (ret < 0) | 799 | if (ret < 0) |
829 | return ret; | 800 | return ret; |
830 | 801 | ||
diff --git a/include/linux/platform_data/mipi-csis.h b/include/linux/platform_data/mipi-csis.h deleted file mode 100644 index c2fd9024717c..000000000000 --- a/include/linux/platform_data/mipi-csis.h +++ /dev/null | |||
@@ -1,28 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2010 - 2012 Samsung Electronics Co., Ltd. | ||
3 | * | ||
4 | * Samsung S5P/Exynos SoC series MIPI CSIS device support | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | #ifndef __PLAT_SAMSUNG_MIPI_CSIS_H_ | ||
12 | #define __PLAT_SAMSUNG_MIPI_CSIS_H_ __FILE__ | ||
13 | |||
14 | /** | ||
15 | * struct s5p_platform_mipi_csis - platform data for S5P MIPI-CSIS driver | ||
16 | * @clk_rate: bus clock frequency | ||
17 | * @wclk_source: CSI wrapper clock selection: 0 - bus clock, 1 - ext. SCLK_CAM | ||
18 | * @lanes: number of data lanes used | ||
19 | * @hs_settle: HS-RX settle time | ||
20 | */ | ||
21 | struct s5p_platform_mipi_csis { | ||
22 | unsigned long clk_rate; | ||
23 | u8 wclk_source; | ||
24 | u8 lanes; | ||
25 | u8 hs_settle; | ||
26 | }; | ||
27 | |||
28 | #endif /* __PLAT_SAMSUNG_MIPI_CSIS_H_ */ | ||
diff --git a/include/media/s5p_fimc.h b/include/media/exynos-fimc.h index b975c285c8a9..aa44660e2041 100644 --- a/include/media/s5p_fimc.h +++ b/include/media/exynos-fimc.h | |||
@@ -61,41 +61,20 @@ enum fimc_bus_type { | |||
61 | #define GRP_ID_FLITE (1 << 13) | 61 | #define GRP_ID_FLITE (1 << 13) |
62 | #define GRP_ID_FIMC_IS (1 << 14) | 62 | #define GRP_ID_FIMC_IS (1 << 14) |
63 | 63 | ||
64 | struct i2c_board_info; | ||
65 | |||
66 | /** | 64 | /** |
67 | * struct fimc_source_info - video source description required for the host | 65 | * struct fimc_source_info - video source description required for the host |
68 | * interface configuration | 66 | * interface configuration |
69 | * | 67 | * |
70 | * @board_info: pointer to I2C subdevice's board info | ||
71 | * @clk_frequency: frequency of the clock the host interface provides to sensor | ||
72 | * @fimc_bus_type: FIMC camera input type | 68 | * @fimc_bus_type: FIMC camera input type |
73 | * @sensor_bus_type: image sensor bus type, MIPI, ITU-R BT.601 etc. | 69 | * @sensor_bus_type: image sensor bus type, MIPI, ITU-R BT.601 etc. |
74 | * @flags: the parallel sensor bus flags defining signals polarity (V4L2_MBUS_*) | 70 | * @flags: the parallel sensor bus flags defining signals polarity (V4L2_MBUS_*) |
75 | * @i2c_bus_num: i2c control bus id the sensor is attached to | ||
76 | * @mux_id: FIMC camera interface multiplexer index (separate for MIPI and ITU) | 71 | * @mux_id: FIMC camera interface multiplexer index (separate for MIPI and ITU) |
77 | * @clk_id: index of the SoC peripheral clock for sensors | ||
78 | */ | 72 | */ |
79 | struct fimc_source_info { | 73 | struct fimc_source_info { |
80 | struct i2c_board_info *board_info; | ||
81 | unsigned long clk_frequency; | ||
82 | enum fimc_bus_type fimc_bus_type; | 74 | enum fimc_bus_type fimc_bus_type; |
83 | enum fimc_bus_type sensor_bus_type; | 75 | enum fimc_bus_type sensor_bus_type; |
84 | u16 flags; | 76 | u16 flags; |
85 | u16 i2c_bus_num; | ||
86 | u16 mux_id; | 77 | u16 mux_id; |
87 | u8 clk_id; | ||
88 | }; | ||
89 | |||
90 | /** | ||
91 | * struct s5p_platform_fimc - camera host interface platform data | ||
92 | * | ||
93 | * @source_info: properties of an image source for the host interface setup | ||
94 | * @num_clients: the number of attached image sources | ||
95 | */ | ||
96 | struct s5p_platform_fimc { | ||
97 | struct fimc_source_info *source_info; | ||
98 | int num_clients; | ||
99 | }; | 78 | }; |
100 | 79 | ||
101 | /* | 80 | /* |