Commit f146e4e7 authored by Guennadi Liakhovetski's avatar Guennadi Liakhovetski Committed by Mauro Carvalho Chehab

[media] sh-mobile-ceu-camera: add primitive OF support

Add an OF hook to sh_mobile_ceu_camera.c, no properties so far. Booting
with DT also requires platform data to be optional.
Signed-off-by: default avatarGuennadi Liakhovetski <g.liakhovetski@gmx.de>
Acked-by: default avatarHans Verkuil <hans.verkuil@cisco.com>
Acked-by: default avatarLaurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent 90438926
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/moduleparam.h> #include <linux/moduleparam.h>
#include <linux/of.h>
#include <linux/time.h> #include <linux/time.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/device.h> #include <linux/device.h>
...@@ -118,6 +119,7 @@ struct sh_mobile_ceu_dev { ...@@ -118,6 +119,7 @@ struct sh_mobile_ceu_dev {
enum v4l2_field field; enum v4l2_field field;
int sequence; int sequence;
unsigned long flags;
unsigned int image_mode:1; unsigned int image_mode:1;
unsigned int is_16bit:1; unsigned int is_16bit:1;
...@@ -706,7 +708,7 @@ static void sh_mobile_ceu_set_rect(struct soc_camera_device *icd) ...@@ -706,7 +708,7 @@ static void sh_mobile_ceu_set_rect(struct soc_camera_device *icd)
} }
/* CSI2 special configuration */ /* CSI2 special configuration */
if (pcdev->pdata->csi2) { if (pcdev->csi2_pdev) {
in_width = ((in_width - 2) * 2); in_width = ((in_width - 2) * 2);
left_offset *= 2; left_offset *= 2;
} }
...@@ -810,7 +812,7 @@ static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd) ...@@ -810,7 +812,7 @@ static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd)
/* Make choises, based on platform preferences */ /* Make choises, based on platform preferences */
if ((common_flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH) && if ((common_flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH) &&
(common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)) { (common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)) {
if (pcdev->pdata->flags & SH_CEU_FLAG_HSYNC_LOW) if (pcdev->flags & SH_CEU_FLAG_HSYNC_LOW)
common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_HIGH; common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_HIGH;
else else
common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_LOW; common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_LOW;
...@@ -818,7 +820,7 @@ static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd) ...@@ -818,7 +820,7 @@ static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd)
if ((common_flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH) && if ((common_flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH) &&
(common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)) { (common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)) {
if (pcdev->pdata->flags & SH_CEU_FLAG_VSYNC_LOW) if (pcdev->flags & SH_CEU_FLAG_VSYNC_LOW)
common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_HIGH; common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_HIGH;
else else
common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_LOW; common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_LOW;
...@@ -873,11 +875,11 @@ static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd) ...@@ -873,11 +875,11 @@ static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd)
value |= common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW ? 1 << 1 : 0; value |= common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW ? 1 << 1 : 0;
value |= common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW ? 1 << 0 : 0; value |= common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW ? 1 << 0 : 0;
if (pcdev->pdata->csi2) /* CSI2 mode */ if (pcdev->csi2_pdev) /* CSI2 mode */
value |= 3 << 12; value |= 3 << 12;
else if (pcdev->is_16bit) else if (pcdev->is_16bit)
value |= 1 << 12; value |= 1 << 12;
else if (pcdev->pdata->flags & SH_CEU_FLAG_LOWER_8BIT) else if (pcdev->flags & SH_CEU_FLAG_LOWER_8BIT)
value |= 2 << 12; value |= 2 << 12;
ceu_write(pcdev, CAMCR, value); ceu_write(pcdev, CAMCR, value);
...@@ -1052,7 +1054,7 @@ static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, unsigned int ...@@ -1052,7 +1054,7 @@ static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, unsigned int
return 0; return 0;
} }
if (!pcdev->pdata->csi2) { if (!pcdev->pdata || !pcdev->pdata->csi2) {
/* Are there any restrictions in the CSI-2 case? */ /* Are there any restrictions in the CSI-2 case? */
ret = sh_mobile_ceu_try_bus_param(icd, fmt->bits_per_sample); ret = sh_mobile_ceu_try_bus_param(icd, fmt->bits_per_sample);
if (ret < 0) if (ret < 0)
...@@ -2107,13 +2109,17 @@ static int sh_mobile_ceu_probe(struct platform_device *pdev) ...@@ -2107,13 +2109,17 @@ static int sh_mobile_ceu_probe(struct platform_device *pdev)
init_completion(&pcdev->complete); init_completion(&pcdev->complete);
pcdev->pdata = pdev->dev.platform_data; pcdev->pdata = pdev->dev.platform_data;
if (!pcdev->pdata) { if (!pcdev->pdata && !pdev->dev.of_node) {
dev_err(&pdev->dev, "CEU platform data not set.\n"); dev_err(&pdev->dev, "CEU platform data not set.\n");
return -EINVAL; return -EINVAL;
} }
pcdev->max_width = pcdev->pdata->max_width ? : 2560; /* TODO: implement per-device bus flags */
pcdev->max_height = pcdev->pdata->max_height ? : 1920; if (pcdev->pdata) {
pcdev->max_width = pcdev->pdata->max_width ? : 2560;
pcdev->max_height = pcdev->pdata->max_height ? : 1920;
pcdev->flags = pcdev->pdata->flags;
}
base = devm_ioremap_resource(&pdev->dev, res); base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(base)) if (IS_ERR(base))
...@@ -2168,7 +2174,7 @@ static int sh_mobile_ceu_probe(struct platform_device *pdev) ...@@ -2168,7 +2174,7 @@ static int sh_mobile_ceu_probe(struct platform_device *pdev)
goto exit_free_ctx; goto exit_free_ctx;
/* CSI2 interfacing */ /* CSI2 interfacing */
csi2 = pcdev->pdata->csi2; csi2 = pcdev->pdata ? pcdev->pdata->csi2 : NULL;
if (csi2) { if (csi2) {
struct platform_device *csi2_pdev = struct platform_device *csi2_pdev =
platform_device_alloc("sh-mobile-csi2", csi2->id); platform_device_alloc("sh-mobile-csi2", csi2->id);
...@@ -2290,10 +2296,17 @@ static const struct dev_pm_ops sh_mobile_ceu_dev_pm_ops = { ...@@ -2290,10 +2296,17 @@ static const struct dev_pm_ops sh_mobile_ceu_dev_pm_ops = {
.runtime_resume = sh_mobile_ceu_runtime_nop, .runtime_resume = sh_mobile_ceu_runtime_nop,
}; };
static const struct of_device_id sh_mobile_ceu_of_match[] = {
{ .compatible = "renesas,sh-mobile-ceu" },
{ }
};
MODULE_DEVICE_TABLE(of, sh_mobile_ceu_of_match);
static struct platform_driver sh_mobile_ceu_driver = { static struct platform_driver sh_mobile_ceu_driver = {
.driver = { .driver = {
.name = "sh_mobile_ceu", .name = "sh_mobile_ceu",
.pm = &sh_mobile_ceu_dev_pm_ops, .pm = &sh_mobile_ceu_dev_pm_ops,
.of_match_table = sh_mobile_ceu_of_match,
}, },
.probe = sh_mobile_ceu_probe, .probe = sh_mobile_ceu_probe,
.remove = sh_mobile_ceu_remove, .remove = sh_mobile_ceu_remove,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment