diff options
| author | Sylwester Nawrocki <s.nawrocki@samsung.com> | 2013-03-29 13:12:39 -0400 |
|---|---|---|
| committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2013-03-31 09:54:18 -0400 |
| commit | 2b13f7d4e3822ed4de37b73b009ff81932e884bb (patch) | |
| tree | 15a7e2ffc126318fdfd6244957ae64b18b03ddc9 | |
| parent | e2985a260e6615503b4fa8e66788708e750c7750 (diff) | |
[media] s5p-fimc: Add device tree based sensors registration
The sensor (I2C and/or SPI client) devices are instantiated by their
corresponding control bus drivers. Since the I2C client's master clock
is often provided by a video bus receiver (host interface) or other
than I2C/SPI controller device, the drivers of those client devices
are not accessing hardware in their driver's probe() callback. Instead,
after enabling clock, the host driver calls back into a sub-device
when it wants to activate them. This pattern is used by some in-tree
drivers and this patch also uses it for DT case. This patch is intended
as a first step for adding device tree support to the S5P/Exynos SoC
camera drivers. The second one is adding support for asynchronous
sub-devices registration and clock control from sub-device driver
level. The bindings shall not change when asynchronous probing support
is added.
Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
| -rw-r--r-- | Documentation/devicetree/bindings/media/samsung-fimc.txt | 86 | ||||
| -rw-r--r-- | drivers/media/platform/s5p-fimc/fimc-mdevice.c | 240 | ||||
| -rw-r--r-- | include/media/s5p_fimc.h | 3 |
3 files changed, 303 insertions, 26 deletions
diff --git a/Documentation/devicetree/bindings/media/samsung-fimc.txt b/Documentation/devicetree/bindings/media/samsung-fimc.txt index 22e2889162c3..bcb0de7462a2 100644 --- a/Documentation/devicetree/bindings/media/samsung-fimc.txt +++ b/Documentation/devicetree/bindings/media/samsung-fimc.txt | |||
| @@ -72,18 +72,95 @@ Optional properties: | |||
| 72 | writeback input. | 72 | writeback input. |
| 73 | 73 | ||
| 74 | 74 | ||
| 75 | 'parallel-ports' node | ||
| 76 | --------------------- | ||
| 77 | |||
| 78 | This node should contain child 'port' nodes specifying active parallel video | ||
| 79 | input ports. It includes camera A and camera B inputs. 'reg' property in the | ||
| 80 | port nodes specifies data input - 0, 1 indicates input A, B respectively. | ||
| 81 | |||
| 82 | Optional properties | ||
| 83 | |||
| 84 | - samsung,camclk-out : specifies clock output for remote sensor, | ||
| 85 | 0 - CAM_A_CLKOUT, 1 - CAM_B_CLKOUT; | ||
| 86 | |||
| 87 | Image sensor nodes | ||
| 88 | ------------------ | ||
| 89 | |||
| 90 | The sensor device nodes should be added to their control bus controller (e.g. | ||
| 91 | I2C0) nodes and linked to a port node in the csis or the parallel-ports node, | ||
| 92 | using the common video interfaces bindings, defined in video-interfaces.txt. | ||
| 93 | The implementation of this bindings requires clock-frequency property to be | ||
| 94 | present in the sensor device nodes. | ||
| 95 | |||
| 75 | Example: | 96 | Example: |
| 76 | 97 | ||
| 77 | aliases { | 98 | aliases { |
| 78 | fimc0 = &fimc_0; | 99 | fimc0 = &fimc_0; |
| 79 | }; | 100 | }; |
| 80 | 101 | ||
| 102 | /* Parallel bus IF sensor */ | ||
| 103 | i2c_0: i2c@13860000 { | ||
| 104 | s5k6aa: sensor@3c { | ||
| 105 | compatible = "samsung,s5k6aafx"; | ||
| 106 | reg = <0x3c>; | ||
| 107 | vddio-supply = <...>; | ||
| 108 | |||
| 109 | clock-frequency = <24000000>; | ||
| 110 | clocks = <...>; | ||
| 111 | clock-names = "mclk"; | ||
| 112 | |||
| 113 | port { | ||
| 114 | s5k6aa_ep: endpoint { | ||
| 115 | remote-endpoint = <&fimc0_ep>; | ||
| 116 | bus-width = <8>; | ||
| 117 | hsync-active = <0>; | ||
| 118 | vsync-active = <1>; | ||
| 119 | pclk-sample = <1>; | ||
| 120 | }; | ||
| 121 | }; | ||
| 122 | }; | ||
| 123 | }; | ||
| 124 | |||
| 125 | /* MIPI CSI-2 bus IF sensor */ | ||
| 126 | s5c73m3: sensor@0x1a { | ||
| 127 | compatible = "samsung,s5c73m3"; | ||
| 128 | reg = <0x1a>; | ||
| 129 | vddio-supply = <...>; | ||
| 130 | |||
| 131 | clock-frequency = <24000000>; | ||
| 132 | clocks = <...>; | ||
| 133 | clock-names = "mclk"; | ||
| 134 | |||
| 135 | port { | ||
| 136 | s5c73m3_1: endpoint { | ||
| 137 | data-lanes = <1 2 3 4>; | ||
| 138 | remote-endpoint = <&csis0_ep>; | ||
| 139 | }; | ||
| 140 | }; | ||
| 141 | }; | ||
| 142 | |||
| 81 | camera { | 143 | camera { |
| 82 | compatible = "samsung,fimc", "simple-bus"; | 144 | compatible = "samsung,fimc", "simple-bus"; |
| 83 | #address-cells = <1>; | 145 | #address-cells = <1>; |
| 84 | #size-cells = <1>; | 146 | #size-cells = <1>; |
| 85 | status = "okay"; | 147 | status = "okay"; |
| 86 | 148 | ||
| 149 | /* parallel camera ports */ | ||
| 150 | parallel-ports { | ||
| 151 | /* camera A input */ | ||
| 152 | port@0 { | ||
| 153 | reg = <0>; | ||
| 154 | fimc0_ep: endpoint { | ||
| 155 | remote-endpoint = <&s5k6aa_ep>; | ||
| 156 | bus-width = <8>; | ||
| 157 | hsync-active = <0>; | ||
| 158 | vsync-active = <1>; | ||
| 159 | pclk-sample = <1>; | ||
| 160 | }; | ||
| 161 | }; | ||
| 162 | }; | ||
| 163 | |||
| 87 | fimc_0: fimc@11800000 { | 164 | fimc_0: fimc@11800000 { |
| 88 | compatible = "samsung,exynos4210-fimc"; | 165 | compatible = "samsung,exynos4210-fimc"; |
| 89 | reg = <0x11800000 0x1000>; | 166 | reg = <0x11800000 0x1000>; |
| @@ -95,6 +172,15 @@ Example: | |||
| 95 | compatible = "samsung,exynos4210-csis"; | 172 | compatible = "samsung,exynos4210-csis"; |
| 96 | reg = <0x11880000 0x1000>; | 173 | reg = <0x11880000 0x1000>; |
| 97 | interrupts = <0 78 0>; | 174 | interrupts = <0 78 0>; |
| 175 | /* camera C input */ | ||
| 176 | port@3 { | ||
| 177 | reg = <3>; | ||
| 178 | csis0_ep: endpoint { | ||
| 179 | remote-endpoint = <&s5c73m3_ep>; | ||
| 180 | data-lanes = <1 2 3 4>; | ||
| 181 | samsung,csis-hs-settle = <12>; | ||
| 182 | }; | ||
| 183 | }; | ||
| 98 | }; | 184 | }; |
| 99 | }; | 185 | }; |
| 100 | 186 | ||
diff --git a/drivers/media/platform/s5p-fimc/fimc-mdevice.c b/drivers/media/platform/s5p-fimc/fimc-mdevice.c index d34106c66427..bfa02abd94c8 100644 --- a/drivers/media/platform/s5p-fimc/fimc-mdevice.c +++ b/drivers/media/platform/s5p-fimc/fimc-mdevice.c | |||
| @@ -251,7 +251,7 @@ static struct v4l2_subdev *fimc_md_register_sensor(struct fimc_md *fmd, | |||
| 251 | sd->grp_id = GRP_ID_SENSOR; | 251 | sd->grp_id = GRP_ID_SENSOR; |
| 252 | 252 | ||
| 253 | v4l2_info(&fmd->v4l2_dev, "Registered sensor subdevice %s\n", | 253 | v4l2_info(&fmd->v4l2_dev, "Registered sensor subdevice %s\n", |
| 254 | s_info->pdata.board_info->type); | 254 | sd->name); |
| 255 | return sd; | 255 | return sd; |
| 256 | } | 256 | } |
| 257 | 257 | ||
| @@ -263,13 +263,191 @@ static void fimc_md_unregister_sensor(struct v4l2_subdev *sd) | |||
| 263 | if (!client) | 263 | if (!client) |
| 264 | return; | 264 | return; |
| 265 | v4l2_device_unregister_subdev(sd); | 265 | v4l2_device_unregister_subdev(sd); |
| 266 | adapter = client->adapter; | 266 | |
| 267 | i2c_unregister_device(client); | 267 | if (!client->dev.of_node) { |
| 268 | if (adapter) | 268 | adapter = client->adapter; |
| 269 | i2c_put_adapter(adapter); | 269 | i2c_unregister_device(client); |
| 270 | if (adapter) | ||
| 271 | i2c_put_adapter(adapter); | ||
| 272 | } | ||
| 270 | } | 273 | } |
| 271 | 274 | ||
| 272 | #ifdef CONFIG_OF | 275 | #ifdef CONFIG_OF |
| 276 | /* Register I2C client subdev associated with @node. */ | ||
| 277 | static int fimc_md_of_add_sensor(struct fimc_md *fmd, | ||
| 278 | struct device_node *node, int index) | ||
| 279 | { | ||
| 280 | struct fimc_sensor_info *si; | ||
| 281 | struct i2c_client *client; | ||
| 282 | struct v4l2_subdev *sd; | ||
| 283 | int ret; | ||
| 284 | |||
| 285 | if (WARN_ON(index >= ARRAY_SIZE(fmd->sensor))) | ||
| 286 | return -EINVAL; | ||
| 287 | si = &fmd->sensor[index]; | ||
| 288 | |||
| 289 | client = of_find_i2c_device_by_node(node); | ||
| 290 | if (!client) | ||
| 291 | return -EPROBE_DEFER; | ||
| 292 | |||
| 293 | device_lock(&client->dev); | ||
| 294 | |||
| 295 | if (!client->driver || | ||
| 296 | !try_module_get(client->driver->driver.owner)) { | ||
| 297 | ret = -EPROBE_DEFER; | ||
| 298 | v4l2_info(&fmd->v4l2_dev, "No driver found for %s\n", | ||
| 299 | node->full_name); | ||
| 300 | goto dev_put; | ||
| 301 | } | ||
| 302 | |||
| 303 | /* Enable sensor's master clock */ | ||
| 304 | ret = __fimc_md_set_camclk(fmd, si, true); | ||
| 305 | if (ret < 0) | ||
| 306 | goto mod_put; | ||
| 307 | sd = i2c_get_clientdata(client); | ||
| 308 | |||
| 309 | ret = v4l2_device_register_subdev(&fmd->v4l2_dev, sd); | ||
| 310 | __fimc_md_set_camclk(fmd, si, false); | ||
| 311 | if (ret < 0) | ||
| 312 | goto mod_put; | ||
| 313 | |||
| 314 | v4l2_set_subdev_hostdata(sd, si); | ||
| 315 | sd->grp_id = GRP_ID_SENSOR; | ||
| 316 | si->subdev = sd; | ||
| 317 | v4l2_info(&fmd->v4l2_dev, "Registered sensor subdevice: %s (%d)\n", | ||
| 318 | sd->name, fmd->num_sensors); | ||
| 319 | fmd->num_sensors++; | ||
| 320 | |||
| 321 | mod_put: | ||
| 322 | module_put(client->driver->driver.owner); | ||
| 323 | dev_put: | ||
| 324 | device_unlock(&client->dev); | ||
| 325 | put_device(&client->dev); | ||
| 326 | return ret; | ||
| 327 | } | ||
| 328 | |||
| 329 | /* Parse port node and register as a sub-device any sensor specified there. */ | ||
| 330 | static int fimc_md_parse_port_node(struct fimc_md *fmd, | ||
| 331 | struct device_node *port, | ||
| 332 | unsigned int index) | ||
| 333 | { | ||
| 334 | struct device_node *rem, *ep, *np; | ||
| 335 | struct fimc_source_info *pd; | ||
| 336 | struct v4l2_of_endpoint endpoint; | ||
| 337 | int ret; | ||
| 338 | u32 val; | ||
| 339 | |||
| 340 | pd = &fmd->sensor[index].pdata; | ||
| 341 | |||
| 342 | /* Assume here a port node can have only one endpoint node. */ | ||
| 343 | ep = of_get_next_child(port, NULL); | ||
| 344 | if (!ep) | ||
| 345 | return 0; | ||
| 346 | |||
| 347 | v4l2_of_parse_endpoint(ep, &endpoint); | ||
| 348 | if (WARN_ON(endpoint.port == 0) || index >= FIMC_MAX_SENSORS) | ||
| 349 | return -EINVAL; | ||
| 350 | |||
| 351 | pd->mux_id = (endpoint.port - 1) & 0x1; | ||
| 352 | |||
| 353 | rem = v4l2_of_get_remote_port_parent(ep); | ||
| 354 | of_node_put(ep); | ||
| 355 | if (rem == NULL) { | ||
| 356 | v4l2_info(&fmd->v4l2_dev, "Remote device at %s not found\n", | ||
| 357 | ep->full_name); | ||
| 358 | return 0; | ||
| 359 | } | ||
| 360 | if (!of_property_read_u32(rem, "samsung,camclk-out", &val)) | ||
| 361 | pd->clk_id = val; | ||
| 362 | |||
| 363 | if (!of_property_read_u32(rem, "clock-frequency", &val)) | ||
| 364 | pd->clk_frequency = val; | ||
| 365 | |||
| 366 | if (pd->clk_frequency == 0) { | ||
| 367 | v4l2_err(&fmd->v4l2_dev, "Wrong clock frequency at node %s\n", | ||
| 368 | rem->full_name); | ||
| 369 | of_node_put(rem); | ||
| 370 | return -EINVAL; | ||
| 371 | } | ||
| 372 | |||
| 373 | if (fimc_input_is_parallel(endpoint.port)) { | ||
| 374 | if (endpoint.bus_type == V4L2_MBUS_PARALLEL) | ||
| 375 | pd->sensor_bus_type = FIMC_BUS_TYPE_ITU_601; | ||
| 376 | else | ||
| 377 | pd->sensor_bus_type = FIMC_BUS_TYPE_ITU_656; | ||
| 378 | pd->flags = endpoint.bus.parallel.flags; | ||
| 379 | } else if (fimc_input_is_mipi_csi(endpoint.port)) { | ||
| 380 | /* | ||
| 381 | * MIPI CSI-2: only input mux selection and | ||
| 382 | * the sensor's clock frequency is needed. | ||
| 383 | */ | ||
| 384 | pd->sensor_bus_type = FIMC_BUS_TYPE_MIPI_CSI2; | ||
| 385 | } else { | ||
| 386 | v4l2_err(&fmd->v4l2_dev, "Wrong port id (%u) at node %s\n", | ||
| 387 | endpoint.port, rem->full_name); | ||
| 388 | } | ||
| 389 | /* | ||
| 390 | * For FIMC-IS handled sensors, that are placed under i2c-isp device | ||
| 391 | * node, FIMC is connected to the FIMC-IS through its ISP Writeback | ||
| 392 | * input. Sensors are attached to the FIMC-LITE hostdata interface | ||
| 393 | * directly or through MIPI-CSIS, depending on the external media bus | ||
| 394 | * used. This needs to be handled in a more reliable way, not by just | ||
| 395 | * checking parent's node name. | ||
| 396 | */ | ||
| 397 | np = of_get_parent(rem); | ||
| 398 | |||
| 399 | if (np && !of_node_cmp(np->name, "i2c-isp")) | ||
| 400 | pd->fimc_bus_type = FIMC_BUS_TYPE_ISP_WRITEBACK; | ||
| 401 | else | ||
| 402 | pd->fimc_bus_type = pd->sensor_bus_type; | ||
| 403 | |||
| 404 | ret = fimc_md_of_add_sensor(fmd, rem, index); | ||
| 405 | of_node_put(rem); | ||
| 406 | |||
| 407 | return ret; | ||
| 408 | } | ||
| 409 | |||
| 410 | /* Register all SoC external sub-devices */ | ||
| 411 | static int fimc_md_of_sensors_register(struct fimc_md *fmd, | ||
| 412 | struct device_node *np) | ||
| 413 | { | ||
| 414 | struct device_node *parent = fmd->pdev->dev.of_node; | ||
| 415 | struct device_node *node, *ports; | ||
| 416 | int index = 0; | ||
| 417 | int ret; | ||
| 418 | |||
| 419 | /* Attach sensors linked to MIPI CSI-2 receivers */ | ||
| 420 | for_each_available_child_of_node(parent, node) { | ||
| 421 | struct device_node *port; | ||
| 422 | |||
| 423 | if (of_node_cmp(node->name, "csis")) | ||
| 424 | continue; | ||
| 425 | /* The csis node can have only port subnode. */ | ||
| 426 | port = of_get_next_child(node, NULL); | ||
| 427 | if (!port) | ||
| 428 | continue; | ||
| 429 | |||
| 430 | ret = fimc_md_parse_port_node(fmd, port, index); | ||
| 431 | if (ret < 0) | ||
| 432 | return ret; | ||
| 433 | index++; | ||
| 434 | } | ||
| 435 | |||
| 436 | /* Attach sensors listed in the parallel-ports node */ | ||
| 437 | ports = of_get_child_by_name(parent, "parallel-ports"); | ||
| 438 | if (!ports) | ||
| 439 | return 0; | ||
| 440 | |||
| 441 | for_each_child_of_node(ports, node) { | ||
| 442 | ret = fimc_md_parse_port_node(fmd, node, index); | ||
| 443 | if (ret < 0) | ||
| 444 | break; | ||
| 445 | index++; | ||
| 446 | } | ||
| 447 | |||
| 448 | return 0; | ||
| 449 | } | ||
| 450 | |||
| 273 | static int __of_get_csis_id(struct device_node *np) | 451 | static int __of_get_csis_id(struct device_node *np) |
| 274 | { | 452 | { |
| 275 | u32 reg = 0; | 453 | u32 reg = 0; |
| @@ -281,14 +459,17 @@ static int __of_get_csis_id(struct device_node *np) | |||
| 281 | return reg - FIMC_INPUT_MIPI_CSI2_0; | 459 | return reg - FIMC_INPUT_MIPI_CSI2_0; |
| 282 | } | 460 | } |
| 283 | #else | 461 | #else |
| 462 | #define fimc_md_of_sensors_register(fmd, np) (-ENOSYS) | ||
| 284 | #define __of_get_csis_id(np) (-ENOSYS) | 463 | #define __of_get_csis_id(np) (-ENOSYS) |
| 285 | #endif | 464 | #endif |
| 286 | 465 | ||
| 287 | static int fimc_md_register_sensor_entities(struct fimc_md *fmd) | 466 | static int fimc_md_register_sensor_entities(struct fimc_md *fmd) |
| 288 | { | 467 | { |
| 289 | struct s5p_platform_fimc *pdata = fmd->pdev->dev.platform_data; | 468 | struct s5p_platform_fimc *pdata = fmd->pdev->dev.platform_data; |
| 469 | struct device_node *of_node = fmd->pdev->dev.of_node; | ||
| 290 | struct fimc_dev *fd = NULL; | 470 | struct fimc_dev *fd = NULL; |
| 291 | int num_clients, ret, i; | 471 | int num_clients = 0; |
| 472 | int ret, i; | ||
| 292 | 473 | ||
| 293 | /* | 474 | /* |
| 294 | * Runtime resume one of the FIMC entities to make sure | 475 | * Runtime resume one of the FIMC entities to make sure |
| @@ -299,34 +480,41 @@ static int fimc_md_register_sensor_entities(struct fimc_md *fmd) | |||
| 299 | fd = fmd->fimc[i]; | 480 | fd = fmd->fimc[i]; |
| 300 | if (!fd) | 481 | if (!fd) |
| 301 | return -ENXIO; | 482 | return -ENXIO; |
| 483 | |||
| 302 | ret = pm_runtime_get_sync(&fd->pdev->dev); | 484 | ret = pm_runtime_get_sync(&fd->pdev->dev); |
| 303 | if (ret < 0) | 485 | if (ret < 0) |
| 304 | return ret; | 486 | return ret; |
| 305 | 487 | ||
| 306 | WARN_ON(pdata->num_clients > ARRAY_SIZE(fmd->sensor)); | 488 | if (of_node) { |
| 307 | num_clients = min_t(u32, pdata->num_clients, ARRAY_SIZE(fmd->sensor)); | 489 | fmd->num_sensors = 0; |
| 490 | ret = fimc_md_of_sensors_register(fmd, of_node); | ||
| 491 | } else if (pdata) { | ||
| 492 | WARN_ON(pdata->num_clients > ARRAY_SIZE(fmd->sensor)); | ||
| 493 | num_clients = min_t(u32, pdata->num_clients, | ||
| 494 | ARRAY_SIZE(fmd->sensor)); | ||
| 495 | fmd->num_sensors = num_clients; | ||
| 308 | 496 | ||
| 309 | fmd->num_sensors = num_clients; | 497 | for (i = 0; i < num_clients; i++) { |
| 310 | for (i = 0; i < num_clients; i++) { | 498 | struct v4l2_subdev *sd; |
| 311 | struct v4l2_subdev *sd; | ||
| 312 | 499 | ||
| 313 | fmd->sensor[i].pdata = pdata->source_info[i]; | 500 | fmd->sensor[i].pdata = pdata->source_info[i]; |
| 314 | ret = __fimc_md_set_camclk(fmd, &fmd->sensor[i], true); | 501 | ret = __fimc_md_set_camclk(fmd, &fmd->sensor[i], true); |
| 315 | if (ret) | 502 | if (ret) |
| 316 | break; | 503 | break; |
| 317 | sd = fimc_md_register_sensor(fmd, &fmd->sensor[i]); | 504 | sd = fimc_md_register_sensor(fmd, &fmd->sensor[i]); |
| 318 | ret = __fimc_md_set_camclk(fmd, &fmd->sensor[i], false); | 505 | ret = __fimc_md_set_camclk(fmd, &fmd->sensor[i], false); |
| 319 | 506 | ||
| 320 | if (!IS_ERR(sd)) { | 507 | if (IS_ERR(sd)) { |
| 508 | fmd->sensor[i].subdev = NULL; | ||
| 509 | ret = PTR_ERR(sd); | ||
| 510 | break; | ||
| 511 | } | ||
| 321 | fmd->sensor[i].subdev = sd; | 512 | fmd->sensor[i].subdev = sd; |
| 322 | } else { | 513 | if (ret) |
| 323 | fmd->sensor[i].subdev = NULL; | 514 | break; |
| 324 | ret = PTR_ERR(sd); | ||
| 325 | break; | ||
| 326 | } | 515 | } |
| 327 | if (ret) | ||
| 328 | break; | ||
| 329 | } | 516 | } |
| 517 | |||
| 330 | pm_runtime_put(&fd->pdev->dev); | 518 | pm_runtime_put(&fd->pdev->dev); |
| 331 | return ret; | 519 | return ret; |
| 332 | } | 520 | } |
| @@ -1037,7 +1225,7 @@ static int fimc_md_probe(struct platform_device *pdev) | |||
| 1037 | if (ret) | 1225 | if (ret) |
| 1038 | goto err_unlock; | 1226 | goto err_unlock; |
| 1039 | 1227 | ||
| 1040 | if (dev->platform_data) { | 1228 | if (dev->platform_data || dev->of_node) { |
| 1041 | ret = fimc_md_register_sensor_entities(fmd); | 1229 | ret = fimc_md_register_sensor_entities(fmd); |
| 1042 | if (ret) | 1230 | if (ret) |
| 1043 | goto err_unlock; | 1231 | goto err_unlock; |
diff --git a/include/media/s5p_fimc.h b/include/media/s5p_fimc.h index e2c598962698..e2434bb0b308 100644 --- a/include/media/s5p_fimc.h +++ b/include/media/s5p_fimc.h | |||
| @@ -45,6 +45,9 @@ enum fimc_bus_type { | |||
| 45 | FIMC_BUS_TYPE_ISP_WRITEBACK = FIMC_BUS_TYPE_LCD_WRITEBACK_B, | 45 | FIMC_BUS_TYPE_ISP_WRITEBACK = FIMC_BUS_TYPE_LCD_WRITEBACK_B, |
| 46 | }; | 46 | }; |
| 47 | 47 | ||
| 48 | #define fimc_input_is_parallel(x) ((x) == 1 || (x) == 2) | ||
| 49 | #define fimc_input_is_mipi_csi(x) ((x) == 3 || (x) == 4) | ||
| 50 | |||
| 48 | struct i2c_board_info; | 51 | struct i2c_board_info; |
| 49 | 52 | ||
| 50 | /** | 53 | /** |
