linux/drivers/media/platform/ti/omap3isp/ispccdc.c

// SPDX-License-Identifier: GPL-2.0-only
/*
 * ispccdc.c
 *
 * TI OMAP3 ISP - CCDC module
 *
 * Copyright (C) 2009-2010 Nokia Corporation
 * Copyright (C) 2009 Texas Instruments, Inc.
 *
 * Contacts: Laurent Pinchart <[email protected]>
 *	     Sakari Ailus <[email protected]>
 */

#include <linux/module.h>
#include <linux/uaccess.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/dma-mapping.h>
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <media/v4l2-event.h>

#include "isp.h"
#include "ispreg.h"
#include "ispccdc.h"

#define CCDC_MIN_WIDTH
#define CCDC_MIN_HEIGHT

static struct v4l2_mbus_framefmt *
__ccdc_get_format(struct isp_ccdc_device *ccdc,
		  struct v4l2_subdev_state *sd_state,
		  unsigned int pad, enum v4l2_subdev_format_whence which);

static const unsigned int ccdc_fmts[] =;

/*
 * ccdc_print_status - Print current CCDC Module register values.
 * @ccdc: Pointer to ISP CCDC device.
 *
 * Also prints other debug information stored in the CCDC module.
 */
#define CCDC_PRINT_REGISTER(isp, name)

static void ccdc_print_status(struct isp_ccdc_device *ccdc)
{}

/*
 * omap3isp_ccdc_busy - Get busy state of the CCDC.
 * @ccdc: Pointer to ISP CCDC device.
 */
int omap3isp_ccdc_busy(struct isp_ccdc_device *ccdc)
{}

/* -----------------------------------------------------------------------------
 * Lens Shading Compensation
 */

/*
 * ccdc_lsc_validate_config - Check that LSC configuration is valid.
 * @ccdc: Pointer to ISP CCDC device.
 * @lsc_cfg: the LSC configuration to check.
 *
 * Returns 0 if the LSC configuration is valid, or -EINVAL if invalid.
 */
static int ccdc_lsc_validate_config(struct isp_ccdc_device *ccdc,
				    struct omap3isp_ccdc_lsc_config *lsc_cfg)
{}

/*
 * ccdc_lsc_program_table - Program Lens Shading Compensation table address.
 * @ccdc: Pointer to ISP CCDC device.
 */
static void ccdc_lsc_program_table(struct isp_ccdc_device *ccdc,
				   dma_addr_t addr)
{}

/*
 * ccdc_lsc_setup_regs - Configures the lens shading compensation module
 * @ccdc: Pointer to ISP CCDC device.
 */
static void ccdc_lsc_setup_regs(struct isp_ccdc_device *ccdc,
				struct omap3isp_ccdc_lsc_config *cfg)
{}

static int ccdc_lsc_wait_prefetch(struct isp_ccdc_device *ccdc)
{}

/*
 * __ccdc_lsc_enable - Enables/Disables the Lens Shading Compensation module.
 * @ccdc: Pointer to ISP CCDC device.
 * @enable: 0 Disables LSC, 1 Enables LSC.
 */
static int __ccdc_lsc_enable(struct isp_ccdc_device *ccdc, int enable)
{}

static int ccdc_lsc_busy(struct isp_ccdc_device *ccdc)
{}

/*
 * __ccdc_lsc_configure - Apply a new configuration to the LSC engine
 * @ccdc: Pointer to ISP CCDC device
 * @req: New configuration request
 */
static int __ccdc_lsc_configure(struct isp_ccdc_device *ccdc,
				struct ispccdc_lsc_config_req *req)
{}

/*
 * ccdc_lsc_error_handler - Handle LSC prefetch error scenario.
 * @ccdc: Pointer to ISP CCDC device.
 *
 * Disables LSC, and defers enablement to shadow registers update time.
 */
static void ccdc_lsc_error_handler(struct isp_ccdc_device *ccdc)
{}

static void ccdc_lsc_free_request(struct isp_ccdc_device *ccdc,
				  struct ispccdc_lsc_config_req *req)
{}

static void ccdc_lsc_free_queue(struct isp_ccdc_device *ccdc,
				struct list_head *queue)
{}

static void ccdc_lsc_free_table_work(struct work_struct *work)
{}

