diff options
author | Guennadi Liakhovetski <g.liakhovetski@gmx.de> | 2012-09-17 06:42:55 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2013-06-21 15:07:46 -0400 |
commit | f146e4e79a6f5d457553dfe2ac66b93c7a39f676 (patch) | |
tree | 81a665e8f4cc8ffc7b14b08a0c860962f44392ac | |
parent | 90438926e807bca4f80237f436bc7d904151fc2b (diff) |
[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: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r-- | drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c | 33 |
1 files changed, 23 insertions, 10 deletions
diff --git a/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c b/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c index 9037472e9ced..fcc13d8eb070 100644 --- a/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c +++ b/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/kernel.h> | 27 | #include <linux/kernel.h> |
28 | #include <linux/mm.h> | 28 | #include <linux/mm.h> |
29 | #include <linux/moduleparam.h> | 29 | #include <linux/moduleparam.h> |
30 | #include <linux/of.h> | ||
30 | #include <linux/time.h> | 31 | #include <linux/time.h> |
31 | #include <linux/slab.h> | 32 | #include <linux/slab.h> |
32 | #include <linux/device.h> | 33 | #include <linux/device.h> |
@@ -118,6 +119,7 @@ struct sh_mobile_ceu_dev { | |||
118 | 119 | ||
119 | enum v4l2_field field; | 120 | enum v4l2_field field; |
120 | int sequence; | 121 | int sequence; |
122 | unsigned long flags; | ||
121 | 123 | ||
122 | unsigned int image_mode:1; | 124 | unsigned int image_mode:1; |
123 | unsigned int is_16bit:1; | 125 | unsigned int is_16bit:1; |
@@ -706,7 +708,7 @@ static void sh_mobile_ceu_set_rect(struct soc_camera_device *icd) | |||
706 | } | 708 | } |
707 | 709 | ||
708 | /* CSI2 special configuration */ | 710 | /* CSI2 special configuration */ |
709 | if (pcdev->pdata->csi2) { | 711 | if (pcdev->csi2_pdev) { |
710 | in_width = ((in_width - 2) * 2); | 712 | in_width = ((in_width - 2) * 2); |
711 | left_offset *= 2; | 713 | left_offset *= 2; |
712 | } | 714 | } |
@@ -810,7 +812,7 @@ static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd) | |||
810 | /* Make choises, based on platform preferences */ | 812 | /* Make choises, based on platform preferences */ |
811 | if ((common_flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH) && | 813 | if ((common_flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH) && |
812 | (common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)) { | 814 | (common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)) { |
813 | if (pcdev->pdata->flags & SH_CEU_FLAG_HSYNC_LOW) | 815 | if (pcdev->flags & SH_CEU_FLAG_HSYNC_LOW) |
814 | common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_HIGH; | 816 | common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_HIGH; |
815 | else | 817 | else |
816 | common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_LOW; | 818 | 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 | 820 | ||
819 | if ((common_flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH) && | 821 | if ((common_flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH) && |
820 | (common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)) { | 822 | (common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)) { |
821 | if (pcdev->pdata->flags & SH_CEU_FLAG_VSYNC_LOW) | 823 | if (pcdev->flags & SH_CEU_FLAG_VSYNC_LOW) |
822 | common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_HIGH; | 824 | common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_HIGH; |
823 | else | 825 | else |
824 | common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_LOW; | 826 | 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 | value |= common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW ? 1 << 1 : 0; | 875 | value |= common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW ? 1 << 1 : 0; |
874 | value |= common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW ? 1 << 0 : 0; | 876 | value |= common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW ? 1 << 0 : 0; |
875 | 877 | ||
876 | if (pcdev->pdata->csi2) /* CSI2 mode */ | 878 | if (pcdev->csi2_pdev) /* CSI2 mode */ |
877 | value |= 3 << 12; | 879 | value |= 3 << 12; |
878 | else if (pcdev->is_16bit) | 880 | else if (pcdev->is_16bit) |
879 | value |= 1 << 12; | 881 | value |= 1 << 12; |
880 | else if (pcdev->pdata->flags & SH_CEU_FLAG_LOWER_8BIT) | 882 | else if (pcdev->flags & SH_CEU_FLAG_LOWER_8BIT) |
881 | value |= 2 << 12; | 883 | value |= 2 << 12; |
882 | 884 | ||
883 | ceu_write(pcdev, CAMCR, value); | 885 | ceu_write(pcdev, CAMCR, value); |
@@ -1052,7 +1054,7 @@ static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, unsigned int | |||
1052 | return 0; | 1054 | return 0; |
1053 | } | 1055 | } |
1054 | 1056 | ||
1055 | if (!pcdev->pdata->csi2) { | 1057 | if (!pcdev->pdata || !pcdev->pdata->csi2) { |
1056 | /* Are there any restrictions in the CSI-2 case? */ | 1058 | /* Are there any restrictions in the CSI-2 case? */ |
1057 | ret = sh_mobile_ceu_try_bus_param(icd, fmt->bits_per_sample); | 1059 | ret = sh_mobile_ceu_try_bus_param(icd, fmt->bits_per_sample); |
1058 | if (ret < 0) | 1060 | if (ret < 0) |
@@ -2107,13 +2109,17 @@ static int sh_mobile_ceu_probe(struct platform_device *pdev) | |||
2107 | init_completion(&pcdev->complete); | 2109 | init_completion(&pcdev->complete); |
2108 | 2110 | ||
2109 | pcdev->pdata = pdev->dev.platform_data; | 2111 | pcdev->pdata = pdev->dev.platform_data; |
2110 | if (!pcdev->pdata) { | 2112 | if (!pcdev->pdata && !pdev->dev.of_node) { |
2111 | dev_err(&pdev->dev, "CEU platform data not set.\n"); | 2113 | dev_err(&pdev->dev, "CEU platform data not set.\n"); |
2112 | return -EINVAL; | 2114 | return -EINVAL; |
2113 | } | 2115 | } |
2114 | 2116 | ||
2115 | pcdev->max_width = pcdev->pdata->max_width ? : 2560; | 2117 | /* TODO: implement per-device bus flags */ |
2116 | pcdev->max_height = pcdev->pdata->max_height ? : 1920; | 2118 | if (pcdev->pdata) { |
2119 | pcdev->max_width = pcdev->pdata->max_width ? : 2560; | ||
2120 | pcdev->max_height = pcdev->pdata->max_height ? : 1920; | ||
2121 | pcdev->flags = pcdev->pdata->flags; | ||
2122 | } | ||
2117 | 2123 | ||
2118 | base = devm_ioremap_resource(&pdev->dev, res); | 2124 | base = devm_ioremap_resource(&pdev->dev, res); |
2119 | if (IS_ERR(base)) | 2125 | if (IS_ERR(base)) |
@@ -2168,7 +2174,7 @@ static int sh_mobile_ceu_probe(struct platform_device *pdev) | |||
2168 | goto exit_free_ctx; | 2174 | goto exit_free_ctx; |
2169 | 2175 | ||
2170 | /* CSI2 interfacing */ | 2176 | /* CSI2 interfacing */ |
2171 | csi2 = pcdev->pdata->csi2; | 2177 | csi2 = pcdev->pdata ? pcdev->pdata->csi2 : NULL; |
2172 | if (csi2) { | 2178 | if (csi2) { |
2173 | struct platform_device *csi2_pdev = | 2179 | struct platform_device *csi2_pdev = |
2174 | platform_device_alloc("sh-mobile-csi2", csi2->id); | 2180 | 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 | .runtime_resume = sh_mobile_ceu_runtime_nop, | 2296 | .runtime_resume = sh_mobile_ceu_runtime_nop, |
2291 | }; | 2297 | }; |
2292 | 2298 | ||
2299 | static const struct of_device_id sh_mobile_ceu_of_match[] = { | ||
2300 | { .compatible = "renesas,sh-mobile-ceu" }, | ||
2301 | { } | ||
2302 | }; | ||
2303 | MODULE_DEVICE_TABLE(of, sh_mobile_ceu_of_match); | ||
2304 | |||
2293 | static struct platform_driver sh_mobile_ceu_driver = { | 2305 | static struct platform_driver sh_mobile_ceu_driver = { |
2294 | .driver = { | 2306 | .driver = { |
2295 | .name = "sh_mobile_ceu", | 2307 | .name = "sh_mobile_ceu", |
2296 | .pm = &sh_mobile_ceu_dev_pm_ops, | 2308 | .pm = &sh_mobile_ceu_dev_pm_ops, |
2309 | .of_match_table = sh_mobile_ceu_of_match, | ||
2297 | }, | 2310 | }, |
2298 | .probe = sh_mobile_ceu_probe, | 2311 | .probe = sh_mobile_ceu_probe, |
2299 | .remove = sh_mobile_ceu_remove, | 2312 | .remove = sh_mobile_ceu_remove, |