linux/drivers/media/platform/intel/pxa_camera.c

// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * V4L2 Driver for PXA camera host
 *
 * Copyright (C) 2006, Sascha Hauer, Pengutronix
 * Copyright (C) 2008, Guennadi Liakhovetski <[email protected]>
 * Copyright (C) 2016, Robert Jarzmik <[email protected]>
 */

#include <linux/init.h>
#include <linux/module.h>
#include <linux/io.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/dma-mapping.h>
#include <linux/err.h>
#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/moduleparam.h>
#include <linux/of.h>
#include <linux/of_graph.h>
#include <linux/time.h>
#include <linux/platform_device.h>
#include <linux/clk.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/dmaengine.h>
#include <linux/dma/pxa-dma.h>

#include <media/v4l2-async.h>
#include <media/v4l2-common.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
#include <media/v4l2-event.h>
#include <media/v4l2-ioctl.h>
#include <media/v4l2-fwnode.h>

#include <media/videobuf2-dma-sg.h>

#include <linux/videodev2.h>

#include <linux/platform_data/media/camera-pxa.h>
#include <linux/workqueue.h>

#define PXA_CAM_VERSION
#define PXA_CAM_DRV_NAME

#define DEFAULT_WIDTH
#define DEFAULT_HEIGHT

/* Camera Interface */
#define CICR0
#define CICR1
#define CICR2
#define CICR3
#define CICR4
#define CISR
#define CIFR
#define CITOR
#define CIBR0
#define CIBR1
#define CIBR2

#define CICR0_DMAEN
#define CICR0_PAR_EN
#define CICR0_SL_CAP_EN
#define CICR0_ENB
#define CICR0_DIS
#define CICR0_SIM
#define CICR0_TOM
#define CICR0_RDAVM
#define CICR0_FEM
#define CICR0_EOLM
#define CICR0_PERRM
#define CICR0_QDM
#define CICR0_CDM
#define CICR0_SOFM
#define CICR0_EOFM
#define CICR0_FOM

#define CICR1_TBIT
#define CICR1_RGBT_CONV
#define CICR1_PPL
#define CICR1_RGB_CONV
#define CICR1_RGB_F
#define CICR1_YCBCR_F
#define CICR1_RGB_BPP
#define CICR1_RAW_BPP
#define CICR1_COLOR_SP
#define CICR1_DW

#define CICR2_BLW
#define CICR2_ELW
#define CICR2_HSW
#define CICR2_BFPW
#define CICR2_FSW

#define CICR3_BFW
#define CICR3_EFW
#define CICR3_VSW
#define CICR3_BFPW
#define CICR3_LPF

#define CICR4_MCLK_DLY
#define CICR4_PCLK_EN
#define CICR4_PCP
#define CICR4_HSP
#define CICR4_VSP
#define CICR4_MCLK_EN
#define CICR4_FR_RATE
#define CICR4_DIV

#define CISR_FTO
#define CISR_RDAV_2
#define CISR_RDAV_1
#define CISR_RDAV_0
#define CISR_FEMPTY_2
#define CISR_FEMPTY_1
#define CISR_FEMPTY_0
#define CISR_EOL
#define CISR_PAR_ERR
#define CISR_CQD
#define CISR_CDD
#define CISR_SOF
#define CISR_EOF
#define CISR_IFO_2
#define CISR_IFO_1
#define CISR_IFO_0

#define CIFR_FLVL2
#define CIFR_FLVL1
#define CIFR_FLVL0
#define CIFR_THL_0
#define CIFR_RESET_F
#define CIFR_FEN2
#define CIFR_FEN1
#define CIFR_FEN0

#define CICR0_SIM_MP
#define CICR0_SIM_SP
#define CICR0_SIM_MS
#define CICR0_SIM_EP
#define CICR0_SIM_ES

#define CICR1_DW_VAL(x)
#define CICR1_PPL_VAL(x)
#define CICR1_COLOR_SP_VAL(x)
#define CICR1_RGB_BPP_VAL(x)
#define CICR1_RGBT_CONV_VAL(x)

#define CICR2_BLW_VAL(x)
#define CICR2_ELW_VAL(x)
#define CICR2_HSW_VAL(x)
#define CICR2_BFPW_VAL(x)
#define CICR2_FSW_VAL(x)

#define CICR3_BFW_VAL(x)
#define CICR3_EFW_VAL(x)
#define CICR3_VSW_VAL(x)
#define CICR3_LPF_VAL(x)

#define CICR0_IRQ_MASK

#define sensor_call(cam, o, f, args...)

