// SPDX-License-Identifier: GPL-2.0-only
/*
* Driver for the VIA Chrome integrated camera controller.
*
* Copyright 2009,2010 Jonathan Corbet <corbet@lwn.net>
*
* This work was supported by the One Laptop Per Child project
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/device.h>
#include <linux/list.h>
#include <linux/pci.h>
#include <linux/gpio.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/videodev2.h>
#include <media/v4l2-device.h>
#include <media/v4l2-ioctl.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-event.h>
#include <media/v4l2-image-sizes.h>
#include <media/i2c/ov7670.h>
#include <media/videobuf2-dma-sg.h>
#include <linux/delay.h>
#include <linux/dma-mapping.h>
#include <linux/pm_qos.h>
#include <linux/via-core.h>
#include <linux/via-gpio.h>
#include <linux/via_i2c.h>
#ifdef CONFIG_X86
#include <asm/olpc.h>
#else
#define machine_is_olpc(x) 0
#endif
#include "via-camera.h"
MODULE_ALIAS("platform:viafb-camera");
MODULE_AUTHOR("Jonathan Corbet <corbet@lwn.net>");
MODULE_DESCRIPTION("VIA framebuffer-based camera controller driver");
MODULE_LICENSE("GPL");
static bool flip_image;
module_param(flip_image, bool, 0444);
MODULE_PARM_DESC(flip_image,
"If set, the sensor will be instructed to flip the image vertically.");
static bool override_serial;
module_param(override_serial, bool, 0444);
MODULE_PARM_DESC(override_serial,
"The camera driver will normally refuse to load if the XO 1.5 serial port is enabled. Set this option to force-enable the camera.");
/*
* The structure describing our camera.
*/
enum viacam_opstate { S_IDLE = 0, S_RUNNING = 1 };
struct via_camera {
struct v4l2_device v4l2_dev;
struct v4l2_ctrl_handler ctrl_handler;
struct video_device vdev;
struct v4l2_subdev *sensor;
struct platform_device *platdev;
struct viafb_dev *viadev;
struct mutex lock;
enum viacam_opstate opstate;
unsigned long flags;
struct pm_qos_request qos_request;
/*
* GPIO info for power/reset management
*/
int power_gpio;
int reset_gpio;
/*
* I/O memory stuff.
*/
void __iomem *mmio; /* Where the registers live */
void __iomem *fbmem; /* Frame buffer memory */
u32 fb_offset; /* Reserved memory offset (FB) */
/*
* Capture buffers and related. The controller supports
* up to three, so that's what we have here. These buffers
* live in frame buffer memory, so we don't call them "DMA".
*/
unsigned int cb_offsets[3]; /* offsets into fb mem */
u8 __iomem *cb_addrs[3]; /* Kernel-space addresses */
int n_cap_bufs; /* How many are we using? */
struct vb2_queue vq;
struct list_head buffer_queue;
u32 sequence;
/*
* Video format information. sensor_format is kept in a form
* that we can use to pass to the sensor. We always run the
* sensor in VGA resolution, though, and let the controller
* downscale things if need be. So we keep the "real*
* dimensions separately.
*/
struct v4l2_pix_format sensor_format;
struct v4l2_pix_format user_format;
u32 mbus_code;
};
/* buffer for one video frame */
struct via_buffer {
/* common v4l buffer stuff -- must be first */
struct vb2_v4l2_buffer vbuf;
struct list_head queue;
};
/*
* Yes, this is a hack, but there's only going to be one of these
* on any system we know of.
*/
static struct via_camera *via_cam_info;
/*
* Flag values, manipulat