linux/drivers/media/pci/sta2x11/sta2x11_vip.c

// SPDX-License-Identifier: GPL-2.0-only
/*
 * This is the driver for the STA2x11 Video Input Port.
 *
 * Copyright (C) 2012       ST Microelectronics
 *     author: Federico Vaga <[email protected]>
 * Copyright (C) 2010       WindRiver Systems, Inc.
 *     authors: Andreas Kies <[email protected]>
 *              Vlad Lungu   <[email protected]>
 */

#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/videodev2.h>
#include <linux/kmod.h>
#include <linux/pci.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/gpio/consumer.h>
#include <linux/gpio.h>
#include <linux/i2c.h>
#include <linux/delay.h>
#include <media/v4l2-common.h>
#include <media/v4l2-device.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-ioctl.h>
#include <media/v4l2-fh.h>
#include <media/v4l2-event.h>
#include <media/videobuf2-dma-contig.h>

#include "sta2x11_vip.h"

#define DRV_VERSION

#ifndef PCI_DEVICE_ID_STMICRO_VIP
#define PCI_DEVICE_ID_STMICRO_VIP
#endif

#define MAX_FRAMES

/*Register offsets*/
#define DVP_CTL
#define DVP_TFO
#define DVP_TFS
#define DVP_BFO
#define DVP_BFS
#define DVP_VTP
#define DVP_VBP
#define DVP_VMP
#define DVP_ITM
#define DVP_ITS
#define DVP_STA
#define DVP_HLFLN
#define DVP_RGB
#define DVP_PKZ

/*Register fields*/
#define DVP_CTL_ENA
#define DVP_CTL_RST
#define DVP_CTL_DIS

#define DVP_IT_VSB
#define DVP_IT_VST
#define DVP_IT_FIFO

#define DVP_HLFLN_SD

#define SAVE_COUNT
#define AUX_COUNT
#define IRQ_COUNT


struct vip_buffer {};
static inline struct vip_buffer *to_vip_buffer(struct vb2_v4l2_buffer *vb2)
{}

/**
 * struct sta2x11_vip - All internal data for one instance of device
 * @v4l2_dev: device registered in v4l layer
 * @video_dev: properties of our device
 * @pdev: PCI device
 * @adapter: contains I2C adapter information
 * @register_save_area: All relevant register are saved here during suspend
 * @decoder: contains information about video DAC
 * @ctrl_hdl: handler for control framework
 * @format: pixel format, fixed UYVY
 * @std: video standard (e.g. PAL/NTSC)
 * @input: input line for video signal ( 0 or 1 )
 * @disabled: Device is in power down state
 * @slock: for excluse access of registers
 * @vb_vidq: queue maintained by videobuf2 layer
 * @buffer_list: list of buffer in use
 * @sequence: sequence number of acquired buffer
 * @active: current active buffer
 * @lock: used in videobuf2 callback
 * @v4l_lock: serialize its video4linux ioctls
 * @tcount: Number of top frames
 * @bcount: Number of bottom frames
 * @overflow: Number of FIFO overflows
 * @iomem: hardware base address
 * @config: I2C and gpio config from platform
 *
 * All non-local data is accessed via this structure.
 */
struct sta2x11_vip {};

static const unsigned int registers_to_save[AUX_COUNT] =;

static struct v4l2_pix_format formats_50[] =;

static struct v4l2_pix_format formats_60[] =;

/* Write VIP register */
static inline void reg_write(struct sta2x11_vip *vip, unsigned int reg, u32 val)
{}
/* Read VIP register */
static inline u32 reg_read(struct sta2x11_vip *vip, unsigned int reg)
{}
/* Start DMA acquisition */
static void start_dma(struct sta2x11_vip *vip, struct vip_buffer *vip_buf)
{}

/* Fetch the next buffer to activate */
static void vip_active_buf_next(struct sta2x11_vip *vip)
{}


