aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
authorJosh Wu <josh.wu@atmel.com>2014-07-28 03:25:17 -0400
committerMauro Carvalho Chehab <m.chehab@samsung.com>2014-07-30 18:48:36 -0400
commit8ff19bc437f8d42d8a03dafe2bb28c5b3fc1bff1 (patch)
tree4701913487f39c3687b2f002e4c40a7e64b16463 /drivers/media
parent833e1063266ebbf75934f1171c6546cdf33e9848 (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.c65
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 */
38struct fbd { 40struct fbd {
@@ -876,6 +878,51 @@ static int atmel_isi_remove(struct platform_device *pdev)
876 return 0; 878 return 0;
877} 879}
878 880
881static 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
920err_probe_dt:
921 of_node_put(np);
922
923 return err;
924}
925
879static int atmel_isi_probe(struct platform_device *pdev) 926static 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
1062static const struct of_device_id atmel_isi_of_match[] = {
1063 { .compatible = "atmel,at91sam9g45-isi" },
1064 { }
1065};
1066MODULE_DEVICE_TABLE(of, atmel_isi_of_match);
1067
1008static struct platform_driver atmel_isi_driver = { 1068static 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