Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * vimc-lens.c Virtual Media Controller Driver
0004  * Copyright (C) 2022 Google, Inc
0005  * Author: yunkec@google.com (Yunke Cao)
0006  */
0007 
0008 #include <media/v4l2-ctrls.h>
0009 #include <media/v4l2-event.h>
0010 #include <media/v4l2-subdev.h>
0011 
0012 #include "vimc-common.h"
0013 
0014 #define VIMC_LENS_MAX_FOCUS_POS 1023
0015 #define VIMC_LENS_MAX_FOCUS_STEP    1
0016 
0017 struct vimc_lens_device {
0018     struct vimc_ent_device ved;
0019     struct v4l2_subdev sd;
0020     struct v4l2_ctrl_handler hdl;
0021     u32 focus_absolute;
0022 };
0023 
0024 static const struct v4l2_subdev_core_ops vimc_lens_core_ops = {
0025     .log_status = v4l2_ctrl_subdev_log_status,
0026     .subscribe_event = v4l2_ctrl_subdev_subscribe_event,
0027     .unsubscribe_event = v4l2_event_subdev_unsubscribe,
0028 };
0029 
0030 static const struct v4l2_subdev_ops vimc_lens_ops = {
0031     .core = &vimc_lens_core_ops
0032 };
0033 
0034 static int vimc_lens_s_ctrl(struct v4l2_ctrl *ctrl)
0035 {
0036     struct vimc_lens_device *vlens =
0037         container_of(ctrl->handler, struct vimc_lens_device, hdl);
0038     if (ctrl->id == V4L2_CID_FOCUS_ABSOLUTE) {
0039         vlens->focus_absolute = ctrl->val;
0040         return 0;
0041     }
0042     return -EINVAL;
0043 }
0044 
0045 static const struct v4l2_ctrl_ops vimc_lens_ctrl_ops = {
0046     .s_ctrl = vimc_lens_s_ctrl,
0047 };
0048 
0049 static struct vimc_ent_device *vimc_lens_add(struct vimc_device *vimc,
0050                          const char *vcfg_name)
0051 {
0052     struct v4l2_device *v4l2_dev = &vimc->v4l2_dev;
0053     struct vimc_lens_device *vlens;
0054     int ret;
0055 
0056     /* Allocate the vlens struct */
0057     vlens = kzalloc(sizeof(*vlens), GFP_KERNEL);
0058     if (!vlens)
0059         return ERR_PTR(-ENOMEM);
0060 
0061     v4l2_ctrl_handler_init(&vlens->hdl, 1);
0062 
0063     v4l2_ctrl_new_std(&vlens->hdl, &vimc_lens_ctrl_ops,
0064               V4L2_CID_FOCUS_ABSOLUTE, 0,
0065               VIMC_LENS_MAX_FOCUS_POS, VIMC_LENS_MAX_FOCUS_STEP, 0);
0066     vlens->sd.ctrl_handler = &vlens->hdl;
0067     if (vlens->hdl.error) {
0068         ret = vlens->hdl.error;
0069         goto err_free_vlens;
0070     }
0071     vlens->ved.dev = vimc->mdev.dev;
0072 
0073     ret = vimc_ent_sd_register(&vlens->ved, &vlens->sd, v4l2_dev,
0074                    vcfg_name, MEDIA_ENT_F_LENS, 0,
0075                    NULL, &vimc_lens_ops);
0076     if (ret)
0077         goto err_free_hdl;
0078 
0079     return &vlens->ved;
0080 
0081 err_free_hdl:
0082     v4l2_ctrl_handler_free(&vlens->hdl);
0083 err_free_vlens:
0084     kfree(vlens);
0085 
0086     return ERR_PTR(ret);
0087 }
0088 
0089 static void vimc_lens_release(struct vimc_ent_device *ved)
0090 {
0091     struct vimc_lens_device *vlens =
0092         container_of(ved, struct vimc_lens_device, ved);
0093 
0094     v4l2_ctrl_handler_free(&vlens->hdl);
0095     media_entity_cleanup(vlens->ved.ent);
0096     kfree(vlens);
0097 }
0098 
0099 struct vimc_ent_type vimc_lens_type = {
0100     .add = vimc_lens_add,
0101     .release = vimc_lens_release
0102 };