Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
fimc-mdevice.c
Go to the documentation of this file.
1 /*
2  * S5P/EXYNOS4 SoC series camera host interface media device driver
3  *
4  * Copyright (C) 2011 Samsung Electronics Co., Ltd.
5  * Contact: Sylwester Nawrocki, <[email protected]>
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published
9  * by the Free Software Foundation, either version 2 of the License,
10  * or (at your option) any later version.
11  */
12 
13 #include <linux/bug.h>
14 #include <linux/device.h>
15 #include <linux/errno.h>
16 #include <linux/i2c.h>
17 #include <linux/kernel.h>
18 #include <linux/list.h>
19 #include <linux/module.h>
20 #include <linux/platform_device.h>
21 #include <linux/pm_runtime.h>
22 #include <linux/types.h>
23 #include <linux/slab.h>
24 #include <media/v4l2-ctrls.h>
25 #include <media/media-device.h>
26 #include <media/s5p_fimc.h>
27 
28 #include "fimc-core.h"
29 #include "fimc-lite.h"
30 #include "fimc-mdevice.h"
31 #include "mipi-csis.h"
32 
33 static int __fimc_md_set_camclk(struct fimc_md *fmd,
34  struct fimc_sensor_info *s_info,
35  bool on);
42 static void fimc_pipeline_prepare(struct fimc_pipeline *p,
43  struct media_entity *me)
44 {
45  struct media_pad *pad = &me->pads[0];
46  struct v4l2_subdev *sd;
47  int i;
48 
49  for (i = 0; i < IDX_MAX; i++)
50  p->subdevs[i] = NULL;
51 
52  while (1) {
53  if (!(pad->flags & MEDIA_PAD_FL_SINK))
54  break;
55 
56  /* source pad */
57  pad = media_entity_remote_source(pad);
58  if (pad == NULL ||
59  media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
60  break;
61 
63 
64  switch (sd->grp_id) {
65  case SENSOR_GROUP_ID:
66  p->subdevs[IDX_SENSOR] = sd;
67  break;
68  case CSIS_GROUP_ID:
69  p->subdevs[IDX_CSIS] = sd;
70  break;
71  case FLITE_GROUP_ID:
72  p->subdevs[IDX_FLITE] = sd;
73  break;
74  case FIMC_GROUP_ID:
75  /* No need to control FIMC subdev through subdev ops */
76  break;
77  default:
78  pr_warn("%s: Unknown subdev grp_id: %#x\n",
79  __func__, sd->grp_id);
80  }
81  /* sink pad */
82  pad = &sd->entity.pads[0];
83  }
84 }
85 
94 static int __subdev_set_power(struct v4l2_subdev *sd, int on)
95 {
96  int *use_count;
97  int ret;
98 
99  if (sd == NULL)
100  return -ENXIO;
101 
102  use_count = &sd->entity.use_count;
103  if (on && (*use_count)++ > 0)
104  return 0;
105  else if (!on && (*use_count == 0 || --(*use_count) > 0))
106  return 0;
107  ret = v4l2_subdev_call(sd, core, s_power, on);
108 
109  return ret != -ENOIOCTLCMD ? ret : 0;
110 }
111 
119 static int fimc_pipeline_s_power(struct fimc_pipeline *p, bool state)
120 {
121  unsigned int i;
122  int ret;
123 
124  if (p->subdevs[IDX_SENSOR] == NULL)
125  return -ENXIO;
126 
127  for (i = 0; i < IDX_MAX; i++) {
128  unsigned int idx = state ? (IDX_MAX - 1) - i : i;
129 
130  ret = __subdev_set_power(p->subdevs[idx], state);
131  if (ret < 0 && ret != -ENXIO)
132  return ret;
133  }
134 
135  return 0;
136 }
137 
146 static int __fimc_pipeline_open(struct fimc_pipeline *p,
147  struct media_entity *me, bool prep)
148 {
149  int ret;
150 
151  if (prep)
152  fimc_pipeline_prepare(p, me);
153 
154  if (p->subdevs[IDX_SENSOR] == NULL)
155  return -EINVAL;
156 
157  ret = fimc_md_set_camclk(p->subdevs[IDX_SENSOR], true);
158  if (ret)
159  return ret;
160 
161  return fimc_pipeline_s_power(p, 1);
162 }
163 
164 static int fimc_pipeline_open(struct fimc_pipeline *p,
165  struct media_entity *me, bool prep)
166 {
167  int ret;
168 
169  mutex_lock(&me->parent->graph_mutex);
170  ret = __fimc_pipeline_open(p, me, prep);
171  mutex_unlock(&me->parent->graph_mutex);
172 
173  return ret;
174 }
175 
184 static int __fimc_pipeline_close(struct fimc_pipeline *p)
185 {
186  int ret = 0;
187 
188  if (p->subdevs[IDX_SENSOR]) {
189  ret = fimc_pipeline_s_power(p, 0);
191  }
192  return ret == -ENXIO ? 0 : ret;
193 }
194 
195 static int fimc_pipeline_close(struct fimc_pipeline *p)
196 {
197  struct media_entity *me;
198  int ret;
199 
200  if (!p || !p->subdevs[IDX_SENSOR])
201  return -EINVAL;
202 
203  me = &p->subdevs[IDX_SENSOR]->entity;
204  mutex_lock(&me->parent->graph_mutex);
205  ret = __fimc_pipeline_close(p);
206  mutex_unlock(&me->parent->graph_mutex);
207 
208  return ret;
209 }
210 
216 int fimc_pipeline_s_stream(struct fimc_pipeline *p, bool on)
217 {
218  int i, ret;
219 
220  if (p->subdevs[IDX_SENSOR] == NULL)
221  return -ENODEV;
222 
223  for (i = 0; i < IDX_MAX; i++) {
224  unsigned int idx = on ? (IDX_MAX - 1) - i : i;
225 
226  ret = v4l2_subdev_call(p->subdevs[idx], video, s_stream, on);
227 
228  if (ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV)
229  return ret;
230  }
231 
232  return 0;
233 
234 }
235 
236 /* Media pipeline operations for the FIMC/FIMC-LITE video device driver */
237 static const struct fimc_pipeline_ops fimc_pipeline_ops = {
238  .open = fimc_pipeline_open,
239  .close = fimc_pipeline_close,
240  .set_stream = fimc_pipeline_s_stream,
241 };
242 
243 /*
244  * Sensor subdevice helper functions
245  */
246 static struct v4l2_subdev *fimc_md_register_sensor(struct fimc_md *fmd,
247  struct fimc_sensor_info *s_info)
248 {
249  struct i2c_adapter *adapter;
250  struct v4l2_subdev *sd = NULL;
251 
252  if (!s_info || !fmd)
253  return NULL;
254 
255  adapter = i2c_get_adapter(s_info->pdata.i2c_bus_num);
256  if (!adapter) {
257  v4l2_warn(&fmd->v4l2_dev,
258  "Failed to get I2C adapter %d, deferring probe\n",
259  s_info->pdata.i2c_bus_num);
260  return ERR_PTR(-EPROBE_DEFER);
261  }
262  sd = v4l2_i2c_new_subdev_board(&fmd->v4l2_dev, adapter,
263  s_info->pdata.board_info, NULL);
264  if (IS_ERR_OR_NULL(sd)) {
265  i2c_put_adapter(adapter);
266  v4l2_warn(&fmd->v4l2_dev,
267  "Failed to acquire subdev %s, deferring probe\n",
268  s_info->pdata.board_info->type);
269  return ERR_PTR(-EPROBE_DEFER);
270  }
271  v4l2_set_subdev_hostdata(sd, s_info);
272  sd->grp_id = SENSOR_GROUP_ID;
273 
274  v4l2_info(&fmd->v4l2_dev, "Registered sensor subdevice %s\n",
275  s_info->pdata.board_info->type);
276  return sd;
277 }
278 
279 static void fimc_md_unregister_sensor(struct v4l2_subdev *sd)
280 {
281  struct i2c_client *client = v4l2_get_subdevdata(sd);
282  struct i2c_adapter *adapter;
283 
284  if (!client)
285  return;
287  adapter = client->adapter;
288  i2c_unregister_device(client);
289  if (adapter)
290  i2c_put_adapter(adapter);
291 }
292 
293 static int fimc_md_register_sensor_entities(struct fimc_md *fmd)
294 {
295  struct s5p_platform_fimc *pdata = fmd->pdev->dev.platform_data;
296  struct fimc_dev *fd = NULL;
297  int num_clients, ret, i;
298 
299  /*
300  * Runtime resume one of the FIMC entities to make sure
301  * the sclk_cam clocks are not globally disabled.
302  */
303  for (i = 0; !fd && i < ARRAY_SIZE(fmd->fimc); i++)
304  if (fmd->fimc[i])
305  fd = fmd->fimc[i];
306  if (!fd)
307  return -ENXIO;
308  ret = pm_runtime_get_sync(&fd->pdev->dev);
309  if (ret < 0)
310  return ret;
311 
312  WARN_ON(pdata->num_clients > ARRAY_SIZE(fmd->sensor));
313  num_clients = min_t(u32, pdata->num_clients, ARRAY_SIZE(fmd->sensor));
314 
315  fmd->num_sensors = num_clients;
316  for (i = 0; i < num_clients; i++) {
317  struct v4l2_subdev *sd;
318 
319  fmd->sensor[i].pdata = pdata->isp_info[i];
320  ret = __fimc_md_set_camclk(fmd, &fmd->sensor[i], true);
321  if (ret)
322  break;
323  sd = fimc_md_register_sensor(fmd, &fmd->sensor[i]);
324  ret = __fimc_md_set_camclk(fmd, &fmd->sensor[i], false);
325 
326  if (!IS_ERR(sd)) {
327  fmd->sensor[i].subdev = sd;
328  } else {
329  fmd->sensor[i].subdev = NULL;
330  ret = PTR_ERR(sd);
331  break;
332  }
333  if (ret)
334  break;
335  }
336  pm_runtime_put(&fd->pdev->dev);
337  return ret;
338 }
339 
340 /*
341  * MIPI CSIS and FIMC platform devices registration.
342  */
343 static int fimc_register_callback(struct device *dev, void *p)
344 {
345  struct fimc_dev *fimc = dev_get_drvdata(dev);
346  struct v4l2_subdev *sd;
347  struct fimc_md *fmd = p;
348  int ret;
349 
350  if (fimc == NULL || fimc->id >= FIMC_MAX_DEVS)
351  return 0;
352 
353  sd = &fimc->vid_cap.subdev;
354  sd->grp_id = FIMC_GROUP_ID;
355  v4l2_set_subdev_hostdata(sd, (void *)&fimc_pipeline_ops);
356 
357  ret = v4l2_device_register_subdev(&fmd->v4l2_dev, sd);
358  if (ret) {
359  v4l2_err(&fmd->v4l2_dev, "Failed to register FIMC.%d (%d)\n",
360  fimc->id, ret);
361  return ret;
362  }
363 
364  fmd->fimc[fimc->id] = fimc;
365  return 0;
366 }
367 
368 static int fimc_lite_register_callback(struct device *dev, void *p)
369 {
370  struct fimc_lite *fimc = dev_get_drvdata(dev);
371  struct fimc_md *fmd = p;
372  int ret;
373 
374  if (fimc == NULL || fimc->index >= FIMC_LITE_MAX_DEVS)
375  return 0;
376 
377  fimc->subdev.grp_id = FLITE_GROUP_ID;
378  v4l2_set_subdev_hostdata(&fimc->subdev, (void *)&fimc_pipeline_ops);
379 
380  ret = v4l2_device_register_subdev(&fmd->v4l2_dev, &fimc->subdev);
381  if (ret) {
382  v4l2_err(&fmd->v4l2_dev,
383  "Failed to register FIMC-LITE.%d (%d)\n",
384  fimc->index, ret);
385  return ret;
386  }
387 
388  fmd->fimc_lite[fimc->index] = fimc;
389  return 0;
390 }
391 
392 static int csis_register_callback(struct device *dev, void *p)
393 {
394  struct v4l2_subdev *sd = dev_get_drvdata(dev);
395  struct platform_device *pdev;
396  struct fimc_md *fmd = p;
397  int id, ret;
398 
399  if (!sd)
400  return 0;
401  pdev = v4l2_get_subdevdata(sd);
402  if (!pdev || pdev->id < 0 || pdev->id >= CSIS_MAX_ENTITIES)
403  return 0;
404  v4l2_info(sd, "csis%d sd: %s\n", pdev->id, sd->name);
405 
406  id = pdev->id < 0 ? 0 : pdev->id;
407  sd->grp_id = CSIS_GROUP_ID;
408 
409  ret = v4l2_device_register_subdev(&fmd->v4l2_dev, sd);
410  if (!ret)
411  fmd->csis[id].sd = sd;
412  else
413  v4l2_err(&fmd->v4l2_dev,
414  "Failed to register CSIS subdevice: %d\n", ret);
415  return ret;
416 }
417 
421 static int fimc_md_register_platform_entities(struct fimc_md *fmd)
422 {
423  struct s5p_platform_fimc *pdata = fmd->pdev->dev.platform_data;
424  struct device_driver *driver;
425  int ret, i;
426 
428  if (!driver) {
429  v4l2_warn(&fmd->v4l2_dev,
430  "%s driver not found, deffering probe\n",
432  return -EPROBE_DEFER;
433  }
434 
435  ret = driver_for_each_device(driver, NULL, fmd,
436  fimc_register_callback);
437  if (ret)
438  return ret;
439 
441  if (driver && try_module_get(driver->owner)) {
442  ret = driver_for_each_device(driver, NULL, fmd,
443  fimc_lite_register_callback);
444  if (ret)
445  return ret;
446  module_put(driver->owner);
447  }
448  /*
449  * Check if there is any sensor on the MIPI-CSI2 bus and
450  * if not skip the s5p-csis module loading.
451  */
452  if (pdata == NULL)
453  return 0;
454  for (i = 0; i < pdata->num_clients; i++) {
455  if (pdata->isp_info[i].bus_type == FIMC_MIPI_CSI2) {
456  ret = 1;
457  break;
458  }
459  }
460  if (!ret)
461  return 0;
462 
464  if (!driver || !try_module_get(driver->owner)) {
465  v4l2_warn(&fmd->v4l2_dev,
466  "%s driver not found, deffering probe\n",
468  return -EPROBE_DEFER;
469  }
470 
471  return driver_for_each_device(driver, NULL, fmd,
472  csis_register_callback);
473 }
474 
475 static void fimc_md_unregister_entities(struct fimc_md *fmd)
476 {
477  int i;
478 
479  for (i = 0; i < FIMC_MAX_DEVS; i++) {
480  if (fmd->fimc[i] == NULL)
481  continue;
482  v4l2_device_unregister_subdev(&fmd->fimc[i]->vid_cap.subdev);
483  fmd->fimc[i]->pipeline_ops = NULL;
484  fmd->fimc[i] = NULL;
485  }
486  for (i = 0; i < FIMC_LITE_MAX_DEVS; i++) {
487  if (fmd->fimc_lite[i] == NULL)
488  continue;
489  v4l2_device_unregister_subdev(&fmd->fimc_lite[i]->subdev);
490  fmd->fimc[i]->pipeline_ops = NULL;
491  fmd->fimc_lite[i] = NULL;
492  }
493  for (i = 0; i < CSIS_MAX_ENTITIES; i++) {
494  if (fmd->csis[i].sd == NULL)
495  continue;
497  module_put(fmd->csis[i].sd->owner);
498  fmd->csis[i].sd = NULL;
499  }
500  for (i = 0; i < fmd->num_sensors; i++) {
501  if (fmd->sensor[i].subdev == NULL)
502  continue;
503  fimc_md_unregister_sensor(fmd->sensor[i].subdev);
504  fmd->sensor[i].subdev = NULL;
505  }
506 }
507 
516 static int __fimc_md_create_fimc_sink_links(struct fimc_md *fmd,
517  struct media_entity *source,
518  struct v4l2_subdev *sensor,
519  int pad, int link_mask)
520 {
521  struct fimc_sensor_info *s_info;
522  struct media_entity *sink;
523  unsigned int flags = 0;
524  int ret, i;
525 
526  for (i = 0; i < FIMC_MAX_DEVS; i++) {
527  if (!fmd->fimc[i])
528  continue;
529  /*
530  * Some FIMC variants are not fitted with camera capture
531  * interface. Skip creating a link from sensor for those.
532  */
533  if (!fmd->fimc[i]->variant->has_cam_if)
534  continue;
535 
536  flags = ((1 << i) & link_mask) ? MEDIA_LNK_FL_ENABLED : 0;
537 
538  sink = &fmd->fimc[i]->vid_cap.subdev.entity;
539  ret = media_entity_create_link(source, pad, sink,
540  FIMC_SD_PAD_SINK, flags);
541  if (ret)
542  return ret;
543 
544  /* Notify FIMC capture subdev entity */
545  ret = media_entity_call(sink, link_setup, &sink->pads[0],
546  &source->pads[pad], flags);
547  if (ret)
548  break;
549 
550  v4l2_info(&fmd->v4l2_dev, "created link [%s] %c> [%s]",
551  source->name, flags ? '=' : '-', sink->name);
552 
553  if (flags == 0 || sensor == NULL)
554  continue;
555  s_info = v4l2_get_subdev_hostdata(sensor);
556  if (!WARN_ON(s_info == NULL)) {
557  unsigned long irq_flags;
558  spin_lock_irqsave(&fmd->slock, irq_flags);
559  s_info->host = fmd->fimc[i];
560  spin_unlock_irqrestore(&fmd->slock, irq_flags);
561  }
562  }
563 
564  for (i = 0; i < FIMC_LITE_MAX_DEVS; i++) {
565  if (!fmd->fimc_lite[i])
566  continue;
567 
568  if (link_mask & (1 << (i + FIMC_MAX_DEVS)))
569  flags = MEDIA_LNK_FL_ENABLED;
570  else
571  flags = 0;
572 
573  sink = &fmd->fimc_lite[i]->subdev.entity;
574  ret = media_entity_create_link(source, pad, sink,
575  FLITE_SD_PAD_SINK, flags);
576  if (ret)
577  return ret;
578 
579  /* Notify FIMC-LITE subdev entity */
580  ret = media_entity_call(sink, link_setup, &sink->pads[0],
581  &source->pads[pad], flags);
582  if (ret)
583  break;
584 
585  v4l2_info(&fmd->v4l2_dev, "created link [%s] %c> [%s]",
586  source->name, flags ? '=' : '-', sink->name);
587  }
588  return 0;
589 }
590 
591 /* Create links from FIMC-LITE source pads to other entities */
592 static int __fimc_md_create_flite_source_links(struct fimc_md *fmd)
593 {
594  struct media_entity *source, *sink;
595  unsigned int flags = MEDIA_LNK_FL_ENABLED;
596  int i, ret;
597 
598  for (i = 0; i < FIMC_LITE_MAX_DEVS; i++) {
599  struct fimc_lite *fimc = fmd->fimc_lite[i];
600  if (fimc == NULL)
601  continue;
602  source = &fimc->subdev.entity;
603  sink = &fimc->vfd.entity;
604  /* FIMC-LITE's subdev and video node */
606  sink, 0, flags);
607  if (ret)
608  break;
609  /* TODO: create links to other entities */
610  }
611 
612  return ret;
613 }
614 
627 static int fimc_md_create_links(struct fimc_md *fmd)
628 {
629  struct v4l2_subdev *csi_sensors[2] = { NULL };
630  struct v4l2_subdev *sensor, *csis;
631  struct s5p_fimc_isp_info *pdata;
632  struct fimc_sensor_info *s_info;
633  struct media_entity *source, *sink;
634  int i, pad, fimc_id = 0, ret = 0;
635  u32 flags, link_mask = 0;
636 
637  for (i = 0; i < fmd->num_sensors; i++) {
638  if (fmd->sensor[i].subdev == NULL)
639  continue;
640 
641  sensor = fmd->sensor[i].subdev;
642  s_info = v4l2_get_subdev_hostdata(sensor);
643  if (!s_info)
644  continue;
645 
646  source = NULL;
647  pdata = &s_info->pdata;
648 
649  switch (pdata->bus_type) {
650  case FIMC_MIPI_CSI2:
651  if (WARN(pdata->mux_id >= CSIS_MAX_ENTITIES,
652  "Wrong CSI channel id: %d\n", pdata->mux_id))
653  return -EINVAL;
654 
655  csis = fmd->csis[pdata->mux_id].sd;
656  if (WARN(csis == NULL,
657  "MIPI-CSI interface specified "
658  "but s5p-csis module is not loaded!\n"))
659  return -EINVAL;
660 
661  ret = media_entity_create_link(&sensor->entity, 0,
662  &csis->entity, CSIS_PAD_SINK,
665  if (ret)
666  return ret;
667 
668  v4l2_info(&fmd->v4l2_dev, "created link [%s] => [%s]",
669  sensor->entity.name, csis->entity.name);
670 
671  source = NULL;
672  csi_sensors[pdata->mux_id] = sensor;
673  break;
674 
675  case FIMC_ITU_601...FIMC_ITU_656:
676  source = &sensor->entity;
677  pad = 0;
678  break;
679 
680  default:
681  v4l2_err(&fmd->v4l2_dev, "Wrong bus_type: %x\n",
682  pdata->bus_type);
683  return -EINVAL;
684  }
685  if (source == NULL)
686  continue;
687 
688  link_mask = 1 << fimc_id++;
689  ret = __fimc_md_create_fimc_sink_links(fmd, source, sensor,
690  pad, link_mask);
691  }
692 
693  for (i = 0; i < ARRAY_SIZE(fmd->csis); i++) {
694  if (fmd->csis[i].sd == NULL)
695  continue;
696  source = &fmd->csis[i].sd->entity;
697  pad = CSIS_PAD_SOURCE;
698  sensor = csi_sensors[i];
699 
700  link_mask = 1 << fimc_id++;
701  ret = __fimc_md_create_fimc_sink_links(fmd, source, sensor,
702  pad, link_mask);
703  }
704 
705  /* Create immutable links between each FIMC's subdev and video node */
707  for (i = 0; i < FIMC_MAX_DEVS; i++) {
708  if (!fmd->fimc[i])
709  continue;
710  source = &fmd->fimc[i]->vid_cap.subdev.entity;
711  sink = &fmd->fimc[i]->vid_cap.vfd.entity;
713  sink, 0, flags);
714  if (ret)
715  break;
716  }
717 
718  return __fimc_md_create_flite_source_links(fmd);
719 }
720 
721 /*
722  * The peripheral sensor clock management.
723  */
724 static int fimc_md_get_clocks(struct fimc_md *fmd)
725 {
726  char clk_name[32];
727  struct clk *clock;
728  int i;
729 
730  for (i = 0; i < FIMC_MAX_CAMCLKS; i++) {
731  snprintf(clk_name, sizeof(clk_name), "sclk_cam%u", i);
732  clock = clk_get(NULL, clk_name);
733  if (IS_ERR_OR_NULL(clock)) {
734  v4l2_err(&fmd->v4l2_dev, "Failed to get clock: %s",
735  clk_name);
736  return -ENXIO;
737  }
738  fmd->camclk[i].clock = clock;
739  }
740  return 0;
741 }
742 
743 static void fimc_md_put_clocks(struct fimc_md *fmd)
744 {
745  int i = FIMC_MAX_CAMCLKS;
746 
747  while (--i >= 0) {
748  if (IS_ERR_OR_NULL(fmd->camclk[i].clock))
749  continue;
750  clk_put(fmd->camclk[i].clock);
751  fmd->camclk[i].clock = NULL;
752  }
753 }
754 
755 static int __fimc_md_set_camclk(struct fimc_md *fmd,
756  struct fimc_sensor_info *s_info,
757  bool on)
758 {
759  struct s5p_fimc_isp_info *pdata = &s_info->pdata;
760  struct fimc_camclk_info *camclk;
761  int ret = 0;
762 
763  if (WARN_ON(pdata->clk_id >= FIMC_MAX_CAMCLKS) || fmd == NULL)
764  return -EINVAL;
765 
766  camclk = &fmd->camclk[pdata->clk_id];
767 
768  dbg("camclk %d, f: %lu, use_count: %d, on: %d",
769  pdata->clk_id, pdata->clk_frequency, camclk->use_count, on);
770 
771  if (on) {
772  if (camclk->use_count > 0 &&
773  camclk->frequency != pdata->clk_frequency)
774  return -EINVAL;
775 
776  if (camclk->use_count++ == 0) {
777  clk_set_rate(camclk->clock, pdata->clk_frequency);
778  camclk->frequency = pdata->clk_frequency;
779  ret = clk_enable(camclk->clock);
780  dbg("Enabled camclk %d: f: %lu", pdata->clk_id,
781  clk_get_rate(camclk->clock));
782  }
783  return ret;
784  }
785 
786  if (WARN_ON(camclk->use_count == 0))
787  return 0;
788 
789  if (--camclk->use_count == 0) {
790  clk_disable(camclk->clock);
791  dbg("Disabled camclk %d", pdata->clk_id);
792  }
793  return ret;
794 }
795 
808 int fimc_md_set_camclk(struct v4l2_subdev *sd, bool on)
809 {
810  struct fimc_sensor_info *s_info = v4l2_get_subdev_hostdata(sd);
811  struct fimc_md *fmd = entity_to_fimc_mdev(&sd->entity);
812 
813  return __fimc_md_set_camclk(fmd, s_info, on);
814 }
815 
816 static int fimc_md_link_notify(struct media_pad *source,
817  struct media_pad *sink, u32 flags)
818 {
819  struct fimc_lite *fimc_lite = NULL;
820  struct fimc_dev *fimc = NULL;
821  struct fimc_pipeline *pipeline;
822  struct v4l2_subdev *sd;
823  int ret = 0;
824 
825  if (media_entity_type(sink->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
826  return 0;
827 
829 
830  switch (sd->grp_id) {
831  case FLITE_GROUP_ID:
832  fimc_lite = v4l2_get_subdevdata(sd);
833  pipeline = &fimc_lite->pipeline;
834  break;
835  case FIMC_GROUP_ID:
836  fimc = v4l2_get_subdevdata(sd);
837  pipeline = &fimc->pipeline;
838  break;
839  default:
840  return 0;
841  }
842 
843  if (!(flags & MEDIA_LNK_FL_ENABLED)) {
844  ret = __fimc_pipeline_close(pipeline);
845  pipeline->subdevs[IDX_SENSOR] = NULL;
846  pipeline->subdevs[IDX_CSIS] = NULL;
847 
848  if (fimc) {
849  mutex_lock(&fimc->lock);
850  fimc_ctrls_delete(fimc->vid_cap.ctx);
851  mutex_unlock(&fimc->lock);
852  }
853  return ret;
854  }
855  /*
856  * Link activation. Enable power of pipeline elements only if the
857  * pipeline is already in use, i.e. its video node is opened.
858  * Recreate the controls destroyed during the link deactivation.
859  */
860  if (fimc) {
861  mutex_lock(&fimc->lock);
862  if (fimc->vid_cap.refcnt > 0) {
863  ret = __fimc_pipeline_open(pipeline,
864  source->entity, true);
865  if (!ret)
866  ret = fimc_capture_ctrls_create(fimc);
867  }
868  mutex_unlock(&fimc->lock);
869  } else {
870  mutex_lock(&fimc_lite->lock);
871  if (fimc_lite->ref_count > 0) {
872  ret = __fimc_pipeline_open(pipeline,
873  source->entity, true);
874  }
875  mutex_unlock(&fimc_lite->lock);
876  }
877  return ret ? -EPIPE : ret;
878 }
879 
880 static ssize_t fimc_md_sysfs_show(struct device *dev,
881  struct device_attribute *attr, char *buf)
882 {
883  struct platform_device *pdev = to_platform_device(dev);
884  struct fimc_md *fmd = platform_get_drvdata(pdev);
885 
886  if (fmd->user_subdev_api)
887  return strlcpy(buf, "Sub-device API (sub-dev)\n", PAGE_SIZE);
888 
889  return strlcpy(buf, "V4L2 video node only API (vid-dev)\n", PAGE_SIZE);
890 }
891 
892 static ssize_t fimc_md_sysfs_store(struct device *dev,
893  struct device_attribute *attr,
894  const char *buf, size_t count)
895 {
896  struct platform_device *pdev = to_platform_device(dev);
897  struct fimc_md *fmd = platform_get_drvdata(pdev);
898  bool subdev_api;
899  int i;
900 
901  if (!strcmp(buf, "vid-dev\n"))
902  subdev_api = false;
903  else if (!strcmp(buf, "sub-dev\n"))
904  subdev_api = true;
905  else
906  return count;
907 
908  fmd->user_subdev_api = subdev_api;
909  for (i = 0; i < FIMC_MAX_DEVS; i++)
910  if (fmd->fimc[i])
911  fmd->fimc[i]->vid_cap.user_subdev_api = subdev_api;
912  return count;
913 }
914 /*
915  * This device attribute is to select video pipeline configuration method.
916  * There are following valid values:
917  * vid-dev - for V4L2 video node API only, subdevice will be configured
918  * by the host driver.
919  * sub-dev - for media controller API, subdevs must be configured in user
920  * space before starting streaming.
921  */
922 static DEVICE_ATTR(subdev_conf_mode, S_IWUSR | S_IRUGO,
923  fimc_md_sysfs_show, fimc_md_sysfs_store);
924 
925 static int fimc_md_probe(struct platform_device *pdev)
926 {
927  struct v4l2_device *v4l2_dev;
928  struct fimc_md *fmd;
929  int ret;
930 
931  fmd = devm_kzalloc(&pdev->dev, sizeof(*fmd), GFP_KERNEL);
932  if (!fmd)
933  return -ENOMEM;
934 
935  spin_lock_init(&fmd->slock);
936  fmd->pdev = pdev;
937 
938  strlcpy(fmd->media_dev.model, "SAMSUNG S5P FIMC",
939  sizeof(fmd->media_dev.model));
940  fmd->media_dev.link_notify = fimc_md_link_notify;
941  fmd->media_dev.dev = &pdev->dev;
942 
943  v4l2_dev = &fmd->v4l2_dev;
944  v4l2_dev->mdev = &fmd->media_dev;
945  v4l2_dev->notify = fimc_sensor_notify;
946  snprintf(v4l2_dev->name, sizeof(v4l2_dev->name), "%s",
947  dev_name(&pdev->dev));
948 
949  ret = v4l2_device_register(&pdev->dev, &fmd->v4l2_dev);
950  if (ret < 0) {
951  v4l2_err(v4l2_dev, "Failed to register v4l2_device: %d\n", ret);
952  return ret;
953  }
954  ret = media_device_register(&fmd->media_dev);
955  if (ret < 0) {
956  v4l2_err(v4l2_dev, "Failed to register media device: %d\n", ret);
957  goto err_md;
958  }
959  ret = fimc_md_get_clocks(fmd);
960  if (ret)
961  goto err_clk;
962 
963  fmd->user_subdev_api = false;
964 
965  /* Protect the media graph while we're registering entities */
966  mutex_lock(&fmd->media_dev.graph_mutex);
967 
968  ret = fimc_md_register_platform_entities(fmd);
969  if (ret)
970  goto err_unlock;
971 
972  if (pdev->dev.platform_data) {
973  ret = fimc_md_register_sensor_entities(fmd);
974  if (ret)
975  goto err_unlock;
976  }
977  ret = fimc_md_create_links(fmd);
978  if (ret)
979  goto err_unlock;
981  if (ret)
982  goto err_unlock;
983 
984  ret = device_create_file(&pdev->dev, &dev_attr_subdev_conf_mode);
985  if (ret)
986  goto err_unlock;
987 
988  platform_set_drvdata(pdev, fmd);
989  mutex_unlock(&fmd->media_dev.graph_mutex);
990  return 0;
991 
992 err_unlock:
993  mutex_unlock(&fmd->media_dev.graph_mutex);
994 err_clk:
996  fimc_md_put_clocks(fmd);
997  fimc_md_unregister_entities(fmd);
998 err_md:
1000  return ret;
1001 }
1002 
1003 static int __devexit fimc_md_remove(struct platform_device *pdev)
1004 {
1005  struct fimc_md *fmd = platform_get_drvdata(pdev);
1006 
1007  if (!fmd)
1008  return 0;
1009  device_remove_file(&pdev->dev, &dev_attr_subdev_conf_mode);
1010  fimc_md_unregister_entities(fmd);
1012  fimc_md_put_clocks(fmd);
1013  return 0;
1014 }
1015 
1016 static struct platform_driver fimc_md_driver = {
1017  .probe = fimc_md_probe,
1018  .remove = __devexit_p(fimc_md_remove),
1019  .driver = {
1020  .name = "s5p-fimc-md",
1021  .owner = THIS_MODULE,
1022  }
1023 };
1024 
1025 static int __init fimc_md_init(void)
1026 {
1027  int ret;
1028 
1029  request_module("s5p-csis");
1030  ret = fimc_register_driver();
1031  if (ret)
1032  return ret;
1033 
1034  return platform_driver_register(&fimc_md_driver);
1035 }
1036 
1037 static void __exit fimc_md_exit(void)
1038 {
1039  platform_driver_unregister(&fimc_md_driver);
1041 }
1042 
1043 module_init(fimc_md_init);
1044 module_exit(fimc_md_exit);
1045 
1046 MODULE_AUTHOR("Sylwester Nawrocki <[email protected]>");
1047 MODULE_DESCRIPTION("S5P FIMC camera host interface/video postprocessor driver");
1048 MODULE_LICENSE("GPL");
1049 MODULE_VERSION("2.0.1");