Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a4417cef authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: camera: Add camera sync driver" into msm-4.9

parents b37e2f45 4994456f
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
ccflags-y += -Idrivers/media/platform/msm/camera/cam_req_mgr

obj-$(CONFIG_SPECTRA_CAMERA) += cam_req_mgr/
obj-$(CONFIG_SPECTRA_CAMERA) += cam_utils/
obj-$(CONFIG_SPECTRA_CAMERA) += cam_core/
obj-$(CONFIG_SPECTRA_CAMERA) += cam_sync/
+1 −0
Original line number Diff line number Diff line
obj-$(CONFIG_SPECTRA_CAMERA) += cam_sync.o cam_sync_util.o
+1024 −0

File added.

Preview size limit exceeded, changes collapsed.

+128 −0
Original line number Diff line number Diff line
/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * only version 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#ifndef __CAM_SYNC_API_H__
#define __CAM_SYNC_API_H__

#include <linux/mutex.h>
#include <linux/list.h>
#include <linux/completion.h>
#include <linux/videodev2.h>
#include <uapi/media/cam_sync.h>

#define SYNC_DEBUG_NAME_LEN 63
typedef void (*sync_callback)(int32_t sync_obj, int status, void *data);

/* Kernel APIs */

/**
 * @brief: Creates a sync object
 *
 *  The newly created sync obj is assigned to sync_obj.
 *  sync object.
 *
 * @param sync_obj   : Pointer to int referencing the sync object.
 * @param name : Optional parameter associating a name with the sync object for
 * debug purposes. Only first SYNC_DEBUG_NAME_LEN bytes are accepted,
 * rest will be ignored.
 *
 * @return Status of operation. Zero in case of success.
 * -EINVAL will be returned if sync_obj is an invalid pointer.
 * -ENOMEM will be returned if the kernel can't allocate space for
 * sync object.
 */
int cam_sync_create(int32_t *sync_obj, const char *name);

/**
 * @brief: Registers a callback with a sync object
 *
 * @param cb_func:  Pointer to callback to be registered
 * @param userdata: Opaque pointer which will be passed back with callback.
 * @param sync_obj: int referencing the sync object.
 *
 * @return Status of operation. Zero in case of success.
 * -EINVAL will be returned if userdata is invalid.
 * -ENOMEM will be returned if cb_func is invalid.
 *
 */
int cam_sync_register_callback(sync_callback cb_func,
	void *userdata, int32_t sync_obj);

/**
 * @brief: De-registers a callback with a sync object
 *
 * @param cb_func:  Pointer to callback to be de-registered
 * @param userdata: Opaque pointer which will be passed back with callback.
 * @param sync_obj: int referencing the sync object.
 *
 * @return Status of operation. Zero in case of success.
 * -EINVAL will be returned if userdata is invalid.
 * -ENOMEM will be returned if cb_func is invalid.
 */
int cam_sync_deregister_callback(sync_callback cb_func,
	void *userdata, int32_t sync_obj);

/**
 * @brief: Signals a sync object with the status argument.
 *
 * This function will signal the sync object referenced by the sync_obj
 * parameter and when doing so, will trigger callbacks in both user space and
 * kernel. Callbacks will triggered asynchronously and their order of execution
 * is not guaranteed. The status parameter will indicate whether the entity
 * performing the signaling wants to convey an error case or a success case.
 *
 * @param sync_obj: int referencing the sync object.
 * @param status: Status of the signaling. Can be either SYNC_SIGNAL_ERROR or
 * SYNC_SIGNAL_SUCCESS.
 *
 * @return Status of operation. Negative in case of error. Zero otherwise.
 */
int cam_sync_signal(int32_t sync_obj, uint32_t status);

/**
 * @brief: Merges multiple sync objects
 *
 * This function will merge multiple sync objects into a sync group.
 *
 * @param sync_obj: pointer to a block of ints to be merged
 * @param num_objs: Number of ints in the block
 *
 * @return Status of operation. Negative in case of error. Zero otherwise.
 */
int cam_sync_merge(int32_t *sync_obj, uint32_t num_objs, int32_t *merged_obj);

/**
 * @brief: Destroys a sync object
 *
 * @param sync_obj: int referencing the sync object to be destroyed
 *
 * @return Status of operation. Negative in case of error. Zero otherwise.
 */
int cam_sync_destroy(int32_t sync_obj);

/**
 * @brief: Waits for a sync object synchronously
 *
 * Does a wait on the sync object identified by sync_obj for a maximum
 * of timeout_ms milliseconds. Must not be called from interrupt context as
 * this API can sleep. Should be called from process context only.
 *
 * @param sync_obj: int referencing the sync object to be waited upon
 * @timeout_ms sync_obj: Timeout in ms.
 *
 * @return 0 upon success, -EINVAL if sync object is in bad state or arguments
 * are invalid, -ETIMEDOUT if wait times out.
 */
int cam_sync_wait(int32_t sync_obj, uint64_t timeout_ms);


#endif /* __CAM_SYNC_API_H__ */
+186 −0
Original line number Diff line number Diff line
/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * only version 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#ifndef __CAM_SYNC_PRIVATE_H__
#define __CAM_SYNC_PRIVATE_H__

#include <linux/bitmap.h>
#include <linux/videodev2.h>
#include <linux/workqueue.h>
#include <linux/interrupt.h>
#include <media/v4l2-fh.h>
#include <media/v4l2-device.h>
#include <media/v4l2-subdev.h>
#include <media/v4l2-event.h>
#include <media/v4l2-ioctl.h>