/*
 * Format handling
 */

/**
 * enum pxa_mbus_packing - data packing types on the media-bus
 * @PXA_MBUS_PACKING_NONE:	no packing, bit-for-bit transfer to RAM, one
 *				sample represents one pixel
 * @PXA_MBUS_PACKING_2X8_PADHI:	16 bits transferred in 2 8-bit samples, in the
 *				possibly incomplete byte high bits are padding
 * @PXA_MBUS_PACKING_EXTEND16:	sample width (e.g., 10 bits) has to be extended
 *				to 16 bits
 */
enum pxa_mbus_packing {};

/**
 * enum pxa_mbus_order - sample order on the media bus
 * @PXA_MBUS_ORDER_LE:		least significant sample first
 * @PXA_MBUS_ORDER_BE:		most significant sample first
 */
enum pxa_mbus_order {};

/**
 * enum pxa_mbus_layout - planes layout in memory
 * @PXA_MBUS_LAYOUT_PACKED:		color components packed
 * @PXA_MBUS_LAYOUT_PLANAR_2Y_U_V:	YUV components stored in 3 planes (4:2:2)
 * @PXA_MBUS_LAYOUT_PLANAR_2Y_C:	YUV components stored in a luma and a
 *					chroma plane (C plane is half the size
 *					of Y plane)
 * @PXA_MBUS_LAYOUT_PLANAR_Y_C:		YUV components stored in a luma and a
 *					chroma plane (C plane is the same size
 *					as Y plane)
 */
enum pxa_mbus_layout {};

/**
 * struct pxa_mbus_pixelfmt - Data format on the media bus
 * @name:		Name of the format
 * @fourcc:		Fourcc code, that will be obtained if the data is
 *			stored in memory in the following way:
 * @packing:		Type of sample-packing, that has to be used
 * @order:		Sample order when storing in memory
 * @layout:		Planes layout in memory
 * @bits_per_sample:	How many bits the bridge has to sample
 */
struct pxa_mbus_pixelfmt {};

/**
 * struct pxa_mbus_lookup - Lookup FOURCC IDs by mediabus codes for pass-through
 * @code:	mediabus pixel-code
 * @fmt:	pixel format description
 */
struct pxa_mbus_lookup {};

static const struct pxa_mbus_lookup mbus_fmt[] =;

static s32 pxa_mbus_bytes_per_line(u32 width, const struct pxa_mbus_pixelfmt *mf)
{}

static s32 pxa_mbus_image_size(const struct pxa_mbus_pixelfmt *mf,
			u32 bytes_per_line, u32 height)
{}

static const struct pxa_mbus_pixelfmt *pxa_mbus_find_fmtdesc(
	u32 code,
	const struct pxa_mbus_lookup *lookup,
	int n)
{}

static const struct pxa_mbus_pixelfmt *pxa_mbus_get_fmtdesc(
	u32 code)
{}

/**
 * struct pxa_camera_format_xlate - match between host and sensor formats
 * @code: code of a sensor provided format
 * @host_fmt: host format after host translation from code
 *
 * Host and sensor translation structure. Used in table of host and sensor
 * formats matchings in pxa_camera_device. A host can override the generic list
 * generation by implementing get_formats(), and use it for format checks and
 * format setup.
 */
struct pxa_camera_format_xlate {};

/*
 * Structures
 */
enum pxa_camera_active_dma {};

/* buffer for one video frame */
struct pxa_buffer {};

struct pxa_camera_dev {};

struct pxa_cam {};

static const char *pxa_cam_driver_description =;

/*
 * Format translation functions
 */
static const struct pxa_camera_format_xlate
*pxa_mbus_xlate_by_fourcc(struct pxa_camera_format_xlate *user_formats,
			  unsigned int fourcc)
{}

static struct pxa_camera_format_xlate *pxa_mbus_build_fmts_xlate(
	struct v4l2_device *v4l2_dev, struct v4l2_subdev *subdev,
	int (*get_formats)(struct v4l2_device *, unsigned int,
			   struct pxa_camera_format_xlate *xlate))
{}

/*
 *  Videobuf operations
 */
static struct pxa_buffer *vb2_to_pxa_buffer(struct vb2_buffer *vb)
{}

static struct device *pcdev_to_dev(struct pxa_camera_dev *pcdev)
{}

static struct pxa_camera_dev *v4l2_dev_to_pcdev(struct v4l2_device *v4l2_dev)
{}

static void pxa_camera_dma_irq(struct pxa_camera_dev *pcdev,
			       enum pxa_camera_active_dma act_dma);