/* Videobuf2 Operations */
static int queue_setup(struct vb2_queue *vq,
		       unsigned int *nbuffers, unsigned int *nplanes,
		       unsigned int sizes[], struct device *alloc_devs[])
{
	struct sta2x11_vip *vip = vb2_get_drv_priv(vq);

	if (!(*nbuffers) || *nbuffers < MAX_FRAMES)
		*nbuffers = MAX_FRAMES;

	*nplanes = 1;
	sizes[0] = vip->format.sizeimage;

	vip->sequence = 0;
	vip->active = NULL;
	vip->tcount = 0;
	vip->bcount = 0;

	return 0;
};
static int buffer_init(struct vb2_buffer *vb)
{}

static int buffer_prepare(struct vb2_buffer *vb)
{}
static void buffer_queue(struct vb2_buffer *vb)
{}
static void buffer_finish(struct vb2_buffer *vb)
{}

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

/* abort streaming and wait for last buffer */
static void stop_streaming(struct vb2_queue *vq)
{}

static const struct vb2_ops vip_video_qops =;


/* File Operations */
static const struct v4l2_file_operations vip_fops =;


/**
 * vidioc_querycap - return capabilities of device
 * @file: descriptor of device
 * @cap: contains return values
 * @priv: unused
 *
 * the capabilities of the device are returned
 *
 * return value: 0, no error.
 */
static int vidioc_querycap(struct file *file, void *priv,
			   struct v4l2_capability *cap)
{}

/**
 * vidioc_s_std - set video standard
 * @file: descriptor of device
 * @std: contains standard to be set
 * @priv: unused
 *
 * the video standard is set
 *
 * return value: 0, no error.
 *
 * -EIO, no input signal detected
 *
 * other, returned from video DAC.
 */
static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id std)
{}

/**
 * vidioc_g_std - get video standard
 * @file: descriptor of device
 * @priv: unused
 * @std: contains return values
 *
 * the current video standard is returned
 *
 * return value: 0, no error.
 */
static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *std)
{}

/**
 * vidioc_querystd - get possible video standards
 * @file: descriptor of device
 * @priv: unused
 * @std: contains return values
 *
 * all possible video standards are returned
 *
 * return value: delivered by video DAC routine.
 */
static int vidioc_querystd(struct file *file, void *priv, v4l2_std_id *std)
{}

static int vidioc_enum_input(struct file *file, void *priv,
			     struct v4l2_input *inp)
{}

/**
 * vidioc_s_input - set input line
 * @file: descriptor of device
 * @priv: unused
 * @i: new input line number
 *
 * the current active input line is set
 *
 * return value: 0, no error.
 *
 * -EINVAL, line number out of range
 */
static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
{}

/**
 * vidioc_g_input - return input line
 * @file: descriptor of device
 * @priv: unused
 * @i: returned input line number
 *
 * the current active input line is returned
 *
 * return value: always 0.
 */
static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
{}

/**
 * vidioc_enum_fmt_vid_cap - return video capture format
 * @file: descriptor of device
 * @priv: unused
 * @f: returned format information
 *
 * returns name and format of video capture
 * Only UYVY is supported by hardware.
 *
 * return value: always 0.
 */
static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
				   struct v4l2_fmtdesc *f)
{}

/**
 * vidioc_try_fmt_vid_cap - set video capture format
 * @file: descriptor of device
 * @priv: unused
 * @f: new format
 *
 * new video format is set which includes width and
 * field type. width is fixed to 720, no scaling.
 * Only UYVY is supported by this hardware.
 * the minimum height is 200, the maximum is 576 (PAL)
 *
 * return value: 0, no error
 *
 * -EINVAL, pixel or field format not supported
 *
 */
static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
				  struct v4l2_format *f)
{}

/**
 * vidioc_s_fmt_vid_cap - set current video format parameters
 * @file: descriptor of device
 * @priv: unused
 * @f: returned format information
 *
 * set new capture format
 * return value: 0, no error
 *
 * other, delivered by video DAC routine.
 */
static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
				struct v4l2_format *f)
{}

/**
 * vidioc_g_fmt_vid_cap - get current video format parameters
 * @file: descriptor of device
 * @priv: unused
 * @f: contains format information
 *
 * returns current video format parameters
 *
 * return value: 0, always successful
 */
