aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/s5p-fimc/fimc-capture.c
diff options
context:
space:
mode:
authorSylwester Nawrocki <s.nawrocki@samsung.com>2010-12-27 13:34:43 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2011-03-21 19:31:39 -0400
commita25be18dfb6e1b172498a9f6c9793d67057000b0 (patch)
treec824969740de62c2ddc9e80bc689d72ff73ae1a9 /drivers/media/video/s5p-fimc/fimc-capture.c
parentac75934cc644051dc1b33b234448ea4a0990f31f (diff)
[media] s5p-fimc: Add control of the external sensor clock
Manage the camera sensor clock in the host driver rather than leaving this task for sensor drivers. The clock frequency must be passed in the sensor's and host driver's platform data. Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/s5p-fimc/fimc-capture.c')
-rw-r--r--drivers/media/video/s5p-fimc/fimc-capture.c45
1 files changed, 31 insertions, 14 deletions
diff --git a/drivers/media/video/s5p-fimc/fimc-capture.c b/drivers/media/video/s5p-fimc/fimc-capture.c
index c6689a24c85b..03ddf5d6164f 100644
--- a/drivers/media/video/s5p-fimc/fimc-capture.c
+++ b/drivers/media/video/s5p-fimc/fimc-capture.c
@@ -113,26 +113,43 @@ static int fimc_subdev_attach(struct fimc_dev *fimc, int index)
113 return -ENODEV; 113 return -ENODEV;
114} 114}
115 115
116static int fimc_isp_subdev_init(struct fimc_dev *fimc, int index) 116static int fimc_isp_subdev_init(struct fimc_dev *fimc, unsigned int index)
117{ 117{
118 struct s5p_fimc_isp_info *isp_info; 118 struct s5p_fimc_isp_info *isp_info;
119 int ret; 119 int ret;
120 120
121 if (index >= FIMC_MAX_CAMIF_CLIENTS)
122 return -EINVAL;
123
124 isp_info = fimc->pdata->isp_info[index];
125 if (!isp_info)
126 return -EINVAL;
127
128 if (isp_info->clk_frequency)
129 clk_set_rate(fimc->clock[CLK_CAM], isp_info->clk_frequency);
130
131 ret = clk_enable(fimc->clock[CLK_CAM]);
132 if (ret)
133 return ret;
134
121 ret = fimc_subdev_attach(fimc, index); 135 ret = fimc_subdev_attach(fimc, index);
122 if (ret) 136 if (ret)
123 return ret; 137 return ret;
124 138
125 isp_info = fimc->pdata->isp_info[fimc->vid_cap.input_index];
126 ret = fimc_hw_set_camera_polarity(fimc, isp_info); 139 ret = fimc_hw_set_camera_polarity(fimc, isp_info);
127 if (!ret) { 140 if (ret)
128 ret = v4l2_subdev_call(fimc->vid_cap.sd, core, 141 return ret;
129 s_power, 1); 142
130 if (!ret) 143 ret = v4l2_subdev_call(fimc->vid_cap.sd, core, s_power, 1);
131 return ret; 144 if (!ret)
132 } 145 return ret;
133 146
147 /* enabling power failed so unregister subdev */
134 fimc_subdev_unregister(fimc); 148 fimc_subdev_unregister(fimc);
135 err("ISP initialization failed: %d", ret); 149
150 v4l2_err(&fimc->vid_cap.v4l2_dev, "ISP initialization failed: %d\n",
151 ret);
152
136 return ret; 153 return ret;
137} 154}
138 155
@@ -190,10 +207,7 @@ static int fimc_stop_capture(struct fimc_dev *fimc)
190 test_bit(ST_CAPT_SHUT, &fimc->state), 207 test_bit(ST_CAPT_SHUT, &fimc->state),
191 FIMC_SHUTDOWN_TIMEOUT); 208 FIMC_SHUTDOWN_TIMEOUT);
192 209
193 ret = v4l2_subdev_call(cap->sd, video, s_stream, 0); 210 v4l2_subdev_call(cap->sd, video, s_stream, 0);
194
195 if (ret && ret != -ENOIOCTLCMD)
196 v4l2_err(&fimc->vid_cap.v4l2_dev, "s_stream(0) failed\n");
197 211
198 spin_lock_irqsave(&fimc->slock, flags); 212 spin_lock_irqsave(&fimc->slock, flags);
199 fimc->state &= ~(1 << ST_CAPT_RUN | 1 << ST_CAPT_PEND | 213 fimc->state &= ~(1 << ST_CAPT_RUN | 1 << ST_CAPT_PEND |
@@ -408,7 +422,7 @@ static int fimc_capture_open(struct file *file)
408 return -EBUSY; 422 return -EBUSY;
409 423
410 if (++fimc->vid_cap.refcnt == 1) { 424 if (++fimc->vid_cap.refcnt == 1) {
411 ret = fimc_isp_subdev_init(fimc, -1); 425 ret = fimc_isp_subdev_init(fimc, 0);
412 if (ret) { 426 if (ret) {
413 fimc->vid_cap.refcnt--; 427 fimc->vid_cap.refcnt--;
414 return -EIO; 428 return -EIO;
@@ -433,6 +447,7 @@ static int fimc_capture_close(struct file *file)
433 v4l2_err(&fimc->vid_cap.v4l2_dev, "releasing ISP\n"); 447 v4l2_err(&fimc->vid_cap.v4l2_dev, "releasing ISP\n");
434 448
435 v4l2_subdev_call(fimc->vid_cap.sd, core, s_power, 0); 449 v4l2_subdev_call(fimc->vid_cap.sd, core, s_power, 0);
450 clk_disable(fimc->clock[CLK_CAM]);
436 fimc_subdev_unregister(fimc); 451 fimc_subdev_unregister(fimc);
437 } 452 }
438 453
@@ -604,6 +619,8 @@ static int fimc_cap_s_input(struct file *file, void *priv,
604 int ret = v4l2_subdev_call(fimc->vid_cap.sd, core, s_power, 0); 619 int ret = v4l2_subdev_call(fimc->vid_cap.sd, core, s_power, 0);
605 if (ret) 620 if (ret)
606 err("s_power failed: %d", ret); 621 err("s_power failed: %d", ret);
622
623 clk_disable(fimc->clock[CLK_CAM]);
607 } 624 }
608 625
609 /* Release the attached sensor subdevice. */ 626 /* Release the attached sensor subdevice. */