static void pxa_camera_dma_irq_y(void *data)
{}

static void pxa_camera_dma_irq_u(void *data)
{}

static void pxa_camera_dma_irq_v(void *data)
{}

/**
 * pxa_init_dma_channel - init dma descriptors
 * @pcdev: pxa camera device
 * @buf: pxa camera buffer
 * @channel: dma channel (0 => 'Y', 1 => 'U', 2 => 'V')
 * @sg: dma scatter list
 * @sglen: dma scatter list length
 *
 * Prepares the pxa dma descriptors to transfer one camera channel.
 *
 * Returns 0 if success or -ENOMEM if no memory is available
 */
static int pxa_init_dma_channel(struct pxa_camera_dev *pcdev,
				struct pxa_buffer *buf, int channel,
				struct scatterlist *sg, int sglen)
{}

static void pxa_video_buf_set_actdma(struct pxa_camera_dev *pcdev,
				    struct pxa_buffer *buf)
{}

/**
 * pxa_dma_start_channels - start DMA channel for active buffer
 * @pcdev: pxa camera device
 *
 * Initialize DMA channels to the beginning of the active video buffer, and
 * start these channels.
 */
static void pxa_dma_start_channels(struct pxa_camera_dev *pcdev)
{}

static void pxa_dma_stop_channels(struct pxa_camera_dev *pcdev)
{}

static void pxa_dma_add_tail_buf(struct pxa_camera_dev *pcdev,
				 struct pxa_buffer *buf)
{}

/**
 * pxa_camera_start_capture - start video capturing
 * @pcdev: camera device
 *
 * Launch capturing. DMA channels should not be active yet. They should get
 * activated at the end of frame interrupt, to capture only whole frames, and
 * never begin the capture of a partial frame.
 */
static void pxa_camera_start_capture(struct pxa_camera_dev *pcdev)
{}

static void pxa_camera_stop_capture(struct pxa_camera_dev *pcdev)
{}

static void pxa_camera_wakeup(struct pxa_camera_dev *pcdev,
			      struct pxa_buffer *buf,
			      enum vb2_buffer_state state)
{}

/**
 * pxa_camera_check_link_miss - check missed DMA linking
 * @pcdev: camera device
 * @last_submitted: an opaque DMA cookie for last submitted
 * @last_issued: an opaque DMA cookie for last issued
 *
 * The DMA chaining is done with DMA running. This means a tiny temporal window
 * remains, where a buffer is queued on the chain, while the chain is already
 * stopped. This means the tailed buffer would never be transferred by DMA.
 * This function restarts the capture for this corner case, where :
 *  - DADR() == DADDR_STOP
 *  - a video buffer is queued on the pcdev->capture list
 *
 * Please check the "DMA hot chaining timeslice issue" in
 *   Documentation/driver-api/media/drivers/pxa_camera.rst
 *
 * Context: should only be called within the dma irq handler
 */
static void pxa_camera_check_link_miss(struct pxa_camera_dev *pcdev,
				       dma_cookie_t last_submitted,
				       dma_cookie_t last_issued)
{}

static void pxa_camera_dma_irq(struct pxa_camera_dev *pcdev,
			       enum pxa_camera_active_dma act_dma)
{}

static u32 mclk_get_divisor(struct platform_device *pdev,
			    struct pxa_camera_dev *pcdev)
{}

static void recalculate_fifo_timeout(struct pxa_camera_dev *pcdev,
				     unsigned long pclk)
{}

static void pxa_camera_activate(struct pxa_camera_dev *pcdev)
{}

static void pxa_camera_deactivate(struct pxa_camera_dev *pcdev)
{}

static void pxa_camera_eof_bh_work(struct work_struct *t)
{}

static irqreturn_t pxa_camera_irq(int irq, void *data)
{}

static void pxa_camera_setup_cicr(struct pxa_camera_dev *pcdev,
				  unsigned long flags, __u32 pixfmt)
{}

/*
 * Videobuf2 section
 */
static void pxa_buffer_cleanup(struct pxa_buffer *buf)
{}

static int pxa_buffer_init(struct pxa_camera_dev *pcdev,
			   struct pxa_buffer *buf)
{}

static void pxac_vb2_cleanup(struct vb2_buffer *vb)
{}

static void pxac_vb2_queue(struct vb2_buffer *vb)
{}

/*
 * Please check the DMA prepared buffer structure in :
 *   Documentation/driver-api/media/drivers/pxa_camera.rst
 * Please check also in pxa_camera_check_link_miss() to understand why DMA chain
 * modification while DMA chain is running will work anyway.
 */
