aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/platform
diff options
context:
space:
mode:
authorSylwester Nawrocki <s.nawrocki@samsung.com>2013-04-09 10:11:58 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2013-04-14 14:48:44 -0400
commit4c8f0629f53bb198ed00c2c54cf80cc2be95acab (patch)
treeeff60e69d410225ead429093e6dc4a97fcb70e3a /drivers/media/platform
parent756e6e14484b3249dad9663ed1398711b62676a3 (diff)
[media] exynos4-is: Make fimc-lite independent of struct fimc_sensor_info
Make the sensor subdevs host_data hold a pointer to struct fimc_source_info, which is defined in the driver's public header, rather than a pointer to struct fimc_sensor_info which is specific to exynos4-is media device driver. The purpose of this change is to allow easier reuse of the fimc-lite module in the exynos5-is driver, which should similarly store a pointer to struct fimc_source_info instance in the sensor's subdev host_data. Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/platform')
-rw-r--r--drivers/media/platform/exynos4-is/fimc-capture.c7
-rw-r--r--drivers/media/platform/exynos4-is/fimc-lite.c10
-rw-r--r--drivers/media/platform/exynos4-is/media-dev.c74
-rw-r--r--drivers/media/platform/exynos4-is/media-dev.h6
4 files changed, 54 insertions, 43 deletions
diff --git a/drivers/media/platform/exynos4-is/fimc-capture.c b/drivers/media/platform/exynos4-is/fimc-capture.c
index 28c6b26f6ff5..72c516af40f6 100644
--- a/drivers/media/platform/exynos4-is/fimc-capture.c
+++ b/drivers/media/platform/exynos4-is/fimc-capture.c
@@ -1450,7 +1450,7 @@ static const struct media_entity_operations fimc_sd_media_ops = {
1450void fimc_sensor_notify(struct v4l2_subdev *sd, unsigned int notification, 1450void fimc_sensor_notify(struct v4l2_subdev *sd, unsigned int notification,
1451 void *arg) 1451 void *arg)
1452{ 1452{
1453 struct fimc_sensor_info *sensor; 1453 struct fimc_source_info *si;
1454 struct fimc_vid_buffer *buf; 1454 struct fimc_vid_buffer *buf;
1455 struct fimc_md *fmd; 1455 struct fimc_md *fmd;
1456 struct fimc_dev *fimc; 1456 struct fimc_dev *fimc;
@@ -1459,11 +1459,12 @@ void fimc_sensor_notify(struct v4l2_subdev *sd, unsigned int notification,
1459 if (sd == NULL) 1459 if (sd == NULL)
1460 return; 1460 return;
1461 1461
1462 sensor = v4l2_get_subdev_hostdata(sd); 1462 si = v4l2_get_subdev_hostdata(sd);
1463 fmd = entity_to_fimc_mdev(&sd->entity); 1463 fmd = entity_to_fimc_mdev(&sd->entity);
1464 1464
1465 spin_lock_irqsave(&fmd->slock, flags); 1465 spin_lock_irqsave(&fmd->slock, flags);
1466 fimc = sensor ? sensor->host : NULL; 1466
1467 fimc = si ? source_to_sensor_info(si)->host : NULL;
1467 1468
1468 if (fimc && arg && notification == S5P_FIMC_TX_END_NOTIFY && 1469 if (fimc && arg && notification == S5P_FIMC_TX_END_NOTIFY &&
1469 test_bit(ST_CAPT_PEND, &fimc->state)) { 1470 test_bit(ST_CAPT_PEND, &fimc->state)) {
diff --git a/drivers/media/platform/exynos4-is/fimc-lite.c b/drivers/media/platform/exynos4-is/fimc-lite.c
index 3ea4fc7beaf7..661d0d148cb5 100644
--- a/drivers/media/platform/exynos4-is/fimc-lite.c
+++ b/drivers/media/platform/exynos4-is/fimc-lite.c
@@ -11,6 +11,7 @@
11#define pr_fmt(fmt) "%s:%d " fmt, __func__, __LINE__ 11#define pr_fmt(fmt) "%s:%d " fmt, __func__, __LINE__
12 12
13#include <linux/bug.h> 13#include <linux/bug.h>
14#include <linux/clk.h>
14#include <linux/device.h> 15#include <linux/device.h>
15#include <linux/errno.h> 16#include <linux/errno.h>
16#include <linux/interrupt.h> 17#include <linux/interrupt.h>
@@ -31,7 +32,7 @@
31#include <media/videobuf2-dma-contig.h> 32#include <media/videobuf2-dma-contig.h>
32#include <media/s5p_fimc.h> 33#include <media/s5p_fimc.h>
33 34
34#include "media-dev.h" 35#include "fimc-core.h"
35#include "fimc-lite.h" 36#include "fimc-lite.h"
36#include "fimc-lite-reg.h" 37#include "fimc-lite-reg.h"
37 38
@@ -156,7 +157,7 @@ static struct v4l2_subdev *__find_remote_sensor(struct media_entity *me)
156 157
157static int fimc_lite_hw_init(struct fimc_lite *fimc, bool isp_output) 158static int fimc_lite_hw_init(struct fimc_lite *fimc, bool isp_output)
158{ 159{
159 struct fimc_sensor_info *si; 160 struct fimc_source_info *si;
160 unsigned long flags; 161 unsigned long flags;
161 162
162 if (fimc->sensor == NULL) 163 if (fimc->sensor == NULL)
@@ -167,9 +168,12 @@ static int fimc_lite_hw_init(struct fimc_lite *fimc, bool isp_output)
167 168
168 /* Get sensor configuration data from the sensor subdev */ 169 /* Get sensor configuration data from the sensor subdev */
169 si = v4l2_get_subdev_hostdata(fimc->sensor); 170 si = v4l2_get_subdev_hostdata(fimc->sensor);
171 if (!si)
172 return -EINVAL;
173
170 spin_lock_irqsave(&fimc->slock, flags); 174 spin_lock_irqsave(&fimc->slock, flags);
171 175
172 flite_hw_set_camera_bus(fimc, &si->pdata); 176 flite_hw_set_camera_bus(fimc, si);
173 flite_hw_set_source_format(fimc, &fimc->inp_frame); 177 flite_hw_set_source_format(fimc, &fimc->inp_frame);
174 flite_hw_set_window_offset(fimc, &fimc->inp_frame); 178 flite_hw_set_window_offset(fimc, &fimc->inp_frame);
175 flite_hw_set_output_dma(fimc, &fimc->out_frame, !isp_output); 179 flite_hw_set_output_dma(fimc, &fimc->out_frame, !isp_output);
diff --git a/drivers/media/platform/exynos4-is/media-dev.c b/drivers/media/platform/exynos4-is/media-dev.c
index 44d6c1d5bf4b..1dbd55422706 100644
--- a/drivers/media/platform/exynos4-is/media-dev.c
+++ b/drivers/media/platform/exynos4-is/media-dev.c
@@ -37,7 +37,7 @@
37#include "mipi-csis.h" 37#include "mipi-csis.h"
38 38
39static int __fimc_md_set_camclk(struct fimc_md *fmd, 39static int __fimc_md_set_camclk(struct fimc_md *fmd,
40 struct fimc_sensor_info *s_info, 40 struct fimc_source_info *si,
41 bool on); 41 bool on);
42/** 42/**
43 * fimc_pipeline_prepare - update pipeline information with subdevice pointers 43 * fimc_pipeline_prepare - update pipeline information with subdevice pointers
@@ -281,36 +281,36 @@ static const struct fimc_pipeline_ops fimc_pipeline_ops = {
281 * Sensor subdevice helper functions 281 * Sensor subdevice helper functions
282 */ 282 */
283static struct v4l2_subdev *fimc_md_register_sensor(struct fimc_md *fmd, 283static struct v4l2_subdev *fimc_md_register_sensor(struct fimc_md *fmd,
284 struct fimc_sensor_info *s_info) 284 struct fimc_source_info *si)
285{ 285{
286 struct i2c_adapter *adapter; 286 struct i2c_adapter *adapter;
287 struct v4l2_subdev *sd = NULL; 287 struct v4l2_subdev *sd = NULL;
288 288
289 if (!s_info || !fmd) 289 if (!si || !fmd)
290 return NULL; 290 return NULL;
291 /* 291 /*
292 * If FIMC bus type is not Writeback FIFO assume it is same 292 * If FIMC bus type is not Writeback FIFO assume it is same
293 * as sensor_bus_type. 293 * as sensor_bus_type.
294 */ 294 */
295 s_info->pdata.fimc_bus_type = s_info->pdata.sensor_bus_type; 295 si->fimc_bus_type = si->sensor_bus_type;
296 296
297 adapter = i2c_get_adapter(s_info->pdata.i2c_bus_num); 297 adapter = i2c_get_adapter(si->i2c_bus_num);
298 if (!adapter) { 298 if (!adapter) {
299 v4l2_warn(&fmd->v4l2_dev, 299 v4l2_warn(&fmd->v4l2_dev,
300 "Failed to get I2C adapter %d, deferring probe\n", 300 "Failed to get I2C adapter %d, deferring probe\n",
301 s_info->pdata.i2c_bus_num); 301 si->i2c_bus_num);
302 return ERR_PTR(-EPROBE_DEFER); 302 return ERR_PTR(-EPROBE_DEFER);
303 } 303 }
304 sd = v4l2_i2c_new_subdev_board(&fmd->v4l2_dev, adapter, 304 sd = v4l2_i2c_new_subdev_board(&fmd->v4l2_dev, adapter,
305 s_info->pdata.board_info, NULL); 305 si->board_info, NULL);
306 if (IS_ERR_OR_NULL(sd)) { 306 if (IS_ERR_OR_NULL(sd)) {
307 i2c_put_adapter(adapter); 307 i2c_put_adapter(adapter);
308 v4l2_warn(&fmd->v4l2_dev, 308 v4l2_warn(&fmd->v4l2_dev,
309 "Failed to acquire subdev %s, deferring probe\n", 309 "Failed to acquire subdev %s, deferring probe\n",
310 s_info->pdata.board_info->type); 310 si->board_info->type);
311 return ERR_PTR(-EPROBE_DEFER); 311 return ERR_PTR(-EPROBE_DEFER);
312 } 312 }
313 v4l2_set_subdev_hostdata(sd, s_info); 313 v4l2_set_subdev_hostdata(sd, si);
314 sd->grp_id = GRP_ID_SENSOR; 314 sd->grp_id = GRP_ID_SENSOR;
315 315
316 v4l2_info(&fmd->v4l2_dev, "Registered sensor subdevice %s\n", 316 v4l2_info(&fmd->v4l2_dev, "Registered sensor subdevice %s\n",
@@ -365,17 +365,17 @@ static int fimc_md_of_add_sensor(struct fimc_md *fmd,
365 } 365 }
366 366
367 /* Enable sensor's master clock */ 367 /* Enable sensor's master clock */
368 ret = __fimc_md_set_camclk(fmd, si, true); 368 ret = __fimc_md_set_camclk(fmd, &si->pdata, true);
369 if (ret < 0) 369 if (ret < 0)
370 goto mod_put; 370 goto mod_put;
371 sd = i2c_get_clientdata(client); 371 sd = i2c_get_clientdata(client);
372 372
373 ret = v4l2_device_register_subdev(&fmd->v4l2_dev, sd); 373 ret = v4l2_device_register_subdev(&fmd->v4l2_dev, sd);
374 __fimc_md_set_camclk(fmd, si, false); 374 __fimc_md_set_camclk(fmd, &si->pdata, false);
375 if (ret < 0) 375 if (ret < 0)
376 goto mod_put; 376 goto mod_put;
377 377
378 v4l2_set_subdev_hostdata(sd, si); 378 v4l2_set_subdev_hostdata(sd, &si->pdata);
379 if (si->pdata.fimc_bus_type == FIMC_BUS_TYPE_ISP_WRITEBACK) 379 if (si->pdata.fimc_bus_type == FIMC_BUS_TYPE_ISP_WRITEBACK)
380 sd->grp_id = GRP_ID_FIMC_IS_SENSOR; 380 sd->grp_id = GRP_ID_FIMC_IS_SENSOR;
381 else 381 else
@@ -559,21 +559,22 @@ static int fimc_md_register_sensor_entities(struct fimc_md *fmd)
559 fmd->num_sensors = num_clients; 559 fmd->num_sensors = num_clients;
560 560
561 for (i = 0; i < num_clients; i++) { 561 for (i = 0; i < num_clients; i++) {
562 struct fimc_sensor_info *si = &fmd->sensor[i];
562 struct v4l2_subdev *sd; 563 struct v4l2_subdev *sd;
563 564
564 fmd->sensor[i].pdata = pdata->source_info[i]; 565 si->pdata = pdata->source_info[i];
565 ret = __fimc_md_set_camclk(fmd, &fmd->sensor[i], true); 566 ret = __fimc_md_set_camclk(fmd, &si->pdata, true);
566 if (ret) 567 if (ret)
567 break; 568 break;
568 sd = fimc_md_register_sensor(fmd, &fmd->sensor[i]); 569 sd = fimc_md_register_sensor(fmd, &si->pdata);
569 ret = __fimc_md_set_camclk(fmd, &fmd->sensor[i], false); 570 ret = __fimc_md_set_camclk(fmd, &si->pdata, false);
570 571
571 if (IS_ERR(sd)) { 572 if (IS_ERR(sd)) {
572 fmd->sensor[i].subdev = NULL; 573 si->subdev = NULL;
573 ret = PTR_ERR(sd); 574 ret = PTR_ERR(sd);
574 break; 575 break;
575 } 576 }
576 fmd->sensor[i].subdev = sd; 577 si->subdev = sd;
577 if (ret) 578 if (ret)
578 break; 579 break;
579 } 580 }
@@ -838,7 +839,7 @@ static int __fimc_md_create_fimc_sink_links(struct fimc_md *fmd,
838 struct v4l2_subdev *sensor, 839 struct v4l2_subdev *sensor,
839 int pad, int link_mask) 840 int pad, int link_mask)
840{ 841{
841 struct fimc_sensor_info *si = NULL; 842 struct fimc_source_info *si = NULL;
842 struct media_entity *sink; 843 struct media_entity *sink;
843 unsigned int flags = 0; 844 unsigned int flags = 0;
844 int i, ret = 0; 845 int i, ret = 0;
@@ -846,7 +847,7 @@ static int __fimc_md_create_fimc_sink_links(struct fimc_md *fmd,
846 if (sensor) { 847 if (sensor) {
847 si = v4l2_get_subdev_hostdata(sensor); 848 si = v4l2_get_subdev_hostdata(sensor);
848 /* Skip direct FIMC links in the logical FIMC-IS sensor path */ 849 /* Skip direct FIMC links in the logical FIMC-IS sensor path */
849 if (si && si->pdata.fimc_bus_type == FIMC_BUS_TYPE_ISP_WRITEBACK) 850 if (si && si->fimc_bus_type == FIMC_BUS_TYPE_ISP_WRITEBACK)
850 ret = 1; 851 ret = 1;
851 } 852 }
852 853
@@ -882,8 +883,10 @@ static int __fimc_md_create_fimc_sink_links(struct fimc_md *fmd,
882 883
883 if (!WARN_ON(si == NULL)) { 884 if (!WARN_ON(si == NULL)) {
884 unsigned long irq_flags; 885 unsigned long irq_flags;
886 struct fimc_sensor_info *inf = source_to_sensor_info(si);
887
885 spin_lock_irqsave(&fmd->slock, irq_flags); 888 spin_lock_irqsave(&fmd->slock, irq_flags);
886 si->host = fmd->fimc[i]; 889 inf->host = fmd->fimc[i];
887 spin_unlock_irqrestore(&fmd->slock, irq_flags); 890 spin_unlock_irqrestore(&fmd->slock, irq_flags);
888 } 891 }
889 } 892 }
@@ -980,7 +983,6 @@ static int fimc_md_create_links(struct fimc_md *fmd)
980 struct v4l2_subdev *csi_sensors[CSIS_MAX_ENTITIES] = { NULL }; 983 struct v4l2_subdev *csi_sensors[CSIS_MAX_ENTITIES] = { NULL };
981 struct v4l2_subdev *sensor, *csis; 984 struct v4l2_subdev *sensor, *csis;
982 struct fimc_source_info *pdata; 985 struct fimc_source_info *pdata;
983 struct fimc_sensor_info *s_info;
984 struct media_entity *source, *sink; 986 struct media_entity *source, *sink;
985 int i, pad, fimc_id = 0, ret = 0; 987 int i, pad, fimc_id = 0, ret = 0;
986 u32 flags, link_mask = 0; 988 u32 flags, link_mask = 0;
@@ -990,12 +992,11 @@ static int fimc_md_create_links(struct fimc_md *fmd)
990 continue; 992 continue;
991 993
992 sensor = fmd->sensor[i].subdev; 994 sensor = fmd->sensor[i].subdev;
993 s_info = v4l2_get_subdev_hostdata(sensor); 995 pdata = v4l2_get_subdev_hostdata(sensor);
994 if (!s_info) 996 if (!pdata)
995 continue; 997 continue;
996 998
997 source = NULL; 999 source = NULL;
998 pdata = &s_info->pdata;
999 1000
1000 switch (pdata->sensor_bus_type) { 1001 switch (pdata->sensor_bus_type) {
1001 case FIMC_BUS_TYPE_MIPI_CSI2: 1002 case FIMC_BUS_TYPE_MIPI_CSI2:
@@ -1164,34 +1165,33 @@ static int fimc_md_get_clocks(struct fimc_md *fmd)
1164} 1165}
1165 1166
1166static int __fimc_md_set_camclk(struct fimc_md *fmd, 1167static int __fimc_md_set_camclk(struct fimc_md *fmd,
1167 struct fimc_sensor_info *s_info, 1168 struct fimc_source_info *si,
1168 bool on) 1169 bool on)
1169{ 1170{
1170 struct fimc_source_info *pdata = &s_info->pdata;
1171 struct fimc_camclk_info *camclk; 1171 struct fimc_camclk_info *camclk;
1172 int ret = 0; 1172 int ret = 0;
1173 1173
1174 if (WARN_ON(pdata->clk_id >= FIMC_MAX_CAMCLKS) || !fmd || !fmd->pmf) 1174 if (WARN_ON(si->clk_id >= FIMC_MAX_CAMCLKS) || !fmd || !fmd->pmf)
1175 return -EINVAL; 1175 return -EINVAL;
1176 1176
1177 camclk = &fmd->camclk[pdata->clk_id]; 1177 camclk = &fmd->camclk[si->clk_id];
1178 1178
1179 dbg("camclk %d, f: %lu, use_count: %d, on: %d", 1179 dbg("camclk %d, f: %lu, use_count: %d, on: %d",
1180 pdata->clk_id, pdata->clk_frequency, camclk->use_count, on); 1180 si->clk_id, si->clk_frequency, camclk->use_count, on);
1181 1181
1182 if (on) { 1182 if (on) {
1183 if (camclk->use_count > 0 && 1183 if (camclk->use_count > 0 &&
1184 camclk->frequency != pdata->clk_frequency) 1184 camclk->frequency != si->clk_frequency)
1185 return -EINVAL; 1185 return -EINVAL;
1186 1186
1187 if (camclk->use_count++ == 0) { 1187 if (camclk->use_count++ == 0) {
1188 clk_set_rate(camclk->clock, pdata->clk_frequency); 1188 clk_set_rate(camclk->clock, si->clk_frequency);
1189 camclk->frequency = pdata->clk_frequency; 1189 camclk->frequency = si->clk_frequency;
1190 ret = pm_runtime_get_sync(fmd->pmf); 1190 ret = pm_runtime_get_sync(fmd->pmf);
1191 if (ret < 0) 1191 if (ret < 0)
1192 return ret; 1192 return ret;
1193 ret = clk_enable(camclk->clock); 1193 ret = clk_enable(camclk->clock);
1194 dbg("Enabled camclk %d: f: %lu", pdata->clk_id, 1194 dbg("Enabled camclk %d: f: %lu", si->clk_id,
1195 clk_get_rate(camclk->clock)); 1195 clk_get_rate(camclk->clock));
1196 } 1196 }
1197 return ret; 1197 return ret;
@@ -1203,7 +1203,7 @@ static int __fimc_md_set_camclk(struct fimc_md *fmd,
1203 if (--camclk->use_count == 0) { 1203 if (--camclk->use_count == 0) {
1204 clk_disable(camclk->clock); 1204 clk_disable(camclk->clock);
1205 pm_runtime_put(fmd->pmf); 1205 pm_runtime_put(fmd->pmf);
1206 dbg("Disabled camclk %d", pdata->clk_id); 1206 dbg("Disabled camclk %d", si->clk_id);
1207 } 1207 }
1208 return ret; 1208 return ret;
1209} 1209}
@@ -1222,10 +1222,10 @@ static int __fimc_md_set_camclk(struct fimc_md *fmd,
1222 */ 1222 */
1223int fimc_md_set_camclk(struct v4l2_subdev *sd, bool on) 1223int fimc_md_set_camclk(struct v4l2_subdev *sd, bool on)
1224{ 1224{
1225 struct fimc_sensor_info *s_info = v4l2_get_subdev_hostdata(sd); 1225 struct fimc_source_info *si = v4l2_get_subdev_hostdata(sd);
1226 struct fimc_md *fmd = entity_to_fimc_mdev(&sd->entity); 1226 struct fimc_md *fmd = entity_to_fimc_mdev(&sd->entity);
1227 1227
1228 return __fimc_md_set_camclk(fmd, s_info, on); 1228 return __fimc_md_set_camclk(fmd, si, on);
1229} 1229}
1230 1230
1231static int fimc_md_link_notify(struct media_pad *source, 1231static int fimc_md_link_notify(struct media_pad *source,
diff --git a/drivers/media/platform/exynos4-is/media-dev.h b/drivers/media/platform/exynos4-is/media-dev.h
index 7f126c3adacf..44d86b61d660 100644
--- a/drivers/media/platform/exynos4-is/media-dev.h
+++ b/drivers/media/platform/exynos4-is/media-dev.h
@@ -115,6 +115,12 @@ struct fimc_md {
115 115
116#define subdev_has_devnode(__sd) (__sd->flags & V4L2_SUBDEV_FL_HAS_DEVNODE) 116#define subdev_has_devnode(__sd) (__sd->flags & V4L2_SUBDEV_FL_HAS_DEVNODE)
117 117
118static inline
119struct fimc_sensor_info *source_to_sensor_info(struct fimc_source_info *si)
120{
121 return container_of(si, struct fimc_sensor_info, pdata);
122}
123
118static inline struct fimc_md *entity_to_fimc_mdev(struct media_entity *me) 124static inline struct fimc_md *entity_to_fimc_mdev(struct media_entity *me)
119{ 125{
120 return me->parent == NULL ? NULL : 126 return me->parent == NULL ? NULL :