/*
 * ccdc_lsc_config - Configure the LSC module from a userspace request
 *
 * Store the request LSC configuration in the LSC engine request pointer. The
 * configuration will be applied to the hardware when the CCDC will be enabled,
 * or at the next LSC interrupt if the CCDC is already running.
 */
static int ccdc_lsc_config(struct isp_ccdc_device *ccdc,
			   struct omap3isp_ccdc_update_config *config)
{}

static inline int ccdc_lsc_is_configured(struct isp_ccdc_device *ccdc)
{}

static int ccdc_lsc_enable(struct isp_ccdc_device *ccdc)
{}

/* -----------------------------------------------------------------------------
 * Parameters configuration
 */

/*
 * ccdc_configure_clamp - Configure optical-black or digital clamping
 * @ccdc: Pointer to ISP CCDC device.
 *
 * The CCDC performs either optical-black or digital clamp. Configure and enable
 * the selected clamp method.
 */
static void ccdc_configure_clamp(struct isp_ccdc_device *ccdc)
{}

/*
 * ccdc_configure_fpc - Configure Faulty Pixel Correction
 * @ccdc: Pointer to ISP CCDC device.
 */
static void ccdc_configure_fpc(struct isp_ccdc_device *ccdc)
{}

/*
 * ccdc_configure_black_comp - Configure Black Level Compensation.
 * @ccdc: Pointer to ISP CCDC device.
 */
static void ccdc_configure_black_comp(struct isp_ccdc_device *ccdc)
{}

/*
 * ccdc_configure_lpf - Configure Low-Pass Filter (LPF).
 * @ccdc: Pointer to ISP CCDC device.
 */
static void ccdc_configure_lpf(struct isp_ccdc_device *ccdc)
{}

/*
 * ccdc_configure_alaw - Configure A-law compression.
 * @ccdc: Pointer to ISP CCDC device.
 */
static void ccdc_configure_alaw(struct isp_ccdc_device *ccdc)
{}

/*
 * ccdc_config_imgattr - Configure sensor image specific attributes.
 * @ccdc: Pointer to ISP CCDC device.
 * @colptn: Color pattern of the sensor.
 */
static void ccdc_config_imgattr(struct isp_ccdc_device *ccdc, u32 colptn)
{}

/*
 * ccdc_config - Set CCDC configuration from userspace
 * @ccdc: Pointer to ISP CCDC device.
 * @ccdc_struct: Structure containing CCDC configuration sent from userspace.
 *
 * Returns 0 if successful, -EINVAL if the pointer to the configuration
 * structure is null, or the copy_from_user function fails to copy user space
 * memory to kernel space memory.
 */
static int ccdc_config(struct isp_ccdc_device *ccdc,
		       struct omap3isp_ccdc_update_config *ccdc_struct)
{}

static void ccdc_apply_controls(struct isp_ccdc_device *ccdc)
{}

/*
 * omap3isp_ccdc_restore_context - Restore values of the CCDC module registers
 * @isp: Pointer to ISP device
 */
void omap3isp_ccdc_restore_context(struct isp_device *isp)
{}

/* -----------------------------------------------------------------------------
 * Format- and pipeline-related configuration helpers
 */

/*
 * ccdc_config_vp - Configure the Video Port.
 * @ccdc: Pointer to ISP CCDC device.
 */
static void ccdc_config_vp(struct isp_ccdc_device *ccdc)
{}

/*
 * ccdc_config_outlineoffset - Configure memory saving output line offset
 * @ccdc: Pointer to ISP CCDC device.
 * @bpl: Number of bytes per line when stored in memory.
 * @field: Field order when storing interlaced formats in memory.
 *
 * Configure the offsets for the line output control:
 *
 * - The horizontal line offset is defined as the number of bytes between the
 *   start of two consecutive lines in memory. Set it to the given bytes per
 *   line value.
 *
 * - The field offset value is defined as the number of lines to offset the
 *   start of the field identified by FID = 1. Set it to one.
 *
 * - The line offset values are defined as the number of lines (as defined by
 *   the horizontal line offset) between the start of two consecutive lines for
 *   all combinations of odd/even lines in odd/even fields. When interleaving
 *   fields set them all to two lines, and to one line otherwise.
 */
static void ccdc_config_outlineoffset(struct isp_ccdc_device *ccdc,
				      unsigned int bpl,
				      enum v4l2_field field)
{}

