aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/platform/vimc/vimc-sensor.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/platform/vimc/vimc-sensor.c')
-rw-r--r--drivers/media/platform/vimc/vimc-sensor.c93
1 files changed, 68 insertions, 25 deletions
diff --git a/drivers/media/platform/vimc/vimc-sensor.c b/drivers/media/platform/vimc/vimc-sensor.c
index d4f97050b544..5ea7b0853936 100644
--- a/drivers/media/platform/vimc/vimc-sensor.c
+++ b/drivers/media/platform/vimc/vimc-sensor.c
@@ -15,18 +15,24 @@
*
*/
+#include <linux/component.h>
#include <linux/freezer.h>
#include <linux/kthread.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
#include <linux/v4l2-mediabus.h>
#include <linux/vmalloc.h>
#include <media/v4l2-subdev.h>
#include <media/v4l2-tpg.h>
-#include "vimc-sensor.h"
+#include "vimc-common.h"
+
+#define VIMC_SEN_DRV_NAME "vimc-sensor"
struct vimc_sen_device {
struct vimc_ent_device ved;
struct v4l2_subdev sd;
+ struct device *dev;
struct tpg_data tpg;
struct task_struct *kthread_sen;
u8 *frame;
@@ -166,7 +172,7 @@ static int vimc_sen_set_fmt(struct v4l2_subdev *sd,
/* Set the new format */
vimc_sen_adjust_fmt(&fmt->format);
- dev_dbg(vsen->sd.v4l2_dev->mdev->dev, "%s: format update: "
+ dev_dbg(vsen->dev, "%s: format update: "
"old:%dx%d (0x%x, %d, %d, %d, %d) "
"new:%dx%d (0x%x, %d, %d, %d, %d)\n", vsen->sd.name,
/* old */
@@ -252,8 +258,8 @@ static int vimc_sen_s_stream(struct v4l2_subdev *sd, int enable)
vsen->kthread_sen = kthread_run(vimc_sen_tpg_thread, vsen,
"%s-sen", vsen->sd.v4l2_dev->name);
if (IS_ERR(vsen->kthread_sen)) {
- dev_err(vsen->sd.v4l2_dev->dev,
- "%s: kernel_thread() failed\n", vsen->sd.name);
+ dev_err(vsen->dev, "%s: kernel_thread() failed\n",
+ vsen->sd.name);
vfree(vsen->frame);
vsen->frame = NULL;
return PTR_ERR(vsen->kthread_sen);
@@ -285,8 +291,10 @@ static const struct v4l2_subdev_ops vimc_sen_ops = {
.video = &vimc_sen_video_ops,
};
-static void vimc_sen_destroy(struct vimc_ent_device *ved)
+static void vimc_sen_comp_unbind(struct device *comp, struct device *master,
+ void *master_data)
{
+ struct vimc_ent_device *ved = dev_get_drvdata(comp);
struct vimc_sen_device *vsen =
container_of(ved, struct vimc_sen_device, ved);
@@ -295,36 +303,31 @@ static void vimc_sen_destroy(struct vimc_ent_device *ved)
kfree(vsen);
}
-struct vimc_ent_device *vimc_sen_create(struct v4l2_device *v4l2_dev,
- const char *const name,
- u16 num_pads,
- const unsigned long *pads_flag)
+static int vimc_sen_comp_bind(struct device *comp, struct device *master,
+ void *master_data)
{
+ struct v4l2_device *v4l2_dev = master_data;
+ struct vimc_platform_data *pdata = comp->platform_data;
struct vimc_sen_device *vsen;
- unsigned int i;
int ret;
- /* NOTE: a sensor node may be created with more then one pad */
- if (!name || !num_pads || !pads_flag)
- return ERR_PTR(-EINVAL);
-
- /* check if all pads are sources */
- for (i = 0; i < num_pads; i++)
- if (!(pads_flag[i] & MEDIA_PAD_FL_SOURCE))
- return ERR_PTR(-EINVAL);
-
/* Allocate the vsen struct */
vsen = kzalloc(sizeof(*vsen), GFP_KERNEL);
if (!vsen)
- return ERR_PTR(-ENOMEM);
+ return -ENOMEM;
/* Initialize ved and sd */
- ret = vimc_ent_sd_register(&vsen->ved, &vsen->sd, v4l2_dev, name,
- MEDIA_ENT_F_CAM_SENSOR, num_pads, pads_flag,
- &vimc_sen_ops, vimc_sen_destroy);
+ ret = vimc_ent_sd_register(&vsen->ved, &vsen->sd, v4l2_dev,
+ pdata->entity_name,
+ MEDIA_ENT_F_ATV_DECODER, 1,
+ (const unsigned long[1]) {MEDIA_PAD_FL_SOURCE},
+ &vimc_sen_ops);
if (ret)
goto err_free_vsen;
+ dev_set_drvdata(comp, &vsen->ved);
+ vsen->dev = comp;
+
/* Initialize the frame format */
vsen->mbus_format = fmt_default;
@@ -335,12 +338,52 @@ struct vimc_ent_device *vimc_sen_create(struct v4l2_device *v4l2_dev,
if (ret)
goto err_unregister_ent_sd;
- return &vsen->ved;
+ return 0;
err_unregister_ent_sd:
vimc_ent_sd_unregister(&vsen->ved, &vsen->sd);
err_free_vsen:
kfree(vsen);
- return ERR_PTR(ret);
+ return ret;
}
+
+static const struct component_ops vimc_sen_comp_ops = {
+ .bind = vimc_sen_comp_bind,
+ .unbind = vimc_sen_comp_unbind,
+};
+
+static int vimc_sen_probe(struct platform_device *pdev)
+{
+ return component_add(&pdev->dev, &vimc_sen_comp_ops);
+}
+
+static int vimc_sen_remove(struct platform_device *pdev)
+{
+ component_del(&pdev->dev, &vimc_sen_comp_ops);
+
+ return 0;
+}
+
+static struct platform_driver vimc_sen_pdrv = {
+ .probe = vimc_sen_probe,
+ .remove = vimc_sen_remove,
+ .driver = {
+ .name = VIMC_SEN_DRV_NAME,
+ },
+};
+
+static const struct platform_device_id vimc_sen_driver_ids[] = {
+ {
+ .name = VIMC_SEN_DRV_NAME,
+ },
+ { }
+};
+
+module_platform_driver(vimc_sen_pdrv);
+
+MODULE_DEVICE_TABLE(platform, vimc_sen_driver_ids);
+
+MODULE_DESCRIPTION("Virtual Media Controller Driver (VIMC) Sensor");
+MODULE_AUTHOR("Helen Mae Koike Fornazier <helen.fornazier@gmail.com>");
+MODULE_LICENSE("GPL");