static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
				struct v4l2_format *f)
{}

static const struct v4l2_ioctl_ops vip_ioctl_ops =;

static const struct video_device video_dev_template =;

/**
 * vip_irq - interrupt routine
 * @irq: Number of interrupt ( not used, correct number is assumed )
 * @data: local data structure containing all information
 *
 * check for both frame interrupts set ( top and bottom ).
 * check FIFO overflow, but limit number of log messages after open.
 * signal a complete buffer if done
 *
 * return value: IRQ_NONE, interrupt was not generated by VIP
 *
 * IRQ_HANDLED, interrupt done.
 */
static irqreturn_t vip_irq(int irq, void *data)
{}

static void sta2x11_vip_init_register(struct sta2x11_vip *vip)
{}
static void sta2x11_vip_clear_register(struct sta2x11_vip *vip)
{}
static int sta2x11_vip_init_buffer(struct sta2x11_vip *vip)
{}

static int sta2x11_vip_init_controls(struct sta2x11_vip *vip)
{}

/**
 * vip_gpio_reserve - reserve gpio pin
 * @dev: device
 * @pin: GPIO pin number
 * @dir: direction, input or output
 * @name: GPIO pin name
 *
 */
static int vip_gpio_reserve(struct device *dev, int pin, int dir,
			    const char *name)
{}

/**
 * vip_gpio_release - release gpio pin
 * @dev: device
 * @pin: GPIO pin number
 * @name: GPIO pin name
 *
 */
static void vip_gpio_release(struct device *dev, int pin, const char *name)
{}

/**
 * sta2x11_vip_init_one - init one instance of video device
 * @pdev: PCI device
 * @ent: (not used)
 *
 * allocate reset pins for DAC.
 * Reset video DAC, this is done via reset line.
 * allocate memory for managing device
 * request interrupt
 * map IO region
 * register device
 * find and initialize video DAC
 *
 * return value: 0, no error
 *
 * -ENOMEM, no memory
 *
 * -ENODEV, device could not be detected or registered
 */
static int sta2x11_vip_init_one(struct pci_dev *pdev,
				const struct pci_device_id *ent)
{}

/**
 * sta2x11_vip_remove_one - release device
 * @pdev: PCI device
 *
 * Undo everything done in .._init_one
 *
 * unregister video device
 * free interrupt
 * unmap ioadresses
 * free memory
 * free GPIO pins
 */
static void sta2x11_vip_remove_one(struct pci_dev *pdev)
{}

/**
 * sta2x11_vip_suspend - set device into power save mode
 * @dev_d: PCI device
 *
 * all relevant registers are saved and an attempt to set a new state is made.
 *
 * return value: 0 always indicate success,
 * even if device could not be disabled. (workaround for hardware problem)
 */
static int __maybe_unused sta2x11_vip_suspend(struct device *dev_d)
{}

/**
 * sta2x11_vip_resume - resume device operation
 * @dev_d : PCI device
 *
 * return value: 0, no error.
 *
 * other, could not set device to power on state.
 */
static int __maybe_unused sta2x11_vip_resume(struct device *dev_d)
{}

static const struct pci_device_id sta2x11_vip_pci_tbl[] =;

static SIMPLE_DEV_PM_OPS(sta2x11_vip_pm_ops,
			 sta2x11_vip_suspend,
			 sta2x11_vip_resume);

static struct pci_driver sta2x11_vip_driver =;

static int __init sta2x11_vip_init_module(void)
{}

static void __exit sta2x11_vip_exit_module(void)
{}

#ifdef MODULE
module_init(sta2x11_vip_init_module);
module_exit(sta2x11_vip_exit_module);
#else
late_initcall_sync(sta2x11_vip_init_module);
#endif

MODULE_DESCRIPTION();
MODULE_AUTHOR();
MODULE_LICENSE();
MODULE_VERSION();
MODULE_DEVICE_TABLE(pci, sta2x11_vip_pci_tbl);