/*
 * ccdc_set_outaddr - Set memory address to save output image
 * @ccdc: Pointer to ISP CCDC device.
 * @addr: ISP MMU Mapped 32-bit memory address aligned on 32 byte boundary.
 *
 * Sets the memory address where the output will be saved.
 */
static void ccdc_set_outaddr(struct isp_ccdc_device *ccdc, u32 addr)
{}

/*
 * omap3isp_ccdc_max_rate - Calculate maximum input data rate based on the input
 * @ccdc: Pointer to ISP CCDC device.
 * @max_rate: Maximum calculated data rate.
 *
 * Returns in *max_rate less value between calculated and passed
 */
void omap3isp_ccdc_max_rate(struct isp_ccdc_device *ccdc,
			    unsigned int *max_rate)
{}

/*
 * ccdc_config_sync_if - Set CCDC sync interface configuration
 * @ccdc: Pointer to ISP CCDC device.
 * @parcfg: Parallel interface platform data (may be NULL)
 * @data_size: Data size
 */
static void ccdc_config_sync_if(struct isp_ccdc_device *ccdc,
				struct isp_parallel_cfg *parcfg,
				unsigned int data_size)
{}

/* CCDC formats descriptions */
static const u32 ccdc_sgrbg_pattern =;

static const u32 ccdc_srggb_pattern =;

static const u32 ccdc_sbggr_pattern =;

static const u32 ccdc_sgbrg_pattern =;

static void ccdc_configure(struct isp_ccdc_device *ccdc)
{}

static void __ccdc_enable(struct isp_ccdc_device *ccdc, int enable)
{}

static int ccdc_disable(struct isp_ccdc_device *ccdc)
{}

static void ccdc_enable(struct isp_ccdc_device *ccdc)
{}

/* -----------------------------------------------------------------------------
 * Interrupt handling
 */

/*
 * ccdc_sbl_busy - Poll idle state of CCDC and related SBL memory write bits
 * @ccdc: Pointer to ISP CCDC device.
 *
 * Returns zero if the CCDC is idle and the image has been written to
 * memory, too.
 */
static int ccdc_sbl_busy(struct isp_ccdc_device *ccdc)
{}

/*
 * ccdc_sbl_wait_idle - Wait until the CCDC and related SBL are idle
 * @ccdc: Pointer to ISP CCDC device.
 * @max_wait: Max retry count in us for wait for idle/busy transition.
 */
static int ccdc_sbl_wait_idle(struct isp_ccdc_device *ccdc,
			      unsigned int max_wait)
{}

/* ccdc_handle_stopping - Handle CCDC and/or LSC stopping sequence
 * @ccdc: Pointer to ISP CCDC device.
 * @event: Pointing which event trigger handler
 *
 * Return 1 when the event and stopping request combination is satisfied,
 * zero otherwise.
 */
static int ccdc_handle_stopping(struct isp_ccdc_device *ccdc, u32 event)
{}

static void ccdc_hs_vs_isr(struct isp_ccdc_device *ccdc)
{}

/*
 * ccdc_lsc_isr - Handle LSC events
 * @ccdc: Pointer to ISP CCDC device.
 * @events: LSC events
 */
static void ccdc_lsc_isr(struct isp_ccdc_device *ccdc, u32 events)
{}

/*
 * Check whether the CCDC has captured all fields necessary to complete the
 * buffer.
 */
static bool ccdc_has_all_fields(struct isp_ccdc_device *ccdc)
{}

static int ccdc_isr_buffer(struct isp_ccdc_device *ccdc)
{}

/*
 * ccdc_vd0_isr - Handle VD0 event
 * @ccdc: Pointer to ISP CCDC device.
 *
 * Executes LSC deferred enablement before next frame starts.
 */
static void ccdc_vd0_isr(struct isp_ccdc_device *ccdc)
{}

/*
 * ccdc_vd1_isr - Handle VD1 event
 * @ccdc: Pointer to ISP CCDC device.
 */
static void ccdc_vd1_isr(struct isp_ccdc_device *ccdc)
{}

/*
 * omap3isp_ccdc_isr - Configure CCDC during interframe time.
 * @ccdc: Pointer to ISP CCDC device.
 * @events: CCDC events
 */
int omap3isp_ccdc_isr(struct isp_ccdc_device *ccdc, u32 events)
{}

/* -----------------------------------------------------------------------------
 * ISP video operations
 */

static int ccdc_video_queue(struct isp_video *video, struct isp_buffer *buffer)
{}

