#include <linux/bits.h>
#include <linux/delay.h>
#include <linux/freezer.h>
#include <linux/hwmon.h>
#include <linux/kthread.h>
#include <linux/i2c.h>
#include <linux/list.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/pm_runtime.h>
#include <linux/nvmem-provider.h>
#include <linux/regmap.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/videodev2.h>
#include <media/v4l2-common.h>
#include <media/v4l2-device.h>
#include <media/v4l2-event.h>
#include <media/v4l2-fh.h>
#include <media/v4l2-ioctl.h>
#include <media/videobuf2-v4l2.h>
#include <media/videobuf2-vmalloc.h>
#define VIDEO_I2C_DRIVER …
#define AMG88XX_REG_PCTL …
#define AMG88XX_PCTL_NORMAL …
#define AMG88XX_PCTL_SLEEP …
#define AMG88XX_REG_RST …
#define AMG88XX_RST_FLAG …
#define AMG88XX_RST_INIT …
#define AMG88XX_REG_FPSC …
#define AMG88XX_FPSC_1FPS …
#define AMG88XX_REG_TTHL …
#define AMG88XX_REG_T01L …
#define MLX90640_RAM_START_ADDR …
#define MLX90640_EEPROM_START_ADDR …
#define MLX90640_REG_CTL1 …
#define MLX90640_REG_CTL1_MASK …
#define MLX90640_REG_CTL1_MASK_SHIFT …
struct video_i2c_chip;
struct video_i2c_buffer { … };
struct video_i2c_data { … };
static const struct v4l2_fmtdesc amg88xx_format = …;
static const struct v4l2_frmsize_discrete amg88xx_size = …;
static const struct v4l2_fmtdesc mlx90640_format = …;
static const struct v4l2_frmsize_discrete mlx90640_size = …;
static const struct regmap_config amg88xx_regmap_config = …;
static const struct regmap_config mlx90640_regmap_config = …;
struct video_i2c_chip { … };
static int mlx90640_nvram_read(void *priv, unsigned int offset, void *val,
size_t bytes)
{ … }
static struct nvmem_config mlx90640_nvram_config = …;
static int amg88xx_xfer(struct video_i2c_data *data, char *buf)
{ … }
static int mlx90640_xfer(struct video_i2c_data *data, char *buf)
{ … }
static int amg88xx_setup(struct video_i2c_data *data)
{ … }
static int mlx90640_setup(struct video_i2c_data *data)
{ … }
static int amg88xx_set_power_on(struct video_i2c_data *data)
{ … }
static int amg88xx_set_power_off(struct video_i2c_data *data)
{ … }
static int amg88xx_set_power(struct video_i2c_data *data, bool on)
{ … }
#if IS_REACHABLE(CONFIG_HWMON)
static const u32 amg88xx_temp_config[] = …;
static const struct hwmon_channel_info amg88xx_temp = …;
static const struct hwmon_channel_info * const amg88xx_info[] = …;
static umode_t amg88xx_is_visible(const void *drvdata,
enum hwmon_sensor_types type,
u32 attr, int channel)
{ … }
static int amg88xx_read(struct device *dev, enum hwmon_sensor_types type,
u32 attr, int channel, long *val)
{ … }
static const struct hwmon_ops amg88xx_hwmon_ops = …;
static const struct hwmon_chip_info amg88xx_chip_info = …;
static int amg88xx_hwmon_init(struct video_i2c_data *data)
{ … }
#else
#define amg88xx_hwmon_init …
#endif
enum { … };
static const struct v4l2_fract amg88xx_frame_intervals[] = …;
static const struct v4l2_fract mlx90640_frame_intervals[] = …;
static const struct video_i2c_chip video_i2c_chip[] = …;
static const struct v4l2_file_operations video_i2c_fops = …;
static int queue_setup(struct vb2_queue *vq,
unsigned int *nbuffers, unsigned int *nplanes,
unsigned int sizes[], struct device *alloc_devs[])
{ … }
static int buffer_prepare(struct vb2_buffer *vb)
{ … }
static void buffer_queue(struct vb2_buffer *vb)
{ … }
static int video_i2c_thread_vid_cap(void *priv)
{ … }
static void video_i2c_del_list(struct vb2_queue *vq, enum vb2_buffer_state state)
{ … }
static int start_streaming(struct vb2_queue *vq, unsigned int count)
{ … }
static void stop_streaming(struct vb2_queue *vq)
{ … }
static const struct vb2_ops video_i2c_video_qops = …;
static int video_i2c_querycap(struct file *file, void *priv,
struct v4l2_capability *vcap)
{ … }
static int video_i2c_g_input(struct file *file, void *fh, unsigned int *inp)
{ … }
static int video_i2c_s_input(struct file *file, void *fh, unsigned int inp)
{ … }
static int video_i2c_enum_input(struct file *file, void *fh,
struct v4l2_input *vin)
{ … }
static int video_i2c_enum_fmt_vid_cap(struct file *file, void *fh,
struct v4l2_fmtdesc *fmt)
{ … }
static int video_i2c_enum_framesizes(struct file *file, void *fh,
struct v4l2_frmsizeenum *fsize)
{ … }
static int video_i2c_enum_frameintervals(struct file *file, void *priv,
struct v4l2_frmivalenum *fe)
{ … }
static int video_i2c_try_fmt_vid_cap(struct file *file, void *fh,
struct v4l2_format *fmt)
{ … }
static int video_i2c_s_fmt_vid_cap(struct file *file, void *fh,
struct v4l2_format *fmt)
{ … }
static int video_i2c_g_parm(struct file *filp, void *priv,
struct v4l2_streamparm *parm)
{ … }
static int video_i2c_s_parm(struct file *filp, void *priv,
struct v4l2_streamparm *parm)
{ … }
static const struct v4l2_ioctl_ops video_i2c_ioctl_ops = …;
static void video_i2c_release(struct video_device *vdev)
{ … }
static int video_i2c_probe(struct i2c_client *client)
{ … }
static void video_i2c_remove(struct i2c_client *client)
{ … }
#ifdef CONFIG_PM
static int video_i2c_pm_runtime_suspend(struct device *dev)
{ … }
static int video_i2c_pm_runtime_resume(struct device *dev)
{ … }
#endif
static const struct dev_pm_ops video_i2c_pm_ops = …;
static const struct i2c_device_id video_i2c_id_table[] = …;
MODULE_DEVICE_TABLE(i2c, video_i2c_id_table);
static const struct of_device_id video_i2c_of_match[] = …;
MODULE_DEVICE_TABLE(of, video_i2c_of_match);
static struct i2c_driver video_i2c_driver = …;
module_i2c_driver(…) …;
MODULE_AUTHOR(…) …;
MODULE_DESCRIPTION(…) …;
MODULE_LICENSE(…) …;