aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuennadi Liakhovetski <g.liakhovetski@gmx.de>2012-09-17 06:42:55 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2013-06-21 15:07:46 -0400
commitf146e4e79a6f5d457553dfe2ac66b93c7a39f676 (patch)
tree81a665e8f4cc8ffc7b14b08a0c860962f44392ac
parent90438926e807bca4f80237f436bc7d904151fc2b (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.c33
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
2299static const struct of_device_id sh_mobile_ceu_of_match[] = {
2300 { .compatible = "renesas,sh-mobile-ceu" },
2301 { }
2302};
2303MODULE_DEVICE_TABLE(of, sh_mobile_ceu_of_match);
2304
2293static struct platform_driver sh_mobile_ceu_driver = { 2305static 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,