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 @@
15 * 15 *
16 */ 16 */
17 17
18#include <linux/component.h>
18#include <linux/freezer.h> 19#include <linux/freezer.h>
19#include <linux/kthread.h> 20#include <linux/kthread.h>
21#include <linux/module.h>
22#include <linux/platform_device.h>
20#include <linux/v4l2-mediabus.h> 23#include <linux/v4l2-mediabus.h>
21#include <linux/vmalloc.h> 24#include <linux/vmalloc.h>
22#include <media/v4l2-subdev.h> 25#include <media/v4l2-subdev.h>
23#include <media/v4l2-tpg.h> 26#include <media/v4l2-tpg.h>
24 27
25#include "vimc-sensor.h" 28#include "vimc-common.h"
29
30#define VIMC_SEN_DRV_NAME "vimc-sensor"
26 31
27struct vimc_sen_device { 32struct vimc_sen_device {
28 struct vimc_ent_device ved; 33 struct vimc_ent_device ved;
29 struct v4l2_subdev sd; 34 struct v4l2_subdev sd;
35 struct device *dev;
30 struct tpg_data tpg; 36 struct tpg_data tpg;
31 struct task_struct *kthread_sen; 37 struct task_struct *kthread_sen;
32 u8 *frame; 38 u8 *frame;
@@ -166,7 +172,7 @@ static int vimc_sen_set_fmt(struct v4l2_subdev *sd,
166 /* Set the new format */ 172 /* Set the new format */
167 vimc_sen_adjust_fmt(&fmt->format); 173 vimc_sen_adjust_fmt(&fmt->format);
168 174
169 dev_dbg(vsen->sd.v4l2_dev->mdev->dev, "%s: format update: " 175 dev_dbg(vsen->dev, "%s: format update: "
170 "old:%dx%d (0x%x, %d, %d, %d, %d) " 176 "old:%dx%d (0x%x, %d, %d, %d, %d) "
171 "new:%dx%d (0x%x, %d, %d, %d, %d)\n", vsen->sd.name, 177 "new:%dx%d (0x%x, %d, %d, %d, %d)\n", vsen->sd.name,
172 /* old */ 178 /* old */
@@ -252,8 +258,8 @@ static int vimc_sen_s_stream(struct v4l2_subdev *sd, int enable)
252 vsen->kthread_sen = kthread_run(vimc_sen_tpg_thread, vsen, 258 vsen->kthread_sen = kthread_run(vimc_sen_tpg_thread, vsen,
253 "%s-sen", vsen->sd.v4l2_dev->name); 259 "%s-sen", vsen->sd.v4l2_dev->name);
254 if (IS_ERR(vsen->kthread_sen)) { 260 if (IS_ERR(vsen->kthread_sen)) {
255 dev_err(vsen->sd.v4l2_dev->dev, 261 dev_err(vsen->dev, "%s: kernel_thread() failed\n",
256 "%s: kernel_thread() failed\n", vsen->sd.name); 262 vsen->sd.name);
257 vfree(vsen->frame); 263 vfree(vsen->frame);
258 vsen->frame = NULL; 264 vsen->frame = NULL;
259 return PTR_ERR(vsen->kthread_sen); 265 return PTR_ERR(vsen->kthread_sen);
@@ -285,8 +291,10 @@ static const struct v4l2_subdev_ops vimc_sen_ops = {
285 .video = &vimc_sen_video_ops, 291 .video = &vimc_sen_video_ops,
286}; 292};
287 293
288static void vimc_sen_destroy(struct vimc_ent_device *ved) 294static void vimc_sen_comp_unbind(struct device *comp, struct device *master,
295 void *master_data)
289{ 296{
297 struct vimc_ent_device *ved = dev_get_drvdata(comp);
290 struct vimc_sen_device *vsen = 298 struct vimc_sen_device *vsen =
291 container_of(ved, struct vimc_sen_device, ved); 299 container_of(ved, struct vimc_sen_device, ved);
292 300
@@ -295,36 +303,31 @@ static void vimc_sen_destroy(struct vimc_ent_device *ved)
295 kfree(vsen); 303 kfree(vsen);
296} 304}
297 305
298struct vimc_ent_device *vimc_sen_create(struct v4l2_device *v4l2_dev, 306static int vimc_sen_comp_bind(struct device *comp, struct device *master,
299 const char *const name, 307 void *master_data)
300 u16 num_pads,
301 const unsigned long *pads_flag)
302{ 308{
309 struct v4l2_device *v4l2_dev = master_data;
310 struct vimc_platform_data *pdata = comp->platform_data;
303 struct vimc_sen_device *vsen; 311 struct vimc_sen_device *vsen;
304 unsigned int i;
305 int ret; 312 int ret;
306 313
307 /* NOTE: a sensor node may be created with more then one pad */
308 if (!name || !num_pads || !pads_flag)
309 return ERR_PTR(-EINVAL);
310
311 /* check if all pads are sources */
312 for (i = 0; i < num_pads; i++)
313 if (!(pads_flag[i] & MEDIA_PAD_FL_SOURCE))
314 return ERR_PTR(-EINVAL);
315
316 /* Allocate the vsen struct */ 314 /* Allocate the vsen struct */
317 vsen = kzalloc(sizeof(*vsen), GFP_KERNEL); 315 vsen = kzalloc(sizeof(*vsen), GFP_KERNEL);
318 if (!vsen) 316 if (!vsen)
319 return ERR_PTR(-ENOMEM); 317 return -ENOMEM;
320 318
321 /* Initialize ved and sd */ 319 /* Initialize ved and sd */
322 ret = vimc_ent_sd_register(&vsen->ved, &vsen->sd, v4l2_dev, name, 320 ret = vimc_ent_sd_register(&vsen->ved, &vsen->sd, v4l2_dev,
323 MEDIA_ENT_F_CAM_SENSOR, num_pads, pads_flag, 321 pdata->entity_name,
324 &vimc_sen_ops, vimc_sen_destroy); 322 MEDIA_ENT_F_ATV_DECODER, 1,
323 (const unsigned long[1]) {MEDIA_PAD_FL_SOURCE},
324 &vimc_sen_ops);
325 if (ret) 325 if (ret)
326 goto err_free_vsen; 326 goto err_free_vsen;
327 327
328 dev_set_drvdata(comp, &vsen->ved);
329 vsen->dev = comp;
330
328 /* Initialize the frame format */ 331 /* Initialize the frame format */
329 vsen->mbus_format = fmt_default; 332 vsen->mbus_format = fmt_default;
330 333
@@ -335,12 +338,52 @@ struct vimc_ent_device *vimc_sen_create(struct v4l2_device *v4l2_dev,
335 if (ret) 338 if (ret)
336 goto err_unregister_ent_sd; 339 goto err_unregister_ent_sd;
337 340
338 return &vsen->ved; 341 return 0;
339 342
340err_unregister_ent_sd: 343err_unregister_ent_sd:
341 vimc_ent_sd_unregister(&vsen->ved, &vsen->sd); 344 vimc_ent_sd_unregister(&vsen->ved, &vsen->sd);
342err_free_vsen: 345err_free_vsen:
343 kfree(vsen); 346 kfree(vsen);
344 347
345 return ERR_PTR(ret); 348 return ret;
346} 349}
350
351static const struct component_ops vimc_sen_comp_ops = {
352 .bind = vimc_sen_comp_bind,
353 .unbind = vimc_sen_comp_unbind,
354};
355
356static int vimc_sen_probe(struct platform_device *pdev)
357{
358 return component_add(&pdev->dev, &vimc_sen_comp_ops);
359}
360
361static int vimc_sen_remove(struct platform_device *pdev)
362{
363 component_del(&pdev->dev, &vimc_sen_comp_ops);
364
365 return 0;
366}
367
368static struct platform_driver vimc_sen_pdrv = {
369 .probe = vimc_sen_probe,
370 .remove = vimc_sen_remove,
371 .driver = {
372 .name = VIMC_SEN_DRV_NAME,
373 },
374};
375
376static const struct platform_device_id vimc_sen_driver_ids[] = {
377 {
378 .name = VIMC_SEN_DRV_NAME,
379 },
380 { }
381};
382
383module_platform_driver(vimc_sen_pdrv);
384
385MODULE_DEVICE_TABLE(platform, vimc_sen_driver_ids);
386
387MODULE_DESCRIPTION("Virtual Media Controller Driver (VIMC) Sensor");
388MODULE_AUTHOR("Helen Mae Koike Fornazier <helen.fornazier@gmail.com>");
389MODULE_LICENSE("GPL");