14 #include <linux/device.h>
15 #include <linux/errno.h>
16 #include <linux/i2c.h>
17 #include <linux/kernel.h>
18 #include <linux/list.h>
19 #include <linux/module.h>
22 #include <linux/types.h>
23 #include <linux/slab.h>
33 static int __fimc_md_set_camclk(
struct fimc_md *fmd,
78 pr_warn(
"%s: Unknown subdev grp_id: %#x\n",
82 pad = &sd->entity.pads[0];
94 static int __subdev_set_power(
struct v4l2_subdev *sd,
int on)
102 use_count = &sd->entity.use_count;
103 if (on && (*use_count)++ > 0)
105 else if (!on && (*use_count == 0 || --(*use_count) > 0))
127 for (i = 0; i <
IDX_MAX; i++) {
128 unsigned int idx = state ? (IDX_MAX - 1) - i : i;
130 ret = __subdev_set_power(p->
subdevs[idx], state);
131 if (ret < 0 && ret != -
ENXIO)
152 fimc_pipeline_prepare(p, me);
161 return fimc_pipeline_s_power(p, 1);
170 ret = __fimc_pipeline_open(p, me, prep);
189 ret = fimc_pipeline_s_power(p, 0);
205 ret = __fimc_pipeline_close(p);
223 for (i = 0; i <
IDX_MAX; i++) {
224 unsigned int idx = on ? (IDX_MAX - 1) - i : i;
238 .
open = fimc_pipeline_open,
239 .close = fimc_pipeline_close,
258 "Failed to get I2C adapter %d, deferring probe\n",
259 s_info->
pdata.i2c_bus_num);
264 if (IS_ERR_OR_NULL(sd)) {
267 "Failed to acquire subdev %s, deferring probe\n",
268 s_info->
pdata.board_info->type);
271 v4l2_set_subdev_hostdata(sd, s_info);
275 s_info->
pdata.board_info->type);
279 static void fimc_md_unregister_sensor(
struct v4l2_subdev *sd)
293 static int fimc_md_register_sensor_entities(
struct fimc_md *fmd)
297 int num_clients,
ret,
i;
308 ret = pm_runtime_get_sync(&fd->
pdev->dev);
316 for (i = 0; i < num_clients; i++) {
320 ret = __fimc_md_set_camclk(fmd, &fmd->
sensor[i],
true);
323 sd = fimc_md_register_sensor(fmd, &fmd->
sensor[i]);
324 ret = __fimc_md_set_camclk(fmd, &fmd->
sensor[i],
false);
336 pm_runtime_put(&fd->
pdev->dev);
343 static int fimc_register_callback(
struct device *
dev,
void *p)
355 v4l2_set_subdev_hostdata(sd, (
void *)&fimc_pipeline_ops);
368 static int fimc_lite_register_callback(
struct device *dev,
void *p)
378 v4l2_set_subdev_hostdata(&fimc->
subdev, (
void *)&fimc_pipeline_ops);
383 "Failed to register FIMC-LITE.%d (%d)\n",
392 static int csis_register_callback(
struct device *dev,
void *p)
401 pdev = v4l2_get_subdevdata(sd);
406 id = pdev->
id < 0 ? 0 : pdev->
id;
414 "Failed to register CSIS subdevice: %d\n", ret);
421 static int fimc_md_register_platform_entities(
struct fimc_md *fmd)
430 "%s driver not found, deffering probe\n",
436 fimc_register_callback);
441 if (driver && try_module_get(driver->
owner)) {
443 fimc_lite_register_callback);
446 module_put(driver->
owner);
464 if (!driver || !try_module_get(driver->
owner)) {
466 "%s driver not found, deffering probe\n",
472 csis_register_callback);
475 static void fimc_md_unregister_entities(
struct fimc_md *fmd)
497 module_put(fmd->
csis[i].sd->owner);
503 fimc_md_unregister_sensor(fmd->
sensor[i].subdev);
516 static int __fimc_md_create_fimc_sink_links(
struct fimc_md *fmd,
523 unsigned int flags = 0;
533 if (!fmd->
fimc[i]->variant->has_cam_if)
538 sink = &fmd->
fimc[
i]->vid_cap.subdev.entity;
546 &source->
pads[pad], flags);
551 source->
name, flags ?
'=' :
'-', sink->
name);
553 if (flags == 0 || sensor ==
NULL)
555 s_info = v4l2_get_subdev_hostdata(sensor);
557 unsigned long irq_flags;
560 spin_unlock_irqrestore(&fmd->
slock, irq_flags);
568 if (link_mask & (1 << (i + FIMC_MAX_DEVS)))
581 &source->
pads[pad], flags);
586 source->
name, flags ?
'=' :
'-', sink->
name);
592 static int __fimc_md_create_flite_source_links(
struct fimc_md *fmd)
602 source = &fimc->
subdev.entity;
603 sink = &fimc->
vfd.entity;
627 static int fimc_md_create_links(
struct fimc_md *fmd)
634 int i,
pad, fimc_id = 0, ret = 0;
641 sensor = fmd->
sensor[
i].subdev;
642 s_info = v4l2_get_subdev_hostdata(sensor);
647 pdata = &s_info->
pdata;
652 "Wrong CSI channel id: %d\n", pdata->
mux_id))
657 "MIPI-CSI interface specified "
658 "but s5p-csis module is not loaded!\n"))
669 sensor->entity.
name, csis->entity.
name);
672 csi_sensors[pdata->
mux_id] = sensor;
676 source = &sensor->entity;
688 link_mask = 1 << fimc_id++;
689 ret = __fimc_md_create_fimc_sink_links(fmd, source, sensor,
696 source = &fmd->
csis[
i].sd->entity;
698 sensor = csi_sensors[
i];
700 link_mask = 1 << fimc_id++;
701 ret = __fimc_md_create_fimc_sink_links(fmd, source, sensor,
710 source = &fmd->
fimc[
i]->vid_cap.subdev.entity;
711 sink = &fmd->
fimc[
i]->vid_cap.vfd.entity;
718 return __fimc_md_create_flite_source_links(fmd);
724 static int fimc_md_get_clocks(
struct fimc_md *fmd)
731 snprintf(clk_name,
sizeof(clk_name),
"sclk_cam%u", i);
733 if (IS_ERR_OR_NULL(clock)) {
743 static void fimc_md_put_clocks(
struct fimc_md *fmd)
748 if (IS_ERR_OR_NULL(fmd->
camclk[i].clock))
755 static int __fimc_md_set_camclk(
struct fimc_md *fmd,
768 dbg(
"camclk %d, f: %lu, use_count: %d, on: %d",
780 dbg(
"Enabled camclk %d: f: %lu", pdata->
clk_id,
791 dbg(
"Disabled camclk %d", pdata->
clk_id);
811 struct fimc_md *fmd = entity_to_fimc_mdev(&sd->entity);
813 return __fimc_md_set_camclk(fmd, s_info, on);
816 static int fimc_md_link_notify(
struct media_pad *source,
832 fimc_lite = v4l2_get_subdevdata(sd);
836 fimc = v4l2_get_subdevdata(sd);
844 ret = __fimc_pipeline_close(pipeline);
862 if (fimc->
vid_cap.refcnt > 0) {
863 ret = __fimc_pipeline_open(pipeline,
872 ret = __fimc_pipeline_open(pipeline,
884 struct fimc_md *fmd = platform_get_drvdata(pdev);
894 const char *buf,
size_t count)
897 struct fimc_md *fmd = platform_get_drvdata(pdev);
901 if (!
strcmp(buf,
"vid-dev\n"))
903 else if (!
strcmp(buf,
"sub-dev\n"))
911 fmd->
fimc[
i]->vid_cap.user_subdev_api = subdev_api;
923 fimc_md_sysfs_show, fimc_md_sysfs_store);
940 fmd->
media_dev.link_notify = fimc_md_link_notify;
947 dev_name(&pdev->
dev));
951 v4l2_err(v4l2_dev,
"Failed to register v4l2_device: %d\n", ret);
956 v4l2_err(v4l2_dev,
"Failed to register media device: %d\n", ret);
959 ret = fimc_md_get_clocks(fmd);
968 ret = fimc_md_register_platform_entities(fmd);
972 if (pdev->
dev.platform_data) {
973 ret = fimc_md_register_sensor_entities(fmd);
977 ret = fimc_md_create_links(fmd);
988 platform_set_drvdata(pdev, fmd);
996 fimc_md_put_clocks(fmd);
997 fimc_md_unregister_entities(fmd);
1005 struct fimc_md *fmd = platform_get_drvdata(pdev);
1010 fimc_md_unregister_entities(fmd);
1012 fimc_md_put_clocks(fmd);
1017 .probe = fimc_md_probe,
1020 .name =
"s5p-fimc-md",
1025 static int __init fimc_md_init(
void)
1029 request_module(
"s5p-csis");
1037 static void __exit fimc_md_exit(
void)