aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/atmel-isi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/atmel-isi.c')
-rw-r--r--drivers/media/video/atmel-isi.c35
1 files changed, 31 insertions, 4 deletions
diff --git a/drivers/media/video/atmel-isi.c b/drivers/media/video/atmel-isi.c
index 8c775c59e120..9fe4519176a4 100644
--- a/drivers/media/video/atmel-isi.c
+++ b/drivers/media/video/atmel-isi.c
@@ -90,7 +90,10 @@ struct atmel_isi {
90 struct isi_dma_desc dma_desc[MAX_BUFFER_NUM]; 90 struct isi_dma_desc dma_desc[MAX_BUFFER_NUM];
91 91
92 struct completion complete; 92 struct completion complete;
93 /* ISI peripherial clock */
93 struct clk *pclk; 94 struct clk *pclk;
95 /* ISI_MCK, feed to camera sensor to generate pixel clock */
96 struct clk *mck;
94 unsigned int irq; 97 unsigned int irq;
95 98
96 struct isi_platform_data *pdata; 99 struct isi_platform_data *pdata;
@@ -766,6 +769,12 @@ static int isi_camera_add_device(struct soc_camera_device *icd)
766 if (ret) 769 if (ret)
767 return ret; 770 return ret;
768 771
772 ret = clk_enable(isi->mck);
773 if (ret) {
774 clk_disable(isi->pclk);
775 return ret;
776 }
777
769 isi->icd = icd; 778 isi->icd = icd;
770 dev_dbg(icd->parent, "Atmel ISI Camera driver attached to camera %d\n", 779 dev_dbg(icd->parent, "Atmel ISI Camera driver attached to camera %d\n",
771 icd->devnum); 780 icd->devnum);
@@ -779,6 +788,7 @@ static void isi_camera_remove_device(struct soc_camera_device *icd)
779 788
780 BUG_ON(icd != isi->icd); 789 BUG_ON(icd != isi->icd);
781 790
791 clk_disable(isi->mck);
782 clk_disable(isi->pclk); 792 clk_disable(isi->pclk);
783 isi->icd = NULL; 793 isi->icd = NULL;
784 794
@@ -803,7 +813,7 @@ static int isi_camera_querycap(struct soc_camera_host *ici,
803 return 0; 813 return 0;
804} 814}
805 815
806static int isi_camera_set_bus_param(struct soc_camera_device *icd, u32 pixfmt) 816static int isi_camera_set_bus_param(struct soc_camera_device *icd)
807{ 817{
808 struct v4l2_subdev *sd = soc_camera_to_subdev(icd); 818 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
809 struct soc_camera_host *ici = to_soc_camera_host(icd->parent); 819 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
@@ -874,7 +884,7 @@ static int isi_camera_set_bus_param(struct soc_camera_device *icd, u32 pixfmt)
874 884
875 if (isi->pdata->has_emb_sync) 885 if (isi->pdata->has_emb_sync)
876 cfg1 |= ISI_CFG1_EMB_SYNC; 886 cfg1 |= ISI_CFG1_EMB_SYNC;
877 if (isi->pdata->isi_full_mode) 887 if (isi->pdata->full_mode)
878 cfg1 |= ISI_CFG1_FULL_MODE; 888 cfg1 |= ISI_CFG1_FULL_MODE;
879 889
880 isi_writel(isi, ISI_CTRL, ISI_CTRL_DIS); 890 isi_writel(isi, ISI_CTRL, ISI_CTRL_DIS);
@@ -912,6 +922,7 @@ static int __devexit atmel_isi_remove(struct platform_device *pdev)
912 isi->fb_descriptors_phys); 922 isi->fb_descriptors_phys);
913 923
914 iounmap(isi->regs); 924 iounmap(isi->regs);
925 clk_put(isi->mck);
915 clk_put(isi->pclk); 926 clk_put(isi->pclk);
916 kfree(isi); 927 kfree(isi);
917 928
@@ -930,7 +941,7 @@ static int __devinit atmel_isi_probe(struct platform_device *pdev)
930 struct isi_platform_data *pdata; 941 struct isi_platform_data *pdata;
931 942
932 pdata = dev->platform_data; 943 pdata = dev->platform_data;
933 if (!pdata || !pdata->data_width_flags) { 944 if (!pdata || !pdata->data_width_flags || !pdata->mck_hz) {
934 dev_err(&pdev->dev, 945 dev_err(&pdev->dev,
935 "No config available for Atmel ISI\n"); 946 "No config available for Atmel ISI\n");
936 return -EINVAL; 947 return -EINVAL;
@@ -959,6 +970,19 @@ static int __devinit atmel_isi_probe(struct platform_device *pdev)
959 INIT_LIST_HEAD(&isi->video_buffer_list); 970 INIT_LIST_HEAD(&isi->video_buffer_list);
960 INIT_LIST_HEAD(&isi->dma_desc_head); 971 INIT_LIST_HEAD(&isi->dma_desc_head);
961 972
973 /* Get ISI_MCK, provided by programmable clock or external clock */
974 isi->mck = clk_get(dev, "isi_mck");
975 if (IS_ERR(isi->mck)) {
976 dev_err(dev, "Failed to get isi_mck\n");
977 ret = PTR_ERR(isi->mck);
978 goto err_clk_get;
979 }
980
981 /* Set ISI_MCK's frequency, it should be faster than pixel clock */
982 ret = clk_set_rate(isi->mck, pdata->mck_hz);
983 if (ret < 0)
984 goto err_set_mck_rate;
985
962 isi->p_fb_descriptors = dma_alloc_coherent(&pdev->dev, 986 isi->p_fb_descriptors = dma_alloc_coherent(&pdev->dev,
963 sizeof(struct fbd) * MAX_BUFFER_NUM, 987 sizeof(struct fbd) * MAX_BUFFER_NUM,
964 &isi->fb_descriptors_phys, 988 &isi->fb_descriptors_phys,
@@ -1034,9 +1058,12 @@ err_alloc_ctx:
1034 isi->p_fb_descriptors, 1058 isi->p_fb_descriptors,
1035 isi->fb_descriptors_phys); 1059 isi->fb_descriptors_phys);
1036err_alloc_descriptors: 1060err_alloc_descriptors:
1061err_set_mck_rate:
1062 clk_put(isi->mck);
1063err_clk_get:
1037 kfree(isi); 1064 kfree(isi);
1038err_alloc_isi: 1065err_alloc_isi:
1039 clk_put(isi->pclk); 1066 clk_put(pclk);
1040 1067
1041 return ret; 1068 return ret;
1042} 1069}