#ifdef CONFIG_CAM_SYNC_DBG
#define CDBG(fmt, args...) pr_err(fmt, ##args)
#else
#define CDBG(fmt, args...) pr_debug(fmt, ##args)
#endif

#define CAM_SYNC_OBJ_NAME_LEN           64
#define CAM_SYNC_MAX_OBJS               1024
#define CAM_SYNC_MAX_V4L2_EVENTS        50
#define CAM_SYNC_DEBUG_FILENAME         "cam_debug"
#define CAM_SYNC_DEBUG_BASEDIR          "cam"
#define CAM_SYNC_DEBUG_BUF_SIZE         32
#define CAM_SYNC_PAYLOAD_WORDS          2
#define CAM_SYNC_NAME                   "cam_sync"
#define CAM_SYNC_WORKQUEUE_NAME         "HIPRIO_SYNC_WORK_QUEUE"

#define CAM_SYNC_TYPE_INDV              0
#define CAM_SYNC_TYPE_GROUP             1

/**
 * enum sync_type - Enum to indicate the type of sync object,
 * i.e. individual or group.
 *
 * @SYNC_TYPE_INDV  : Object is an individual sync object
 * @SYNC_TYPE_GROUP : Object is a group sync object
 */
enum sync_type {
	SYNC_TYPE_INDV,
	SYNC_TYPE_GROUP
};

/**
 * struct sync_parent_info - Single node of information about a parent
 * of a sync object, usually part of the parents linked list
 *
 * @sync_id  : Sync object id of parent
 * @list     : List member used to append this node to a linked list
 */
struct sync_parent_info {
	int32_t sync_id;
	struct list_head list;
};

/**
 * struct sync_parent_info - Single node of information about a child
 * of a sync object, usually part of the children linked list
 *
 * @sync_id  : Sync object id of child
 * @list     : List member used to append this node to a linked list
 */
struct sync_child_info {
	int32_t sync_id;
	struct list_head list;
};


/**
 * struct sync_callback_info - Single node of information about a kernel
 * callback registered on a sync object
 *
 * @callback_func    : Callback function, registered by client driver
 * @cb_data          : Callback data, registered by client driver
 * @status........   : Status with which callback will be invoked in client
 * @sync_obj         : Sync id of the object for which callback is registered
 * @cb_dispatch_work : Work representing the call dispatch
 * @list             : List member used to append this node to a linked list
 */
struct sync_callback_info {
	sync_callback callback_func;
	void *cb_data;
	int status;
	int32_t sync_obj;
	struct work_struct cb_dispatch_work;
	struct list_head list;
};

/**
 * struct sync_user_payload - Single node of information about a user space
 * payload registered from user space
 *
 * @payload_data    : Payload data, opaque to kernel
 * @list            : List member used to append this node to a linked list
 */
struct sync_user_payload {
	uint64_t payload_data[CAM_SYNC_PAYLOAD_WORDS];
	struct list_head list;
};

/**
 * struct sync_table_row - Single row of information about a sync object, used
 * for internal book keeping in the sync driver
 *
 * @name              : Optional string representation of the sync object
 * @type              : Type of the sync object (individual or group)
 * @sync_id           : Integer id representing this sync object
 * @parents_list      : Linked list of parents of this sync object
 * @children_list     : Linked list of children of this sync object
 * @state             : State (INVALID, ACTIVE, SIGNALED_SUCCESS or
 *                      SIGNALED_ERROR)
 * @remaining         : Count of remaining children that not been signaled
 * @signaled          : Completion variable on which block calls will wait
 * @callback_list     : Linked list of kernel callbacks registered
 * @user_payload_list : LInked list of user space payloads registered
 */
struct sync_table_row {
	char name[CAM_SYNC_OBJ_NAME_LEN];
	enum sync_type type;
	int32_t sync_id;
	/* List of parents, which are merged objects */
	struct list_head parents_list;
	/* List of children, which constitute the merged object */
	struct list_head children_list;
	uint32_t state;
	uint32_t remaining;
	struct completion signaled;
	struct list_head callback_list;
	struct list_head user_payload_list;
};

/**
 * struct cam_signalable_info - Information for a single sync object that is
 * ready to be signaled
 *
 * @sync_obj : Sync object id of signalable object
 * @status   : Status with which to signal
 * @list     : List member used to append this node to a linked list
 */
struct cam_signalable_info {
	int32_t sync_obj;
	uint32_t status;
	struct list_head list;
};

/**
 * struct sync_device - Internal struct to book keep sync driver details
 *
 * @vdev            : Video device
 * @v4l2_dev        : V4L2 device
 * @sync_table      : Table of all sync objects
 * @row_spinlocks   : Spinlock array, one for each row in the table
 * @table_lock      : Mutex used to lock the table
 * @open_cnt        : Count of file open calls made on the sync driver
 * @work_queue      : Work queue used for dispatching kernel callbacks
 * @cam_sync_eventq : Event queue used to dispatch user payloads to user space
 * @bitmap          : Bitmap representation of all sync objects
 */
struct sync_device {
	struct video_device *vdev;
	struct v4l2_device v4l2_dev;
	struct sync_table_row sync_table[CAM_SYNC_MAX_OBJS];
	spinlock_t row_spinlocks[CAM_SYNC_MAX_OBJS];
	struct mutex table_lock;
	int open_cnt;
	struct workqueue_struct *work_queue;
	struct v4l2_fh *cam_sync_eventq;
	spinlock_t cam_sync_eventq_lock;
	DECLARE_BITMAP(bitmap, CAM_SYNC_MAX_OBJS);
};


#endif /* __CAM_SYNC_PRIVATE_H__ */
Loading