diff options
author | Josh Wu <josh.wu@atmel.com> | 2014-07-28 03:25:17 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <m.chehab@samsung.com> | 2014-07-30 18:48:36 -0400 |
commit | 8ff19bc437f8d42d8a03dafe2bb28c5b3fc1bff1 (patch) | |
tree | 4701913487f39c3687b2f002e4c40a7e64b16463 /drivers/media | |
parent | 833e1063266ebbf75934f1171c6546cdf33e9848 (diff) |
[media] media: atmel-isi: add primary DT support
This patch add the DT support for Atmel ISI driver.
It use the same v4l2 DT interface that defined in video-interfaces.txt.
Signed-off-by: Josh Wu <josh.wu@atmel.com>
Cc: devicetree@vger.kernel.org
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
Diffstat (limited to 'drivers/media')
-rw-r--r-- | drivers/media/platform/soc_camera/atmel-isi.c | 65 |
1 files changed, 63 insertions, 2 deletions
diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c index d32c53383565..3408b045b3f1 100644 --- a/drivers/media/platform/soc_camera/atmel-isi.c +++ b/drivers/media/platform/soc_camera/atmel-isi.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <media/atmel-isi.h> | 25 | #include <media/atmel-isi.h> |
26 | #include <media/soc_camera.h> | 26 | #include <media/soc_camera.h> |
27 | #include <media/soc_mediabus.h> | 27 | #include <media/soc_mediabus.h> |
28 | #include <media/v4l2-of.h> | ||
28 | #include <media/videobuf2-dma-contig.h> | 29 | #include <media/videobuf2-dma-contig.h> |
29 | 30 | ||
30 | #define MAX_BUFFER_NUM 32 | 31 | #define MAX_BUFFER_NUM 32 |
@@ -33,6 +34,7 @@ | |||
33 | #define VID_LIMIT_BYTES (16 * 1024 * 1024) | 34 | #define VID_LIMIT_BYTES (16 * 1024 * 1024) |
34 | #define MIN_FRAME_RATE 15 | 35 | #define MIN_FRAME_RATE 15 |
35 | #define FRAME_INTERVAL_MILLI_SEC (1000 / MIN_FRAME_RATE) | 36 | #define FRAME_INTERVAL_MILLI_SEC (1000 / MIN_FRAME_RATE) |
37 | #define ISI_DEFAULT_MCLK_FREQ 25000000 | ||
36 | 38 | ||
37 | /* Frame buffer descriptor */ | 39 | /* Frame buffer descriptor */ |
38 | struct fbd { | 40 | struct fbd { |
@@ -876,6 +878,51 @@ static int atmel_isi_remove(struct platform_device *pdev) | |||
876 | return 0; | 878 | return 0; |
877 | } | 879 | } |
878 | 880 | ||
881 | static int atmel_isi_probe_dt(struct atmel_isi *isi, | ||
882 | struct platform_device *pdev) | ||
883 | { | ||
884 | struct device_node *np= pdev->dev.of_node; | ||
885 | struct v4l2_of_endpoint ep; | ||
886 | int err; | ||
887 | |||
888 | /* Default settings for ISI */ | ||
889 | isi->pdata.full_mode = 1; | ||
890 | isi->pdata.mck_hz = ISI_DEFAULT_MCLK_FREQ; | ||
891 | isi->pdata.frate = ISI_CFG1_FRATE_CAPTURE_ALL; | ||
892 | |||
893 | np = of_graph_get_next_endpoint(np, NULL); | ||
894 | if (!np) { | ||
895 | dev_err(&pdev->dev, "Could not find the endpoint\n"); | ||
896 | return -EINVAL; | ||
897 | } | ||
898 | |||
899 | err = v4l2_of_parse_endpoint(np, &ep); | ||
900 | if (err) { | ||
901 | dev_err(&pdev->dev, "Could not parse the endpoint\n"); | ||
902 | goto err_probe_dt; | ||
903 | } | ||
904 | |||
905 | switch (ep.bus.parallel.bus_width) { | ||
906 | case 8: | ||
907 | isi->pdata.data_width_flags = ISI_DATAWIDTH_8; | ||
908 | break; | ||
909 | case 10: | ||
910 | isi->pdata.data_width_flags = | ||
911 | ISI_DATAWIDTH_8 | ISI_DATAWIDTH_10; | ||
912 | break; | ||
913 | default: | ||
914 | dev_err(&pdev->dev, "Unsupported bus width: %d\n", | ||
915 | ep.bus.parallel.bus_width); | ||
916 | err = -EINVAL; | ||
917 | goto err_probe_dt; | ||
918 | } | ||
919 | |||
920 | err_probe_dt: | ||
921 | of_node_put(np); | ||
922 | |||
923 | return err; | ||
924 | } | ||
925 | |||
879 | static int atmel_isi_probe(struct platform_device *pdev) | 926 | static int atmel_isi_probe(struct platform_device *pdev) |
880 | { | 927 | { |
881 | unsigned int irq; | 928 | unsigned int irq; |
@@ -887,7 +934,7 @@ static int atmel_isi_probe(struct platform_device *pdev) | |||
887 | struct isi_platform_data *pdata; | 934 | struct isi_platform_data *pdata; |
888 | 935 | ||
889 | pdata = dev->platform_data; | 936 | pdata = dev->platform_data; |
890 | if (!pdata || !pdata->data_width_flags) { | 937 | if ((!pdata || !pdata->data_width_flags) && !pdev->dev.of_node) { |
891 | dev_err(&pdev->dev, | 938 | dev_err(&pdev->dev, |
892 | "No config available for Atmel ISI\n"); | 939 | "No config available for Atmel ISI\n"); |
893 | return -EINVAL; | 940 | return -EINVAL; |
@@ -903,7 +950,14 @@ static int atmel_isi_probe(struct platform_device *pdev) | |||
903 | if (IS_ERR(isi->pclk)) | 950 | if (IS_ERR(isi->pclk)) |
904 | return PTR_ERR(isi->pclk); | 951 | return PTR_ERR(isi->pclk); |
905 | 952 | ||
906 | memcpy(&isi->pdata, pdata, sizeof(isi->pdata)); | 953 | if (pdata) { |
954 | memcpy(&isi->pdata, pdata, sizeof(isi->pdata)); | ||
955 | } else { | ||
956 | ret = atmel_isi_probe_dt(isi, pdev); | ||
957 | if (ret) | ||
958 | return ret; | ||
959 | } | ||
960 | |||
907 | isi->active = NULL; | 961 | isi->active = NULL; |
908 | spin_lock_init(&isi->lock); | 962 | spin_lock_init(&isi->lock); |
909 | INIT_LIST_HEAD(&isi->video_buffer_list); | 963 | INIT_LIST_HEAD(&isi->video_buffer_list); |
@@ -1005,11 +1059,18 @@ err_alloc_ctx: | |||
1005 | return ret; | 1059 | return ret; |
1006 | } | 1060 | } |
1007 | 1061 | ||
1062 | static const struct of_device_id atmel_isi_of_match[] = { | ||
1063 | { .compatible = "atmel,at91sam9g45-isi" }, | ||
1064 | { } | ||
1065 | }; | ||
1066 | MODULE_DEVICE_TABLE(of, atmel_isi_of_match); | ||
1067 | |||
1008 | static struct platform_driver atmel_isi_driver = { | 1068 | static struct platform_driver atmel_isi_driver = { |
1009 | .remove = atmel_isi_remove, | 1069 | .remove = atmel_isi_remove, |
1010 | .driver = { | 1070 | .driver = { |
1011 | .name = "atmel_isi", | 1071 | .name = "atmel_isi", |
1012 | .owner = THIS_MODULE, | 1072 | .owner = THIS_MODULE, |
1073 | .of_match_table = of_match_ptr(atmel_isi_of_match), | ||
1013 | }, | 1074 | }, |
1014 | }; | 1075 | }; |
1015 | 1076 | ||