static const struct isp_video_operations ccdc_video_ops =;

/* -----------------------------------------------------------------------------
 * V4L2 subdev operations
 */

/*
 * ccdc_ioctl - CCDC module private ioctl's
 * @sd: ISP CCDC V4L2 subdevice
 * @cmd: ioctl command
 * @arg: ioctl argument
 *
 * Return 0 on success or a negative error code otherwise.
 */
static long ccdc_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
{}

static int ccdc_subscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh,
				struct v4l2_event_subscription *sub)
{}

static int ccdc_unsubscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh,
				  struct v4l2_event_subscription *sub)
{}

/*
 * ccdc_set_stream - Enable/Disable streaming on the CCDC module
 * @sd: ISP CCDC V4L2 subdevice
 * @enable: Enable/disable stream
 *
 * When writing to memory, the CCDC hardware can't be enabled without a memory
 * buffer to write to. As the s_stream operation is called in response to a
 * STREAMON call without any buffer queued yet, just update the enabled field
 * and return immediately. The CCDC will be enabled in ccdc_isr_buffer().
 *
 * When not writing to memory enable the CCDC immediately.
 */
static int ccdc_set_stream(struct v4l2_subdev *sd, int enable)
{}

static struct v4l2_mbus_framefmt *
__ccdc_get_format(struct isp_ccdc_device *ccdc,
		  struct v4l2_subdev_state *sd_state,
		  unsigned int pad, enum v4l2_subdev_format_whence which)
{}

static struct v4l2_rect *
__ccdc_get_crop(struct isp_ccdc_device *ccdc,
		struct v4l2_subdev_state *sd_state,
		enum v4l2_subdev_format_whence which)
{}

/*
 * ccdc_try_format - Try video format on a pad
 * @ccdc: ISP CCDC device
 * @sd_state: V4L2 subdev state
 * @pad: Pad number
 * @fmt: Format
 */
static void
ccdc_try_format(struct isp_ccdc_device *ccdc,
		struct v4l2_subdev_state *sd_state,
		unsigned int pad, struct v4l2_mbus_framefmt *fmt,
		enum v4l2_subdev_format_whence which)
{}

/*
 * ccdc_try_crop - Validate a crop rectangle
 * @ccdc: ISP CCDC device
 * @sink: format on the sink pad
 * @crop: crop rectangle to be validated
 */
static void ccdc_try_crop(struct isp_ccdc_device *ccdc,
			  const struct v4l2_mbus_framefmt *sink,
			  struct v4l2_rect *crop)
{}

/*
 * ccdc_enum_mbus_code - Handle pixel format enumeration
 * @sd     : pointer to v4l2 subdev structure
 * @sd_state: V4L2 subdev state
 * @code   : pointer to v4l2_subdev_mbus_code_enum structure
 * return -EINVAL or zero on success
 */
static int ccdc_enum_mbus_code(struct v4l2_subdev *sd,
			       struct v4l2_subdev_state *sd_state,
			       struct v4l2_subdev_mbus_code_enum *code)
{}

static int ccdc_enum_frame_size(struct v4l2_subdev *sd,
				struct v4l2_subdev_state *sd_state,
				struct v4l2_subdev_frame_size_enum *fse)
{}

/*
 * ccdc_get_selection - Retrieve a selection rectangle on a pad
 * @sd: ISP CCDC V4L2 subdevice
 * @sd_state: V4L2 subdev state
 * @sel: Selection rectangle
 *
 * The only supported rectangles are the crop rectangles on the output formatter
 * source pad.
 *
 * Return 0 on success or a negative error code otherwise.
 */
static int ccdc_get_selection(struct v4l2_subdev *sd,
			      struct v4l2_subdev_state *sd_state,
			      struct v4l2_subdev_selection *sel)
{}

/*
 * ccdc_set_selection - Set a selection rectangle on a pad
 * @sd: ISP CCDC V4L2 subdevice
 * @sd_state: V4L2 subdev state
 * @sel: Selection rectangle
 *
 * The only supported rectangle is the actual crop rectangle on the output
 * formatter source pad.
 *
 * Return 0 on success or a negative error code otherwise.
 */
static int ccdc_set_selection(struct v4l2_subdev *sd,
			      struct v4l2_subdev_state *sd_state,
			      struct v4l2_subdev_selection *sel)
{}