static int pxac_vb2_prepare(struct vb2_buffer *vb)
{}

static int pxac_vb2_init(struct vb2_buffer *vb)
{}

static int pxac_vb2_queue_setup(struct vb2_queue *vq,
				unsigned int *nbufs,
				unsigned int *num_planes, unsigned int sizes[],
				struct device *alloc_devs[])
{}

static int pxac_vb2_start_streaming(struct vb2_queue *vq, unsigned int count)
{}

static void pxac_vb2_stop_streaming(struct vb2_queue *vq)
{}

static const struct vb2_ops pxac_vb2_ops =;

static int pxa_camera_init_videobuf2(struct pxa_camera_dev *pcdev)
{}

/*
 * Video ioctls section
 */
static int pxa_camera_set_bus_param(struct pxa_camera_dev *pcdev)
{}

static const struct pxa_mbus_pixelfmt pxa_camera_formats[] =;

/* This will be corrected as we get more formats */
static bool pxa_camera_packing_supported(const struct pxa_mbus_pixelfmt *fmt)
{}

static int pxa_camera_get_formats(struct v4l2_device *v4l2_dev,
				  unsigned int idx,
				  struct pxa_camera_format_xlate *xlate)
{}

static int pxa_camera_build_formats(struct pxa_camera_dev *pcdev)
{}

static void pxa_camera_destroy_formats(struct pxa_camera_dev *pcdev)
{}

static int pxa_camera_check_frame(u32 width, u32 height)
{}

#ifdef CONFIG_VIDEO_ADV_DEBUG
static int pxac_vidioc_g_register(struct file *file, void *priv,
				  struct v4l2_dbg_register *reg)
{}

static int pxac_vidioc_s_register(struct file *file, void *priv,
				  const struct v4l2_dbg_register *reg)
{}
#endif

static int pxac_vidioc_enum_fmt_vid_cap(struct file *filp, void  *priv,
					struct v4l2_fmtdesc *f)
{}

static int pxac_vidioc_g_fmt_vid_cap(struct file *filp, void *priv,
				    struct v4l2_format *f)
{}

static int pxac_vidioc_try_fmt_vid_cap(struct file *filp, void *priv,
				      struct v4l2_format *f)
{}

static int pxac_vidioc_s_fmt_vid_cap(struct file *filp, void *priv,
				    struct v4l2_format *f)
{}

static int pxac_vidioc_querycap(struct file *file, void *priv,
				struct v4l2_capability *cap)
{}

static int pxac_vidioc_enum_input(struct file *file, void *priv,
				  struct v4l2_input *i)
{}

static int pxac_vidioc_g_input(struct file *file, void *priv, unsigned int *i)
{}

static int pxac_vidioc_s_input(struct file *file, void *priv, unsigned int i)
{}

static int pxac_sensor_set_power(struct pxa_camera_dev *pcdev, int on)
{}

static int pxac_fops_camera_open(struct file *filp)
{}

static int pxac_fops_camera_release(struct file *filp)
{}

static const struct v4l2_file_operations pxa_camera_fops =;

static const struct v4l2_ioctl_ops pxa_camera_ioctl_ops =;

static const struct video_device pxa_camera_videodev_template =;

static int pxa_camera_sensor_bound(struct v4l2_async_notifier *notifier,
		     struct v4l2_subdev *subdev,
		     struct v4l2_async_connection *asd)
{}

static void pxa_camera_sensor_unbind(struct v4l2_async_notifier *notifier,
		     struct v4l2_subdev *subdev,
		     struct v4l2_async_connection *asd)
{}

static const struct v4l2_async_notifier_operations pxa_camera_sensor_ops =;

/*
 * Driver probe, remove, suspend and resume operations
 */
static int pxa_camera_suspend(struct device *dev)
{}

static int pxa_camera_resume(struct device *dev)
{}

static int pxa_camera_pdata_from_dt(struct device *dev,
				    struct pxa_camera_dev *pcdev)
{}

static int pxa_camera_probe(struct platform_device *pdev)
{}

static void pxa_camera_remove(struct platform_device *pdev)
{}

static const struct dev_pm_ops pxa_camera_pm =;

static const struct of_device_id pxa_camera_of_match[] =;
MODULE_DEVICE_TABLE(of, pxa_camera_of_match);

static struct platform_driver pxa_camera_driver =;

module_platform_driver();

MODULE_DESCRIPTION();
MODULE_AUTHOR();
MODULE_LICENSE();
MODULE_VERSION();
MODULE_ALIAS();