/*
 * ccdc_get_format - Retrieve the video format on a pad
 * @sd : ISP CCDC V4L2 subdevice
 * @sd_state: V4L2 subdev state
 * @fmt: Format
 *
 * Return 0 on success or -EINVAL if the pad is invalid or doesn't correspond
 * to the format type.
 */
static int ccdc_get_format(struct v4l2_subdev *sd,
			   struct v4l2_subdev_state *sd_state,
			   struct v4l2_subdev_format *fmt)
{}

/*
 * ccdc_set_format - Set the video format on a pad
 * @sd : ISP CCDC V4L2 subdevice
 * @sd_state: V4L2 subdev state
 * @fmt: Format
 *
 * Return 0 on success or -EINVAL if the pad is invalid or doesn't correspond
 * to the format type.
 */
static int ccdc_set_format(struct v4l2_subdev *sd,
			   struct v4l2_subdev_state *sd_state,
			   struct v4l2_subdev_format *fmt)
{}

/*
 * Decide whether desired output pixel code can be obtained with
 * the lane shifter by shifting the input pixel code.
 * @in: input pixelcode to shifter
 * @out: output pixelcode from shifter
 * @additional_shift: # of bits the sensor's LSB is offset from CAMEXT[0]
 *
 * return true if the combination is possible
 * return false otherwise
 */
static bool ccdc_is_shiftable(u32 in, u32 out, unsigned int additional_shift)
{}

static int ccdc_link_validate(struct v4l2_subdev *sd,
			      struct media_link *link,
			      struct v4l2_subdev_format *source_fmt,
			      struct v4l2_subdev_format *sink_fmt)
{}

/*
 * ccdc_init_formats - Initialize formats on all pads
 * @sd: ISP CCDC V4L2 subdevice
 * @fh: V4L2 subdev file handle
 *
 * Initialize all pad formats with default values. If fh is not NULL, try
 * formats are initialized on the file handle. Otherwise active formats are
 * initialized on the device.
 */
static int ccdc_init_formats(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
{}

/* V4L2 subdev core operations */
static const struct v4l2_subdev_core_ops ccdc_v4l2_core_ops =;

/* V4L2 subdev video operations */
static const struct v4l2_subdev_video_ops ccdc_v4l2_video_ops =;

/* V4L2 subdev pad operations */
static const struct v4l2_subdev_pad_ops ccdc_v4l2_pad_ops =;

/* V4L2 subdev operations */
static const struct v4l2_subdev_ops ccdc_v4l2_ops =;

/* V4L2 subdev internal operations */
static const struct v4l2_subdev_internal_ops ccdc_v4l2_internal_ops =;

/* -----------------------------------------------------------------------------
 * Media entity operations
 */

/*
 * ccdc_link_setup - Setup CCDC connections
 * @entity: CCDC media entity
 * @local: Pad at the local end of the link
 * @remote: Pad at the remote end of the link
 * @flags: Link flags
 *
 * return -EINVAL or zero on success
 */
static int ccdc_link_setup(struct media_entity *entity,
			   const struct media_pad *local,
			   const struct media_pad *remote, u32 flags)
{}

/* media operations */
static const struct media_entity_operations ccdc_media_ops =;

void omap3isp_ccdc_unregister_entities(struct isp_ccdc_device *ccdc)
{}

int omap3isp_ccdc_register_entities(struct isp_ccdc_device *ccdc,
	struct v4l2_device *vdev)
{}

/* -----------------------------------------------------------------------------
 * ISP CCDC initialisation and cleanup
 */

/*
 * ccdc_init_entities - Initialize V4L2 subdev and media entity
 * @ccdc: ISP CCDC module
 *
 * Return 0 on success and a negative error code on failure.
 */
static int ccdc_init_entities(struct isp_ccdc_device *ccdc)
{}

/*
 * omap3isp_ccdc_init - CCDC module initialization.
 * @isp: Device pointer specific to the OMAP3 ISP.
 *
 * TODO: Get the initialisation values from platform data.
 *
 * Return 0 on success or a negative error code otherwise.
 */
int omap3isp_ccdc_init(struct isp_device *isp)
{}

/*
 * omap3isp_ccdc_cleanup - CCDC module cleanup.
 * @isp: Device pointer specific to the OMAP3 ISP.
 */
void omap3isp_ccdc_cleanup(struct isp_device *isp)
{}