source "drivers/media/pci/tw5864/Kconfig"
 source "drivers/media/pci/tw68/Kconfig"
 source "drivers/media/pci/tw686x/Kconfig"
+source "drivers/media/pci/zoran/Kconfig"
 
 endif
 
 
 obj-$(CONFIG_VIDEO_TW5864) += tw5864/
 obj-$(CONFIG_VIDEO_TW686X) += tw686x/
 obj-$(CONFIG_VIDEO_TW68) += tw68/
+obj-$(CONFIG_VIDEO_ZORAN) += zoran/
 
--- /dev/null
+config VIDEO_ZORAN
+       tristate "Zoran ZR36057/36067 Video For Linux (Deprecated)"
+       depends on PCI && I2C_ALGOBIT && VIDEO_DEV
+       depends on !ALPHA
+       depends on DEBUG_FS
+       select VIDEOBUF2_DMA_CONTIG
+       select VIDEO_ADV7170 if VIDEO_ZORAN_LML33R10
+       select VIDEO_ADV7175 if VIDEO_ZORAN_DC10 || VIDEO_ZORAN_DC30
+       select VIDEO_BT819 if VIDEO_ZORAN_LML33
+       select VIDEO_BT856 if VIDEO_ZORAN_LML33 || VIDEO_ZORAN_AVS6EYES
+       select VIDEO_BT866 if VIDEO_ZORAN_AVS6EYES
+       select VIDEO_KS0127 if VIDEO_ZORAN_AVS6EYES
+       select VIDEO_SAA711X if VIDEO_ZORAN_BUZ || VIDEO_ZORAN_LML33R10
+       select VIDEO_SAA7110 if VIDEO_ZORAN_DC10
+       select VIDEO_SAA7185 if VIDEO_ZORAN_BUZ
+       select VIDEO_VPX3220 if VIDEO_ZORAN_DC30
+       help
+         Say Y for support for MJPEG capture cards based on the Zoran
+         36057/36067 PCI controller chipset. This includes the Iomega
+         Buz, Pinnacle DC10+ and the Linux Media Labs LML33. There is
+         a driver homepage at <http://mjpeg.sf.net/driver-zoran/>. For
+         more information, check <file:Documentation/driver-api/media/drivers/zoran.rst>.
+
+         To compile this driver as a module, choose M here: the
+         module will be called zr36067.
+
+config VIDEO_ZORAN_DC30
+       bool "Pinnacle/Miro DC30(+) support"
+       depends on VIDEO_ZORAN
+       help
+         Support for the Pinnacle/Miro DC30(+) MJPEG capture/playback
+         card. This also supports really old DC10 cards based on the
+         zr36050 MJPEG codec and zr36016 VFE.
+
+config VIDEO_ZORAN_ZR36060
+       bool "Zoran ZR36060"
+       depends on VIDEO_ZORAN
+       help
+         Say Y to support Zoran boards based on 36060 chips.
+         This includes Iomega Buz, Pinnacle DC10, Linux media Labs 33
+         and 33 R10 and AverMedia 6 boards.
+
+config VIDEO_ZORAN_BUZ
+       bool "Iomega Buz support"
+       depends on VIDEO_ZORAN_ZR36060
+       help
+         Support for the Iomega Buz MJPEG capture/playback card.
+
+config VIDEO_ZORAN_DC10
+       bool "Pinnacle/Miro DC10(+) support"
+       depends on VIDEO_ZORAN_ZR36060
+       help
+         Support for the Pinnacle/Miro DC10(+) MJPEG capture/playback
+         card.
+
+config VIDEO_ZORAN_LML33
+       bool "Linux Media Labs LML33 support"
+       depends on VIDEO_ZORAN_ZR36060
+       help
+         Support for the Linux Media Labs LML33 MJPEG capture/playback
+         card.
+
+config VIDEO_ZORAN_LML33R10
+       bool "Linux Media Labs LML33R10 support"
+       depends on VIDEO_ZORAN_ZR36060
+       help
+         support for the Linux Media Labs LML33R10 MJPEG capture/playback
+         card.
+
+config VIDEO_ZORAN_AVS6EYES
+       bool "AverMedia 6 Eyes support"
+       depends on VIDEO_ZORAN_ZR36060
+       help
+         Support for the AverMedia 6 Eyes video surveillance card.
 
--- /dev/null
+# SPDX-License-Identifier: GPL-2.0
+zr36067-objs   :=      zoran_device.o \
+                       zoran_driver.o zoran_card.o videocodec.o
+
+obj-$(CONFIG_VIDEO_ZORAN) += zr36067.o
+zr36067-$(CONFIG_VIDEO_ZORAN_DC30) += zr36050.o zr36016.o
+zr36067-$(CONFIG_VIDEO_ZORAN_ZR36060) += zr36060.o
 
--- /dev/null
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * VIDEO MOTION CODECs internal API for video devices
+ *
+ * Interface for MJPEG (and maybe later MPEG/WAVELETS) codec's
+ * bound to a master device.
+ *
+ * (c) 2002 Wolfgang Scherr <scherr@net4you.at>
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+
+#include "videocodec.h"
+
+struct attached_list {
+       struct videocodec *codec;
+       struct attached_list *next;
+};
+
+struct codec_list {
+       const struct videocodec *codec;
+       int attached;
+       struct attached_list *list;
+       struct codec_list *next;
+};
+
+static struct codec_list *codeclist_top;
+
+/* ================================================= */
+/* function prototypes of the master/slave interface */
+/* ================================================= */
+
+struct videocodec *videocodec_attach(struct videocodec_master *master)
+{
+       struct codec_list *h = codeclist_top;
+       struct zoran *zr;
+       struct attached_list *a, *ptr;
+       struct videocodec *codec;
+       int res;
+
+       if (!master) {
+               pr_err("%s: no data\n", __func__);
+               return NULL;
+       }
+
+       zr = videocodec_master_to_zoran(master);
+
+       zrdev_dbg(zr, "%s: '%s', flags %lx, magic %lx\n", __func__,
+                 master->name, master->flags, master->magic);
+
+       if (!h) {
+               zrdev_err(zr, "%s: no device available\n", __func__);
+               return NULL;
+       }
+
+       while (h) {
+               // attach only if the slave has at least the flags
+               // expected by the master
+               if ((master->flags & h->codec->flags) == master->flags) {
+                       zrdev_dbg(zr, "%s: try '%s'\n", __func__, h->codec->name);
+
+                       codec = kmemdup(h->codec, sizeof(struct videocodec), GFP_KERNEL);
+                       if (!codec)
+                               goto out_kfree;
+
+                       res = strlen(codec->name);
+                       snprintf(codec->name + res, sizeof(codec->name) - res, "[%d]", h->attached);
+                       codec->master_data = master;
+                       res = codec->setup(codec);
+                       if (res == 0) {
+                               zrdev_dbg(zr, "%s: '%s'\n", __func__, codec->name);
+                               ptr = kzalloc(sizeof(*ptr), GFP_KERNEL);
+                               if (!ptr)
+                                       goto out_kfree;
+                               ptr->codec = codec;
+
+                               a = h->list;
+                               if (!a) {
+                                       h->list = ptr;
+                                       zrdev_dbg(zr, "videocodec: first element\n");
+                               } else {
+                                       while (a->next)
+                                               a = a->next;    // find end
+                                       a->next = ptr;
+                                       zrdev_dbg(zr, "videocodec: in after '%s'\n",
+                                                 h->codec->name);
+                               }
+
+                               h->attached += 1;
+                               return codec;
+                       }
+                       kfree(codec);
+               }
+               h = h->next;
+       }
+
+       zrdev_err(zr, "%s: no codec found!\n", __func__);
+       return NULL;
+
+ out_kfree:
+       kfree(codec);
+       return NULL;
+}
+
+int videocodec_detach(struct videocodec *codec)
+{
+       struct codec_list *h = codeclist_top;
+       struct zoran *zr;
+       struct attached_list *a, *prev;
+       int res;
+
+       if (!codec) {
+               pr_err("%s: no data\n", __func__);
+               return -EINVAL;
+       }
+
+       zr = videocodec_to_zoran(codec);
+
+       zrdev_dbg(zr, "%s: '%s', type: %x, flags %lx, magic %lx\n", __func__,
+                 codec->name, codec->type, codec->flags, codec->magic);
+
+       if (!h) {
+               zrdev_err(zr, "%s: no device left...\n", __func__);
+               return -ENXIO;
+       }
+
+       while (h) {
+               a = h->list;
+               prev = NULL;
+               while (a) {
+                       if (codec == a->codec) {
+                               res = a->codec->unset(a->codec);
+                               if (res >= 0) {
+                                       zrdev_dbg(zr, "%s: '%s'\n", __func__,
+                                                 a->codec->name);
+                                       a->codec->master_data = NULL;
+                               } else {
+                                       zrdev_err(zr, "%s: '%s'\n", __func__, a->codec->name);
+                                       a->codec->master_data = NULL;
+                               }
+                               if (!prev) {
+                                       h->list = a->next;
+                                       zrdev_dbg(zr, "videocodec: delete first\n");
+                               } else {
+                                       prev->next = a->next;
+                                       zrdev_dbg(zr, "videocodec: delete middle\n");
+                               }
+                               kfree(a->codec);
+                               kfree(a);
+                               h->attached -= 1;
+                               return 0;
+                       }
+                       prev = a;
+                       a = a->next;
+               }
+               h = h->next;
+       }
+
+       zrdev_err(zr, "%s: given codec not found!\n", __func__);
+       return -EINVAL;
+}
+
+int videocodec_register(const struct videocodec *codec)
+{
+       struct codec_list *ptr, *h = codeclist_top;
+       struct zoran *zr;
+
+       if (!codec) {
+               pr_err("%s: no data!\n", __func__);
+               return -EINVAL;
+       }
+
+       zr = videocodec_to_zoran((struct videocodec *)codec);
+
+       zrdev_dbg(zr,
+                 "videocodec: register '%s', type: %x, flags %lx, magic %lx\n",
+                 codec->name, codec->type, codec->flags, codec->magic);
+
+       ptr = kzalloc(sizeof(*ptr), GFP_KERNEL);
+       if (!ptr)
+               return -ENOMEM;
+       ptr->codec = codec;
+
+       if (!h) {
+               codeclist_top = ptr;
+               zrdev_dbg(zr, "videocodec: hooked in as first element\n");
+       } else {
+               while (h->next)
+                       h = h->next;    // find the end
+               h->next = ptr;
+               zrdev_dbg(zr, "videocodec: hooked in after '%s'\n",
+                         h->codec->name);
+       }
+
+       return 0;
+}
+
+int videocodec_unregister(const struct videocodec *codec)
+{
+       struct codec_list *prev = NULL, *h = codeclist_top;
+       struct zoran *zr;
+
+       if (!codec) {
+               pr_err("%s: no data!\n", __func__);
+               return -EINVAL;
+       }
+
+       zr = videocodec_to_zoran((struct videocodec *)codec);
+
+       zrdev_dbg(zr,
+                 "videocodec: unregister '%s', type: %x, flags %lx, magic %lx\n",
+                 codec->name, codec->type, codec->flags, codec->magic);
+
+       if (!h) {
+               zrdev_err(zr, "%s: no device left...\n", __func__);
+               return -ENXIO;
+       }
+
+       while (h) {
+               if (codec == h->codec) {
+                       if (h->attached) {
+                               zrdev_err(zr, "videocodec: '%s' is used\n",
+                                         h->codec->name);
+                               return -EBUSY;
+                       }
+                       zrdev_dbg(zr, "videocodec: unregister '%s' is ok.\n",
+                                 h->codec->name);
+                       if (!prev) {
+                               codeclist_top = h->next;
+                               zrdev_dbg(zr,
+                                         "videocodec: delete first element\n");
+                       } else {
+                               prev->next = h->next;
+                               zrdev_dbg(zr,
+                                         "videocodec: delete middle element\n");
+                       }
+                       kfree(h);
+                       return 0;
+               }
+               prev = h;
+               h = h->next;
+       }
+
+       zrdev_err(zr, "%s: given codec not found!\n", __func__);
+       return -EINVAL;
+}
+
+int videocodec_debugfs_show(struct seq_file *m)
+{
+       struct codec_list *h = codeclist_top;
+       struct attached_list *a;
+
+       seq_puts(m, "<S>lave or attached <M>aster name  type flags    magic    ");
+       seq_puts(m, "(connected as)\n");
+
+       while (h) {
+               seq_printf(m, "S %32s %04x %08lx %08lx (TEMPLATE)\n",
+                          h->codec->name, h->codec->type,
+                             h->codec->flags, h->codec->magic);
+               a = h->list;
+               while (a) {
+                       seq_printf(m, "M %32s %04x %08lx %08lx (%s)\n",
+                                  a->codec->master_data->name,
+                                     a->codec->master_data->type,
+                                     a->codec->master_data->flags,
+                                     a->codec->master_data->magic,
+                                     a->codec->name);
+                       a = a->next;
+               }
+               h = h->next;
+       }
+
+       return 0;
+}
 
--- /dev/null
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * VIDEO MOTION CODECs internal API for video devices
+ *
+ * Interface for MJPEG (and maybe later MPEG/WAVELETS) codec's
+ * bound to a master device.
+ *
+ * (c) 2002 Wolfgang Scherr <scherr@net4you.at>
+ */
+
+/* =================== */
+/* general description */
+/* =================== */
+
+/*
+ * Should ease the (re-)usage of drivers supporting cards with (different)
+ * video codecs. The codecs register to this module their functionality,
+ * and the processors (masters) can attach to them if they fit.
+ *
+ * The codecs are typically have a "strong" binding to their master - so I
+ * don't think it makes sense to have a full blown interfacing as with e.g.
+ * i2c. If you have an other opinion, let's discuss & implement it :-)))
+ *
+ * Usage:
+ *
+ * The slave has just to setup the videocodec structure and use two functions:
+ * videocodec_register(codecdata);
+ * videocodec_unregister(codecdata);
+ * The best is just calling them at module (de-)initialisation.
+ *
+ * The master sets up the structure videocodec_master and calls:
+ * codecdata=videocodec_attach(master_codecdata);
+ * videocodec_detach(codecdata);
+ *
+ * The slave is called during attach/detach via functions setup previously
+ * during register. At that time, the master_data pointer is set up
+ * and the slave can access any io registers of the master device (in the case
+ * the slave is bound to it). Otherwise it doesn't need this functions and
+ * therefor they may not be initialized.
+ *
+ * The other functions are just for convenience, as they are for sure used by
+ * most/all of the codecs. The last ones may be omitted, too.
+ *
+ * See the structure declaration below for more information and which data has
+ * to be set up for the master and the slave.
+ *
+ * ----------------------------------------------------------------------------
+ * The master should have "knowledge" of the slave and vice versa.  So the data
+ * structures sent to/from slave via set_data/get_data set_image/get_image are
+ * device dependent and vary between MJPEG/MPEG/WAVELET/... devices. (!!!!)
+ * ----------------------------------------------------------------------------
+ */
+
+/* ========================================== */
+/* description of the videocodec_io structure */
+/* ========================================== */
+
+/*
+ * ==== master setup ====
+ * name -> name of the device structure for reference and debugging
+ * master_data ->  data ref. for the master (e.g. the zr36055,57,67)
+ * readreg -> ref. to read-fn from register (setup by master, used by slave)
+ * writereg -> ref. to write-fn to register (setup by master, used by slave)
+ *            this two functions do the lowlevel I/O job
+ *
+ * ==== slave functionality setup ====
+ * slave_data -> data ref. for the slave (e.g. the zr36050,60)
+ * check -> fn-ref. checks availability of an device, returns -EIO on failure or
+ *         the type on success
+ *         this makes espcecially sense if a driver module supports more than
+ *         one codec which may be quite similar to access, nevertheless it
+ *         is good for a first functionality check
+ *
+ * -- main functions you always need for compression/decompression --
+ *
+ * set_mode -> this fn-ref. resets the entire codec, and sets up the mode
+ *            with the last defined norm/size (or device default if not
+ *            available) - it returns 0 if the mode is possible
+ * set_size -> this fn-ref. sets the norm and image size for
+ *            compression/decompression (returns 0 on success)
+ *            the norm param is defined in videodev2.h (V4L2_STD_*)
+ *
+ * additional setup may be available, too - but the codec should work with
+ * some default values even without this
+ *
+ * set_data -> sets device-specific data (tables, quality etc.)
+ * get_data -> query device-specific data (tables, quality etc.)
+ *
+ * if the device delivers interrupts, they may be setup/handled here
+ * setup_interrupt -> codec irq setup (not needed for 36050/60)
+ * handle_interrupt -> codec irq handling (not needed for 36050/60)
+
+ * if the device delivers pictures, they may be handled here
+ * put_image -> puts image data to the codec (not needed for 36050/60)
+ * get_image -> gets image data from the codec (not needed for 36050/60)
+ *             the calls include frame numbers and flags (even/odd/...)
+ *             if needed and a flag which allows blocking until its ready
+ */
+
+/* ============== */
+/* user interface */
+/* ============== */
+
+/*
+ * Currently there is only a information display planned, as the layer
+ * is not visible for the user space at all.
+ *
+ * Information is available via procfs. The current entry is "/proc/videocodecs"
+ * but it makes sense to "hide" it in the /proc/video tree of v4l(2) --TODO--.
+ *
+ * A example for such an output is:
+ *
+ * <S>lave or attached <M>aster name  type flags    magic    (connected as)
+ * S                          zr36050 0002 0000d001 00000000 (TEMPLATE)
+ * M                       zr36055[0] 0001 0000c001 00000000 (zr36050[0])
+ * M                       zr36055[1] 0001 0000c001 00000000 (zr36050[1])
+ */
+
+/* =============================================== */
+/* special defines for the videocodec_io structure */
+/* =============================================== */
+
+#ifndef __LINUX_VIDEOCODEC_H
+#define __LINUX_VIDEOCODEC_H
+
+#include <linux/debugfs.h>
+#include <linux/videodev2.h>
+
+#define CODEC_DO_COMPRESSION 0
+#define CODEC_DO_EXPANSION   1
+
+/* this are the current codec flags I think they are needed */
+/*  -> type value in structure */
+#define CODEC_FLAG_JPEG      0x00000001L       // JPEG codec
+#define CODEC_FLAG_MPEG      0x00000002L       // MPEG1/2/4 codec
+#define CODEC_FLAG_DIVX      0x00000004L       // DIVX codec
+#define CODEC_FLAG_WAVELET   0x00000008L       // WAVELET codec
+                                         // room for other types
+
+#define CODEC_FLAG_MAGIC     0x00000800L       // magic key must match
+#define CODEC_FLAG_HARDWARE  0x00001000L       // is a hardware codec
+#define CODEC_FLAG_VFE       0x00002000L       // has direct video frontend
+#define CODEC_FLAG_ENCODER   0x00004000L       // compression capability
+#define CODEC_FLAG_DECODER   0x00008000L       // decompression capability
+#define CODEC_FLAG_NEEDIRQ   0x00010000L       // needs irq handling
+#define CODEC_FLAG_RDWRPIC   0x00020000L       // handles picture I/O
+
+/* a list of modes, some are just examples (is there any HW?) */
+#define CODEC_MODE_BJPG      0x0001    // Baseline JPEG
+#define CODEC_MODE_LJPG      0x0002    // Lossless JPEG
+#define CODEC_MODE_MPEG1     0x0003    // MPEG 1
+#define CODEC_MODE_MPEG2     0x0004    // MPEG 2
+#define CODEC_MODE_MPEG4     0x0005    // MPEG 4
+#define CODEC_MODE_MSDIVX    0x0006    // MS DivX
+#define CODEC_MODE_ODIVX     0x0007    // Open DivX
+#define CODEC_MODE_WAVELET   0x0008    // Wavelet
+
+/* this are the current codec types I want to implement */
+/*  -> type value in structure */
+#define CODEC_TYPE_NONE    0
+#define CODEC_TYPE_L64702  1
+#define CODEC_TYPE_ZR36050 2
+#define CODEC_TYPE_ZR36016 3
+#define CODEC_TYPE_ZR36060 4
+
+/* the type of data may be enhanced by future implementations (data-fn.'s) */
+/*  -> used in command                                                     */
+#define CODEC_G_STATUS         0x0000  /* codec status (query only) */
+#define CODEC_S_CODEC_MODE     0x0001  /* codec mode (baseline JPEG, MPEG1,... */
+#define CODEC_G_CODEC_MODE     0x8001
+#define CODEC_S_VFE            0x0002  /* additional video frontend setup */
+#define CODEC_G_VFE            0x8002
+#define CODEC_S_MMAP           0x0003  /* MMAP setup (if available) */
+
+#define CODEC_S_JPEG_TDS_BYTE  0x0010  /* target data size in bytes */
+#define CODEC_G_JPEG_TDS_BYTE  0x8010
+#define CODEC_S_JPEG_SCALE     0x0011  /* scaling factor for quant. tables */
+#define CODEC_G_JPEG_SCALE     0x8011
+#define CODEC_S_JPEG_HDT_DATA  0x0018  /* huffman-tables */
+#define CODEC_G_JPEG_HDT_DATA  0x8018
+#define CODEC_S_JPEG_QDT_DATA  0x0019  /* quantizing-tables */
+#define CODEC_G_JPEG_QDT_DATA  0x8019
+#define CODEC_S_JPEG_APP_DATA  0x001A  /* APP marker */
+#define CODEC_G_JPEG_APP_DATA  0x801A
+#define CODEC_S_JPEG_COM_DATA  0x001B  /* COM marker */
+#define CODEC_G_JPEG_COM_DATA  0x801B
+
+#define CODEC_S_PRIVATE        0x1000  /* "private" commands start here */
+#define CODEC_G_PRIVATE        0x9000
+
+#define CODEC_G_FLAG           0x8000  /* this is how 'get' is detected */
+
+/* types of transfer, directly user space or a kernel buffer (image-fn.'s) */
+/*  -> used in get_image, put_image */
+#define CODEC_TRANSFER_KERNEL 0        /* use "memcopy" */
+#define CODEC_TRANSFER_USER   1        /* use "to/from_user" */
+
+/* ========================= */
+/* the structures itself ... */
+/* ========================= */
+
+struct vfe_polarity {
+       unsigned int vsync_pol:1;
+       unsigned int hsync_pol:1;
+       unsigned int field_pol:1;
+       unsigned int blank_pol:1;
+       unsigned int subimg_pol:1;
+       unsigned int poe_pol:1;
+       unsigned int pvalid_pol:1;
+       unsigned int vclk_pol:1;
+};
+
+struct vfe_settings {
+       __u32 x, y;             /* Offsets into image */
+       __u32 width, height;    /* Area to capture */
+       __u16 decimation;       /* Decimation divider */
+       __u16 flags;            /* Flags for capture */
+       __u16 quality;          /* quality of the video */
+};
+
+struct tvnorm {
+       u16 wt, wa, h_start, h_sync_start, ht, ha, v_start;
+};
+
+struct jpeg_com_marker {
+       int len; /* number of usable bytes in data */
+       char data[60];
+};
+
+struct jpeg_app_marker {
+       int appn; /* number app segment */
+       int len; /* number of usable bytes in data */
+       char data[60];
+};
+
+struct videocodec {
+       /* -- filled in by slave device during register -- */
+       char name[32];
+       unsigned long magic;    /* may be used for client<->master attaching */
+       unsigned long flags;    /* functionality flags */
+       unsigned int type;      /* codec type */
+
+       /* -- these is filled in later during master device attach -- */
+
+       struct videocodec_master *master_data;
+
+       /* -- these are filled in by the slave device during register -- */
+
+       void *data;             /* private slave data */
+
+       /* attach/detach client functions (indirect call) */
+       int (*setup)(struct videocodec *codec);
+       int (*unset)(struct videocodec *codec);
+
+       /* main functions, every client needs them for sure! */
+       // set compression or decompression (or freeze, stop, standby, etc)
+       int (*set_mode)(struct videocodec *codec, int mode);
+       // setup picture size and norm (for the codec's video frontend)
+       int (*set_video)(struct videocodec *codec, const struct tvnorm *norm,
+                        struct vfe_settings *cap, struct vfe_polarity *pol);
+       // other control commands, also mmap setup etc.
+       int (*control)(struct videocodec *codec, int type, int size, void *data);
+
+       /* additional setup/query/processing (may be NULL pointer) */
+       // interrupt setup / handling (for irq's delivered by master)
+       int (*setup_interrupt)(struct videocodec *codec, long mode);
+       int (*handle_interrupt)(struct videocodec *codec, int source, long flag);
+       // picture interface (if any)
+       long (*put_image)(struct videocodec *codec, int tr_type, int block,
+                         long *fr_num, long *flag, long size, void *buf);
+       long (*get_image)(struct videocodec *codec, int tr_type, int block,
+                         long *fr_num, long *flag, long size, void *buf);
+};
+
+struct videocodec_master {
+       /* -- filled in by master device for registration -- */
+       char name[32];
+       unsigned long magic;    /* may be used for client<->master attaching */
+       unsigned long flags;    /* functionality flags */
+       unsigned int type;      /* master type */
+
+       void *data;             /* private master data */
+
+       __u32 (*readreg)(struct videocodec *codec, __u16 reg);
+       void (*writereg)(struct videocodec *codec, __u16 reg, __u32 value);
+};
+
+/* ================================================= */
+/* function prototypes of the master/slave interface */
+/* ================================================= */
+
+/* attach and detach commands for the master */
+// * master structure needs to be kmalloc'ed before calling attach
+//   and free'd after calling detach
+// * returns pointer on success, NULL on failure
+struct videocodec *videocodec_attach(struct videocodec_master *master);
+// * 0 on success, <0 (errno) on failure
+int videocodec_detach(struct videocodec *codec);
+
+/* register and unregister commands for the slaves */
+// * 0 on success, <0 (errno) on failure
+int videocodec_register(const struct videocodec *codec);
+// * 0 on success, <0 (errno) on failure
+int videocodec_unregister(const struct videocodec *codec);
+
+/* the other calls are directly done via the videocodec structure! */
+
+int videocodec_debugfs_show(struct seq_file *m);
+
+#include "zoran.h"
+static inline struct zoran *videocodec_master_to_zoran(struct videocodec_master *master)
+{
+       struct zoran *zr = master->data;
+
+       return zr;
+}
+
+static inline struct zoran *videocodec_to_zoran(struct videocodec *codec)
+{
+       struct videocodec_master *master = codec->master_data;
+
+       return videocodec_master_to_zoran(master);
+}
+
+#endif                         /*ifndef __LINUX_VIDEOCODEC_H */
 
--- /dev/null
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * zoran - Iomega Buz driver
+ *
+ * Copyright (C) 1999 Rainer Johanni <Rainer@Johanni.de>
+ *
+ * based on
+ *
+ * zoran.0.0.3 Copyright (C) 1998 Dave Perks <dperks@ibm.net>
+ *
+ * and
+ *
+ * bttv - Bt848 frame grabber driver
+ * Copyright (C) 1996,97,98 Ralph  Metzler (rjkm@thp.uni-koeln.de)
+ *                        & Marcus Metzler (mocm@thp.uni-koeln.de)
+ */
+
+#ifndef _BUZ_H_
+#define _BUZ_H_
+
+#include <linux/debugfs.h>
+#include <linux/pci.h>
+#include <linux/i2c-algo-bit.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-ctrls.h>
+#include <media/videobuf2-core.h>
+#include <media/videobuf2-v4l2.h>
+#include <media/videobuf2-dma-contig.h>
+
+#define ZR_NORM_PAL 0
+#define ZR_NORM_NTSC 1
+#define ZR_NORM_SECAM 2
+
+struct zr_buffer {
+       /* common v4l buffer stuff -- must be first */
+       struct vb2_v4l2_buffer          vbuf;
+       struct list_head                queue;
+};
+
+static inline struct zr_buffer *vb2_to_zr_buffer(struct vb2_buffer *vb)
+{
+       struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+
+       return container_of(vbuf, struct zr_buffer, vbuf);
+}
+
+#define ZORAN_NAME    "ZORAN"  /* name of the device */
+
+#define ZR_DEVNAME(zr) ((zr)->name)
+
+#define   BUZ_MAX_WIDTH   (zr->timing->wa)
+#define   BUZ_MAX_HEIGHT  (zr->timing->ha)
+#define   BUZ_MIN_WIDTH    32  /* never display less than 32 pixels */
+#define   BUZ_MIN_HEIGHT   24  /* never display less than 24 rows */
+
+#define BUZ_NUM_STAT_COM    4
+#define BUZ_MASK_STAT_COM   3
+
+#define BUZ_MAX_INPUT       16
+
+#include "zr36057.h"
+
+enum card_type {
+       UNKNOWN = -1,
+
+       /* Pinnacle/Miro */
+       DC10_OLD,               /* DC30 like */
+       DC10_NEW,               /* DC10_PLUS like */
+       DC10_PLUS,
+       DC30,
+       DC30_PLUS,
+
+       /* Linux Media Labs */
+       LML33,
+       LML33R10,
+
+       /* Iomega */
+       BUZ,
+
+       /* AverMedia */
+       AVS6EYES,
+
+       /* total number of cards */
+       NUM_CARDS
+};
+
+enum zoran_codec_mode {
+       BUZ_MODE_IDLE,          /* nothing going on */
+       BUZ_MODE_MOTION_COMPRESS,       /* grabbing frames */
+       BUZ_MODE_MOTION_DECOMPRESS,     /* playing frames */
+       BUZ_MODE_STILL_COMPRESS,        /* still frame conversion */
+       BUZ_MODE_STILL_DECOMPRESS       /* still frame conversion */
+};
+
+enum zoran_map_mode {
+       ZORAN_MAP_MODE_NONE,
+       ZORAN_MAP_MODE_RAW,
+       ZORAN_MAP_MODE_JPG_REC,
+       ZORAN_MAP_MODE_JPG_PLAY,
+};
+
+enum gpio_type {
+       ZR_GPIO_JPEG_SLEEP = 0,
+       ZR_GPIO_JPEG_RESET,
+       ZR_GPIO_JPEG_FRAME,
+       ZR_GPIO_VID_DIR,
+       ZR_GPIO_VID_EN,
+       ZR_GPIO_VID_RESET,
+       ZR_GPIO_CLK_SEL1,
+       ZR_GPIO_CLK_SEL2,
+       ZR_GPIO_MAX,
+};
+
+enum gpcs_type {
+       GPCS_JPEG_RESET = 0,
+       GPCS_JPEG_START,
+       GPCS_MAX,
+};
+
+struct zoran_format {
+       char *name;
+       __u32 fourcc;
+       int colorspace;
+       int depth;
+       __u32 flags;
+       __u32 vfespfr;
+};
+
+/* flags */
+#define ZORAN_FORMAT_COMPRESSED BIT(0)
+#define ZORAN_FORMAT_OVERLAY BIT(1)
+#define ZORAN_FORMAT_CAPTURE BIT(2)
+#define ZORAN_FORMAT_PLAYBACK BIT(3)
+
+/* v4l-capture settings */
+struct zoran_v4l_settings {
+       int width, height, bytesperline;        /* capture size */
+       const struct zoran_format *format;      /* capture format */
+};
+
+/* jpg-capture/-playback settings */
+struct zoran_jpg_settings {
+       /* this bit is used to set everything to default */
+       int decimation;
+       /* capture decimation settings (tmp_dcm=1 means both fields) */
+       int hor_dcm, ver_dcm, tmp_dcm;
+       /* field-settings (odd_even=1 (+tmp_dcm=1) means top-field-first) */
+       int field_per_buff, odd_even;
+       /* crop settings (subframe capture) */
+       int img_x, img_y, img_width, img_height;
+       /* JPEG-specific capture settings */
+       struct v4l2_jpegcompression jpg_comp;
+};
+
+struct zoran;
+
+/* zoran_fh contains per-open() settings */
+struct zoran_fh {
+       struct v4l2_fh fh;
+       struct zoran *zr;
+};
+
+struct card_info {
+       enum card_type type;
+       char name[32];
+       const char *i2c_decoder;        /* i2c decoder device */
+       const unsigned short *addrs_decoder;
+       const char *i2c_encoder;        /* i2c encoder device */
+       const unsigned short *addrs_encoder;
+       u16 video_vfe, video_codec;                     /* videocodec types */
+       u16 audio_chip;                                 /* audio type */
+
+       int inputs;             /* number of video inputs */
+       struct input {
+               int muxsel;
+               char name[32];
+       } input[BUZ_MAX_INPUT];
+
+       v4l2_std_id norms;
+       const struct tvnorm *tvn[3];    /* supported TV norms */
+
+       u32 jpeg_int;           /* JPEG interrupt */
+       u32 vsync_int;          /* VSYNC interrupt */
+       s8 gpio[ZR_GPIO_MAX];
+       u8 gpcs[GPCS_MAX];
+
+       struct vfe_polarity vfe_pol;
+       u8 gpio_pol[ZR_GPIO_MAX];
+
+       /* is the /GWS line connected? */
+       u8 gws_not_connected;
+
+       /* avs6eyes mux setting */
+       u8 input_mux;
+
+       void (*init)(struct zoran *zr);
+};
+
+struct zoran {
+       struct v4l2_device v4l2_dev;
+       struct v4l2_ctrl_handler hdl;
+       struct video_device *video_dev;
+       struct vb2_queue vq;
+
+       struct i2c_adapter i2c_adapter; /* */
+       struct i2c_algo_bit_data i2c_algo;      /* */
+       u32 i2cbr;
+
+       struct v4l2_subdev *decoder;    /* video decoder sub-device */
+       struct v4l2_subdev *encoder;    /* video encoder sub-device */
+
+       struct videocodec *codec;       /* video codec */
+       struct videocodec *vfe; /* video front end */
+
+       struct mutex lock;      /* file ops serialize lock */
+
+       u8 initialized;         /* flag if zoran has been correctly initialized */
+       struct card_info card;
+       const struct tvnorm *timing;
+
+       unsigned short id;      /* number of this device */
+       char name[32];          /* name of this device */
+       struct pci_dev *pci_dev;        /* PCI device */
+       unsigned char revision; /* revision of zr36057 */
+       unsigned char __iomem *zr36057_mem;/* pointer to mapped IO memory */
+
+       spinlock_t spinlock;    /* Spinlock */
+
+       /* Video for Linux parameters */
+       int input;      /* card's norm and input */
+       v4l2_std_id norm;
+
+       /* Current buffer params */
+       unsigned int buffer_size;
+
+       struct zoran_v4l_settings v4l_settings; /* structure with a lot of things to play with */
+
+       /* Buz MJPEG parameters */
+       enum zoran_codec_mode codec_mode;       /* status of codec */
+       struct zoran_jpg_settings jpg_settings; /* structure with a lot of things to play with */
+
+       /* grab queue counts/indices, mask with BUZ_MASK_STAT_COM before using as index */
+       /* (dma_head - dma_tail) is number active in DMA, must be <= BUZ_NUM_STAT_COM */
+       /* (value & BUZ_MASK_STAT_COM) corresponds to index in stat_com table */
+       unsigned long jpg_que_head;     /* Index where to put next buffer which is queued */
+       unsigned long jpg_dma_head;     /* Index of next buffer which goes into stat_com */
+       unsigned long jpg_dma_tail;     /* Index of last buffer in stat_com */
+       unsigned long jpg_que_tail;     /* Index of last buffer in queue */
+       unsigned long jpg_seq_num;      /* count of frames since grab/play started */
+       unsigned long jpg_err_seq;      /* last seq_num before error */
+       unsigned long jpg_err_shift;
+       unsigned long jpg_queued_num;   /* count of frames queued since grab/play started */
+       unsigned long vbseq;
+
+       /* zr36057's code buffer table */
+       /* stat_com[i] is indexed by dma_head/tail & BUZ_MASK_STAT_COM */
+       __le32 *stat_com;
+
+       /* Additional stuff for testing */
+       unsigned int ghost_int;
+       int intr_counter_GIRQ1;
+       int intr_counter_GIRQ0;
+       int intr_counter_cod_rep_irq;
+       int intr_counter_jpeg_rep_irq;
+       int field_counter;
+       int irq1_in;
+       int irq1_out;
+       int jpeg_in;
+       int jpeg_out;
+       int JPEG_0;
+       int JPEG_1;
+       int end_event_missed;
+       int jpeg_missed;
+       int jpeg_error;
+       int num_errors;
+       int jpeg_max_missed;
+       int jpeg_min_missed;
+       unsigned int prepared;
+       unsigned int queued;
+
+       u32 last_isr;
+       unsigned long frame_num;
+       int running;
+       int buf_in_reserve;
+
+       dma_addr_t p_sc;
+       __le32 *stat_comb;
+       dma_addr_t p_scb;
+       enum zoran_map_mode map_mode;
+       struct list_head queued_bufs;
+       spinlock_t queued_bufs_lock; /* Protects queued_bufs */
+       struct zr_buffer *inuse[BUZ_NUM_STAT_COM * 2];
+       struct dentry *dbgfs_dir;
+};
+
+static inline struct zoran *to_zoran(struct v4l2_device *v4l2_dev)
+{
+       return container_of(v4l2_dev, struct zoran, v4l2_dev);
+}
+
+/*
+ * There was something called _ALPHA_BUZ that used the PCI address instead of
+ * the kernel iomapped address for btread/btwrite.
+ */
+#define btwrite(dat, adr)    writel((dat), zr->zr36057_mem + (adr))
+#define btread(adr)         readl(zr->zr36057_mem + (adr))
+
+#define btand(dat, adr)      btwrite((dat) & btread(adr), (adr))
+#define btor(dat, adr)       btwrite((dat) | btread(adr), (adr))
+#define btaor(dat, mask, adr) btwrite((dat) | ((mask) & btread(adr)), (adr))
+
+#endif
+
+/*
+ * Debugging macros
+ */
+#define zrdev_dbg(zr, format, args...) \
+       pci_dbg((zr)->pci_dev, format, ##args) \
+
+#define zrdev_err(zr, format, args...) \
+       pci_err((zr)->pci_dev, format, ##args) \
+
+#define zrdev_info(zr, format, args...) \
+       pci_info((zr)->pci_dev, format, ##args) \
+
+int zoran_queue_init(struct zoran *zr, struct vb2_queue *vq, int dir);
+void zoran_queue_exit(struct zoran *zr);
+int zr_set_buf(struct zoran *zr);
 
--- /dev/null
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Zoran zr36057/zr36067 PCI controller driver, for the
+ * Pinnacle/Miro DC10/DC10+/DC30/DC30+, Iomega Buz, Linux
+ * Media Labs LML33/LML33R10.
+ *
+ * This part handles card-specific data and detection
+ *
+ * Copyright (C) 2000 Serguei Miridonov <mirsev@cicese.mx>
+ */
+
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+
+#include <linux/i2c.h>
+#include <linux/i2c-algo-bit.h>
+#include <linux/videodev2.h>
+#include <linux/spinlock.h>
+
+#include <linux/pci.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <media/v4l2-common.h>
+#include <media/i2c/bt819.h>
+
+#include "videocodec.h"
+#include "zoran.h"
+#include "zoran_card.h"
+#include "zoran_device.h"
+#include "zr36016.h"
+#include "zr36050.h"
+#include "zr36060.h"
+
+extern const struct zoran_format zoran_formats[];
+
+static int card[BUZ_MAX] = { [0 ... (BUZ_MAX - 1)] = -1 };
+module_param_array(card, int, NULL, 0444);
+MODULE_PARM_DESC(card, "Card type");
+
+/* Default input and video norm at startup of the driver. */
+
+static unsigned int default_input;     /* default 0 = Composite, 1 = S-Video */
+module_param(default_input, uint, 0444);
+MODULE_PARM_DESC(default_input,
+                "Default input (0=Composite, 1=S-Video, 2=Internal)");
+
+static int default_mux = 1;    /* 6 Eyes input selection */
+module_param(default_mux, int, 0644);
+MODULE_PARM_DESC(default_mux,
+                "Default 6 Eyes mux setting (Input selection)");
+
+static int default_norm;       /* default 0 = PAL, 1 = NTSC 2 = SECAM */
+module_param(default_norm, int, 0444);
+MODULE_PARM_DESC(default_norm, "Default norm (0=PAL, 1=NTSC, 2=SECAM)");
+
+/* /dev/videoN, -1 for autodetect */
+static int video_nr[BUZ_MAX] = { [0 ... (BUZ_MAX - 1)] = -1 };
+module_param_array(video_nr, int, NULL, 0444);
+MODULE_PARM_DESC(video_nr, "Video device number (-1=Auto)");
+
+/* 1=Pass through TV signal when device is not used */
+/* 0=Show color bar when device is not used (LML33: only if lml33dpath=1) */
+int pass_through;
+module_param(pass_through, int, 0644);
+MODULE_PARM_DESC(pass_through,
+                "Pass TV signal through to TV-out when idling");
+
+int zr36067_debug = 1;
+module_param_named(debug, zr36067_debug, int, 0644);
+MODULE_PARM_DESC(debug, "Debug level (0-5)");
+
+#define ZORAN_VERSION "0.10.1"
+
+MODULE_DESCRIPTION("Zoran-36057/36067 JPEG codec driver");
+MODULE_AUTHOR("Serguei Miridonov");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(ZORAN_VERSION);
+
+#define ZR_DEVICE(subven, subdev, data)        { \
+       .vendor = PCI_VENDOR_ID_ZORAN, .device = PCI_DEVICE_ID_ZORAN_36057, \
+       .subvendor = (subven), .subdevice = (subdev), .driver_data = (data) }
+
+static const struct pci_device_id zr36067_pci_tbl[] = {
+       ZR_DEVICE(PCI_VENDOR_ID_MIRO, PCI_DEVICE_ID_MIRO_DC10PLUS, DC10_PLUS),
+       ZR_DEVICE(PCI_VENDOR_ID_MIRO, PCI_DEVICE_ID_MIRO_DC30PLUS, DC30_PLUS),
+       ZR_DEVICE(PCI_VENDOR_ID_ELECTRONICDESIGNGMBH, PCI_DEVICE_ID_LML_33R10, LML33R10),
+       ZR_DEVICE(PCI_VENDOR_ID_IOMEGA, PCI_DEVICE_ID_IOMEGA_BUZ, BUZ),
+       ZR_DEVICE(PCI_ANY_ID, PCI_ANY_ID, NUM_CARDS),
+       {0}
+};
+MODULE_DEVICE_TABLE(pci, zr36067_pci_tbl);
+
+static unsigned int zoran_num;         /* number of cards found */
+
+/* videocodec bus functions ZR36060 */
+static u32 zr36060_read(struct videocodec *codec, u16 reg)
+{
+       struct zoran *zr = (struct zoran *)codec->master_data->data;
+       __u32 data;
+
+       if (post_office_wait(zr) || post_office_write(zr, 0, 1, reg >> 8) ||
+           post_office_write(zr, 0, 2, reg & 0xff))
+               return -1;
+
+       data = post_office_read(zr, 0, 3) & 0xff;
+       return data;
+}
+
+static void zr36060_write(struct videocodec *codec, u16 reg, u32 val)
+{
+       struct zoran *zr = (struct zoran *)codec->master_data->data;
+
+       if (post_office_wait(zr) || post_office_write(zr, 0, 1, reg >> 8) ||
+           post_office_write(zr, 0, 2, reg & 0xff))
+               return;
+
+       post_office_write(zr, 0, 3, val & 0xff);
+}
+
+/* videocodec bus functions ZR36050 */
+static u32 zr36050_read(struct videocodec *codec, u16 reg)
+{
+       struct zoran *zr = (struct zoran *)codec->master_data->data;
+       __u32 data;
+
+       if (post_office_wait(zr) || post_office_write(zr, 1, 0, reg >> 2))      // reg. HIGHBYTES
+               return -1;
+
+       data = post_office_read(zr, 0, reg & 0x03) & 0xff;      // reg. LOWBYTES + read
+       return data;
+}
+
+static void zr36050_write(struct videocodec *codec, u16 reg, u32 val)
+{
+       struct zoran *zr = (struct zoran *)codec->master_data->data;
+
+       if (post_office_wait(zr) || post_office_write(zr, 1, 0, reg >> 2))      // reg. HIGHBYTES
+               return;
+
+       post_office_write(zr, 0, reg & 0x03, val & 0xff);       // reg. LOWBYTES + wr. data
+}
+
+/* videocodec bus functions ZR36016 */
+static u32 zr36016_read(struct videocodec *codec, u16 reg)
+{
+       struct zoran *zr = (struct zoran *)codec->master_data->data;
+       __u32 data;
+
+       if (post_office_wait(zr))
+               return -1;
+
+       data = post_office_read(zr, 2, reg & 0x03) & 0xff;      // read
+       return data;
+}
+
+/* hack for in zoran_device.c */
+void zr36016_write(struct videocodec *codec, u16 reg, u32 val)
+{
+       struct zoran *zr = (struct zoran *)codec->master_data->data;
+
+       if (post_office_wait(zr))
+               return;
+
+       post_office_write(zr, 2, reg & 0x03, val & 0x0ff);      // wr. data
+}
+
+/*
+ * Board specific information
+ */
+
+static void dc10_init(struct zoran *zr)
+{
+       /* Pixel clock selection */
+       GPIO(zr, 4, 0);
+       GPIO(zr, 5, 1);
+       /* Enable the video bus sync signals */
+       GPIO(zr, 7, 0);
+}
+
+static void dc10plus_init(struct zoran *zr)
+{
+}
+
+static void buz_init(struct zoran *zr)
+{
+       /* some stuff from Iomega */
+       pci_write_config_dword(zr->pci_dev, 0xfc, 0x90680f15);
+       pci_write_config_dword(zr->pci_dev, 0x0c, 0x00012020);
+       pci_write_config_dword(zr->pci_dev, 0xe8, 0xc0200000);
+}
+
+static void lml33_init(struct zoran *zr)
+{
+       GPIO(zr, 2, 1);         // Set Composite input/output
+}
+
+static void avs6eyes_init(struct zoran *zr)
+{
+       // AverMedia 6-Eyes original driver by Christer Weinigel
+
+       // Lifted straight from Christer's old driver and
+       // modified slightly by Martin Samuelsson.
+
+       int mux = default_mux; /* 1 = BT866, 7 = VID1 */
+
+       GPIO(zr, 4, 1); /* Bt866 SLEEP on */
+       udelay(2);
+
+       GPIO(zr, 0, 1); /* ZR36060 /RESET on */
+       GPIO(zr, 1, 0); /* ZR36060 /SLEEP on */
+       GPIO(zr, 2, mux & 1);   /* MUX S0 */
+       GPIO(zr, 3, 0); /* /FRAME on */
+       GPIO(zr, 4, 0); /* Bt866 SLEEP off */
+       GPIO(zr, 5, mux & 2);   /* MUX S1 */
+       GPIO(zr, 6, 0); /* ? */
+       GPIO(zr, 7, mux & 4);   /* MUX S2 */
+}
+
+static const char *codecid_to_modulename(u16 codecid)
+{
+       const char *name = NULL;
+
+       switch (codecid) {
+       case CODEC_TYPE_ZR36060:
+               name = "zr36060";
+               break;
+       case CODEC_TYPE_ZR36050:
+               name = "zr36050";
+               break;
+       case CODEC_TYPE_ZR36016:
+               name = "zr36016";
+               break;
+       }
+
+       return name;
+}
+
+static int codec_init(struct zoran *zr, u16 codecid)
+{
+       switch (codecid) {
+       case CODEC_TYPE_ZR36060:
+#ifdef CONFIG_VIDEO_ZORAN_ZR36060
+               return zr36060_init_module();
+#else
+               pci_err(zr->pci_dev, "ZR36060 support is not enabled\n");
+               return -EINVAL;
+#endif
+               break;
+       case CODEC_TYPE_ZR36050:
+#ifdef CONFIG_VIDEO_ZORAN_DC30
+               return zr36050_init_module();
+#else
+               pci_err(zr->pci_dev, "ZR36050 support is not enabled\n");
+               return -EINVAL;
+#endif
+               break;
+       case CODEC_TYPE_ZR36016:
+#ifdef CONFIG_VIDEO_ZORAN_DC30
+               return zr36016_init_module();
+#else
+               pci_err(zr->pci_dev, "ZR36016 support is not enabled\n");
+               return -EINVAL;
+#endif
+               break;
+       }
+
+       pci_err(zr->pci_dev, "unknown codec id %x\n", codecid);
+       return -EINVAL;
+}
+
+static void codec_exit(struct zoran *zr, u16 codecid)
+{
+       switch (codecid) {
+       case CODEC_TYPE_ZR36060:
+#ifdef CONFIG_VIDEO_ZORAN_ZR36060
+               zr36060_cleanup_module();
+#endif
+               break;
+       case CODEC_TYPE_ZR36050:
+#ifdef CONFIG_VIDEO_ZORAN_DC30
+               zr36050_cleanup_module();
+#endif
+               break;
+       case CODEC_TYPE_ZR36016:
+#ifdef CONFIG_VIDEO_ZORAN_DC30
+               zr36016_cleanup_module();
+#endif
+               break;
+       }
+}
+
+static int videocodec_init(struct zoran *zr)
+{
+       const char *codec_name, *vfe_name;
+       int result;
+
+       codec_name = codecid_to_modulename(zr->card.video_codec);
+       if (codec_name) {
+               result = codec_init(zr, zr->card.video_codec);
+               if (result < 0) {
+                       pci_err(zr->pci_dev, "failed to load video codec %s: %d\n",
+                               codec_name, result);
+                       return result;
+               }
+       }
+       vfe_name = codecid_to_modulename(zr->card.video_vfe);
+       if (vfe_name) {
+               result = codec_init(zr, zr->card.video_vfe);
+               if (result < 0) {
+                       pci_err(zr->pci_dev, "failed to load video vfe %s: %d\n",
+                               vfe_name, result);
+                       if (codec_name)
+                               codec_exit(zr, zr->card.video_codec);
+                       return result;
+               }
+       }
+       return 0;
+}
+
+static void videocodec_exit(struct zoran *zr)
+{
+       if (zr->card.video_codec != CODEC_TYPE_NONE)
+               codec_exit(zr, zr->card.video_codec);
+       if (zr->card.video_vfe != CODEC_TYPE_NONE)
+               codec_exit(zr, zr->card.video_vfe);
+}
+
+static const struct tvnorm f50sqpixel = { 944, 768, 83, 880, 625, 576, 16 };
+static const struct tvnorm f60sqpixel = { 780, 640, 51, 716, 525, 480, 12 };
+static const struct tvnorm f50ccir601 = { 864, 720, 75, 804, 625, 576, 18 };
+static const struct tvnorm f60ccir601 = { 858, 720, 57, 788, 525, 480, 16 };
+
+static const struct tvnorm f50ccir601_lml33 = { 864, 720, 75 + 34, 804, 625, 576, 18 };
+static const struct tvnorm f60ccir601_lml33 = { 858, 720, 57 + 34, 788, 525, 480, 16 };
+
+/* The DC10 (57/16/50) uses VActive as HSync, so h_start must be 0 */
+static const struct tvnorm f50sqpixel_dc10 = { 944, 768, 0, 880, 625, 576, 0 };
+static const struct tvnorm f60sqpixel_dc10 = { 780, 640, 0, 716, 525, 480, 12 };
+
+/*
+ * FIXME: I cannot swap U and V in saa7114, so i do one pixel left shift in zoran (75 -> 74)
+ * (Maxim Yevtyushkin <max@linuxmedialabs.com>)
+ */
+static const struct tvnorm f50ccir601_lm33r10 = { 864, 720, 74 + 54, 804, 625, 576, 18 };
+static const struct tvnorm f60ccir601_lm33r10 = { 858, 720, 56 + 54, 788, 525, 480, 16 };
+
+/*
+ * FIXME: The ks0127 seem incapable of swapping U and V, too, which is why I copy Maxim's left
+ * shift hack for the 6 Eyes.
+ *
+ * Christer's driver used the unshifted norms, though...
+ * /Sam
+ */
+static const struct tvnorm f50ccir601_avs6eyes = { 864, 720, 74, 804, 625, 576, 18 };
+static const struct tvnorm f60ccir601_avs6eyes = { 858, 720, 56, 788, 525, 480, 16 };
+
+static const unsigned short vpx3220_addrs[] = { 0x43, 0x47, I2C_CLIENT_END };
+static const unsigned short saa7110_addrs[] = { 0x4e, 0x4f, I2C_CLIENT_END };
+static const unsigned short saa7111_addrs[] = { 0x25, 0x24, I2C_CLIENT_END };
+static const unsigned short saa7114_addrs[] = { 0x21, 0x20, I2C_CLIENT_END };
+static const unsigned short adv717x_addrs[] = { 0x6a, 0x6b, 0x2a, 0x2b, I2C_CLIENT_END };
+static const unsigned short ks0127_addrs[] = { 0x6c, 0x6d, I2C_CLIENT_END };
+static const unsigned short saa7185_addrs[] = { 0x44, I2C_CLIENT_END };
+static const unsigned short bt819_addrs[] = { 0x45, I2C_CLIENT_END };
+static const unsigned short bt856_addrs[] = { 0x44, I2C_CLIENT_END };
+static const unsigned short bt866_addrs[] = { 0x44, I2C_CLIENT_END };
+
+static struct card_info zoran_cards[NUM_CARDS] = {
+       {
+               .type = DC10_OLD,
+               .name = "DC10(old)",
+               .i2c_decoder = "vpx3220a",
+               .addrs_decoder = vpx3220_addrs,
+               .video_codec = CODEC_TYPE_ZR36050,
+               .video_vfe = CODEC_TYPE_ZR36016,
+
+               .inputs = 3,
+               .input = {
+                       { 1, "Composite" },
+                       { 2, "S-Video" },
+                       { 0, "Internal/comp" }
+               },
+               .norms = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM,
+               .tvn = {
+                       &f50sqpixel_dc10,
+                       &f60sqpixel_dc10,
+                       &f50sqpixel_dc10
+               },
+               .jpeg_int = 0,
+               .vsync_int = ZR36057_ISR_GIRQ1,
+               .gpio = { 2, 1, -1, 3, 7, 0, 4, 5 },
+               .gpio_pol = { 0, 0, 0, 1, 0, 0, 0, 0 },
+               .gpcs = { -1, 0 },
+               .vfe_pol = { 0, 0, 0, 0, 0, 0, 0, 0 },
+               .gws_not_connected = 0,
+               .input_mux = 0,
+               .init = &dc10_init,
+       }, {
+               .type = DC10_NEW,
+               .name = "DC10(new)",
+               .i2c_decoder = "saa7110",
+               .addrs_decoder = saa7110_addrs,
+               .i2c_encoder = "adv7175",
+               .addrs_encoder = adv717x_addrs,
+               .video_codec = CODEC_TYPE_ZR36060,
+
+               .inputs = 3,
+               .input = {
+                               { 0, "Composite" },
+                               { 7, "S-Video" },
+                               { 5, "Internal/comp" }
+                       },
+               .norms = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM,
+               .tvn = {
+                               &f50sqpixel,
+                               &f60sqpixel,
+                               &f50sqpixel},
+               .jpeg_int = ZR36057_ISR_GIRQ0,
+               .vsync_int = ZR36057_ISR_GIRQ1,
+               .gpio = { 3, 0, 6, 1, 2, -1, 4, 5 },
+               .gpio_pol = { 0, 0, 0, 0, 0, 0, 0, 0 },
+               .gpcs = { -1, 1},
+               .vfe_pol = { 1, 1, 1, 1, 0, 0, 0, 0 },
+               .gws_not_connected = 0,
+               .input_mux = 0,
+               .init = &dc10plus_init,
+       }, {
+               .type = DC10_PLUS,
+               .name = "DC10_PLUS",
+               .i2c_decoder = "saa7110",
+               .addrs_decoder = saa7110_addrs,
+               .i2c_encoder = "adv7175",
+               .addrs_encoder = adv717x_addrs,
+               .video_codec = CODEC_TYPE_ZR36060,
+
+               .inputs = 3,
+               .input = {
+                       { 0, "Composite" },
+                       { 7, "S-Video" },
+                       { 5, "Internal/comp" }
+               },
+               .norms = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM,
+               .tvn = {
+                       &f50sqpixel,
+                       &f60sqpixel,
+                       &f50sqpixel
+               },
+               .jpeg_int = ZR36057_ISR_GIRQ0,
+               .vsync_int = ZR36057_ISR_GIRQ1,
+               .gpio = { 3, 0, 6, 1, 2, -1, 4, 5 },
+               .gpio_pol = { 0, 0, 0, 0, 0, 0, 0, 0 },
+               .gpcs = { -1, 1 },
+               .vfe_pol = { 1, 1, 1, 1, 0, 0, 0, 0 },
+               .gws_not_connected = 0,
+               .input_mux = 0,
+               .init = &dc10plus_init,
+       }, {
+               .type = DC30,
+               .name = "DC30",
+               .i2c_decoder = "vpx3220a",
+               .addrs_decoder = vpx3220_addrs,
+               .i2c_encoder = "adv7175",
+               .addrs_encoder = adv717x_addrs,
+               .video_codec = CODEC_TYPE_ZR36050,
+               .video_vfe = CODEC_TYPE_ZR36016,
+
+               .inputs = 3,
+               .input = {
+                       { 1, "Composite" },
+                       { 2, "S-Video" },
+                       { 0, "Internal/comp" }
+               },
+               .norms = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM,
+               .tvn = {
+                       &f50sqpixel_dc10,
+                       &f60sqpixel_dc10,
+                       &f50sqpixel_dc10
+               },
+               .jpeg_int = 0,
+               .vsync_int = ZR36057_ISR_GIRQ1,
+               .gpio = { 2, 1, -1, 3, 7, 0, 4, 5 },
+               .gpio_pol = { 0, 0, 0, 1, 0, 0, 0, 0 },
+               .gpcs = { -1, 0 },
+               .vfe_pol = { 0, 0, 0, 0, 0, 0, 0, 0 },
+               .gws_not_connected = 0,
+               .input_mux = 0,
+               .init = &dc10_init,
+       }, {
+               .type = DC30_PLUS,
+               .name = "DC30_PLUS",
+               .i2c_decoder = "vpx3220a",
+               .addrs_decoder = vpx3220_addrs,
+               .i2c_encoder = "adv7175",
+               .addrs_encoder = adv717x_addrs,
+               .video_codec = CODEC_TYPE_ZR36050,
+               .video_vfe = CODEC_TYPE_ZR36016,
+
+               .inputs = 3,
+               .input = {
+                       { 1, "Composite" },
+                       { 2, "S-Video" },
+                       { 0, "Internal/comp" }
+               },
+               .norms = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM,
+               .tvn = {
+                       &f50sqpixel_dc10,
+                       &f60sqpixel_dc10,
+                       &f50sqpixel_dc10
+               },
+               .jpeg_int = 0,
+               .vsync_int = ZR36057_ISR_GIRQ1,
+               .gpio = { 2, 1, -1, 3, 7, 0, 4, 5 },
+               .gpio_pol = { 0, 0, 0, 1, 0, 0, 0, 0 },
+               .gpcs = { -1, 0 },
+               .vfe_pol = { 0, 0, 0, 0, 0, 0, 0, 0 },
+               .gws_not_connected = 0,
+               .input_mux = 0,
+               .init = &dc10_init,
+       }, {
+               .type = LML33,
+               .name = "LML33",
+               .i2c_decoder = "bt819a",
+               .addrs_decoder = bt819_addrs,
+               .i2c_encoder = "bt856",
+               .addrs_encoder = bt856_addrs,
+               .video_codec = CODEC_TYPE_ZR36060,
+
+               .inputs = 2,
+               .input = {
+                       { 0, "Composite" },
+                       { 7, "S-Video" }
+               },
+               .norms = V4L2_STD_NTSC | V4L2_STD_PAL,
+               .tvn = {
+                       &f50ccir601_lml33,
+                       &f60ccir601_lml33,
+                       NULL
+               },
+               .jpeg_int = ZR36057_ISR_GIRQ1,
+               .vsync_int = ZR36057_ISR_GIRQ0,
+               .gpio = { 1, -1, 3, 5, 7, -1, -1, -1 },
+               .gpio_pol = { 0, 0, 0, 0, 1, 0, 0, 0 },
+               .gpcs = { 3, 1 },
+               .vfe_pol = { 1, 1, 0, 0, 0, 1, 0, 0 },
+               .gws_not_connected = 1,
+               .input_mux = 0,
+               .init = &lml33_init,
+       }, {
+               .type = LML33R10,
+               .name = "LML33R10",
+               .i2c_decoder = "saa7114",
+               .addrs_decoder = saa7114_addrs,
+               .i2c_encoder = "adv7170",
+               .addrs_encoder = adv717x_addrs,
+               .video_codec = CODEC_TYPE_ZR36060,
+
+               .inputs = 2,
+               .input = {
+                       { 0, "Composite" },
+                       { 7, "S-Video" }
+               },
+               .norms = V4L2_STD_NTSC | V4L2_STD_PAL,
+               .tvn = {
+                       &f50ccir601_lm33r10,
+                       &f60ccir601_lm33r10,
+                       NULL
+               },
+               .jpeg_int = ZR36057_ISR_GIRQ1,
+               .vsync_int = ZR36057_ISR_GIRQ0,
+               .gpio = { 1, -1, 3, 5, 7, -1, -1, -1 },
+               .gpio_pol = { 0, 0, 0, 0, 1, 0, 0, 0 },
+               .gpcs = { 3, 1 },
+               .vfe_pol = { 1, 1, 0, 0, 0, 1, 0, 0 },
+               .gws_not_connected = 1,
+               .input_mux = 0,
+               .init = &lml33_init,
+       }, {
+               .type = BUZ,
+               .name = "Buz",
+               .i2c_decoder = "saa7111",
+               .addrs_decoder = saa7111_addrs,
+               .i2c_encoder = "saa7185",
+               .addrs_encoder = saa7185_addrs,
+               .video_codec = CODEC_TYPE_ZR36060,
+
+               .inputs = 2,
+               .input = {
+                       { 3, "Composite" },
+                       { 7, "S-Video" }
+               },
+               .norms = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM,
+               .tvn = {
+                       &f50ccir601,
+                       &f60ccir601,
+                       &f50ccir601
+               },
+               .jpeg_int = ZR36057_ISR_GIRQ1,
+               .vsync_int = ZR36057_ISR_GIRQ0,
+               .gpio = { 1, -1, 3, -1, -1, -1, -1, -1 },
+               .gpio_pol = { 0, 0, 0, 0, 0, 0, 0, 0 },
+               .gpcs = { 3, 1 },
+               .vfe_pol = { 1, 1, 0, 0, 0, 1, 0, 0 },
+               .gws_not_connected = 1,
+               .input_mux = 0,
+               .init = &buz_init,
+       }, {
+               .type = AVS6EYES,
+               .name = "6-Eyes",
+               /*
+                * AverMedia chose not to brand the 6-Eyes. Thus it can't be
+                * autodetected, and requires card=x.
+                */
+               .i2c_decoder = "ks0127",
+               .addrs_decoder = ks0127_addrs,
+               .i2c_encoder = "bt866",
+               .addrs_encoder = bt866_addrs,
+               .video_codec = CODEC_TYPE_ZR36060,
+
+               .inputs = 10,
+               .input = {
+                       { 0, "Composite 1" },
+                       { 1, "Composite 2" },
+                       { 2, "Composite 3" },
+                       { 4, "Composite 4" },
+                       { 5, "Composite 5" },
+                       { 6, "Composite 6" },
+                       { 8, "S-Video 1" },
+                       { 9, "S-Video 2" },
+                       {10, "S-Video 3" },
+                       {15, "YCbCr" }
+               },
+               .norms = V4L2_STD_NTSC | V4L2_STD_PAL,
+               .tvn = {
+                       &f50ccir601_avs6eyes,
+                       &f60ccir601_avs6eyes,
+                       NULL
+               },
+               .jpeg_int = ZR36057_ISR_GIRQ1,
+               .vsync_int = ZR36057_ISR_GIRQ0,
+               .gpio = { 1, 0, 3, -1, -1, -1, -1, -1 },// Validity unknown /Sam
+               .gpio_pol = { 0, 0, 0, 0, 0, 0, 0, 0 }, // Validity unknown /Sam
+               .gpcs = { 3, 1 },                       // Validity unknown /Sam
+               .vfe_pol = { 1, 0, 0, 0, 0, 1, 0, 0 },  // Validity unknown /Sam
+               .gws_not_connected = 1,
+               .input_mux = 1,
+               .init = &avs6eyes_init,
+       }
+
+};
+
+/*
+ * I2C functions
+ */
+/* software I2C functions */
+static int zoran_i2c_getsda(void *data)
+{
+       struct zoran *zr = (struct zoran *)data;
+
+       return (btread(ZR36057_I2CBR) >> 1) & 1;
+}
+
+static int zoran_i2c_getscl(void *data)
+{
+       struct zoran *zr = (struct zoran *)data;
+
+       return btread(ZR36057_I2CBR) & 1;
+}
+
+static void zoran_i2c_setsda(void *data, int state)
+{
+       struct zoran *zr = (struct zoran *)data;
+
+       if (state)
+               zr->i2cbr |= 2;
+       else
+               zr->i2cbr &= ~2;
+       btwrite(zr->i2cbr, ZR36057_I2CBR);
+}
+
+static void zoran_i2c_setscl(void *data, int state)
+{
+       struct zoran *zr = (struct zoran *)data;
+
+       if (state)
+               zr->i2cbr |= 1;
+       else
+               zr->i2cbr &= ~1;
+       btwrite(zr->i2cbr, ZR36057_I2CBR);
+}
+
+static const struct i2c_algo_bit_data zoran_i2c_bit_data_template = {
+       .setsda = zoran_i2c_setsda,
+       .setscl = zoran_i2c_setscl,
+       .getsda = zoran_i2c_getsda,
+       .getscl = zoran_i2c_getscl,
+       .udelay = 10,
+       .timeout = 100,
+};
+
+static int zoran_register_i2c(struct zoran *zr)
+{
+       zr->i2c_algo = zoran_i2c_bit_data_template;
+       zr->i2c_algo.data = zr;
+       strscpy(zr->i2c_adapter.name, ZR_DEVNAME(zr),
+               sizeof(zr->i2c_adapter.name));
+       i2c_set_adapdata(&zr->i2c_adapter, &zr->v4l2_dev);
+       zr->i2c_adapter.algo_data = &zr->i2c_algo;
+       zr->i2c_adapter.dev.parent = &zr->pci_dev->dev;
+       return i2c_bit_add_bus(&zr->i2c_adapter);
+}
+
+static void zoran_unregister_i2c(struct zoran *zr)
+{
+       i2c_del_adapter(&zr->i2c_adapter);
+}
+
+/* Check a zoran_params struct for correctness, insert default params */
+int zoran_check_jpg_settings(struct zoran *zr,
+                            struct zoran_jpg_settings *settings, int try)
+{
+       int err = 0, err0 = 0;
+
+       pci_dbg(zr->pci_dev, "%s - dec: %d, Hdcm: %d, Vdcm: %d, Tdcm: %d\n",
+               __func__, settings->decimation, settings->hor_dcm,
+               settings->ver_dcm, settings->tmp_dcm);
+       pci_dbg(zr->pci_dev, "%s - x: %d, y: %d, w: %d, y: %d\n", __func__,
+               settings->img_x, settings->img_y,
+               settings->img_width, settings->img_height);
+       /* Check decimation, set default values for decimation = 1, 2, 4 */
+       switch (settings->decimation) {
+       case 1:
+
+               settings->hor_dcm = 1;
+               settings->ver_dcm = 1;
+               settings->tmp_dcm = 1;
+               settings->field_per_buff = 2;
+               settings->img_x = 0;
+               settings->img_y = 0;
+               settings->img_width = BUZ_MAX_WIDTH;
+               settings->img_height = BUZ_MAX_HEIGHT / 2;
+               break;
+       case 2:
+
+               settings->hor_dcm = 2;
+               settings->ver_dcm = 1;
+               settings->tmp_dcm = 2;
+               settings->field_per_buff = 1;
+               settings->img_x = (BUZ_MAX_WIDTH == 720) ? 8 : 0;
+               settings->img_y = 0;
+               settings->img_width =
+                   (BUZ_MAX_WIDTH == 720) ? 704 : BUZ_MAX_WIDTH;
+               settings->img_height = BUZ_MAX_HEIGHT / 2;
+               break;
+       case 4:
+
+               if (zr->card.type == DC10_NEW) {
+                       pci_dbg(zr->pci_dev,
+                               "%s - HDec by 4 is not supported on the DC10\n",
+                               __func__);
+                       err0++;
+                       break;
+               }
+
+               settings->hor_dcm = 4;
+               settings->ver_dcm = 2;
+               settings->tmp_dcm = 2;
+               settings->field_per_buff = 1;
+               settings->img_x = (BUZ_MAX_WIDTH == 720) ? 8 : 0;
+               settings->img_y = 0;
+               settings->img_width =
+                   (BUZ_MAX_WIDTH == 720) ? 704 : BUZ_MAX_WIDTH;
+               settings->img_height = BUZ_MAX_HEIGHT / 2;
+               break;
+       case 0:
+
+               /* We have to check the data the user has set */
+
+               if (settings->hor_dcm != 1 && settings->hor_dcm != 2 &&
+                   (zr->card.type == DC10_NEW || settings->hor_dcm != 4)) {
+                       settings->hor_dcm = clamp(settings->hor_dcm, 1, 2);
+                       err0++;
+               }
+               if (settings->ver_dcm != 1 && settings->ver_dcm != 2) {
+                       settings->ver_dcm = clamp(settings->ver_dcm, 1, 2);
+                       err0++;
+               }
+               if (settings->tmp_dcm != 1 && settings->tmp_dcm != 2) {
+                       settings->tmp_dcm = clamp(settings->tmp_dcm, 1, 2);
+                       err0++;
+               }
+               if (settings->field_per_buff != 1 &&
+                   settings->field_per_buff != 2) {
+                       settings->field_per_buff = clamp(settings->field_per_buff, 1, 2);
+                       err0++;
+               }
+               if (settings->img_x < 0) {
+                       settings->img_x = 0;
+                       err0++;
+               }
+               if (settings->img_y < 0) {
+                       settings->img_y = 0;
+                       err0++;
+               }
+               if (settings->img_width < 0 || settings->img_width > BUZ_MAX_WIDTH) {
+                       settings->img_width = clamp(settings->img_width, 0, (int)BUZ_MAX_WIDTH);
+                       err0++;
+               }
+               if (settings->img_height < 0 || settings->img_height > BUZ_MAX_HEIGHT / 2) {
+                       settings->img_height = clamp(settings->img_height, 0, BUZ_MAX_HEIGHT / 2);
+                       err0++;
+               }
+               if (settings->img_x + settings->img_width > BUZ_MAX_WIDTH) {
+                       settings->img_x = BUZ_MAX_WIDTH - settings->img_width;
+                       err0++;
+               }
+               if (settings->img_y + settings->img_height > BUZ_MAX_HEIGHT / 2) {
+                       settings->img_y = BUZ_MAX_HEIGHT / 2 - settings->img_height;
+                       err0++;
+               }
+               if (settings->img_width % (16 * settings->hor_dcm) != 0) {
+                       settings->img_width -= settings->img_width % (16 * settings->hor_dcm);
+                       if (settings->img_width == 0)
+                               settings->img_width = 16 * settings->hor_dcm;
+                       err0++;
+               }
+               if (settings->img_height % (8 * settings->ver_dcm) != 0) {
+                       settings->img_height -= settings->img_height % (8 * settings->ver_dcm);
+                       if (settings->img_height == 0)
+                               settings->img_height = 8 * settings->ver_dcm;
+                       err0++;
+               }
+
+               if (!try && err0) {
+                       pci_err(zr->pci_dev, "%s - error in params for decimation = 0\n", __func__);
+                       err++;
+               }
+               break;
+       default:
+               pci_err(zr->pci_dev, "%s - decimation = %d, must be 0, 1, 2 or 4\n",
+                       __func__, settings->decimation);
+               err++;
+               break;
+       }
+
+       if (settings->jpg_comp.quality > 100)
+               settings->jpg_comp.quality = 100;
+       if (settings->jpg_comp.quality < 5)
+               settings->jpg_comp.quality = 5;
+       if (settings->jpg_comp.APPn < 0)
+               settings->jpg_comp.APPn = 0;
+       if (settings->jpg_comp.APPn > 15)
+               settings->jpg_comp.APPn = 15;
+       if (settings->jpg_comp.APP_len < 0)
+               settings->jpg_comp.APP_len = 0;
+       if (settings->jpg_comp.APP_len > 60)
+               settings->jpg_comp.APP_len = 60;
+       if (settings->jpg_comp.COM_len < 0)
+               settings->jpg_comp.COM_len = 0;
+       if (settings->jpg_comp.COM_len > 60)
+               settings->jpg_comp.COM_len = 60;
+       if (err)
+               return -EINVAL;
+       return 0;
+}
+
+static int zoran_init_video_device(struct zoran *zr, struct video_device *video_dev, int dir)
+{
+       int err;
+
+       /* Now add the template and register the device unit. */
+       *video_dev = zoran_template;
+       video_dev->v4l2_dev = &zr->v4l2_dev;
+       video_dev->lock = &zr->lock;
+       video_dev->device_caps = V4L2_CAP_STREAMING | dir;
+
+       strscpy(video_dev->name, ZR_DEVNAME(zr), sizeof(video_dev->name));
+       video_dev->vfl_dir = VFL_DIR_RX;
+       zoran_queue_init(zr, &zr->vq, V4L2_BUF_TYPE_VIDEO_CAPTURE);
+
+       err = video_register_device(video_dev, VFL_TYPE_VIDEO, video_nr[zr->id]);
+       if (err < 0)
+               return err;
+       video_set_drvdata(video_dev, zr);
+       return 0;
+}
+
+static void zoran_exit_video_devices(struct zoran *zr)
+{
+       video_unregister_device(zr->video_dev);
+       kfree(zr->video_dev);
+}
+
+static int zoran_init_video_devices(struct zoran *zr)
+{
+       int err;
+
+       zr->video_dev = video_device_alloc();
+       if (!zr->video_dev)
+               return -ENOMEM;
+
+       err = zoran_init_video_device(zr, zr->video_dev, V4L2_CAP_VIDEO_CAPTURE);
+       if (err)
+               kfree(zr->video_dev);
+       return err;
+}
+
+/*
+ * v4l2_device_unregister() will care about removing zr->encoder/zr->decoder
+ * via v4l2_i2c_subdev_unregister()
+ */
+static int zoran_i2c_init(struct zoran *zr)
+{
+       int err;
+
+       pci_info(zr->pci_dev, "Initializing i2c bus...\n");
+
+       err = zoran_register_i2c(zr);
+       if (err) {
+               pci_err(zr->pci_dev, "%s - cannot initialize i2c bus\n", __func__);
+               return err;
+       }
+
+       zr->decoder = v4l2_i2c_new_subdev(&zr->v4l2_dev, &zr->i2c_adapter,
+                                         zr->card.i2c_decoder, 0,
+                                         zr->card.addrs_decoder);
+       if (!zr->decoder) {
+               pci_err(zr->pci_dev, "Fail to get decoder %s\n", zr->card.i2c_decoder);
+               err = -EINVAL;
+               goto error_decoder;
+       }
+
+       if (zr->card.i2c_encoder) {
+               zr->encoder = v4l2_i2c_new_subdev(&zr->v4l2_dev, &zr->i2c_adapter,
+                                                 zr->card.i2c_encoder, 0,
+                                                 zr->card.addrs_encoder);
+               if (!zr->encoder) {
+                       pci_err(zr->pci_dev, "Fail to get encoder %s\n", zr->card.i2c_encoder);
+                       err = -EINVAL;
+                       goto error_decoder;
+               }
+       }
+       return 0;
+
+error_decoder:
+       zoran_unregister_i2c(zr);
+       return err;
+}
+
+static void zoran_i2c_exit(struct zoran *zr)
+{
+       zoran_unregister_i2c(zr);
+}
+
+void zoran_open_init_params(struct zoran *zr)
+{
+       int i;
+
+       zr->v4l_settings.width = 192;
+       zr->v4l_settings.height = 144;
+       zr->v4l_settings.format = &zoran_formats[7];    /* YUY2 - YUV-4:2:2 packed */
+       zr->v4l_settings.bytesperline = zr->v4l_settings.width *
+               ((zr->v4l_settings.format->depth + 7) / 8);
+
+       /* Set necessary params and call zoran_check_jpg_settings to set the defaults */
+       zr->jpg_settings.decimation = 1;
+       zr->jpg_settings.jpg_comp.quality = 50; /* default compression factor 8 */
+       if (zr->card.type != BUZ)
+               zr->jpg_settings.odd_even = 1;
+       else
+               zr->jpg_settings.odd_even = 0;
+       zr->jpg_settings.jpg_comp.APPn = 0;
+       zr->jpg_settings.jpg_comp.APP_len = 0;  /* No APPn marker */
+       memset(zr->jpg_settings.jpg_comp.APP_data, 0,
+              sizeof(zr->jpg_settings.jpg_comp.APP_data));
+       zr->jpg_settings.jpg_comp.COM_len = 0;  /* No COM marker */
+       memset(zr->jpg_settings.jpg_comp.COM_data, 0,
+              sizeof(zr->jpg_settings.jpg_comp.COM_data));
+       zr->jpg_settings.jpg_comp.jpeg_markers =
+           V4L2_JPEG_MARKER_DHT | V4L2_JPEG_MARKER_DQT;
+       i = zoran_check_jpg_settings(zr, &zr->jpg_settings, 0);
+       if (i)
+               pci_err(zr->pci_dev, "%s internal error\n", __func__);
+
+       zr->buffer_size = zr->v4l_settings.bytesperline * zr->v4l_settings.height;
+
+       clear_interrupt_counters(zr);
+}
+
+static int zr36057_init(struct zoran *zr)
+{
+       int j, err;
+
+       pci_info(zr->pci_dev, "initializing card[%d]\n", zr->id);
+
+       /* Avoid nonsense settings from user for default input/norm */
+       if (default_norm < 0 || default_norm > 2)
+               default_norm = 0;
+       if (default_norm == 0) {
+               zr->norm = V4L2_STD_PAL;
+               zr->timing = zr->card.tvn[ZR_NORM_PAL];
+       } else if (default_norm == 1) {
+               zr->norm = V4L2_STD_NTSC;
+               zr->timing = zr->card.tvn[ZR_NORM_NTSC];
+       } else {
+               zr->norm = V4L2_STD_SECAM;
+               zr->timing = zr->card.tvn[ZR_NORM_SECAM];
+       }
+       if (!zr->timing) {
+               pci_warn(zr->pci_dev,
+                        "%s - default TV standard not supported by hardware. PAL will be used.\n",
+                        __func__);
+               zr->norm = V4L2_STD_PAL;
+               zr->timing = zr->card.tvn[ZR_NORM_PAL];
+       }
+
+       if (default_input > zr->card.inputs - 1) {
+               pci_warn(zr->pci_dev, "default_input value %d out of range (0-%d)\n",
+                        default_input, zr->card.inputs - 1);
+               default_input = 0;
+       }
+       zr->input = default_input;
+
+       /* default setup (will be repeated at every open) */
+       zoran_open_init_params(zr);
+
+       /* allocate memory *before* doing anything to the hardware in case allocation fails */
+       zr->stat_com = dma_alloc_coherent(&zr->pci_dev->dev,
+                                         BUZ_NUM_STAT_COM * sizeof(u32),
+                                         &zr->p_sc, GFP_KERNEL);
+       if (!zr->stat_com)
+               return -ENOMEM;
+
+       for (j = 0; j < BUZ_NUM_STAT_COM; j++)
+               zr->stat_com[j] = cpu_to_le32(1); /* mark as unavailable to zr36057 */
+
+       zr->stat_comb = dma_alloc_coherent(&zr->pci_dev->dev,
+                                          BUZ_NUM_STAT_COM * sizeof(u32) * 2,
+                                          &zr->p_scb, GFP_KERNEL);
+       if (!zr->stat_comb) {
+               err = -ENOMEM;
+               goto exit_statcom;
+       }
+
+       err = zoran_init_video_devices(zr);
+       if (err)
+               goto exit_statcomb;
+
+       zoran_init_hardware(zr);
+       if (!pass_through) {
+               decoder_call(zr, video, s_stream, 0);
+               encoder_call(zr, video, s_routing, 2, 0, 0);
+       }
+
+       zr->initialized = 1;
+       return 0;
+
+exit_statcomb:
+       dma_free_coherent(&zr->pci_dev->dev, BUZ_NUM_STAT_COM * sizeof(u32) * 2,
+                         zr->stat_comb, zr->p_scb);
+exit_statcom:
+       dma_free_coherent(&zr->pci_dev->dev, BUZ_NUM_STAT_COM * sizeof(u32),
+                         zr->stat_com, zr->p_sc);
+       return err;
+}
+
+static void zoran_remove(struct pci_dev *pdev)
+{
+       struct v4l2_device *v4l2_dev = dev_get_drvdata(&pdev->dev);
+       struct zoran *zr = to_zoran(v4l2_dev);
+
+       if (!zr->initialized)
+               goto exit_free;
+
+       debugfs_remove_recursive(zr->dbgfs_dir);
+
+       zoran_queue_exit(zr);
+
+       /* unregister videocodec bus */
+       if (zr->codec)
+               videocodec_detach(zr->codec);
+       if (zr->vfe)
+               videocodec_detach(zr->vfe);
+       videocodec_exit(zr);
+
+       /* unregister i2c bus */
+       zoran_i2c_exit(zr);
+       /* disable PCI bus-mastering */
+       zoran_set_pci_master(zr, 0);
+       /* put chip into reset */
+       btwrite(0, ZR36057_SPGPPCR);
+       pci_free_irq(zr->pci_dev, 0, zr);
+       /* unmap and free memory */
+       dma_free_coherent(&zr->pci_dev->dev, BUZ_NUM_STAT_COM * sizeof(u32),
+                         zr->stat_com, zr->p_sc);
+       dma_free_coherent(&zr->pci_dev->dev, BUZ_NUM_STAT_COM * sizeof(u32) * 2,
+                         zr->stat_comb, zr->p_scb);
+       pci_release_regions(pdev);
+       pci_disable_device(zr->pci_dev);
+       zoran_exit_video_devices(zr);
+exit_free:
+       v4l2_ctrl_handler_free(&zr->hdl);
+       v4l2_device_unregister(&zr->v4l2_dev);
+}
+
+void zoran_vdev_release(struct video_device *vdev)
+{
+       kfree(vdev);
+}
+
+static struct videocodec_master *zoran_setup_videocodec(struct zoran *zr,
+                                                       int type)
+{
+       struct videocodec_master *m = NULL;
+
+       m = devm_kmalloc(&zr->pci_dev->dev, sizeof(*m), GFP_KERNEL);
+       if (!m)
+               return m;
+
+       /*
+        * magic and type are unused for master struct. Makes sense only at codec structs.
+        * In the past, .type were initialized to the old V4L1 .hardware value,
+        * as VID_HARDWARE_ZR36067
+        */
+       m->magic = 0L;
+       m->type = 0;
+
+       m->flags = CODEC_FLAG_ENCODER | CODEC_FLAG_DECODER;
+       strscpy(m->name, ZR_DEVNAME(zr), sizeof(m->name));
+       m->data = zr;
+
+       switch (type) {
+       case CODEC_TYPE_ZR36060:
+               m->readreg = zr36060_read;
+               m->writereg = zr36060_write;
+               m->flags |= CODEC_FLAG_JPEG | CODEC_FLAG_VFE;
+               break;
+       case CODEC_TYPE_ZR36050:
+               m->readreg = zr36050_read;
+               m->writereg = zr36050_write;
+               m->flags |= CODEC_FLAG_JPEG;
+               break;
+       case CODEC_TYPE_ZR36016:
+               m->readreg = zr36016_read;
+               m->writereg = zr36016_write;
+               m->flags |= CODEC_FLAG_VFE;
+               break;
+       }
+
+       return m;
+}
+
+static void zoran_subdev_notify(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
+{
+       struct zoran *zr = to_zoran(sd->v4l2_dev);
+
+       /*
+        * Bt819 needs to reset its FIFO buffer using #FRST pin and
+        * LML33 card uses GPIO(7) for that.
+        */
+       if (cmd == BT819_FIFO_RESET_LOW)
+               GPIO(zr, 7, 0);
+       else if (cmd == BT819_FIFO_RESET_HIGH)
+               GPIO(zr, 7, 1);
+}
+
+static int zoran_video_set_ctrl(struct v4l2_ctrl *ctrl)
+{
+       struct zoran *zr = container_of(ctrl->handler, struct zoran, hdl);
+
+       switch (ctrl->id) {
+       case V4L2_CID_JPEG_COMPRESSION_QUALITY:
+               zr->jpg_settings.jpg_comp.quality = ctrl->val;
+               return zoran_check_jpg_settings(zr, &zr->jpg_settings, 0);
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static const struct v4l2_ctrl_ops zoran_video_ctrl_ops = {
+       .s_ctrl = zoran_video_set_ctrl,
+};
+
+static int zoran_debugfs_show(struct seq_file *seq, void *v)
+{
+       struct zoran *zr = seq->private;
+
+       seq_printf(seq, "Running mode %x\n", zr->running);
+       seq_printf(seq, "Codec mode %x\n", zr->codec_mode);
+       seq_printf(seq, "Norm %llx\n", zr->norm);
+       seq_printf(seq, "Input %d\n", zr->input);
+       seq_printf(seq, "Buffersize %d\n", zr->buffer_size);
+
+       seq_printf(seq, "V4L width %dx%d\n", zr->v4l_settings.width, zr->v4l_settings.height);
+       seq_printf(seq, "V4L bytesperline %d\n", zr->v4l_settings.bytesperline);
+
+       seq_printf(seq, "JPG decimation %u\n", zr->jpg_settings.decimation);
+       seq_printf(seq, "JPG hor_dcm %u\n", zr->jpg_settings.hor_dcm);
+       seq_printf(seq, "JPG ver_dcm %u\n", zr->jpg_settings.ver_dcm);
+       seq_printf(seq, "JPG tmp_dcm %u\n", zr->jpg_settings.tmp_dcm);
+       seq_printf(seq, "JPG odd_even %u\n", zr->jpg_settings.odd_even);
+       seq_printf(seq, "JPG crop %dx%d %d %d\n",
+                  zr->jpg_settings.img_x,
+                  zr->jpg_settings.img_y,
+                  zr->jpg_settings.img_width,
+                  zr->jpg_settings.img_height);
+
+       seq_printf(seq, "Prepared %u\n", zr->prepared);
+       seq_printf(seq, "Queued %u\n", zr->queued);
+
+       videocodec_debugfs_show(seq);
+       return 0;
+}
+
+DEFINE_SHOW_ATTRIBUTE(zoran_debugfs);
+
+/*
+ *   Scan for a Buz card (actually for the PCI controller ZR36057),
+ *   request the irq and map the io memory
+ */
+static int zoran_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+{
+       unsigned char latency, need_latency;
+       struct zoran *zr;
+       int result;
+       struct videocodec_master *master_vfe = NULL;
+       struct videocodec_master *master_codec = NULL;
+       int card_num;
+       unsigned int nr;
+       int err;
+
+       pci_info(pdev, "Zoran MJPEG board driver version %s\n", ZORAN_VERSION);
+
+       /* some mainboards might not do PCI-PCI data transfer well */
+       if (pci_pci_problems & (PCIPCI_FAIL | PCIAGP_FAIL | PCIPCI_ALIMAGIK))
+               pci_warn(pdev, "%s: chipset does not support reliable PCI-PCI DMA\n",
+                        ZORAN_NAME);
+
+       err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
+       if (err)
+               return err;
+       err = vb2_dma_contig_set_max_seg_size(&pdev->dev, U32_MAX);
+       if (err)
+               return err;
+
+       nr = zoran_num++;
+       if (nr >= BUZ_MAX) {
+               pci_err(pdev, "driver limited to %d card(s) maximum\n", BUZ_MAX);
+               return -ENOENT;
+       }
+
+       zr = devm_kzalloc(&pdev->dev, sizeof(*zr), GFP_KERNEL);
+       if (!zr)
+               return -ENOMEM;
+
+       zr->v4l2_dev.notify = zoran_subdev_notify;
+       if (v4l2_device_register(&pdev->dev, &zr->v4l2_dev))
+               goto zr_free_mem;
+       zr->pci_dev = pdev;
+       zr->id = nr;
+       snprintf(ZR_DEVNAME(zr), sizeof(ZR_DEVNAME(zr)), "MJPEG[%u]", zr->id);
+       if (v4l2_ctrl_handler_init(&zr->hdl, 10))
+               goto zr_unreg;
+       zr->v4l2_dev.ctrl_handler = &zr->hdl;
+       v4l2_ctrl_new_std(&zr->hdl, &zoran_video_ctrl_ops,
+                         V4L2_CID_JPEG_COMPRESSION_QUALITY, 0,
+                         100, 1, 50);
+       spin_lock_init(&zr->spinlock);
+       mutex_init(&zr->lock);
+       if (pci_enable_device(pdev))
+               goto zr_unreg;
+       zr->revision = zr->pci_dev->revision;
+
+       pci_info(zr->pci_dev, "Zoran ZR360%c7 (rev %d), irq: %d, memory: 0x%08llx\n",
+                zr->revision < 2 ? '5' : '6', zr->revision,
+                zr->pci_dev->irq, (uint64_t)pci_resource_start(zr->pci_dev, 0));
+       if (zr->revision >= 2)
+               pci_info(zr->pci_dev, "Subsystem vendor=0x%04x id=0x%04x\n",
+                        zr->pci_dev->subsystem_vendor, zr->pci_dev->subsystem_device);
+
+       /* Use auto-detected card type? */
+       if (card[nr] == -1) {
+               if (zr->revision < 2) {
+                       pci_err(pdev, "No card type specified, please use the card=X module parameter\n");
+                       pci_err(pdev, "It is not possible to auto-detect ZR36057 based cards\n");
+                       goto zr_unreg;
+               }
+
+               card_num = ent->driver_data;
+               if (card_num >= NUM_CARDS) {
+                       pci_err(pdev, "Unknown card, try specifying card=X module parameter\n");
+                       goto zr_unreg;
+               }
+               pci_info(zr->pci_dev, "%s() - card %s detected\n", __func__,
+                        zoran_cards[card_num].name);
+       } else {
+               card_num = card[nr];
+               if (card_num >= NUM_CARDS || card_num < 0) {
+                       pci_err(pdev, "User specified card type %d out of range (0 .. %d)\n",
+                               card_num, NUM_CARDS - 1);
+                       goto zr_unreg;
+               }
+       }
+
+       /*
+        * even though we make this a non pointer and thus
+        * theoretically allow for making changes to this struct
+        * on a per-individual card basis at runtime, this is
+        * strongly discouraged. This structure is intended to
+        * keep general card information, no settings or anything
+        */
+       zr->card = zoran_cards[card_num];
+       snprintf(ZR_DEVNAME(zr), sizeof(ZR_DEVNAME(zr)), "%s[%u]",
+                zr->card.name, zr->id);
+
+       err = pci_request_regions(pdev, ZR_DEVNAME(zr));
+       if (err)
+               goto zr_unreg;
+
+       zr->zr36057_mem = devm_ioremap(&pdev->dev, pci_resource_start(pdev, 0),
+                                      pci_resource_len(pdev, 0));
+       if (!zr->zr36057_mem) {
+               pci_err(pdev, "%s() - ioremap failed\n", __func__);
+               goto zr_pci_release;
+       }
+
+       result = pci_request_irq(pdev, 0, zoran_irq, NULL, zr, ZR_DEVNAME(zr));
+       if (result < 0) {
+               if (result == -EINVAL) {
+                       pci_err(pdev, "%s - bad IRQ number or handler\n", __func__);
+               } else if (result == -EBUSY) {
+                       pci_err(pdev, "%s - IRQ %d busy, change your PnP config in BIOS\n",
+                               __func__, zr->pci_dev->irq);
+               } else {
+                       pci_err(pdev, "%s - cannot assign IRQ, error code %d\n", __func__, result);
+               }
+               goto zr_pci_release;
+       }
+
+       /* set PCI latency timer */
+       pci_read_config_byte(zr->pci_dev, PCI_LATENCY_TIMER,
+                            &latency);
+       need_latency = zr->revision > 1 ? 32 : 48;
+       if (latency != need_latency) {
+               pci_info(zr->pci_dev, "Changing PCI latency from %d to %d\n",
+                        latency, need_latency);
+               pci_write_config_byte(zr->pci_dev, PCI_LATENCY_TIMER, need_latency);
+       }
+
+       zr36057_restart(zr);
+
+       err = zoran_i2c_init(zr);
+       if (err)
+               goto zr_free_irq;
+
+       pci_info(zr->pci_dev, "Initializing videocodec bus...\n");
+       err = videocodec_init(zr);
+       if (err)
+               goto zr_unreg_i2c;
+
+       /* reset JPEG codec */
+       jpeg_codec_sleep(zr, 1);
+       jpeg_codec_reset(zr);
+       /* video bus enabled */
+       /* display codec revision */
+       if (zr->card.video_codec != 0) {
+               master_codec = zoran_setup_videocodec(zr, zr->card.video_codec);
+               if (!master_codec)
+                       goto zr_unreg_videocodec;
+               zr->codec = videocodec_attach(master_codec);
+               if (!zr->codec) {
+                       pci_err(pdev, "%s - no codec found\n", __func__);
+                       goto zr_unreg_videocodec;
+               }
+               if (zr->codec->type != zr->card.video_codec) {
+                       pci_err(pdev, "%s - wrong codec\n", __func__);
+                       goto zr_unreg_videocodec;
+               }
+       }
+       if (zr->card.video_vfe != 0) {
+               master_vfe = zoran_setup_videocodec(zr, zr->card.video_vfe);
+               if (!master_vfe)
+                       goto zr_detach_codec;
+               zr->vfe = videocodec_attach(master_vfe);
+               if (!zr->vfe) {
+                       pci_err(pdev, "%s - no VFE found\n", __func__);
+                       goto zr_detach_codec;
+               }
+               if (zr->vfe->type != zr->card.video_vfe) {
+                       pci_err(pdev, "%s = wrong VFE\n", __func__);
+                       goto zr_detach_vfe;
+               }
+       }
+
+       /* take care of Natoma chipset and a revision 1 zr36057 */
+       if ((pci_pci_problems & PCIPCI_NATOMA) && zr->revision <= 1)
+               pci_info(zr->pci_dev, "ZR36057/Natoma bug, max. buffer size is 128K\n");
+
+       if (zr36057_init(zr) < 0)
+               goto zr_detach_vfe;
+
+       zr->map_mode = ZORAN_MAP_MODE_RAW;
+
+       zr->dbgfs_dir = debugfs_create_dir(ZR_DEVNAME(zr), NULL);
+       debugfs_create_file("debug", 0444, zr->dbgfs_dir, zr,
+                           &zoran_debugfs_fops);
+       return 0;
+
+zr_detach_vfe:
+       videocodec_detach(zr->vfe);
+zr_detach_codec:
+       videocodec_detach(zr->codec);
+zr_unreg_videocodec:
+       videocodec_exit(zr);
+zr_unreg_i2c:
+       zoran_i2c_exit(zr);
+zr_free_irq:
+       btwrite(0, ZR36057_SPGPPCR);
+       pci_free_irq(zr->pci_dev, 0, zr);
+zr_pci_release:
+       pci_release_regions(pdev);
+zr_unreg:
+       v4l2_ctrl_handler_free(&zr->hdl);
+       v4l2_device_unregister(&zr->v4l2_dev);
+zr_free_mem:
+
+       return -ENODEV;
+}
+
+static struct pci_driver zoran_driver = {
+       .name = "zr36067",
+       .id_table = zr36067_pci_tbl,
+       .probe = zoran_probe,
+       .remove = zoran_remove,
+};
+
+module_pci_driver(zoran_driver);
 
--- /dev/null
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Zoran zr36057/zr36067 PCI controller driver, for the
+ * Pinnacle/Miro DC10/DC10+/DC30/DC30+, Iomega Buz, Linux
+ * Media Labs LML33/LML33R10.
+ *
+ * This part handles card-specific data and detection
+ *
+ * Copyright (C) 2000 Serguei Miridonov <mirsev@cicese.mx>
+ */
+
+#ifndef __ZORAN_CARD_H__
+#define __ZORAN_CARD_H__
+
+extern int zr36067_debug;
+
+/* Anybody who uses more than four? */
+#define BUZ_MAX 4
+
+extern const struct video_device zoran_template;
+
+int zoran_check_jpg_settings(struct zoran *zr,
+                            struct zoran_jpg_settings *settings, int try);
+void zoran_open_init_params(struct zoran *zr);
+void zoran_vdev_release(struct video_device *vdev);
+
+void zr36016_write(struct videocodec *codec, u16 reg, u32 val);
+
+#endif                         /* __ZORAN_CARD_H__ */
 
--- /dev/null
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Zoran zr36057/zr36067 PCI controller driver, for the
+ * Pinnacle/Miro DC10/DC10+/DC30/DC30+, Iomega Buz, Linux
+ * Media Labs LML33/LML33R10.
+ *
+ * This part handles device access (PCI/I2C/codec/...)
+ *
+ * Copyright (C) 2000 Serguei Miridonov <mirsev@cicese.mx>
+ */
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+#include <linux/interrupt.h>
+#include <linux/i2c.h>
+#include <linux/i2c-algo-bit.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-common.h>
+#include <linux/spinlock.h>
+
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/wait.h>
+#include <linux/dma-mapping.h>
+
+#include <linux/io.h>
+
+#include "videocodec.h"
+#include "zoran.h"
+#include "zoran_device.h"
+#include "zoran_card.h"
+
+#define IRQ_MASK (ZR36057_ISR_GIRQ0 | \
+                 ZR36057_ISR_GIRQ1 | \
+                 ZR36057_ISR_JPEG_REP_IRQ)
+
+static bool lml33dpath;                /* default = 0
+                                * 1 will use digital path in capture
+                                * mode instead of analog. It can be
+                                * used for picture adjustments using
+                                * tool like xawtv while watching image
+                                * on TV monitor connected to the output.
+                                * However, due to absence of 75 Ohm
+                                * load on Bt819 input, there will be
+                                * some image imperfections
+                                */
+
+module_param(lml33dpath, bool, 0644);
+MODULE_PARM_DESC(lml33dpath, "Use digital path capture mode (on LML33 cards)");
+
+/*
+ * initialize video front end
+ */
+static void zr36057_init_vfe(struct zoran *zr)
+{
+       u32 reg;
+
+       reg = btread(ZR36057_VFESPFR);
+       reg |= ZR36057_VFESPFR_LITTLE_ENDIAN;
+       reg &= ~ZR36057_VFESPFR_VCLK_POL;
+       reg |= ZR36057_VFESPFR_EXT_FL;
+       reg |= ZR36057_VFESPFR_TOP_FIELD;
+       btwrite(reg, ZR36057_VFESPFR);
+       reg = btread(ZR36057_VDCR);
+       if (pci_pci_problems & PCIPCI_TRITON)
+               // || zr->revision < 1) // Revision 1 has also Triton support
+               reg &= ~ZR36057_VDCR_TRITON;
+       else
+               reg |= ZR36057_VDCR_TRITON;
+       btwrite(reg, ZR36057_VDCR);
+}
+
+/*
+ * General Purpose I/O and Guest bus access
+ */
+
+/*
+ * This is a bit tricky. When a board lacks a GPIO function, the corresponding
+ * GPIO bit number in the card_info structure is set to 0.
+ */
+
+void GPIO(struct zoran *zr, int bit, unsigned int value)
+{
+       u32 reg;
+       u32 mask;
+
+       /* Make sure the bit number is legal
+        * A bit number of -1 (lacking) gives a mask of 0,
+        * making it harmless
+        */
+       mask = (1 << (24 + bit)) & 0xff000000;
+       reg = btread(ZR36057_GPPGCR1) & ~mask;
+       if (value)
+               reg |= mask;
+
+       btwrite(reg, ZR36057_GPPGCR1);
+       udelay(1);
+}
+
+/*
+ * Wait til post office is no longer busy
+ */
+
+int post_office_wait(struct zoran *zr)
+{
+       u32 por;
+
+       while ((por = btread(ZR36057_POR)) & ZR36057_POR_PO_PEN) {
+               /* wait for something to happen */
+               /* TODO add timeout */
+       }
+       if ((por & ZR36057_POR_PO_TIME) && !zr->card.gws_not_connected) {
+               /* In LML33/BUZ \GWS line is not connected, so it has always timeout set */
+               pci_info(zr->pci_dev, "pop timeout %08x\n", por);
+               return -1;
+       }
+
+       return 0;
+}
+
+int post_office_write(struct zoran *zr, unsigned int guest,
+                     unsigned int reg, unsigned int value)
+{
+       u32 por;
+
+       por =
+           ZR36057_POR_PO_DIR | ZR36057_POR_PO_TIME | ((guest & 7) << 20) |
+           ((reg & 7) << 16) | (value & 0xFF);
+       btwrite(por, ZR36057_POR);
+
+       return post_office_wait(zr);
+}
+
+int post_office_read(struct zoran *zr, unsigned int guest, unsigned int reg)
+{
+       u32 por;
+
+       por = ZR36057_POR_PO_TIME | ((guest & 7) << 20) | ((reg & 7) << 16);
+       btwrite(por, ZR36057_POR);
+       if (post_office_wait(zr) < 0)
+               return -1;
+
+       return btread(ZR36057_POR) & 0xFF;
+}
+
+/*
+ * JPEG Codec access
+ */
+
+void jpeg_codec_sleep(struct zoran *zr, int sleep)
+{
+       GPIO(zr, zr->card.gpio[ZR_GPIO_JPEG_SLEEP], !sleep);
+       if (!sleep) {
+               pci_dbg(zr->pci_dev, "%s() - wake GPIO=0x%08x\n",
+                       __func__, btread(ZR36057_GPPGCR1));
+               usleep_range(500, 1000);
+       } else {
+               pci_dbg(zr->pci_dev, "%s() - sleep GPIO=0x%08x\n",
+                       __func__, btread(ZR36057_GPPGCR1));
+               udelay(2);
+       }
+}
+
+int jpeg_codec_reset(struct zoran *zr)
+{
+       /* Take the codec out of sleep */
+       jpeg_codec_sleep(zr, 0);
+
+       if (zr->card.gpcs[GPCS_JPEG_RESET] != 0xff) {
+               post_office_write(zr, zr->card.gpcs[GPCS_JPEG_RESET], 0,
+                                 0);
+               udelay(2);
+       } else {
+               GPIO(zr, zr->card.gpio[ZR_GPIO_JPEG_RESET], 0);
+               udelay(2);
+               GPIO(zr, zr->card.gpio[ZR_GPIO_JPEG_RESET], 1);
+               udelay(2);
+       }
+
+       return 0;
+}
+
+/*
+ *   Set the registers for the size we have specified. Don't bother
+ *   trying to understand this without the ZR36057 manual in front of
+ *   you [AC].
+ */
+static void zr36057_adjust_vfe(struct zoran *zr, enum zoran_codec_mode mode)
+{
+       u32 reg;
+
+       switch (mode) {
+       case BUZ_MODE_MOTION_DECOMPRESS:
+               btand(~ZR36057_VFESPFR_EXT_FL, ZR36057_VFESPFR);
+               reg = btread(ZR36057_VFEHCR);
+               if ((reg & (1 << 10)) && zr->card.type != LML33R10)
+                       reg += ((1 << 10) | 1);
+
+               btwrite(reg, ZR36057_VFEHCR);
+               break;
+       case BUZ_MODE_MOTION_COMPRESS:
+       case BUZ_MODE_IDLE:
+       default:
+               if ((zr->norm & V4L2_STD_NTSC) ||
+                   (zr->card.type == LML33R10 &&
+                    (zr->norm & V4L2_STD_PAL)))
+                       btand(~ZR36057_VFESPFR_EXT_FL, ZR36057_VFESPFR);
+               else
+                       btor(ZR36057_VFESPFR_EXT_FL, ZR36057_VFESPFR);
+               reg = btread(ZR36057_VFEHCR);
+               if (!(reg & (1 << 10)) && zr->card.type != LML33R10)
+                       reg -= ((1 << 10) | 1);
+
+               btwrite(reg, ZR36057_VFEHCR);
+               break;
+       }
+}
+
+/*
+ * set geometry
+ */
+
+static void zr36057_set_vfe(struct zoran *zr, int video_width, int video_height,
+                           const struct zoran_format *format)
+{
+       const struct tvnorm *tvn;
+       unsigned int h_start, h_end, v_start, v_end;
+       unsigned int disp_mode;
+       unsigned int vid_win_wid, vid_win_ht;
+       unsigned int hcrop1, hcrop2, vcrop1, vcrop2;
+       unsigned int wa, we, ha, he;
+       unsigned int X, Y, hor_dcm, ver_dcm;
+       u32 reg;
+
+       tvn = zr->timing;
+
+       wa = tvn->wa;
+       ha = tvn->ha;
+
+       pci_dbg(zr->pci_dev, "set_vfe() - width = %d, height = %d\n", video_width, video_height);
+
+       if (video_width < BUZ_MIN_WIDTH ||
+           video_height < BUZ_MIN_HEIGHT ||
+           video_width > wa || video_height > ha) {
+               pci_err(zr->pci_dev, "set_vfe: w=%d h=%d not valid\n", video_width, video_height);
+               return;
+       }
+
+       /**** zr36057 ****/
+
+       /* horizontal */
+       vid_win_wid = video_width;
+       X = DIV_ROUND_UP(vid_win_wid * 64, tvn->wa);
+       we = (vid_win_wid * 64) / X;
+       hor_dcm = 64 - X;
+       hcrop1 = 2 * ((tvn->wa - we) / 4);
+       hcrop2 = tvn->wa - we - hcrop1;
+       h_start = tvn->h_start ? tvn->h_start : 1;
+       /* (Ronald) Original comment:
+        * "| 1 Doesn't have any effect, tested on both a DC10 and a DC10+"
+        * this is false. It inverses chroma values on the LML33R10 (so Cr
+        * suddenly is shown as Cb and reverse, really cool effect if you
+        * want to see blue faces, not useful otherwise). So don't use |1.
+        * However, the DC10 has '0' as h_start, but does need |1, so we
+        * use a dirty check...
+        */
+       h_end = h_start + tvn->wa - 1;
+       h_start += hcrop1;
+       h_end -= hcrop2;
+       reg = ((h_start & ZR36057_VFEHCR_HMASK) << ZR36057_VFEHCR_H_START)
+           | ((h_end & ZR36057_VFEHCR_HMASK) << ZR36057_VFEHCR_H_END);
+       if (zr->card.vfe_pol.hsync_pol)
+               reg |= ZR36057_VFEHCR_HS_POL;
+       btwrite(reg, ZR36057_VFEHCR);
+
+       /* Vertical */
+       disp_mode = !(video_height > BUZ_MAX_HEIGHT / 2);
+       vid_win_ht = disp_mode ? video_height : video_height / 2;
+       Y = DIV_ROUND_UP(vid_win_ht * 64 * 2, tvn->ha);
+       he = (vid_win_ht * 64) / Y;
+       ver_dcm = 64 - Y;
+       vcrop1 = (tvn->ha / 2 - he) / 2;
+       vcrop2 = tvn->ha / 2 - he - vcrop1;
+       v_start = tvn->v_start;
+       // FIXME SnapShot times out with -1 in 768*576 on the DC10 - LP
+       v_end = v_start + tvn->ha / 2;  // - 1;
+       v_start += vcrop1;
+       v_end -= vcrop2;
+       reg = ((v_start & ZR36057_VFEVCR_VMASK) << ZR36057_VFEVCR_V_START)
+           | ((v_end & ZR36057_VFEVCR_VMASK) << ZR36057_VFEVCR_V_END);
+       if (zr->card.vfe_pol.vsync_pol)
+               reg |= ZR36057_VFEVCR_VS_POL;
+       btwrite(reg, ZR36057_VFEVCR);
+
+       /* scaler and pixel format */
+       reg = 0;
+       reg |= (hor_dcm << ZR36057_VFESPFR_HOR_DCM);
+       reg |= (ver_dcm << ZR36057_VFESPFR_VER_DCM);
+       reg |= (disp_mode << ZR36057_VFESPFR_DISP_MODE);
+       /*
+        * RJ: I don't know, why the following has to be the opposite
+        * of the corresponding ZR36060 setting, but only this way
+        * we get the correct colors when uncompressing to the screen
+        */
+       //reg |= ZR36057_VFESPFR_VCLK_POL;
+       /* RJ: Don't know if that is needed for NTSC also */
+       if (!(zr->norm & V4L2_STD_NTSC))
+               reg |= ZR36057_VFESPFR_EXT_FL;  // NEEDED!!!!!!! Wolfgang
+       reg |= ZR36057_VFESPFR_TOP_FIELD;
+       if (hor_dcm >= 48)
+               reg |= 3 << ZR36057_VFESPFR_H_FILTER;   /* 5 tap filter */
+       else if (hor_dcm >= 32)
+               reg |= 2 << ZR36057_VFESPFR_H_FILTER;   /* 4 tap filter */
+       else if (hor_dcm >= 16)
+               reg |= 1 << ZR36057_VFESPFR_H_FILTER;   /* 3 tap filter */
+
+       reg |= format->vfespfr;
+       btwrite(reg, ZR36057_VFESPFR);
+
+       /* display configuration */
+       reg = (16 << ZR36057_VDCR_MIN_PIX)
+           | (vid_win_ht << ZR36057_VDCR_VID_WIN_HT)
+           | (vid_win_wid << ZR36057_VDCR_VID_WIN_WID);
+       if (pci_pci_problems & PCIPCI_TRITON)
+               // || zr->revision < 1) // Revision 1 has also Triton support
+               reg &= ~ZR36057_VDCR_TRITON;
+       else
+               reg |= ZR36057_VDCR_TRITON;
+       btwrite(reg, ZR36057_VDCR);
+
+       zr36057_adjust_vfe(zr, zr->codec_mode);
+}
+
+/* Enable/Disable uncompressed memory grabbing of the 36057 */
+void zr36057_set_memgrab(struct zoran *zr, int mode)
+{
+       if (mode) {
+               /* We only check SnapShot and not FrameGrab here.  SnapShot==1
+                * means a capture is already in progress, but FrameGrab==1
+                * doesn't necessary mean that.  It's more correct to say a 1
+                * to 0 transition indicates a capture completed.  If a
+                * capture is pending when capturing is tuned off, FrameGrab
+                * will be stuck at 1 until capturing is turned back on.
+                */
+               if (btread(ZR36057_VSSFGR) & ZR36057_VSSFGR_SNAP_SHOT)
+                       pci_warn(zr->pci_dev, "%s(1) with SnapShot on!?\n", __func__);
+
+               /* switch on VSync interrupts */
+               btwrite(IRQ_MASK, ZR36057_ISR); // Clear Interrupts
+               btor(zr->card.vsync_int, ZR36057_ICR);  // SW
+
+               /* enable SnapShot */
+               btor(ZR36057_VSSFGR_SNAP_SHOT, ZR36057_VSSFGR);
+
+               /* Set zr36057 video front end  and enable video */
+               zr36057_set_vfe(zr, zr->v4l_settings.width,
+                               zr->v4l_settings.height,
+                               zr->v4l_settings.format);
+       } else {
+               /* switch off VSync interrupts */
+               btand(~zr->card.vsync_int, ZR36057_ICR);        // SW
+
+               /* re-enable grabbing to screen if it was running */
+               btand(~ZR36057_VDCR_VID_EN, ZR36057_VDCR);
+               btand(~ZR36057_VSSFGR_SNAP_SHOT, ZR36057_VSSFGR);
+       }
+}
+
+/*****************************************************************************
+ *                                                                           *
+ *  Set up the Buz-specific MJPEG part                                       *
+ *                                                                           *
+ *****************************************************************************/
+
+static inline void set_frame(struct zoran *zr, int val)
+{
+       GPIO(zr, zr->card.gpio[ZR_GPIO_JPEG_FRAME], val);
+}
+
+static void set_videobus_dir(struct zoran *zr, int val)
+{
+       switch (zr->card.type) {
+       case LML33:
+       case LML33R10:
+               if (!lml33dpath)
+                       GPIO(zr, 5, val);
+               else
+                       GPIO(zr, 5, 1);
+               break;
+       default:
+               GPIO(zr, zr->card.gpio[ZR_GPIO_VID_DIR],
+                    zr->card.gpio_pol[ZR_GPIO_VID_DIR] ? !val : val);
+               break;
+       }
+}
+
+static void init_jpeg_queue(struct zoran *zr)
+{
+       int i;
+
+       /* re-initialize DMA ring stuff */
+       zr->jpg_que_head = 0;
+       zr->jpg_dma_head = 0;
+       zr->jpg_dma_tail = 0;
+       zr->jpg_que_tail = 0;
+       zr->jpg_seq_num = 0;
+       zr->jpeg_error = 0;
+       zr->num_errors = 0;
+       zr->jpg_err_seq = 0;
+       zr->jpg_err_shift = 0;
+       zr->jpg_queued_num = 0;
+       for (i = 0; i < BUZ_NUM_STAT_COM; i++)
+               zr->stat_com[i] = cpu_to_le32(1);       /* mark as unavailable to zr36057 */
+}
+
+static void zr36057_set_jpg(struct zoran *zr, enum zoran_codec_mode mode)
+{
+       const struct tvnorm *tvn;
+       u32 reg;
+
+       tvn = zr->timing;
+
+       /* assert P_Reset, disable code transfer, deassert Active */
+       btwrite(0, ZR36057_JPC);
+
+       /* MJPEG compression mode */
+       switch (mode) {
+       case BUZ_MODE_MOTION_COMPRESS:
+       default:
+               reg = ZR36057_JMC_MJPG_CMP_MODE;
+               break;
+
+       case BUZ_MODE_MOTION_DECOMPRESS:
+               reg = ZR36057_JMC_MJPG_EXP_MODE;
+               reg |= ZR36057_JMC_SYNC_MSTR;
+               /* RJ: The following is experimental - improves the output to screen */
+               //if(zr->jpg_settings.VFIFO_FB) reg |= ZR36057_JMC_VFIFO_FB; // No, it doesn't. SM
+               break;
+
+       case BUZ_MODE_STILL_COMPRESS:
+               reg = ZR36057_JMC_JPG_CMP_MODE;
+               break;
+
+       case BUZ_MODE_STILL_DECOMPRESS:
+               reg = ZR36057_JMC_JPG_EXP_MODE;
+               break;
+       }
+       reg |= ZR36057_JMC_JPG;
+       if (zr->jpg_settings.field_per_buff == 1)
+               reg |= ZR36057_JMC_FLD_PER_BUFF;
+       btwrite(reg, ZR36057_JMC);
+
+       /* vertical */
+       btor(ZR36057_VFEVCR_VS_POL, ZR36057_VFEVCR);
+       reg = (6 << ZR36057_VSP_VSYNC_SIZE) |
+             (tvn->ht << ZR36057_VSP_FRM_TOT);
+       btwrite(reg, ZR36057_VSP);
+       reg = ((zr->jpg_settings.img_y + tvn->v_start) << ZR36057_FVAP_NAY) |
+             (zr->jpg_settings.img_height << ZR36057_FVAP_PAY);
+       btwrite(reg, ZR36057_FVAP);
+
+       /* horizontal */
+       if (zr->card.vfe_pol.hsync_pol)
+               btor(ZR36057_VFEHCR_HS_POL, ZR36057_VFEHCR);
+       else
+               btand(~ZR36057_VFEHCR_HS_POL, ZR36057_VFEHCR);
+       reg = ((tvn->h_sync_start) << ZR36057_HSP_HSYNC_START) |
+             (tvn->wt << ZR36057_HSP_LINE_TOT);
+       btwrite(reg, ZR36057_HSP);
+       reg = ((zr->jpg_settings.img_x +
+               tvn->h_start + 4) << ZR36057_FHAP_NAX) |
+             (zr->jpg_settings.img_width << ZR36057_FHAP_PAX);
+       btwrite(reg, ZR36057_FHAP);
+
+       /* field process parameters */
+       if (zr->jpg_settings.odd_even)
+               reg = ZR36057_FPP_ODD_EVEN;
+       else
+               reg = 0;
+
+       btwrite(reg, ZR36057_FPP);
+
+       /* Set proper VCLK Polarity, else colors will be wrong during playback */
+       //btor(ZR36057_VFESPFR_VCLK_POL, ZR36057_VFESPFR);
+
+       /* code base address */
+       btwrite(zr->p_sc, ZR36057_JCBA);
+
+       /* FIFO threshold (FIFO is 160. double words) */
+       /* NOTE: decimal values here */
+       switch (mode) {
+       case BUZ_MODE_STILL_COMPRESS:
+       case BUZ_MODE_MOTION_COMPRESS:
+               if (zr->card.type != BUZ)
+                       reg = 140;
+               else
+                       reg = 60;
+               break;
+
+       case BUZ_MODE_STILL_DECOMPRESS:
+       case BUZ_MODE_MOTION_DECOMPRESS:
+               reg = 20;
+               break;
+
+       default:
+               reg = 80;
+               break;
+       }
+       btwrite(reg, ZR36057_JCFT);
+       zr36057_adjust_vfe(zr, mode);
+}
+
+void clear_interrupt_counters(struct zoran *zr)
+{
+       zr->intr_counter_GIRQ1 = 0;
+       zr->intr_counter_GIRQ0 = 0;
+       zr->intr_counter_cod_rep_irq = 0;
+       zr->intr_counter_jpeg_rep_irq = 0;
+       zr->field_counter = 0;
+       zr->irq1_in = 0;
+       zr->irq1_out = 0;
+       zr->jpeg_in = 0;
+       zr->jpeg_out = 0;
+       zr->JPEG_0 = 0;
+       zr->JPEG_1 = 0;
+       zr->end_event_missed = 0;
+       zr->jpeg_missed = 0;
+       zr->jpeg_max_missed = 0;
+       zr->jpeg_min_missed = 0x7fffffff;
+}
+
+static u32 count_reset_interrupt(struct zoran *zr)
+{
+       u32 isr;
+
+       isr = btread(ZR36057_ISR) & 0x78000000;
+       if (isr) {
+               if (isr & ZR36057_ISR_GIRQ1) {
+                       btwrite(ZR36057_ISR_GIRQ1, ZR36057_ISR);
+                       zr->intr_counter_GIRQ1++;
+               }
+               if (isr & ZR36057_ISR_GIRQ0) {
+                       btwrite(ZR36057_ISR_GIRQ0, ZR36057_ISR);
+                       zr->intr_counter_GIRQ0++;
+               }
+               if (isr & ZR36057_ISR_COD_REP_IRQ) {
+                       btwrite(ZR36057_ISR_COD_REP_IRQ, ZR36057_ISR);
+                       zr->intr_counter_cod_rep_irq++;
+               }
+               if (isr & ZR36057_ISR_JPEG_REP_IRQ) {
+                       btwrite(ZR36057_ISR_JPEG_REP_IRQ, ZR36057_ISR);
+                       zr->intr_counter_jpeg_rep_irq++;
+               }
+       }
+       return isr;
+}
+
+void jpeg_start(struct zoran *zr)
+{
+       int reg;
+
+       zr->frame_num = 0;
+
+       /* deassert P_reset, disable code transfer, deassert Active */
+       btwrite(ZR36057_JPC_P_RESET, ZR36057_JPC);
+       /* stop flushing the internal code buffer */
+       btand(~ZR36057_MCTCR_C_FLUSH, ZR36057_MCTCR);
+       /* enable code transfer */
+       btor(ZR36057_JPC_COD_TRNS_EN, ZR36057_JPC);
+
+       /* clear IRQs */
+       btwrite(IRQ_MASK, ZR36057_ISR);
+       /* enable the JPEG IRQs */
+       btwrite(zr->card.jpeg_int | ZR36057_ICR_JPEG_REP_IRQ | ZR36057_ICR_INT_PIN_EN,
+               ZR36057_ICR);
+
+       set_frame(zr, 0);       // \FRAME
+
+       /* set the JPEG codec guest ID */
+       reg = (zr->card.gpcs[1] << ZR36057_JCGI_JPE_GUEST_ID) |
+              (0 << ZR36057_JCGI_JPE_GUEST_REG);
+       btwrite(reg, ZR36057_JCGI);
+
+       if (zr->card.video_vfe == CODEC_TYPE_ZR36016 &&
+           zr->card.video_codec == CODEC_TYPE_ZR36050) {
+               /* Enable processing on the ZR36016 */
+               if (zr->vfe)
+                       zr36016_write(zr->vfe, 0, 1);
+
+               /* load the address of the GO register in the ZR36050 latch */
+               post_office_write(zr, 0, 0, 0);
+       }
+
+       /* assert Active */
+       btor(ZR36057_JPC_ACTIVE, ZR36057_JPC);
+
+       /* enable the Go generation */
+       btor(ZR36057_JMC_GO_EN, ZR36057_JMC);
+       usleep_range(30, 100);
+
+       set_frame(zr, 1);       // /FRAME
+}
+
+void zr36057_enable_jpg(struct zoran *zr, enum zoran_codec_mode mode)
+{
+       struct vfe_settings cap;
+       int field_size = zr->buffer_size / zr->jpg_settings.field_per_buff;
+
+       zr->codec_mode = mode;
+
+       cap.x = zr->jpg_settings.img_x;
+       cap.y = zr->jpg_settings.img_y;
+       cap.width = zr->jpg_settings.img_width;
+       cap.height = zr->jpg_settings.img_height;
+       cap.decimation =
+           zr->jpg_settings.hor_dcm | (zr->jpg_settings.ver_dcm << 8);
+       cap.quality = zr->jpg_settings.jpg_comp.quality;
+
+       switch (mode) {
+       case BUZ_MODE_MOTION_COMPRESS: {
+               struct jpeg_app_marker app;
+               struct jpeg_com_marker com;
+
+               /* In motion compress mode, the decoder output must be enabled, and
+                * the video bus direction set to input.
+                */
+               set_videobus_dir(zr, 0);
+               decoder_call(zr, video, s_stream, 1);
+               encoder_call(zr, video, s_routing, 0, 0, 0);
+
+               /* Take the JPEG codec and the VFE out of sleep */
+               jpeg_codec_sleep(zr, 0);
+
+               /* set JPEG app/com marker */
+               app.appn = zr->jpg_settings.jpg_comp.APPn;
+               app.len = zr->jpg_settings.jpg_comp.APP_len;
+               memcpy(app.data, zr->jpg_settings.jpg_comp.APP_data, 60);
+               zr->codec->control(zr->codec, CODEC_S_JPEG_APP_DATA,
+                                  sizeof(struct jpeg_app_marker), &app);
+
+               com.len = zr->jpg_settings.jpg_comp.COM_len;
+               memcpy(com.data, zr->jpg_settings.jpg_comp.COM_data, 60);
+               zr->codec->control(zr->codec, CODEC_S_JPEG_COM_DATA,
+                                  sizeof(struct jpeg_com_marker), &com);
+
+               /* Setup the JPEG codec */
+               zr->codec->control(zr->codec, CODEC_S_JPEG_TDS_BYTE,
+                                  sizeof(int), &field_size);
+               zr->codec->set_video(zr->codec, zr->timing, &cap,
+                                    &zr->card.vfe_pol);
+               zr->codec->set_mode(zr->codec, CODEC_DO_COMPRESSION);
+
+               /* Setup the VFE */
+               if (zr->vfe) {
+                       zr->vfe->control(zr->vfe, CODEC_S_JPEG_TDS_BYTE,
+                                        sizeof(int), &field_size);
+                       zr->vfe->set_video(zr->vfe, zr->timing, &cap,
+                                          &zr->card.vfe_pol);
+                       zr->vfe->set_mode(zr->vfe, CODEC_DO_COMPRESSION);
+               }
+
+               init_jpeg_queue(zr);
+               zr36057_set_jpg(zr, mode);      // \P_Reset, ... Video param, FIFO
+
+               clear_interrupt_counters(zr);
+               pci_dbg(zr->pci_dev, "enable_jpg(MOTION_COMPRESS)\n");
+               break;
+       }
+
+       case BUZ_MODE_MOTION_DECOMPRESS:
+               /* In motion decompression mode, the decoder output must be disabled, and
+                * the video bus direction set to output.
+                */
+               decoder_call(zr, video, s_stream, 0);
+               set_videobus_dir(zr, 1);
+               encoder_call(zr, video, s_routing, 1, 0, 0);
+
+               /* Take the JPEG codec and the VFE out of sleep */
+               jpeg_codec_sleep(zr, 0);
+               /* Setup the VFE */
+               if (zr->vfe) {
+                       zr->vfe->set_video(zr->vfe, zr->timing, &cap,
+                                          &zr->card.vfe_pol);
+                       zr->vfe->set_mode(zr->vfe, CODEC_DO_EXPANSION);
+               }
+               /* Setup the JPEG codec */
+               zr->codec->set_video(zr->codec, zr->timing, &cap,
+                                    &zr->card.vfe_pol);
+               zr->codec->set_mode(zr->codec, CODEC_DO_EXPANSION);
+
+               init_jpeg_queue(zr);
+               zr36057_set_jpg(zr, mode);      // \P_Reset, ... Video param, FIFO
+
+               clear_interrupt_counters(zr);
+               pci_dbg(zr->pci_dev, "enable_jpg(MOTION_DECOMPRESS)\n");
+               break;
+
+       case BUZ_MODE_IDLE:
+       default:
+               /* shut down processing */
+               btand(~(zr->card.jpeg_int | ZR36057_ICR_JPEG_REP_IRQ),
+                     ZR36057_ICR);
+               btwrite(zr->card.jpeg_int | ZR36057_ICR_JPEG_REP_IRQ,
+                       ZR36057_ISR);
+               btand(~ZR36057_JMC_GO_EN, ZR36057_JMC); // \Go_en
+
+               msleep(50);
+
+               set_videobus_dir(zr, 0);
+               set_frame(zr, 1);       // /FRAME
+               btor(ZR36057_MCTCR_C_FLUSH, ZR36057_MCTCR);     // /CFlush
+               btwrite(0, ZR36057_JPC);        // \P_Reset,\CodTrnsEn,\Active
+               btand(~ZR36057_JMC_VFIFO_FB, ZR36057_JMC);
+               btand(~ZR36057_JMC_SYNC_MSTR, ZR36057_JMC);
+               jpeg_codec_reset(zr);
+               jpeg_codec_sleep(zr, 1);
+               zr36057_adjust_vfe(zr, mode);
+
+               decoder_call(zr, video, s_stream, 1);
+               encoder_call(zr, video, s_routing, 0, 0, 0);
+
+               pci_dbg(zr->pci_dev, "enable_jpg(IDLE)\n");
+               break;
+       }
+}
+
+/* when this is called the spinlock must be held */
+void zoran_feed_stat_com(struct zoran *zr)
+{
+       /* move frames from pending queue to DMA */
+
+       int i, max_stat_com;
+       struct zr_buffer *buf;
+       struct vb2_v4l2_buffer *vbuf;
+       dma_addr_t phys_addr = 0;
+       unsigned long flags;
+       unsigned long payload;
+
+       max_stat_com =
+           (zr->jpg_settings.tmp_dcm ==
+            1) ? BUZ_NUM_STAT_COM : (BUZ_NUM_STAT_COM >> 1);
+
+       spin_lock_irqsave(&zr->queued_bufs_lock, flags);
+       while ((zr->jpg_dma_head - zr->jpg_dma_tail) < max_stat_com) {
+               buf = list_first_entry_or_null(&zr->queued_bufs, struct zr_buffer, queue);
+               if (!buf) {
+                       pci_err(zr->pci_dev, "No buffer available to queue\n");
+                       spin_unlock_irqrestore(&zr->queued_bufs_lock, flags);
+                       return;
+               }
+               list_del(&buf->queue);
+               zr->buf_in_reserve--;
+               vbuf = &buf->vbuf;
+               vbuf->vb2_buf.state = VB2_BUF_STATE_ACTIVE;
+               phys_addr = vb2_dma_contig_plane_dma_addr(&vbuf->vb2_buf, 0);
+               payload = vb2_get_plane_payload(&vbuf->vb2_buf, 0);
+               if (payload == 0)
+                       payload = zr->buffer_size;
+               if (zr->jpg_settings.tmp_dcm == 1) {
+                       /* fill 1 stat_com entry */
+                       i = (zr->jpg_dma_head -
+                            zr->jpg_err_shift) & BUZ_MASK_STAT_COM;
+                       if (!(zr->stat_com[i] & cpu_to_le32(1)))
+                               break;
+                       zr->stat_comb[i * 2] = cpu_to_le32(phys_addr);
+                       zr->stat_comb[i * 2 + 1] = cpu_to_le32((payload >> 1) | 1);
+                       zr->inuse[i] = buf;
+                       zr->stat_com[i] = cpu_to_le32(zr->p_scb + i * 2 * 4);
+               } else {
+                       /* fill 2 stat_com entries */
+                       i = ((zr->jpg_dma_head -
+                             zr->jpg_err_shift) & 1) * 2;
+                       if (!(zr->stat_com[i] & cpu_to_le32(1)))
+                               break;
+                       zr->stat_com[i] = cpu_to_le32(zr->p_scb + i * 2 * 4);
+                       zr->stat_com[i + 1] = cpu_to_le32(zr->p_scb + i * 2 * 4);
+
+                       zr->stat_comb[i * 2] = cpu_to_le32(phys_addr);
+                       zr->stat_comb[i * 2 + 1] = cpu_to_le32((payload >> 1) | 1);
+
+                       zr->inuse[i] = buf;
+                       zr->inuse[i + 1] = NULL;
+               }
+               zr->jpg_dma_head++;
+       }
+       spin_unlock_irqrestore(&zr->queued_bufs_lock, flags);
+       if (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS)
+               zr->jpg_queued_num++;
+}
+
+/* when this is called the spinlock must be held */
+static void zoran_reap_stat_com(struct zoran *zr)
+{
+       /* move frames from DMA queue to done queue */
+
+       int i;
+       u32 stat_com;
+       unsigned int seq;
+       unsigned int dif;
+       unsigned long flags;
+       struct zr_buffer *buf;
+       unsigned int size = 0;
+       u32 fcnt;
+
+       /*
+        * In motion decompress we don't have a hardware frame counter,
+        * we just count the interrupts here
+        */
+
+       if (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS)
+               zr->jpg_seq_num++;
+
+       spin_lock_irqsave(&zr->queued_bufs_lock, flags);
+       while (zr->jpg_dma_tail < zr->jpg_dma_head) {
+               if (zr->jpg_settings.tmp_dcm == 1)
+                       i = (zr->jpg_dma_tail - zr->jpg_err_shift) & BUZ_MASK_STAT_COM;
+               else
+                       i = ((zr->jpg_dma_tail - zr->jpg_err_shift) & 1) * 2;
+
+               stat_com = le32_to_cpu(zr->stat_com[i]);
+               if ((stat_com & 1) == 0) {
+                       spin_unlock_irqrestore(&zr->queued_bufs_lock, flags);
+                       return;
+               }
+
+               fcnt = (stat_com & GENMASK(31, 24)) >> 24;
+               size = (stat_com & GENMASK(22, 1)) >> 1;
+
+               buf = zr->inuse[i];
+               if (!buf) {
+                       spin_unlock_irqrestore(&zr->queued_bufs_lock, flags);
+                       pci_err(zr->pci_dev, "No buffer at slot %d\n", i);
+                       return;
+               }
+               buf->vbuf.vb2_buf.timestamp = ktime_get_ns();
+
+               if (zr->codec_mode == BUZ_MODE_MOTION_COMPRESS) {
+                       vb2_set_plane_payload(&buf->vbuf.vb2_buf, 0, size);
+
+                       /* update sequence number with the help of the counter in stat_com */
+                       seq = (fcnt + zr->jpg_err_seq) & 0xff;
+                       dif = (seq - zr->jpg_seq_num) & 0xff;
+                       zr->jpg_seq_num += dif;
+               }
+               buf->vbuf.sequence = zr->jpg_settings.tmp_dcm ==
+                   2 ? (zr->jpg_seq_num >> 1) : zr->jpg_seq_num;
+               zr->inuse[i] = NULL;
+               if (zr->jpg_settings.tmp_dcm != 1)
+                       buf->vbuf.field = zr->jpg_settings.odd_even ?
+                               V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM;
+               else
+                       buf->vbuf.field = zr->jpg_settings.odd_even ?
+                               V4L2_FIELD_SEQ_TB : V4L2_FIELD_SEQ_BT;
+               vb2_buffer_done(&buf->vbuf.vb2_buf, VB2_BUF_STATE_DONE);
+
+               zr->jpg_dma_tail++;
+       }
+       spin_unlock_irqrestore(&zr->queued_bufs_lock, flags);
+}
+
+irqreturn_t zoran_irq(int irq, void *dev_id)
+{
+       struct zoran *zr = dev_id;
+       u32 stat, astat;
+
+       stat = count_reset_interrupt(zr);
+       astat = stat & IRQ_MASK;
+       if (astat & zr->card.vsync_int) {
+               if (zr->running == ZORAN_MAP_MODE_RAW) {
+                       if ((btread(ZR36057_VSSFGR) & ZR36057_VSSFGR_SNAP_SHOT) == 0)
+                               pci_warn(zr->pci_dev, "BuzIRQ with SnapShot off ???\n");
+                       if ((btread(ZR36057_VSSFGR) & ZR36057_VSSFGR_FRAME_GRAB) == 0)
+                               zr_set_buf(zr);
+                       return IRQ_HANDLED;
+               }
+               if (astat & ZR36057_ISR_JPEG_REP_IRQ) {
+                       if (zr->codec_mode != BUZ_MODE_MOTION_DECOMPRESS &&
+                           zr->codec_mode != BUZ_MODE_MOTION_COMPRESS) {
+                               pci_err(zr->pci_dev, "JPG IRQ when not in good mode\n");
+                               return IRQ_HANDLED;
+                       }
+                       zr->frame_num++;
+                       zoran_reap_stat_com(zr);
+                       zoran_feed_stat_com(zr);
+                       return IRQ_HANDLED;
+               }
+               /* unused interrupts */
+       }
+       zr->ghost_int++;
+       return IRQ_HANDLED;
+}
+
+void zoran_set_pci_master(struct zoran *zr, int set_master)
+{
+       if (set_master) {
+               pci_set_master(zr->pci_dev);
+       } else {
+               u16 command;
+
+               pci_read_config_word(zr->pci_dev, PCI_COMMAND, &command);
+               command &= ~PCI_COMMAND_MASTER;
+               pci_write_config_word(zr->pci_dev, PCI_COMMAND, command);
+       }
+}
+
+void zoran_init_hardware(struct zoran *zr)
+{
+       /* Enable bus-mastering */
+       zoran_set_pci_master(zr, 1);
+
+       /* Initialize the board */
+       if (zr->card.init)
+               zr->card.init(zr);
+
+       decoder_call(zr, core, init, 0);
+       decoder_call(zr, video, s_std, zr->norm);
+       decoder_call(zr, video, s_routing,
+                    zr->card.input[zr->input].muxsel, 0, 0);
+
+       encoder_call(zr, core, init, 0);
+       encoder_call(zr, video, s_std_output, zr->norm);
+       encoder_call(zr, video, s_routing, 0, 0, 0);
+
+       /* toggle JPEG codec sleep to sync PLL */
+       jpeg_codec_sleep(zr, 1);
+       jpeg_codec_sleep(zr, 0);
+
+       /*
+        * set individual interrupt enables (without GIRQ1)
+        * but don't global enable until zoran_open()
+        */
+       zr36057_init_vfe(zr);
+
+       zr36057_enable_jpg(zr, BUZ_MODE_IDLE);
+
+       btwrite(IRQ_MASK, ZR36057_ISR); // Clears interrupts
+}
+
+void zr36057_restart(struct zoran *zr)
+{
+       btwrite(0, ZR36057_SPGPPCR);
+       usleep_range(1000, 2000);
+       btor(ZR36057_SPGPPCR_SOFT_RESET, ZR36057_SPGPPCR);
+       usleep_range(1000, 2000);
+
+       /* assert P_Reset */
+       btwrite(0, ZR36057_JPC);
+       /* set up GPIO direction - all output */
+       btwrite(ZR36057_SPGPPCR_SOFT_RESET | 0, ZR36057_SPGPPCR);
+
+       /* set up GPIO pins and guest bus timing */
+       btwrite((0x81 << 24) | 0x8888, ZR36057_GPPGCR1);
+}
+
 
--- /dev/null
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Zoran zr36057/zr36067 PCI controller driver, for the
+ * Pinnacle/Miro DC10/DC10+/DC30/DC30+, Iomega Buz, Linux
+ * Media Labs LML33/LML33R10.
+ *
+ * This part handles card-specific data and detection
+ *
+ * Copyright (C) 2000 Serguei Miridonov <mirsev@cicese.mx>
+ */
+
+#ifndef __ZORAN_DEVICE_H__
+#define __ZORAN_DEVICE_H__
+
+/* general purpose I/O */
+void GPIO(struct zoran *zr, int bit, unsigned int value);
+
+/* codec (or actually: guest bus) access */
+int post_office_wait(struct zoran *zr);
+int post_office_write(struct zoran *zr, unsigned int guest, unsigned int reg,
+                     unsigned int value);
+int post_office_read(struct zoran *zr, unsigned int guest, unsigned int reg);
+
+void jpeg_codec_sleep(struct zoran *zr, int sleep);
+int jpeg_codec_reset(struct zoran *zr);
+
+/* zr360x7 access to raw capture */
+void zr36057_overlay(struct zoran *zr, int on);
+void write_overlay_mask(struct zoran_fh *fh, struct v4l2_clip *vp, int count);
+void zr36057_set_memgrab(struct zoran *zr, int mode);
+int wait_grab_pending(struct zoran *zr);
+
+/* interrupts */
+void print_interrupts(struct zoran *zr);
+void clear_interrupt_counters(struct zoran *zr);
+irqreturn_t zoran_irq(int irq, void *dev_id);
+
+/* JPEG codec access */
+void jpeg_start(struct zoran *zr);
+void zr36057_enable_jpg(struct zoran *zr, enum zoran_codec_mode mode);
+void zoran_feed_stat_com(struct zoran *zr);
+
+/* general */
+void zoran_set_pci_master(struct zoran *zr, int set_master);
+void zoran_init_hardware(struct zoran *zr);
+void zr36057_restart(struct zoran *zr);
+
+extern const struct zoran_format zoran_formats[];
+
+extern int v4l_bufsize;
+extern int jpg_bufsize;
+extern int pass_through;
+
+/* i2c */
+#define decoder_call(zr, o, f, args...) \
+       v4l2_subdev_call((zr)->decoder, o, f, ##args)
+#define encoder_call(zr, o, f, args...) \
+       v4l2_subdev_call((zr)->encoder, o, f, ##args)
+
+#endif                         /* __ZORAN_DEVICE_H__ */
 
--- /dev/null
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Zoran zr36057/zr36067 PCI controller driver, for the
+ * Pinnacle/Miro DC10/DC10+/DC30/DC30+, Iomega Buz, Linux
+ * Media Labs LML33/LML33R10.
+ *
+ * Copyright (C) 2000 Serguei Miridonov <mirsev@cicese.mx>
+ *
+ * Changes for BUZ by Wolfgang Scherr <scherr@net4you.net>
+ *
+ * Changes for DC10/DC30 by Laurent Pinchart <laurent.pinchart@skynet.be>
+ *
+ * Changes for LML33R10 by Maxim Yevtyushkin <max@linuxmedialabs.com>
+ *
+ * Changes for videodev2/v4l2 by Ronald Bultje <rbultje@ronald.bitfreak.net>
+ *
+ * Based on
+ *
+ * Miro DC10 driver
+ * Copyright (C) 1999 Wolfgang Scherr <scherr@net4you.net>
+ *
+ * Iomega Buz driver version 1.0
+ * Copyright (C) 1999 Rainer Johanni <Rainer@Johanni.de>
+ *
+ * buz.0.0.3
+ * Copyright (C) 1998 Dave Perks <dperks@ibm.net>
+ *
+ * bttv - Bt848 frame grabber driver
+ * Copyright (C) 1996,97,98 Ralph  Metzler (rjkm@thp.uni-koeln.de)
+ *                        & Marcus Metzler (mocm@thp.uni-koeln.de)
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/pci.h>
+#include <linux/wait.h>
+
+#include <linux/interrupt.h>
+#include <linux/i2c.h>
+#include <linux/i2c-algo-bit.h>
+
+#include <linux/spinlock.h>
+
+#include <linux/videodev2.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-event.h>
+#include "videocodec.h"
+
+#include <linux/io.h>
+#include <linux/uaccess.h>
+
+#include <linux/mutex.h>
+#include "zoran.h"
+#include "zoran_device.h"
+#include "zoran_card.h"
+
+const struct zoran_format zoran_formats[] = {
+       {
+               .name = "15-bit RGB LE",
+               .fourcc = V4L2_PIX_FMT_RGB555,
+               .colorspace = V4L2_COLORSPACE_SRGB,
+               .depth = 15,
+               .flags = ZORAN_FORMAT_CAPTURE,
+               .vfespfr = ZR36057_VFESPFR_RGB555 | ZR36057_VFESPFR_ERR_DIF |
+                          ZR36057_VFESPFR_LITTLE_ENDIAN,
+       }, {
+               .name = "15-bit RGB BE",
+               .fourcc = V4L2_PIX_FMT_RGB555X,
+               .colorspace = V4L2_COLORSPACE_SRGB,
+               .depth = 15,
+               .flags = ZORAN_FORMAT_CAPTURE,
+               .vfespfr = ZR36057_VFESPFR_RGB555 | ZR36057_VFESPFR_ERR_DIF,
+       }, {
+               .name = "16-bit RGB LE",
+               .fourcc = V4L2_PIX_FMT_RGB565,
+               .colorspace = V4L2_COLORSPACE_SRGB,
+               .depth = 16,
+               .flags = ZORAN_FORMAT_CAPTURE,
+               .vfespfr = ZR36057_VFESPFR_RGB565 | ZR36057_VFESPFR_ERR_DIF |
+                          ZR36057_VFESPFR_LITTLE_ENDIAN,
+       }, {
+               .name = "16-bit RGB BE",
+               .fourcc = V4L2_PIX_FMT_RGB565X,
+               .colorspace = V4L2_COLORSPACE_SRGB,
+               .depth = 16,
+               .flags = ZORAN_FORMAT_CAPTURE,
+               .vfespfr = ZR36057_VFESPFR_RGB565 | ZR36057_VFESPFR_ERR_DIF,
+       }, {
+               .name = "24-bit RGB",
+               .fourcc = V4L2_PIX_FMT_BGR24,
+               .colorspace = V4L2_COLORSPACE_SRGB,
+               .depth = 24,
+               .flags = ZORAN_FORMAT_CAPTURE,
+               .vfespfr = ZR36057_VFESPFR_RGB888 | ZR36057_VFESPFR_PACK24,
+       }, {
+               .name = "32-bit RGB LE",
+               .fourcc = V4L2_PIX_FMT_BGR32,
+               .colorspace = V4L2_COLORSPACE_SRGB,
+               .depth = 32,
+               .flags = ZORAN_FORMAT_CAPTURE,
+               .vfespfr = ZR36057_VFESPFR_RGB888 | ZR36057_VFESPFR_LITTLE_ENDIAN,
+       }, {
+               .name = "32-bit RGB BE",
+               .fourcc = V4L2_PIX_FMT_RGB32,
+               .colorspace = V4L2_COLORSPACE_SRGB,
+               .depth = 32,
+               .flags = ZORAN_FORMAT_CAPTURE,
+               .vfespfr = ZR36057_VFESPFR_RGB888,
+       }, {
+               .name = "4:2:2, packed, YUYV",
+               .fourcc = V4L2_PIX_FMT_YUYV,
+               .colorspace = V4L2_COLORSPACE_SMPTE170M,
+               .depth = 16,
+               .flags = ZORAN_FORMAT_CAPTURE,
+               .vfespfr = ZR36057_VFESPFR_YUV422,
+       }, {
+               .name = "4:2:2, packed, UYVY",
+               .fourcc = V4L2_PIX_FMT_UYVY,
+               .colorspace = V4L2_COLORSPACE_SMPTE170M,
+               .depth = 16,
+               .flags = ZORAN_FORMAT_CAPTURE,
+               .vfespfr = ZR36057_VFESPFR_YUV422 | ZR36057_VFESPFR_LITTLE_ENDIAN,
+       }, {
+               .name = "Hardware-encoded Motion-JPEG",
+               .fourcc = V4L2_PIX_FMT_MJPEG,
+               .colorspace = V4L2_COLORSPACE_SMPTE170M,
+               .depth = 0,
+               .flags = ZORAN_FORMAT_CAPTURE |
+                        ZORAN_FORMAT_PLAYBACK |
+                        ZORAN_FORMAT_COMPRESSED,
+       }
+};
+
+#define NUM_FORMATS ARRAY_SIZE(zoran_formats)
+
+       /*
+        * small helper function for calculating buffersizes for v4l2
+        * we calculate the nearest higher power-of-two, which
+        * will be the recommended buffersize
+        */
+static __u32 zoran_v4l2_calc_bufsize(struct zoran_jpg_settings *settings)
+{
+       __u8 div = settings->ver_dcm * settings->hor_dcm * settings->tmp_dcm;
+       __u32 num = (1024 * 512) / (div);
+       __u32 result = 2;
+
+       num--;
+       while (num) {
+               num >>= 1;
+               result <<= 1;
+       }
+
+       if (result < 8192)
+               return 8192;
+
+       return result;
+}
+
+/*
+ *   V4L Buffer grabbing
+ */
+static int zoran_v4l_set_format(struct zoran *zr, int width, int height,
+                               const struct zoran_format *format)
+{
+       int bpp;
+
+       /* Check size and format of the grab wanted */
+
+       if (height < BUZ_MIN_HEIGHT || width < BUZ_MIN_WIDTH ||
+           height > BUZ_MAX_HEIGHT || width > BUZ_MAX_WIDTH) {
+               pci_dbg(zr->pci_dev, "%s - wrong frame size (%dx%d)\n", __func__, width, height);
+               return -EINVAL;
+       }
+
+       bpp = (format->depth + 7) / 8;
+
+       zr->buffer_size = height * width * bpp;
+
+       /* Check against available buffer size */
+       if (height * width * bpp > zr->buffer_size) {
+               pci_dbg(zr->pci_dev, "%s - video buffer size (%d kB) is too small\n",
+                       __func__, zr->buffer_size >> 10);
+               return -EINVAL;
+       }
+
+       /* The video front end needs 4-byte alinged line sizes */
+
+       if ((bpp == 2 && (width & 1)) || (bpp == 3 && (width & 3))) {
+               pci_dbg(zr->pci_dev, "%s - wrong frame alignment\n", __func__);
+               return -EINVAL;
+       }
+
+       zr->v4l_settings.width = width;
+       zr->v4l_settings.height = height;
+       zr->v4l_settings.format = format;
+       zr->v4l_settings.bytesperline = bpp * zr->v4l_settings.width;
+
+       return 0;
+}
+
+static int zoran_set_norm(struct zoran *zr, v4l2_std_id norm)
+{
+       if (!(norm & zr->card.norms)) {
+               pci_dbg(zr->pci_dev, "%s - unsupported norm %llx\n", __func__, norm);
+               return -EINVAL;
+       }
+
+       if (norm & V4L2_STD_SECAM)
+               zr->timing = zr->card.tvn[ZR_NORM_SECAM];
+       else if (norm & V4L2_STD_NTSC)
+               zr->timing = zr->card.tvn[ZR_NORM_NTSC];
+       else
+               zr->timing = zr->card.tvn[ZR_NORM_PAL];
+
+       decoder_call(zr, video, s_std, norm);
+       encoder_call(zr, video, s_std_output, norm);
+
+       /* Make sure the changes come into effect */
+       zr->norm = norm;
+
+       return 0;
+}
+
+static int zoran_set_input(struct zoran *zr, int input)
+{
+       if (input == zr->input)
+               return 0;
+
+       if (input < 0 || input >= zr->card.inputs) {
+               pci_dbg(zr->pci_dev, "%s - unsupported input %d\n", __func__, input);
+               return -EINVAL;
+       }
+
+       zr->input = input;
+
+       decoder_call(zr, video, s_routing, zr->card.input[input].muxsel, 0, 0);
+
+       return 0;
+}
+
+/*
+ *   ioctl routine
+ */
+
+static int zoran_querycap(struct file *file, void *__fh, struct v4l2_capability *cap)
+{
+       struct zoran *zr = video_drvdata(file);
+
+       strscpy(cap->card, ZR_DEVNAME(zr), sizeof(cap->card));
+       strscpy(cap->driver, "zoran", sizeof(cap->driver));
+       snprintf(cap->bus_info, sizeof(cap->bus_info), "PCI:%s", pci_name(zr->pci_dev));
+       return 0;
+}
+
+static int zoran_enum_fmt(struct zoran *zr, struct v4l2_fmtdesc *fmt, int flag)
+{
+       unsigned int num, i;
+
+       if (fmt->index >= ARRAY_SIZE(zoran_formats))
+               return -EINVAL;
+       if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+               return -EINVAL;
+
+       for (num = i = 0; i < NUM_FORMATS; i++) {
+               if (zoran_formats[i].flags & flag && num++ == fmt->index) {
+                       strscpy(fmt->description, zoran_formats[i].name,
+                               sizeof(fmt->description));
+                       /* fmt struct pre-zeroed, so adding '\0' not needed */
+                       fmt->pixelformat = zoran_formats[i].fourcc;
+                       if (zoran_formats[i].flags & ZORAN_FORMAT_COMPRESSED)
+                               fmt->flags |= V4L2_FMT_FLAG_COMPRESSED;
+                       return 0;
+               }
+       }
+       return -EINVAL;
+}
+
+static int zoran_enum_fmt_vid_cap(struct file *file, void *__fh,
+                                 struct v4l2_fmtdesc *f)
+{
+       struct zoran *zr = video_drvdata(file);
+
+       return zoran_enum_fmt(zr, f, ZORAN_FORMAT_CAPTURE);
+}
+
+static int zoran_g_fmt_vid_out(struct file *file, void *__fh,
+                              struct v4l2_format *fmt)
+{
+       struct zoran *zr = video_drvdata(file);
+
+       fmt->fmt.pix.width = zr->jpg_settings.img_width / zr->jpg_settings.hor_dcm;
+       fmt->fmt.pix.height = zr->jpg_settings.img_height * 2 /
+               (zr->jpg_settings.ver_dcm * zr->jpg_settings.tmp_dcm);
+       fmt->fmt.pix.sizeimage = zr->buffer_size;
+       fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_MJPEG;
+       if (zr->jpg_settings.tmp_dcm == 1)
+               fmt->fmt.pix.field = (zr->jpg_settings.odd_even ?
+                               V4L2_FIELD_SEQ_TB : V4L2_FIELD_SEQ_BT);
+       else
+               fmt->fmt.pix.field = (zr->jpg_settings.odd_even ?
+                               V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM);
+       fmt->fmt.pix.bytesperline = 0;
+       fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
+
+       return 0;
+}
+
+static int zoran_g_fmt_vid_cap(struct file *file, void *__fh,
+                              struct v4l2_format *fmt)
+{
+       struct zoran *zr = video_drvdata(file);
+
+       if (zr->map_mode != ZORAN_MAP_MODE_RAW)
+               return zoran_g_fmt_vid_out(file, __fh, fmt);
+       fmt->fmt.pix.width = zr->v4l_settings.width;
+       fmt->fmt.pix.height = zr->v4l_settings.height;
+       fmt->fmt.pix.sizeimage = zr->buffer_size;
+       fmt->fmt.pix.pixelformat = zr->v4l_settings.format->fourcc;
+       fmt->fmt.pix.colorspace = zr->v4l_settings.format->colorspace;
+       fmt->fmt.pix.bytesperline = zr->v4l_settings.bytesperline;
+       if (BUZ_MAX_HEIGHT < (zr->v4l_settings.height * 2))
+               fmt->fmt.pix.field = V4L2_FIELD_INTERLACED;
+       else
+               fmt->fmt.pix.field = V4L2_FIELD_TOP;
+       return 0;
+}
+
+static int zoran_try_fmt_vid_out(struct file *file, void *__fh,
+                                struct v4l2_format *fmt)
+{
+       struct zoran *zr = video_drvdata(file);
+       struct zoran_jpg_settings settings;
+       int res = 0;
+
+       if (fmt->fmt.pix.pixelformat != V4L2_PIX_FMT_MJPEG)
+               return -EINVAL;
+
+       settings = zr->jpg_settings;
+
+       /* we actually need to set 'real' parameters now */
+       if ((fmt->fmt.pix.height * 2) > BUZ_MAX_HEIGHT)
+               settings.tmp_dcm = 1;
+       else
+               settings.tmp_dcm = 2;
+       settings.decimation = 0;
+       if (fmt->fmt.pix.height <= zr->jpg_settings.img_height / 2)
+               settings.ver_dcm = 2;
+       else
+               settings.ver_dcm = 1;
+       if (fmt->fmt.pix.width <= zr->jpg_settings.img_width / 4)
+               settings.hor_dcm = 4;
+       else if (fmt->fmt.pix.width <= zr->jpg_settings.img_width / 2)
+               settings.hor_dcm = 2;
+       else
+               settings.hor_dcm = 1;
+       if (settings.tmp_dcm == 1)
+               settings.field_per_buff = 2;
+       else
+               settings.field_per_buff = 1;
+
+       if (settings.hor_dcm > 1) {
+               settings.img_x = (BUZ_MAX_WIDTH == 720) ? 8 : 0;
+               settings.img_width = (BUZ_MAX_WIDTH == 720) ? 704 : BUZ_MAX_WIDTH;
+       } else {
+               settings.img_x = 0;
+               settings.img_width = BUZ_MAX_WIDTH;
+       }
+
+       /* check */
+       res = zoran_check_jpg_settings(zr, &settings, 1);
+       if (res)
+               return res;
+
+       /* tell the user what we actually did */
+       fmt->fmt.pix.width = settings.img_width / settings.hor_dcm;
+       fmt->fmt.pix.height = settings.img_height * 2 /
+               (settings.tmp_dcm * settings.ver_dcm);
+       if (settings.tmp_dcm == 1)
+               fmt->fmt.pix.field = (zr->jpg_settings.odd_even ?
+                               V4L2_FIELD_SEQ_TB : V4L2_FIELD_SEQ_BT);
+       else
+               fmt->fmt.pix.field = (zr->jpg_settings.odd_even ?
+                               V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM);
+
+       fmt->fmt.pix.sizeimage = zoran_v4l2_calc_bufsize(&settings);
+       fmt->fmt.pix.bytesperline = 0;
+       fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
+       return res;
+}
+
+static int zoran_try_fmt_vid_cap(struct file *file, void *__fh,
+                                struct v4l2_format *fmt)
+{
+       struct zoran *zr = video_drvdata(file);
+       int bpp;
+       int i;
+
+       if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG)
+               return zoran_try_fmt_vid_out(file, __fh, fmt);
+
+       for (i = 0; i < NUM_FORMATS; i++)
+               if (zoran_formats[i].fourcc == fmt->fmt.pix.pixelformat)
+                       break;
+
+       if (i == NUM_FORMATS) {
+               /* TODO do not return here to fix the TRY_FMT cannot handle an invalid pixelformat*/
+               return -EINVAL;
+       }
+
+       fmt->fmt.pix.pixelformat = zoran_formats[i].fourcc;
+       fmt->fmt.pix.colorspace = zoran_formats[i].colorspace;
+       if (BUZ_MAX_HEIGHT < (fmt->fmt.pix.height * 2))
+               fmt->fmt.pix.field = V4L2_FIELD_INTERLACED;
+       else
+               fmt->fmt.pix.field = V4L2_FIELD_TOP;
+
+       bpp = DIV_ROUND_UP(zoran_formats[i].depth, 8);
+       v4l_bound_align_image(&fmt->fmt.pix.width, BUZ_MIN_WIDTH, BUZ_MAX_WIDTH,
+                             bpp == 2 ? 1 : 2,
+                             &fmt->fmt.pix.height, BUZ_MIN_HEIGHT, BUZ_MAX_HEIGHT,
+                             0, 0);
+       fmt->fmt.pix.bytesperline = fmt->fmt.pix.width * bpp;
+       fmt->fmt.pix.sizeimage = fmt->fmt.pix.bytesperline * fmt->fmt.pix.height;
+       return 0;
+}
+
+static int zoran_s_fmt_vid_out(struct file *file, void *__fh,
+                              struct v4l2_format *fmt)
+{
+       struct zoran *zr = video_drvdata(file);
+       __le32 printformat = __cpu_to_le32(fmt->fmt.pix.pixelformat);
+       struct zoran_jpg_settings settings;
+       int res = 0;
+
+       pci_dbg(zr->pci_dev, "size=%dx%d, fmt=0x%x (%4.4s)\n",
+               fmt->fmt.pix.width, fmt->fmt.pix.height,
+                       fmt->fmt.pix.pixelformat,
+                       (char *)&printformat);
+       if (fmt->fmt.pix.pixelformat != V4L2_PIX_FMT_MJPEG)
+               return -EINVAL;
+
+       if (!fmt->fmt.pix.height || !fmt->fmt.pix.width)
+               return -EINVAL;
+
+       settings = zr->jpg_settings;
+
+       /* we actually need to set 'real' parameters now */
+       if (fmt->fmt.pix.height * 2 > BUZ_MAX_HEIGHT)
+               settings.tmp_dcm = 1;
+       else
+               settings.tmp_dcm = 2;
+       settings.decimation = 0;
+       if (fmt->fmt.pix.height <= zr->jpg_settings.img_height / 2)
+               settings.ver_dcm = 2;
+       else
+               settings.ver_dcm = 1;
+       if (fmt->fmt.pix.width <= zr->jpg_settings.img_width / 4)
+               settings.hor_dcm = 4;
+       else if (fmt->fmt.pix.width <= zr->jpg_settings.img_width / 2)
+               settings.hor_dcm = 2;
+       else
+               settings.hor_dcm = 1;
+       if (settings.tmp_dcm == 1)
+               settings.field_per_buff = 2;
+       else
+               settings.field_per_buff = 1;
+
+       if (settings.hor_dcm > 1) {
+               settings.img_x = (BUZ_MAX_WIDTH == 720) ? 8 : 0;
+               settings.img_width = (BUZ_MAX_WIDTH == 720) ? 704 : BUZ_MAX_WIDTH;
+       } else {
+               settings.img_x = 0;
+               settings.img_width = BUZ_MAX_WIDTH;
+       }
+
+       /* check */
+       res = zoran_check_jpg_settings(zr, &settings, 0);
+       if (res)
+               return res;
+
+       /* it's ok, so set them */
+       zr->jpg_settings = settings;
+
+       if (fmt->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
+               zr->map_mode = ZORAN_MAP_MODE_JPG_REC;
+       else
+               zr->map_mode = ZORAN_MAP_MODE_JPG_PLAY;
+
+       zr->buffer_size = zoran_v4l2_calc_bufsize(&zr->jpg_settings);
+
+       /* tell the user what we actually did */
+       fmt->fmt.pix.width = settings.img_width / settings.hor_dcm;
+       fmt->fmt.pix.height = settings.img_height * 2 /
+               (settings.tmp_dcm * settings.ver_dcm);
+       if (settings.tmp_dcm == 1)
+               fmt->fmt.pix.field = (zr->jpg_settings.odd_even ?
+                               V4L2_FIELD_SEQ_TB : V4L2_FIELD_SEQ_BT);
+       else
+               fmt->fmt.pix.field = (zr->jpg_settings.odd_even ?
+                               V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM);
+       fmt->fmt.pix.bytesperline = 0;
+       fmt->fmt.pix.sizeimage = zr->buffer_size;
+       fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
+       return res;
+}
+
+static int zoran_s_fmt_vid_cap(struct file *file, void *__fh,
+                              struct v4l2_format *fmt)
+{
+       struct zoran *zr = video_drvdata(file);
+       struct zoran_fh *fh = __fh;
+       int i;
+       int res = 0;
+
+       if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG)
+               return zoran_s_fmt_vid_out(file, fh, fmt);
+
+       for (i = 0; i < NUM_FORMATS; i++)
+               if (fmt->fmt.pix.pixelformat == zoran_formats[i].fourcc)
+                       break;
+       if (i == NUM_FORMATS) {
+               pci_dbg(zr->pci_dev, "VIDIOC_S_FMT - unknown/unsupported format 0x%x\n",
+                       fmt->fmt.pix.pixelformat);
+               /* TODO do not return here to fix the TRY_FMT cannot handle an invalid pixelformat*/
+               return -EINVAL;
+       }
+
+       fmt->fmt.pix.pixelformat = zoran_formats[i].fourcc;
+       if (fmt->fmt.pix.height > BUZ_MAX_HEIGHT)
+               fmt->fmt.pix.height = BUZ_MAX_HEIGHT;
+       if (fmt->fmt.pix.width > BUZ_MAX_WIDTH)
+               fmt->fmt.pix.width = BUZ_MAX_WIDTH;
+       if (fmt->fmt.pix.height < BUZ_MIN_HEIGHT)
+               fmt->fmt.pix.height = BUZ_MIN_HEIGHT;
+       if (fmt->fmt.pix.width < BUZ_MIN_WIDTH)
+               fmt->fmt.pix.width = BUZ_MIN_WIDTH;
+
+       zr->map_mode = ZORAN_MAP_MODE_RAW;
+
+       res = zoran_v4l_set_format(zr, fmt->fmt.pix.width, fmt->fmt.pix.height,
+                                  &zoran_formats[i]);
+       if (res)
+               return res;
+
+       /* tell the user the results/missing stuff */
+       fmt->fmt.pix.bytesperline = zr->v4l_settings.bytesperline;
+       fmt->fmt.pix.sizeimage = zr->buffer_size;
+       fmt->fmt.pix.colorspace = zr->v4l_settings.format->colorspace;
+       if (BUZ_MAX_HEIGHT < (zr->v4l_settings.height * 2))
+               fmt->fmt.pix.field = V4L2_FIELD_INTERLACED;
+       else
+               fmt->fmt.pix.field = V4L2_FIELD_TOP;
+       return res;
+}
+
+static int zoran_g_std(struct file *file, void *__fh, v4l2_std_id *std)
+{
+       struct zoran *zr = video_drvdata(file);
+
+       *std = zr->norm;
+       return 0;
+}
+
+static int zoran_s_std(struct file *file, void *__fh, v4l2_std_id std)
+{
+       struct zoran *zr = video_drvdata(file);
+       int res = 0;
+
+       if (zr->norm == std)
+               return 0;
+
+       if (zr->running != ZORAN_MAP_MODE_NONE)
+               return -EBUSY;
+
+       res = zoran_set_norm(zr, std);
+       return res;
+}
+
+static int zoran_enum_input(struct file *file, void *__fh,
+                           struct v4l2_input *inp)
+{
+       struct zoran *zr = video_drvdata(file);
+
+       if (inp->index >= zr->card.inputs)
+               return -EINVAL;
+
+       strscpy(inp->name, zr->card.input[inp->index].name, sizeof(inp->name));
+       inp->type = V4L2_INPUT_TYPE_CAMERA;
+       inp->std = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM;
+
+       /* Get status of video decoder */
+       decoder_call(zr, video, g_input_status, &inp->status);
+       return 0;
+}
+
+static int zoran_g_input(struct file *file, void *__fh, unsigned int *input)
+{
+       struct zoran *zr = video_drvdata(file);
+
+       *input = zr->input;
+
+       return 0;
+}
+
+static int zoran_s_input(struct file *file, void *__fh, unsigned int input)
+{
+       struct zoran *zr = video_drvdata(file);
+       int res;
+
+       if (zr->running != ZORAN_MAP_MODE_NONE)
+               return -EBUSY;
+
+       res = zoran_set_input(zr, input);
+       return res;
+}
+
+/* cropping (sub-frame capture) */
+static int zoran_g_selection(struct file *file, void *__fh, struct v4l2_selection *sel)
+{
+       struct zoran *zr = video_drvdata(file);
+
+       if (sel->type != V4L2_BUF_TYPE_VIDEO_OUTPUT &&
+           sel->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+               pci_dbg(zr->pci_dev, "%s invalid selection type combination\n", __func__);
+               return -EINVAL;
+       }
+
+       switch (sel->target) {
+       case V4L2_SEL_TGT_CROP:
+               sel->r.top = zr->jpg_settings.img_y;
+               sel->r.left = zr->jpg_settings.img_x;
+               sel->r.width = zr->jpg_settings.img_width;
+               sel->r.height = zr->jpg_settings.img_height;
+               break;
+       case V4L2_SEL_TGT_CROP_DEFAULT:
+               sel->r.top = 0;
+               sel->r.left = 0;
+               sel->r.width = BUZ_MIN_WIDTH;
+               sel->r.height = BUZ_MIN_HEIGHT;
+               break;
+       case V4L2_SEL_TGT_CROP_BOUNDS:
+               sel->r.top = 0;
+               sel->r.left = 0;
+               sel->r.width = BUZ_MAX_WIDTH;
+               sel->r.height = BUZ_MAX_HEIGHT;
+               break;
+       default:
+               return -EINVAL;
+       }
+       return 0;
+}
+
+static int zoran_s_selection(struct file *file, void *__fh, struct v4l2_selection *sel)
+{
+       struct zoran *zr = video_drvdata(file);
+       struct zoran_jpg_settings settings;
+       int res;
+
+       if (sel->type != V4L2_BUF_TYPE_VIDEO_OUTPUT &&
+           sel->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+               return -EINVAL;
+
+       if (!sel->r.width || !sel->r.height)
+               return -EINVAL;
+
+       if (sel->target != V4L2_SEL_TGT_CROP)
+               return -EINVAL;
+
+       if (zr->map_mode == ZORAN_MAP_MODE_RAW) {
+               pci_dbg(zr->pci_dev, "VIDIOC_S_SELECTION - subcapture only supported for compressed capture\n");
+               return -EINVAL;
+       }
+
+       settings = zr->jpg_settings;
+
+       /* move into a form that we understand */
+       settings.img_x = sel->r.left;
+       settings.img_y = sel->r.top;
+       settings.img_width = sel->r.width;
+       settings.img_height = sel->r.height;
+
+       /* check validity */
+       res = zoran_check_jpg_settings(zr, &settings, 0);
+       if (res)
+               return res;
+
+       /* accept */
+       zr->jpg_settings = settings;
+       return res;
+}
+
+/*
+ * Output is disabled temporarily
+ * Zoran is picky about jpeg data it accepts. At least it seems to unsupport COM and APPn.
+ * So until a way to filter data will be done, disable output.
+ */
+static const struct v4l2_ioctl_ops zoran_ioctl_ops = {
+       .vidioc_querycap                    = zoran_querycap,
+       .vidioc_s_selection                 = zoran_s_selection,
+       .vidioc_g_selection                 = zoran_g_selection,
+       .vidioc_enum_input                  = zoran_enum_input,
+       .vidioc_g_input                     = zoran_g_input,
+       .vidioc_s_input                     = zoran_s_input,
+       .vidioc_g_std                       = zoran_g_std,
+       .vidioc_s_std                       = zoran_s_std,
+       .vidioc_create_bufs                 = vb2_ioctl_create_bufs,
+       .vidioc_reqbufs                     = vb2_ioctl_reqbufs,
+       .vidioc_querybuf                    = vb2_ioctl_querybuf,
+       .vidioc_qbuf                        = vb2_ioctl_qbuf,
+       .vidioc_dqbuf                       = vb2_ioctl_dqbuf,
+       .vidioc_expbuf                      = vb2_ioctl_expbuf,
+       .vidioc_streamon                    = vb2_ioctl_streamon,
+       .vidioc_streamoff                   = vb2_ioctl_streamoff,
+       .vidioc_enum_fmt_vid_cap            = zoran_enum_fmt_vid_cap,
+       .vidioc_g_fmt_vid_cap               = zoran_g_fmt_vid_cap,
+       .vidioc_s_fmt_vid_cap               = zoran_s_fmt_vid_cap,
+       .vidioc_try_fmt_vid_cap             = zoran_try_fmt_vid_cap,
+       .vidioc_subscribe_event             = v4l2_ctrl_subscribe_event,
+       .vidioc_unsubscribe_event           = v4l2_event_unsubscribe,
+};
+
+static const struct v4l2_file_operations zoran_fops = {
+       .owner = THIS_MODULE,
+       .unlocked_ioctl = video_ioctl2,
+       .open           = v4l2_fh_open,
+       .release        = vb2_fop_release,
+       .mmap           = vb2_fop_mmap,
+       .poll           = vb2_fop_poll,
+};
+
+const struct video_device zoran_template = {
+       .name = ZORAN_NAME,
+       .fops = &zoran_fops,
+       .ioctl_ops = &zoran_ioctl_ops,
+       .release = &zoran_vdev_release,
+       .tvnorms = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM,
+};
+
+static int zr_vb2_queue_setup(struct vb2_queue *vq, unsigned int *nbuffers, unsigned int *nplanes,
+                             unsigned int sizes[], struct device *alloc_devs[])
+{
+       struct zoran *zr = vb2_get_drv_priv(vq);
+       unsigned int size = zr->buffer_size;
+
+       pci_dbg(zr->pci_dev, "%s nbuf=%u nplanes=%u", __func__, *nbuffers, *nplanes);
+
+       zr->buf_in_reserve = 0;
+
+       if (*nbuffers < vq->min_buffers_needed)
+               *nbuffers = vq->min_buffers_needed;
+
+       if (*nplanes) {
+               if (sizes[0] < size)
+                       return -EINVAL;
+               else
+                       return 0;
+       }
+
+       *nplanes = 1;
+       sizes[0] = size;
+
+       return 0;
+}
+
+static void zr_vb2_queue(struct vb2_buffer *vb)
+{
+       struct zoran *zr = vb2_get_drv_priv(vb->vb2_queue);
+       struct zr_buffer *buf = vb2_to_zr_buffer(vb);
+       unsigned long flags;
+
+       spin_lock_irqsave(&zr->queued_bufs_lock, flags);
+       list_add_tail(&buf->queue, &zr->queued_bufs);
+       zr->buf_in_reserve++;
+       spin_unlock_irqrestore(&zr->queued_bufs_lock, flags);
+       if (zr->running == ZORAN_MAP_MODE_JPG_REC)
+               zoran_feed_stat_com(zr);
+       zr->queued++;
+}
+
+static int zr_vb2_prepare(struct vb2_buffer *vb)
+{
+       struct zoran *zr = vb2_get_drv_priv(vb->vb2_queue);
+
+       if (vb2_plane_size(vb, 0) < zr->buffer_size)
+               return -EINVAL;
+       zr->prepared++;
+
+       return 0;
+}
+
+int zr_set_buf(struct zoran *zr)
+{
+       struct zr_buffer *buf;
+       struct vb2_v4l2_buffer *vbuf;
+       dma_addr_t phys_addr;
+       unsigned long flags;
+       u32 reg;
+
+       if (zr->running == ZORAN_MAP_MODE_NONE)
+               return 0;
+
+       if (zr->inuse[0]) {
+               buf = zr->inuse[0];
+               buf->vbuf.vb2_buf.timestamp = ktime_get_ns();
+               buf->vbuf.sequence = zr->vbseq++;
+               vbuf = &buf->vbuf;
+
+               buf->vbuf.field = V4L2_FIELD_INTERLACED;
+               if (BUZ_MAX_HEIGHT < (zr->v4l_settings.height * 2))
+                       buf->vbuf.field = V4L2_FIELD_INTERLACED;
+               else
+                       buf->vbuf.field = V4L2_FIELD_TOP;
+               vb2_set_plane_payload(&buf->vbuf.vb2_buf, 0, zr->buffer_size);
+               vb2_buffer_done(&buf->vbuf.vb2_buf, VB2_BUF_STATE_DONE);
+               zr->inuse[0] = NULL;
+       }
+
+       spin_lock_irqsave(&zr->queued_bufs_lock, flags);
+       if (list_empty(&zr->queued_bufs)) {
+               btand(~ZR36057_ICR_INT_PIN_EN, ZR36057_ICR);
+               vb2_queue_error(zr->video_dev->queue);
+               spin_unlock_irqrestore(&zr->queued_bufs_lock, flags);
+               return -EINVAL;
+       }
+       buf = list_first_entry_or_null(&zr->queued_bufs, struct zr_buffer, queue);
+       if (!buf) {
+               btand(~ZR36057_ICR_INT_PIN_EN, ZR36057_ICR);
+               vb2_queue_error(zr->video_dev->queue);
+               spin_unlock_irqrestore(&zr->queued_bufs_lock, flags);
+               return -EINVAL;
+       }
+       list_del(&buf->queue);
+       zr->buf_in_reserve--;
+       spin_unlock_irqrestore(&zr->queued_bufs_lock, flags);
+
+       vbuf = &buf->vbuf;
+       vbuf->vb2_buf.state = VB2_BUF_STATE_ACTIVE;
+       phys_addr = vb2_dma_contig_plane_dma_addr(&vbuf->vb2_buf, 0);
+
+       if (!phys_addr)
+               return -EINVAL;
+
+       zr->inuse[0] = buf;
+
+       reg = phys_addr;
+       btwrite(reg, ZR36057_VDTR);
+       if (zr->v4l_settings.height > BUZ_MAX_HEIGHT / 2)
+               reg += zr->v4l_settings.bytesperline;
+       btwrite(reg, ZR36057_VDBR);
+
+       reg = 0;
+       if (zr->v4l_settings.height > BUZ_MAX_HEIGHT / 2)
+               reg += zr->v4l_settings.bytesperline;
+       reg = (reg << ZR36057_VSSFGR_DISP_STRIDE);
+       reg |= ZR36057_VSSFGR_VID_OVF;
+       reg |= ZR36057_VSSFGR_SNAP_SHOT;
+       reg |= ZR36057_VSSFGR_FRAME_GRAB;
+       btwrite(reg, ZR36057_VSSFGR);
+
+       btor(ZR36057_VDCR_VID_EN, ZR36057_VDCR);
+       return 0;
+}
+
+static int zr_vb2_start_streaming(struct vb2_queue *vq, unsigned int count)
+{
+       struct zoran *zr = vq->drv_priv;
+       int j;
+
+       for (j = 0; j < BUZ_NUM_STAT_COM; j++) {
+               zr->stat_com[j] = cpu_to_le32(1);
+               zr->inuse[j] = NULL;
+       }
+       zr->vbseq = 0;
+
+       if (zr->map_mode != ZORAN_MAP_MODE_RAW) {
+               pci_dbg(zr->pci_dev, "START JPG\n");
+               zr36057_restart(zr);
+               zoran_init_hardware(zr);
+               if (zr->map_mode == ZORAN_MAP_MODE_JPG_REC)
+                       zr36057_enable_jpg(zr, BUZ_MODE_MOTION_DECOMPRESS);
+               else
+                       zr36057_enable_jpg(zr, BUZ_MODE_MOTION_COMPRESS);
+               zoran_feed_stat_com(zr);
+               jpeg_start(zr);
+               zr->running = zr->map_mode;
+               btor(ZR36057_ICR_INT_PIN_EN, ZR36057_ICR);
+               return 0;
+       }
+
+       pci_dbg(zr->pci_dev, "START RAW\n");
+       zr36057_restart(zr);
+       zoran_init_hardware(zr);
+
+       zr36057_enable_jpg(zr, BUZ_MODE_IDLE);
+       zr36057_set_memgrab(zr, 1);
+       zr->running = zr->map_mode;
+       btor(ZR36057_ICR_INT_PIN_EN, ZR36057_ICR);
+       return 0;
+}
+
+static void zr_vb2_stop_streaming(struct vb2_queue *vq)
+{
+       struct zoran *zr = vq->drv_priv;
+       struct zr_buffer *buf;
+       unsigned long flags;
+       int j;
+
+       btand(~ZR36057_ICR_INT_PIN_EN, ZR36057_ICR);
+       if (zr->map_mode != ZORAN_MAP_MODE_RAW)
+               zr36057_enable_jpg(zr, BUZ_MODE_IDLE);
+       zr36057_set_memgrab(zr, 0);
+       zr->running = ZORAN_MAP_MODE_NONE;
+
+       zoran_set_pci_master(zr, 0);
+
+       if (!pass_through) {    /* Switch to color bar */
+               decoder_call(zr, video, s_stream, 0);
+               encoder_call(zr, video, s_routing, 2, 0, 0);
+       }
+
+       for (j = 0; j < BUZ_NUM_STAT_COM; j++) {
+               zr->stat_com[j] = cpu_to_le32(1);
+               if (!zr->inuse[j])
+                       continue;
+               buf = zr->inuse[j];
+               pci_dbg(zr->pci_dev, "%s clean buf %d\n", __func__, j);
+               vb2_buffer_done(&buf->vbuf.vb2_buf, VB2_BUF_STATE_ERROR);
+               zr->inuse[j] = NULL;
+       }
+
+       spin_lock_irqsave(&zr->queued_bufs_lock, flags);
+       while (!list_empty(&zr->queued_bufs)) {
+               buf = list_entry(zr->queued_bufs.next, struct zr_buffer, queue);
+               list_del(&buf->queue);
+               vb2_buffer_done(&buf->vbuf.vb2_buf, VB2_BUF_STATE_ERROR);
+               zr->buf_in_reserve--;
+       }
+       spin_unlock_irqrestore(&zr->queued_bufs_lock, flags);
+       if (zr->buf_in_reserve)
+               pci_dbg(zr->pci_dev, "Buffer remaining %d\n", zr->buf_in_reserve);
+       zr->map_mode = ZORAN_MAP_MODE_RAW;
+}
+
+static const struct vb2_ops zr_video_qops = {
+       .queue_setup            = zr_vb2_queue_setup,
+       .buf_queue              = zr_vb2_queue,
+       .buf_prepare            = zr_vb2_prepare,
+       .start_streaming        = zr_vb2_start_streaming,
+       .stop_streaming         = zr_vb2_stop_streaming,
+       .wait_prepare           = vb2_ops_wait_prepare,
+       .wait_finish            = vb2_ops_wait_finish,
+};
+
+int zoran_queue_init(struct zoran *zr, struct vb2_queue *vq, int dir)
+{
+       int err;
+
+       spin_lock_init(&zr->queued_bufs_lock);
+       INIT_LIST_HEAD(&zr->queued_bufs);
+
+       vq->dev = &zr->pci_dev->dev;
+       vq->type = dir;
+
+       vq->io_modes = VB2_DMABUF | VB2_MMAP;
+       vq->drv_priv = zr;
+       vq->buf_struct_size = sizeof(struct zr_buffer);
+       vq->ops = &zr_video_qops;
+       vq->mem_ops = &vb2_dma_contig_memops;
+       vq->gfp_flags = GFP_DMA32;
+       vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+       vq->min_buffers_needed = 9;
+       vq->lock = &zr->lock;
+       err = vb2_queue_init(vq);
+       if (err)
+               return err;
+       zr->video_dev->queue = vq;
+       return 0;
+}
+
+void zoran_queue_exit(struct zoran *zr)
+{
+       vb2_queue_release(zr->video_dev->queue);
+}
 
--- /dev/null
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Zoran ZR36016 basic configuration functions
+ *
+ * Copyright (C) 2001 Wolfgang Scherr <scherr@net4you.at>
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+
+/* headerfile of this module */
+#include "zr36016.h"
+
+/* codec io API */
+#include "videocodec.h"
+
+/*
+ * it doesn't make sense to have more than 20 or so,
+ * just to prevent some unwanted loops
+ */
+#define MAX_CODECS 20
+
+/* amount of chips attached via this driver */
+static int zr36016_codecs;
+
+/*
+ * Local hardware I/O functions: read/write via codec layer
+ * (registers are located in the master device)
+ */
+
+/* read and write functions */
+static u8 zr36016_read(struct zr36016 *ptr, u16 reg)
+{
+       u8 value = 0;
+       struct zoran *zr = videocodec_to_zoran(ptr->codec);
+
+       /* just in case something is wrong... */
+       if (ptr->codec->master_data->readreg)
+               value = (ptr->codec->master_data->readreg(ptr->codec, reg)) & 0xFF;
+       else
+               zrdev_err(zr, "%s: invalid I/O setup, nothing read!\n", ptr->name);
+
+       zrdev_dbg(zr, "%s: reading from 0x%04x: %02x\n", ptr->name, reg, value);
+
+       return value;
+}
+
+static void zr36016_write(struct zr36016 *ptr, u16 reg, u8 value)
+{
+       struct zoran *zr = videocodec_to_zoran(ptr->codec);
+
+       zrdev_dbg(zr, "%s: writing 0x%02x to 0x%04x\n", ptr->name, value, reg);
+
+       // just in case something is wrong...
+       if (ptr->codec->master_data->writereg)
+               ptr->codec->master_data->writereg(ptr->codec, reg, value);
+       else
+               zrdev_err(zr, "%s: invalid I/O setup, nothing written!\n", ptr->name);
+}
+
+/*
+ * indirect read and write functions
+ *
+ * the 016 supports auto-addr-increment, but
+ * writing it all time cost not much and is safer...
+ */
+static u8 zr36016_readi(struct zr36016 *ptr, u16 reg)
+{
+       u8 value = 0;
+       struct zoran *zr = videocodec_to_zoran(ptr->codec);
+
+       /* just in case something is wrong... */
+       if ((ptr->codec->master_data->writereg) && (ptr->codec->master_data->readreg)) {
+               ptr->codec->master_data->writereg(ptr->codec, ZR016_IADDR, reg & 0x0F);
+               value = (ptr->codec->master_data->readreg(ptr->codec, ZR016_IDATA)) & 0xFF;
+       } else {
+               zrdev_err(zr, "%s: invalid I/O setup, nothing read (i)!\n", ptr->name);
+       }
+
+       zrdev_dbg(zr, "%s: reading indirect from 0x%04x: %02x\n",
+                 ptr->name, reg, value);
+       return value;
+}
+
+static void zr36016_writei(struct zr36016 *ptr, u16 reg, u8 value)
+{
+       struct zoran *zr = videocodec_to_zoran(ptr->codec);
+
+       zrdev_dbg(zr, "%s: writing indirect 0x%02x to 0x%04x\n", ptr->name,
+                 value, reg);
+
+       /* just in case something is wrong... */
+       if (ptr->codec->master_data->writereg) {
+               ptr->codec->master_data->writereg(ptr->codec, ZR016_IADDR, reg & 0x0F);
+               ptr->codec->master_data->writereg(ptr->codec, ZR016_IDATA, value & 0x0FF);
+       } else {
+               zrdev_err(zr, "%s: invalid I/O setup, nothing written (i)!\n", ptr->name);
+       }
+}
+
+/* Local helper function: version read */
+
+/* version kept in datastructure */
+static u8 zr36016_read_version(struct zr36016 *ptr)
+{
+       ptr->version = zr36016_read(ptr, 0) >> 4;
+       return ptr->version;
+}
+
+/*
+ * Local helper function: basic test of "connectivity", writes/reads
+ * to/from PAX-Lo register
+ */
+
+static int zr36016_basic_test(struct zr36016 *ptr)
+{
+       struct zoran *zr = videocodec_to_zoran(ptr->codec);
+
+       if (*KERN_INFO <= CONSOLE_LOGLEVEL_DEFAULT) {
+               int i;
+
+               zr36016_writei(ptr, ZR016I_PAX_LO, 0x55);
+               zrdev_dbg(zr, "%s: registers: ", ptr->name);
+               for (i = 0; i <= 0x0b; i++)
+                       zrdev_dbg(zr, "%02x ", zr36016_readi(ptr, i));
+               zrdev_dbg(zr, "\n");
+       }
+       // for testing just write 0, then the default value to a register and read
+       // it back in both cases
+       zr36016_writei(ptr, ZR016I_PAX_LO, 0x00);
+       if (zr36016_readi(ptr, ZR016I_PAX_LO) != 0x0) {
+               zrdev_err(zr, "%s: attach failed, can't connect to vfe processor!\n", ptr->name);
+               return -ENXIO;
+       }
+       zr36016_writei(ptr, ZR016I_PAX_LO, 0x0d0);
+       if (zr36016_readi(ptr, ZR016I_PAX_LO) != 0x0d0) {
+               zrdev_err(zr, "%s: attach failed, can't connect to vfe processor!\n", ptr->name);
+               return -ENXIO;
+       }
+       // we allow version numbers from 0-3, should be enough, though
+       zr36016_read_version(ptr);
+       if (ptr->version & 0x0c) {
+               zrdev_err(zr, "%s: attach failed, suspicious version %d found...\n", ptr->name,
+                         ptr->version);
+               return -ENXIO;
+       }
+
+       return 0;               /* looks good! */
+}
+
+/* Basic datasets & init */
+
+static void zr36016_init(struct zr36016 *ptr)
+{
+       // stop any processing
+       zr36016_write(ptr, ZR016_GOSTOP, 0);
+
+       // mode setup (yuv422 in and out, compression/expansuon due to mode)
+       zr36016_write(ptr, ZR016_MODE,
+                     ZR016_YUV422 | ZR016_YUV422_YUV422 |
+                     (ptr->mode == CODEC_DO_COMPRESSION ?
+                      ZR016_COMPRESSION : ZR016_EXPANSION));
+
+       // misc setup
+       zr36016_writei(ptr, ZR016I_SETUP1,
+                      (ptr->xdec ? (ZR016_HRFL | ZR016_HORZ) : 0) |
+                      (ptr->ydec ? ZR016_VERT : 0) | ZR016_CNTI);
+       zr36016_writei(ptr, ZR016I_SETUP2, ZR016_CCIR);
+
+       // Window setup
+       // (no extra offset for now, norm defines offset, default width height)
+       zr36016_writei(ptr, ZR016I_PAX_HI, ptr->width >> 8);
+       zr36016_writei(ptr, ZR016I_PAX_LO, ptr->width & 0xFF);
+       zr36016_writei(ptr, ZR016I_PAY_HI, ptr->height >> 8);
+       zr36016_writei(ptr, ZR016I_PAY_LO, ptr->height & 0xFF);
+       zr36016_writei(ptr, ZR016I_NAX_HI, ptr->xoff >> 8);
+       zr36016_writei(ptr, ZR016I_NAX_LO, ptr->xoff & 0xFF);
+       zr36016_writei(ptr, ZR016I_NAY_HI, ptr->yoff >> 8);
+       zr36016_writei(ptr, ZR016I_NAY_LO, ptr->yoff & 0xFF);
+
+       /* shall we continue now, please? */
+       zr36016_write(ptr, ZR016_GOSTOP, 1);
+}
+
+/*
+ * CODEC API FUNCTIONS
+ *
+ * These functions are accessed by the master via the API structure
+ */
+
+/*
+ * set compression/expansion mode and launches codec -
+ * this should be the last call from the master before starting processing
+ */
+static int zr36016_set_mode(struct videocodec *codec, int mode)
+{
+       struct zr36016 *ptr = (struct zr36016 *)codec->data;
+       struct zoran *zr = videocodec_to_zoran(codec);
+
+       zrdev_dbg(zr, "%s: set_mode %d call\n", ptr->name, mode);
+
+       if ((mode != CODEC_DO_EXPANSION) && (mode != CODEC_DO_COMPRESSION))
+               return -EINVAL;
+
+       ptr->mode = mode;
+       zr36016_init(ptr);
+
+       return 0;
+}
+
+/* set picture size */
+static int zr36016_set_video(struct videocodec *codec, const struct tvnorm *norm,
+                            struct vfe_settings *cap, struct vfe_polarity *pol)
+{
+       struct zr36016 *ptr = (struct zr36016 *)codec->data;
+       struct zoran *zr = videocodec_to_zoran(codec);
+
+       zrdev_dbg(zr, "%s: set_video %d.%d, %d/%d-%dx%d (0x%x) call\n",
+                 ptr->name, norm->h_start, norm->v_start,
+                 cap->x, cap->y, cap->width, cap->height,
+                 cap->decimation);
+
+       /*
+        * if () return -EINVAL;
+        * trust the master driver that it knows what it does - so
+        * we allow invalid startx/y for now ...
+        */
+       ptr->width = cap->width;
+       ptr->height = cap->height;
+       /*
+        * (Ronald) This is ugly. zoran_device.c, line 387
+        * already mentions what happens if h_start is even
+        * (blue faces, etc., cr/cb inversed). There's probably
+        * some good reason why h_start is 0 instead of 1, so I'm
+        * leaving it to this for now, but really... This can be
+        * done a lot simpler
+        */
+       ptr->xoff = (norm->h_start ? norm->h_start : 1) + cap->x;
+       /*
+        * Something to note here (I don't understand it), setting
+        * v_start too high will cause the codec to 'not work'. I
+        * really don't get it. values of 16 (v_start) already break
+        * it here. Just '0' seems to work. More testing needed!
+        */
+       ptr->yoff = norm->v_start + cap->y;
+       /* (Ronald) dzjeeh, can't this thing do hor_decimation = 4? */
+       ptr->xdec = ((cap->decimation & 0xff) == 1) ? 0 : 1;
+       ptr->ydec = (((cap->decimation >> 8) & 0xff) == 1) ? 0 : 1;
+
+       return 0;
+}
+
+/* additional control functions */
+static int zr36016_control(struct videocodec *codec, int type, int size, void *data)
+{
+       struct zr36016 *ptr = (struct zr36016 *)codec->data;
+       struct zoran *zr = videocodec_to_zoran(codec);
+       int *ival = (int *)data;
+
+       zrdev_dbg(zr, "%s: control %d call with %d byte\n",
+                 ptr->name, type, size);
+
+       switch (type) {
+       case CODEC_G_STATUS:    /* get last status - we don't know it ... */
+               if (size != sizeof(int))
+                       return -EFAULT;
+               *ival = 0;
+               break;
+
+       case CODEC_G_CODEC_MODE:
+               if (size != sizeof(int))
+                       return -EFAULT;
+               *ival = 0;
+               break;
+
+       case CODEC_S_CODEC_MODE:
+               if (size != sizeof(int))
+                       return -EFAULT;
+               if (*ival != 0)
+                       return -EINVAL;
+               /* not needed, do nothing */
+               return 0;
+
+       case CODEC_G_VFE:
+       case CODEC_S_VFE:
+               return 0;
+
+       case CODEC_S_MMAP:
+               /* not available, give an error */
+               return -ENXIO;
+
+       default:
+               return -EINVAL;
+       }
+
+       return size;
+}
+
+/*
+ * Exit and unregister function:
+ *
+ * Deinitializes Zoran's JPEG processor
+ */
+
+static int zr36016_unset(struct videocodec *codec)
+{
+       struct zr36016 *ptr = codec->data;
+       struct zoran *zr = videocodec_to_zoran(codec);
+
+       if (ptr) {
+               /* do wee need some codec deinit here, too ???? */
+
+               zrdev_dbg(zr, "%s: finished codec #%d\n", ptr->name, ptr->num);
+               kfree(ptr);
+               codec->data = NULL;
+
+               zr36016_codecs--;
+               return 0;
+       }
+
+       return -EFAULT;
+}
+
+/*
+ * Setup and registry function:
+ *
+ * Initializes Zoran's JPEG processor
+ *
+ * Also sets pixel size, average code size, mode (compr./decompr.)
+ * (the given size is determined by the processor with the video interface)
+ */
+
+static int zr36016_setup(struct videocodec *codec)
+{
+       struct zr36016 *ptr;
+       struct zoran *zr = videocodec_to_zoran(codec);
+       int res;
+
+       zrdev_dbg(zr, "zr36016: initializing VFE subsystem #%d.\n", zr36016_codecs);
+
+       if (zr36016_codecs == MAX_CODECS) {
+               zrdev_err(zr, "zr36016: Can't attach more codecs!\n");
+               return -ENOSPC;
+       }
+       //mem structure init
+       ptr = kzalloc(sizeof(*ptr), GFP_KERNEL);
+       codec->data = ptr;
+       if (!ptr)
+               return -ENOMEM;
+
+       snprintf(ptr->name, sizeof(ptr->name), "zr36016[%d]", zr36016_codecs);
+       ptr->num = zr36016_codecs++;
+       ptr->codec = codec;
+
+       //testing
+       res = zr36016_basic_test(ptr);
+       if (res < 0) {
+               zr36016_unset(codec);
+               return res;
+       }
+       //final setup
+       ptr->mode = CODEC_DO_COMPRESSION;
+       ptr->width = 768;
+       ptr->height = 288;
+       ptr->xdec = 1;
+       ptr->ydec = 0;
+       zr36016_init(ptr);
+
+       zrdev_dbg(zr, "%s: codec v%d attached and running\n",
+                 ptr->name, ptr->version);
+
+       return 0;
+}
+
+static const struct videocodec zr36016_codec = {
+       .name = "zr36016",
+       .magic = 0L,            /* magic not used */
+       .flags =
+           CODEC_FLAG_HARDWARE | CODEC_FLAG_VFE | CODEC_FLAG_ENCODER |
+           CODEC_FLAG_DECODER,
+       .type = CODEC_TYPE_ZR36016,
+       .setup = zr36016_setup, /* functionality */
+       .unset = zr36016_unset,
+       .set_mode = zr36016_set_mode,
+       .set_video = zr36016_set_video,
+       .control = zr36016_control,
+       /* others are not used */
+};
+
+/* HOOK IN DRIVER AS KERNEL MODULE */
+
+int zr36016_init_module(void)
+{
+       zr36016_codecs = 0;
+       return videocodec_register(&zr36016_codec);
+}
+
+void zr36016_cleanup_module(void)
+{
+       if (zr36016_codecs) {
+               pr_debug("zr36016: something's wrong - %d codecs left somehow.\n",
+                        zr36016_codecs);
+       }
+       videocodec_unregister(&zr36016_codec);
+}
 
--- /dev/null
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Zoran ZR36016 basic configuration functions - header file
+ *
+ * Copyright (C) 2001 Wolfgang Scherr <scherr@net4you.at>
+ */
+
+#ifndef ZR36016_H
+#define ZR36016_H
+
+/* data stored for each zoran jpeg codec chip */
+struct zr36016 {
+       char name[32];
+       int num;
+       /* io datastructure */
+       struct videocodec *codec;
+       // coder status
+       __u8 version;
+       // actual coder setup
+       int mode;
+
+       __u16 xoff;
+       __u16 yoff;
+       __u16 width;
+       __u16 height;
+       __u16 xdec;
+       __u16 ydec;
+};
+
+/* direct  register addresses */
+#define ZR016_GOSTOP      0x00
+#define ZR016_MODE        0x01
+#define ZR016_IADDR       0x02
+#define ZR016_IDATA       0x03
+
+/* indirect  register addresses */
+#define ZR016I_SETUP1     0x00
+#define ZR016I_SETUP2     0x01
+#define ZR016I_NAX_LO     0x02
+#define ZR016I_NAX_HI     0x03
+#define ZR016I_PAX_LO     0x04
+#define ZR016I_PAX_HI     0x05
+#define ZR016I_NAY_LO     0x06
+#define ZR016I_NAY_HI     0x07
+#define ZR016I_PAY_LO     0x08
+#define ZR016I_PAY_HI     0x09
+#define ZR016I_NOL_LO     0x0a
+#define ZR016I_NOL_HI     0x0b
+
+/* possible values for mode register */
+#define ZR016_RGB444_YUV444  0x00
+#define ZR016_RGB444_YUV422  0x01
+#define ZR016_RGB444_YUV411  0x02
+#define ZR016_RGB444_Y400    0x03
+#define ZR016_RGB444_RGB444  0x04
+#define ZR016_YUV444_YUV444  0x08
+#define ZR016_YUV444_YUV422  0x09
+#define ZR016_YUV444_YUV411  0x0a
+#define ZR016_YUV444_Y400    0x0b
+#define ZR016_YUV444_RGB444  0x0c
+#define ZR016_YUV422_YUV422  0x11
+#define ZR016_YUV422_YUV411  0x12
+#define ZR016_YUV422_Y400    0x13
+#define ZR016_YUV411_YUV411  0x16
+#define ZR016_YUV411_Y400    0x17
+#define ZR016_4444_4444      0x19
+#define ZR016_100_100        0x1b
+
+#define ZR016_RGB444         0x00
+#define ZR016_YUV444         0x20
+#define ZR016_YUV422         0x40
+
+#define ZR016_COMPRESSION    0x80
+#define ZR016_EXPANSION      0x80
+
+/* possible values for setup 1 register */
+#define ZR016_CKRT           0x80
+#define ZR016_VERT           0x40
+#define ZR016_HORZ           0x20
+#define ZR016_HRFL           0x10
+#define ZR016_DSFL           0x08
+#define ZR016_SBFL           0x04
+#define ZR016_RSTR           0x02
+#define ZR016_CNTI           0x01
+
+/* possible values for setup 2 register */
+#define ZR016_SYEN           0x40
+#define ZR016_CCIR           0x04
+#define ZR016_SIGN           0x02
+#define ZR016_YMCS           0x01
+
+int zr36016_init_module(void);
+void zr36016_cleanup_module(void);
+#endif                         /*fndef ZR36016_H */
 
--- /dev/null
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Zoran ZR36050 basic configuration functions
+ *
+ * Copyright (C) 2001 Wolfgang Scherr <scherr@net4you.at>
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+
+#include <linux/types.h>
+#include <linux/wait.h>
+
+/* I/O commands, error codes */
+#include <linux/io.h>
+
+/* headerfile of this module */
+#include "zr36050.h"
+
+/* codec io API */
+#include "videocodec.h"
+
+/*
+ * it doesn't make sense to have more than 20 or so,
+ * just to prevent some unwanted loops
+ */
+#define MAX_CODECS 20
+
+/* amount of chips attached via this driver */
+static int zr36050_codecs;
+
+/*
+ * Local hardware I/O functions:
+ *
+ * read/write via codec layer (registers are located in the master device)
+ */
+
+/* read and write functions */
+static u8 zr36050_read(struct zr36050 *ptr, u16 reg)
+{
+       struct zoran *zr = videocodec_to_zoran(ptr->codec);
+       u8 value = 0;
+
+       /* just in case something is wrong... */
+       if (ptr->codec->master_data->readreg)
+               value = (ptr->codec->master_data->readreg(ptr->codec, reg)) & 0xFF;
+       else
+               zrdev_err(zr, "%s: invalid I/O setup, nothing read!\n", ptr->name);
+
+       zrdev_dbg(zr, "%s: reading from 0x%04x: %02x\n", ptr->name, reg, value);
+
+       return value;
+}
+
+static void zr36050_write(struct zr36050 *ptr, u16 reg, u8 value)
+{
+       struct zoran *zr = videocodec_to_zoran(ptr->codec);
+
+       zrdev_dbg(zr, "%s: writing 0x%02x to 0x%04x\n", ptr->name, value, reg);
+
+       /* just in case something is wrong... */
+       if (ptr->codec->master_data->writereg)
+               ptr->codec->master_data->writereg(ptr->codec, reg, value);
+       else
+               zrdev_err(zr, "%s: invalid I/O setup, nothing written!\n",
+                         ptr->name);
+}
+
+/* status is kept in datastructure */
+static u8 zr36050_read_status1(struct zr36050 *ptr)
+{
+       ptr->status1 = zr36050_read(ptr, ZR050_STATUS_1);
+
+       zr36050_read(ptr, 0);
+       return ptr->status1;
+}
+
+/* scale factor is kept in datastructure */
+static u16 zr36050_read_scalefactor(struct zr36050 *ptr)
+{
+       ptr->scalefact = (zr36050_read(ptr, ZR050_SF_HI) << 8) |
+                        (zr36050_read(ptr, ZR050_SF_LO) & 0xFF);
+
+       /* leave 0 selected for an eventually GO from master */
+       zr36050_read(ptr, 0);
+       return ptr->scalefact;
+}
+
+/*
+ * Local helper function:
+ *
+ * wait if codec is ready to proceed (end of processing) or time is over
+ */
+
+static void zr36050_wait_end(struct zr36050 *ptr)
+{
+       struct zoran *zr = videocodec_to_zoran(ptr->codec);
+       int i = 0;
+
+       while (!(zr36050_read_status1(ptr) & 0x4)) {
+               udelay(1);
+               if (i++ > 200000) {     // 200ms, there is for sure something wrong!!!
+                       zrdev_err(zr,
+                                 "%s: timeout at wait_end (last status: 0x%02x)\n",
+                                 ptr->name, ptr->status1);
+                       break;
+               }
+       }
+}
+
+/*
+ * Local helper function: basic test of "connectivity", writes/reads
+ * to/from memory the SOF marker
+ */
+
+static int zr36050_basic_test(struct zr36050 *ptr)
+{
+       struct zoran *zr = videocodec_to_zoran(ptr->codec);
+
+       zr36050_write(ptr, ZR050_SOF_IDX, 0x00);
+       zr36050_write(ptr, ZR050_SOF_IDX + 1, 0x00);
+       if ((zr36050_read(ptr, ZR050_SOF_IDX) |
+            zr36050_read(ptr, ZR050_SOF_IDX + 1)) != 0x0000) {
+               zrdev_err(zr,
+                         "%s: attach failed, can't connect to jpeg processor!\n",
+                         ptr->name);
+               return -ENXIO;
+       }
+       zr36050_write(ptr, ZR050_SOF_IDX, 0xff);
+       zr36050_write(ptr, ZR050_SOF_IDX + 1, 0xc0);
+       if (((zr36050_read(ptr, ZR050_SOF_IDX) << 8) |
+            zr36050_read(ptr, ZR050_SOF_IDX + 1)) != 0xffc0) {
+               zrdev_err(zr,
+                         "%s: attach failed, can't connect to jpeg processor!\n",
+                         ptr->name);
+               return -ENXIO;
+       }
+
+       zr36050_wait_end(ptr);
+       if ((ptr->status1 & 0x4) == 0) {
+               zrdev_err(zr,
+                         "%s: attach failed, jpeg processor failed (end flag)!\n",
+                         ptr->name);
+               return -EBUSY;
+       }
+
+       return 0;               /* looks good! */
+}
+
+/* Local helper function: simple loop for pushing the init datasets */
+
+static int zr36050_pushit(struct zr36050 *ptr, u16 startreg, u16 len, const char *data)
+{
+       struct zoran *zr = videocodec_to_zoran(ptr->codec);
+       int i = 0;
+
+       zrdev_dbg(zr, "%s: write data block to 0x%04x (len=%d)\n", ptr->name,
+                 startreg, len);
+       while (i < len)
+               zr36050_write(ptr, startreg++, data[i++]);
+
+       return i;
+}
+
+/*
+ * Basic datasets:
+ *
+ * jpeg baseline setup data (you find it on lots places in internet, or just
+ * extract it from any regular .jpg image...)
+ *
+ * Could be variable, but until it's not needed it they are just fixed to save
+ * memory. Otherwise expand zr36050 structure with arrays, push the values to
+ * it and initialize from there, as e.g. the linux zr36057/60 driver does it.
+ */
+
+static const char zr36050_dqt[0x86] = {
+       0xff, 0xdb,             //Marker: DQT
+       0x00, 0x84,             //Length: 2*65+2
+       0x00,                   //Pq,Tq first table
+       0x10, 0x0b, 0x0c, 0x0e, 0x0c, 0x0a, 0x10, 0x0e,
+       0x0d, 0x0e, 0x12, 0x11, 0x10, 0x13, 0x18, 0x28,
+       0x1a, 0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25,
+       0x1d, 0x28, 0x3a, 0x33, 0x3d, 0x3c, 0x39, 0x33,
+       0x38, 0x37, 0x40, 0x48, 0x5c, 0x4e, 0x40, 0x44,
+       0x57, 0x45, 0x37, 0x38, 0x50, 0x6d, 0x51, 0x57,
+       0x5f, 0x62, 0x67, 0x68, 0x67, 0x3e, 0x4d, 0x71,
+       0x79, 0x70, 0x64, 0x78, 0x5c, 0x65, 0x67, 0x63,
+       0x01,                   //Pq,Tq second table
+       0x11, 0x12, 0x12, 0x18, 0x15, 0x18, 0x2f, 0x1a,
+       0x1a, 0x2f, 0x63, 0x42, 0x38, 0x42, 0x63, 0x63,
+       0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
+       0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
+       0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
+       0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
+       0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
+       0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63
+};
+
+static const char zr36050_dht[0x1a4] = {
+       0xff, 0xc4,             //Marker: DHT
+       0x01, 0xa2,             //Length: 2*AC, 2*DC
+       0x00,                   //DC first table
+       0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01,
+       0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+       0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,
+       0x01,                   //DC second table
+       0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+       0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+       0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,
+       0x10,                   //AC first table
+       0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03,
+       0x05, 0x05, 0x04, 0x04, 0x00, 0x00,
+       0x01, 0x7D, 0x01, 0x02, 0x03, 0x00, 0x04, 0x11,
+       0x05, 0x12, 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61,
+       0x07, 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xA1,
+       0x08, 0x23, 0x42, 0xB1, 0xC1, 0x15, 0x52, 0xD1, 0xF0, 0x24,
+       0x33, 0x62, 0x72, 0x82, 0x09, 0x0A, 0x16, 0x17,
+       0x18, 0x19, 0x1A, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x34,
+       0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x43, 0x44,
+       0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56,
+       0x57, 0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66,
+       0x67, 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
+       0x79, 0x7A, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88,
+       0x89, 0x8A, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99,
+       0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8,
+       0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9,
+       0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8,
+       0xC9, 0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9,
+       0xDA, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
+       0xE8, 0xE9, 0xEA, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
+       0xF8, 0xF9, 0xFA,
+       0x11,                   //AC second table
+       0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04,
+       0x07, 0x05, 0x04, 0x04, 0x00, 0x01,
+       0x02, 0x77, 0x00, 0x01, 0x02, 0x03, 0x11, 0x04,
+       0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
+       0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
+       0xA1, 0xB1, 0xC1, 0x09, 0x23, 0x33, 0x52, 0xF0, 0x15, 0x62,
+       0x72, 0xD1, 0x0A, 0x16, 0x24, 0x34, 0xE1, 0x25,
+       0xF1, 0x17, 0x18, 0x19, 0x1A, 0x26, 0x27, 0x28, 0x29, 0x2A,
+       0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x43, 0x44,
+       0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56,
+       0x57, 0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66,
+       0x67, 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
+       0x79, 0x7A, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
+       0x88, 0x89, 0x8A, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
+       0x99, 0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7,
+       0xA8, 0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8,
+       0xB9, 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
+       0xC8, 0xC9, 0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8,
+       0xD9, 0xDA, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
+       0xE8, 0xE9, 0xEA, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8,
+       0xF9, 0xFA
+};
+
+/* jpeg baseline setup, this is just fixed in this driver (YUV pictures) */
+#define NO_OF_COMPONENTS          0x3  //Y,U,V
+#define BASELINE_PRECISION        0x8  //MCU size (?)
+static const char zr36050_tq[8] = { 0, 1, 1, 0, 0, 0, 0, 0 };  //table idx's QT
+static const char zr36050_td[8] = { 0, 1, 1, 0, 0, 0, 0, 0 };  //table idx's DC
+static const char zr36050_ta[8] = { 0, 1, 1, 0, 0, 0, 0, 0 };  //table idx's AC
+
+/* horizontal 422 decimation setup (maybe we support 411 or so later, too) */
+static const char zr36050_decimation_h[8] = { 2, 1, 1, 0, 0, 0, 0, 0 };
+static const char zr36050_decimation_v[8] = { 1, 1, 1, 0, 0, 0, 0, 0 };
+
+/*
+ * Local helper functions:
+ *
+ * calculation and setup of parameter-dependent JPEG baseline segments
+ * (needed for compression only)
+ */
+
+/* ------------------------------------------------------------------------- */
+
+/*
+ * SOF (start of frame) segment depends on width, height and sampling ratio
+ * of each color component
+ */
+static int zr36050_set_sof(struct zr36050 *ptr)
+{
+       struct zoran *zr = videocodec_to_zoran(ptr->codec);
+       char sof_data[34];      // max. size of register set
+       int i;
+
+       zrdev_dbg(zr, "%s: write SOF (%dx%d, %d components)\n", ptr->name,
+                 ptr->width, ptr->height, NO_OF_COMPONENTS);
+       sof_data[0] = 0xff;
+       sof_data[1] = 0xc0;
+       sof_data[2] = 0x00;
+       sof_data[3] = (3 * NO_OF_COMPONENTS) + 8;
+       sof_data[4] = BASELINE_PRECISION;       // only '8' possible with zr36050
+       sof_data[5] = (ptr->height) >> 8;
+       sof_data[6] = (ptr->height) & 0xff;
+       sof_data[7] = (ptr->width) >> 8;
+       sof_data[8] = (ptr->width) & 0xff;
+       sof_data[9] = NO_OF_COMPONENTS;
+       for (i = 0; i < NO_OF_COMPONENTS; i++) {
+               sof_data[10 + (i * 3)] = i;     // index identifier
+               sof_data[11 + (i * 3)] = (ptr->h_samp_ratio[i] << 4) |
+                                        (ptr->v_samp_ratio[i]);        // sampling ratios
+               sof_data[12 + (i * 3)] = zr36050_tq[i]; // Q table selection
+       }
+       return zr36050_pushit(ptr, ZR050_SOF_IDX,
+                             (3 * NO_OF_COMPONENTS) + 10, sof_data);
+}
+
+/* ------------------------------------------------------------------------- */
+
+/*
+ * SOS (start of scan) segment depends on the used scan components
+ * of each color component
+ */
+
+static int zr36050_set_sos(struct zr36050 *ptr)
+{
+       struct zoran *zr = videocodec_to_zoran(ptr->codec);
+       char sos_data[16];      // max. size of register set
+       int i;
+
+       zrdev_dbg(zr, "%s: write SOS\n", ptr->name);
+       sos_data[0] = 0xff;
+       sos_data[1] = 0xda;
+       sos_data[2] = 0x00;
+       sos_data[3] = 2 + 1 + (2 * NO_OF_COMPONENTS) + 3;
+       sos_data[4] = NO_OF_COMPONENTS;
+       for (i = 0; i < NO_OF_COMPONENTS; i++) {
+               sos_data[5 + (i * 2)] = i;      // index
+               sos_data[6 + (i * 2)] = (zr36050_td[i] << 4) | zr36050_ta[i];   // AC/DC tbl.sel.
+       }
+       sos_data[2 + 1 + (2 * NO_OF_COMPONENTS) + 2] = 00;      // scan start
+       sos_data[2 + 1 + (2 * NO_OF_COMPONENTS) + 3] = 0x3F;
+       sos_data[2 + 1 + (2 * NO_OF_COMPONENTS) + 4] = 00;
+       return zr36050_pushit(ptr, ZR050_SOS1_IDX,
+                             4 + 1 + (2 * NO_OF_COMPONENTS) + 3,
+                             sos_data);
+}
+
+/* ------------------------------------------------------------------------- */
+
+/* DRI (define restart interval) */
+
+static int zr36050_set_dri(struct zr36050 *ptr)
+{
+       struct zoran *zr = videocodec_to_zoran(ptr->codec);
+       char dri_data[6];       // max. size of register set
+
+       zrdev_dbg(zr, "%s: write DRI\n", ptr->name);
+       dri_data[0] = 0xff;
+       dri_data[1] = 0xdd;
+       dri_data[2] = 0x00;
+       dri_data[3] = 0x04;
+       dri_data[4] = ptr->dri >> 8;
+       dri_data[5] = ptr->dri & 0xff;
+       return zr36050_pushit(ptr, ZR050_DRI_IDX, 6, dri_data);
+}
+
+/*
+ * Setup function:
+ *
+ * Setup compression/decompression of Zoran's JPEG processor
+ * ( see also zoran 36050 manual )
+ *
+ * ... sorry for the spaghetti code ...
+ */
+static void zr36050_init(struct zr36050 *ptr)
+{
+       int sum = 0;
+       long bitcnt, tmp;
+       struct zoran *zr = videocodec_to_zoran(ptr->codec);
+
+       if (ptr->mode == CODEC_DO_COMPRESSION) {
+               zrdev_dbg(zr, "%s: COMPRESSION SETUP\n", ptr->name);
+
+               /* 050 communicates with 057 in master mode */
+               zr36050_write(ptr, ZR050_HARDWARE, ZR050_HW_MSTR);
+
+               /* encoding table preload for compression */
+               zr36050_write(ptr, ZR050_MODE,
+                             ZR050_MO_COMP | ZR050_MO_TLM);
+               zr36050_write(ptr, ZR050_OPTIONS, 0);
+
+               /* disable all IRQs */
+               zr36050_write(ptr, ZR050_INT_REQ_0, 0);
+               zr36050_write(ptr, ZR050_INT_REQ_1, 3); // low 2 bits always 1
+
+               /* volume control settings */
+               /*zr36050_write(ptr, ZR050_MBCV, ptr->max_block_vol);*/
+               zr36050_write(ptr, ZR050_SF_HI, ptr->scalefact >> 8);
+               zr36050_write(ptr, ZR050_SF_LO, ptr->scalefact & 0xff);
+
+               zr36050_write(ptr, ZR050_AF_HI, 0xff);
+               zr36050_write(ptr, ZR050_AF_M, 0xff);
+               zr36050_write(ptr, ZR050_AF_LO, 0xff);
+
+               /* setup the variable jpeg tables */
+               sum += zr36050_set_sof(ptr);
+               sum += zr36050_set_sos(ptr);
+               sum += zr36050_set_dri(ptr);
+
+               /*
+                * setup the fixed jpeg tables - maybe variable, though -
+                * (see table init section above)
+                */
+               zrdev_dbg(zr, "%s: write DQT, DHT, APP\n", ptr->name);
+               sum += zr36050_pushit(ptr, ZR050_DQT_IDX,
+                                     sizeof(zr36050_dqt), zr36050_dqt);
+               sum += zr36050_pushit(ptr, ZR050_DHT_IDX,
+                                     sizeof(zr36050_dht), zr36050_dht);
+               zr36050_write(ptr, ZR050_APP_IDX, 0xff);
+               zr36050_write(ptr, ZR050_APP_IDX + 1, 0xe0 + ptr->app.appn);
+               zr36050_write(ptr, ZR050_APP_IDX + 2, 0x00);
+               zr36050_write(ptr, ZR050_APP_IDX + 3, ptr->app.len + 2);
+               sum += zr36050_pushit(ptr, ZR050_APP_IDX + 4, 60,
+                                     ptr->app.data) + 4;
+               zr36050_write(ptr, ZR050_COM_IDX, 0xff);
+               zr36050_write(ptr, ZR050_COM_IDX + 1, 0xfe);
+               zr36050_write(ptr, ZR050_COM_IDX + 2, 0x00);
+               zr36050_write(ptr, ZR050_COM_IDX + 3, ptr->com.len + 2);
+               sum += zr36050_pushit(ptr, ZR050_COM_IDX + 4, 60,
+                                     ptr->com.data) + 4;
+
+               /* do the internal huffman table preload */
+               zr36050_write(ptr, ZR050_MARKERS_EN, ZR050_ME_DHTI);
+
+               zr36050_write(ptr, ZR050_GO, 1);        // launch codec
+               zr36050_wait_end(ptr);
+               zrdev_dbg(zr, "%s: Status after table preload: 0x%02x\n",
+                         ptr->name, ptr->status1);
+
+               if ((ptr->status1 & 0x4) == 0) {
+                       zrdev_err(zr, "%s: init aborted!\n", ptr->name);
+                       return; // something is wrong, its timed out!!!!
+               }
+
+               /* setup misc. data for compression (target code sizes) */
+
+               /* size of compressed code to reach without header data */
+               sum = ptr->real_code_vol - sum;
+               bitcnt = sum << 3;      /* need the size in bits */
+
+               tmp = bitcnt >> 16;
+               zrdev_dbg(zr,
+                         "%s: code: csize=%d, tot=%d, bit=%ld, highbits=%ld\n",
+                         ptr->name, sum, ptr->real_code_vol, bitcnt, tmp);
+               zr36050_write(ptr, ZR050_TCV_NET_HI, tmp >> 8);
+               zr36050_write(ptr, ZR050_TCV_NET_MH, tmp & 0xff);
+               tmp = bitcnt & 0xffff;
+               zr36050_write(ptr, ZR050_TCV_NET_ML, tmp >> 8);
+               zr36050_write(ptr, ZR050_TCV_NET_LO, tmp & 0xff);
+
+               bitcnt -= bitcnt >> 7;  // bits without stuffing
+               bitcnt -= ((bitcnt * 5) >> 6);  // bits without eob
+
+               tmp = bitcnt >> 16;
+               zrdev_dbg(zr, "%s: code: nettobit=%ld, highnettobits=%ld\n",
+                         ptr->name, bitcnt, tmp);
+               zr36050_write(ptr, ZR050_TCV_DATA_HI, tmp >> 8);
+               zr36050_write(ptr, ZR050_TCV_DATA_MH, tmp & 0xff);
+               tmp = bitcnt & 0xffff;
+               zr36050_write(ptr, ZR050_TCV_DATA_ML, tmp >> 8);
+               zr36050_write(ptr, ZR050_TCV_DATA_LO, tmp & 0xff);
+
+               /* compression setup with or without bitrate control */
+               zr36050_write(ptr, ZR050_MODE,
+                             ZR050_MO_COMP | ZR050_MO_PASS2 |
+                             (ptr->bitrate_ctrl ? ZR050_MO_BRC : 0));
+
+               /* this headers seem to deliver "valid AVI" jpeg frames */
+               zr36050_write(ptr, ZR050_MARKERS_EN,
+                             ZR050_ME_DQT | ZR050_ME_DHT |
+                             ((ptr->app.len > 0) ? ZR050_ME_APP : 0) |
+                             ((ptr->com.len > 0) ? ZR050_ME_COM : 0));
+       } else {
+               zrdev_dbg(zr, "%s: EXPANSION SETUP\n", ptr->name);
+
+               /* 050 communicates with 055 in master mode */
+               zr36050_write(ptr, ZR050_HARDWARE,
+                             ZR050_HW_MSTR | ZR050_HW_CFIS_2_CLK);
+
+               /* encoding table preload */
+               zr36050_write(ptr, ZR050_MODE, ZR050_MO_TLM);
+
+               /* disable all IRQs */
+               zr36050_write(ptr, ZR050_INT_REQ_0, 0);
+               zr36050_write(ptr, ZR050_INT_REQ_1, 3); // low 2 bits always 1
+
+               zrdev_dbg(zr, "%s: write DHT\n", ptr->name);
+               zr36050_pushit(ptr, ZR050_DHT_IDX, sizeof(zr36050_dht),
+                              zr36050_dht);
+
+               /* do the internal huffman table preload */
+               zr36050_write(ptr, ZR050_MARKERS_EN, ZR050_ME_DHTI);
+
+               zr36050_write(ptr, ZR050_GO, 1);        // launch codec
+               zr36050_wait_end(ptr);
+               zrdev_dbg(zr, "%s: Status after table preload: 0x%02x\n",
+                         ptr->name, ptr->status1);
+
+               if ((ptr->status1 & 0x4) == 0) {
+                       zrdev_err(zr, "%s: init aborted!\n", ptr->name);
+                       return; // something is wrong, its timed out!!!!
+               }
+
+               /* setup misc. data for expansion */
+               zr36050_write(ptr, ZR050_MODE, 0);
+               zr36050_write(ptr, ZR050_MARKERS_EN, 0);
+       }
+
+       /* adr on selected, to allow GO from master */
+       zr36050_read(ptr, 0);
+}
+
+/*
+ * CODEC API FUNCTIONS
+ *
+ * this functions are accessed by the master via the API structure
+ */
+
+/*
+ * set compression/expansion mode and launches codec -
+ * this should be the last call from the master before starting processing
+ */
+static int zr36050_set_mode(struct videocodec *codec, int mode)
+{
+       struct zr36050 *ptr = (struct zr36050 *)codec->data;
+       struct zoran *zr = videocodec_to_zoran(codec);
+
+       zrdev_dbg(zr, "%s: set_mode %d call\n", ptr->name, mode);
+
+       if ((mode != CODEC_DO_EXPANSION) && (mode != CODEC_DO_COMPRESSION))
+               return -EINVAL;
+
+       ptr->mode = mode;
+       zr36050_init(ptr);
+
+       return 0;
+}
+
+/* set picture size (norm is ignored as the codec doesn't know about it) */
+static int zr36050_set_video(struct videocodec *codec, const struct tvnorm *norm,
+                            struct vfe_settings *cap, struct vfe_polarity *pol)
+{
+       struct zr36050 *ptr = (struct zr36050 *)codec->data;
+       struct zoran *zr = videocodec_to_zoran(codec);
+       int size;
+
+       zrdev_dbg(zr, "%s: set_video %d.%d, %d/%d-%dx%d (0x%x) q%d call\n",
+                 ptr->name, norm->h_start, norm->v_start,
+                 cap->x, cap->y, cap->width, cap->height,
+                 cap->decimation, cap->quality);
+       /*
+        * trust the master driver that it knows what it does - so
+        * we allow invalid startx/y and norm for now ...
+        */
+       ptr->width = cap->width / (cap->decimation & 0xff);
+       ptr->height = cap->height / ((cap->decimation >> 8) & 0xff);
+
+       /* (KM) JPEG quality */
+       size = ptr->width * ptr->height;
+       size *= 16; /* size in bits */
+       /* apply quality setting */
+       size = size * cap->quality / 200;
+
+       /* Minimum: 1kb */
+       if (size < 8192)
+               size = 8192;
+       /* Maximum: 7/8 of code buffer */
+       if (size > ptr->total_code_vol * 7)
+               size = ptr->total_code_vol * 7;
+
+       ptr->real_code_vol = size >> 3; /* in bytes */
+
+       /*
+        * Set max_block_vol here (previously in zr36050_init, moved
+        * here for consistency with zr36060 code
+        */
+       zr36050_write(ptr, ZR050_MBCV, ptr->max_block_vol);
+
+       return 0;
+}
+
+/* additional control functions */
+static int zr36050_control(struct videocodec *codec, int type, int size, void *data)
+{
+       struct zr36050 *ptr = (struct zr36050 *)codec->data;
+       struct zoran *zr = videocodec_to_zoran(codec);
+       int *ival = (int *)data;
+
+       zrdev_dbg(zr, "%s: control %d call with %d byte\n", ptr->name, type,
+                 size);
+
+       switch (type) {
+       case CODEC_G_STATUS:    /* get last status */
+               if (size != sizeof(int))
+                       return -EFAULT;
+               zr36050_read_status1(ptr);
+               *ival = ptr->status1;
+               break;
+
+       case CODEC_G_CODEC_MODE:
+               if (size != sizeof(int))
+                       return -EFAULT;
+               *ival = CODEC_MODE_BJPG;
+               break;
+
+       case CODEC_S_CODEC_MODE:
+               if (size != sizeof(int))
+                       return -EFAULT;
+               if (*ival != CODEC_MODE_BJPG)
+                       return -EINVAL;
+               /* not needed, do nothing */
+               return 0;
+
+       case CODEC_G_VFE:
+       case CODEC_S_VFE:
+               /* not needed, do nothing */
+               return 0;
+
+       case CODEC_S_MMAP:
+               /* not available, give an error */
+               return -ENXIO;
+
+       case CODEC_G_JPEG_TDS_BYTE:     /* get target volume in byte */
+               if (size != sizeof(int))
+                       return -EFAULT;
+               *ival = ptr->total_code_vol;
+               break;
+
+       case CODEC_S_JPEG_TDS_BYTE:     /* get target volume in byte */
+               if (size != sizeof(int))
+                       return -EFAULT;
+               ptr->total_code_vol = *ival;
+               ptr->real_code_vol = (ptr->total_code_vol * 6) >> 3;
+               break;
+
+       case CODEC_G_JPEG_SCALE:        /* get scaling factor */
+               if (size != sizeof(int))
+                       return -EFAULT;
+               *ival = zr36050_read_scalefactor(ptr);
+               break;
+
+       case CODEC_S_JPEG_SCALE:        /* set scaling factor */
+               if (size != sizeof(int))
+                       return -EFAULT;
+               ptr->scalefact = *ival;
+               break;
+
+       case CODEC_G_JPEG_APP_DATA: {   /* get appn marker data */
+               struct jpeg_app_marker *app = data;
+
+               if (size != sizeof(struct jpeg_app_marker))
+                       return -EFAULT;
+
+               *app = ptr->app;
+               break;
+       }
+
+       case CODEC_S_JPEG_APP_DATA: {    /* set appn marker data */
+               struct jpeg_app_marker *app = data;
+
+               if (size != sizeof(struct jpeg_app_marker))
+                       return -EFAULT;
+
+               ptr->app = *app;
+               break;
+       }
+
+       case CODEC_G_JPEG_COM_DATA: {   /* get comment marker data */
+               struct jpeg_com_marker *com = data;
+
+               if (size != sizeof(struct jpeg_com_marker))
+                       return -EFAULT;
+
+               *com = ptr->com;
+               break;
+       }
+
+       case CODEC_S_JPEG_COM_DATA: {   /* set comment marker data */
+               struct jpeg_com_marker *com = data;
+
+               if (size != sizeof(struct jpeg_com_marker))
+                       return -EFAULT;
+
+               ptr->com = *com;
+               break;
+       }
+
+       default:
+               return -EINVAL;
+       }
+
+       return size;
+}
+
+/* Exit and unregister function: Deinitializes Zoran's JPEG processor */
+
+static int zr36050_unset(struct videocodec *codec)
+{
+       struct zr36050 *ptr = codec->data;
+       struct zoran *zr = videocodec_to_zoran(codec);
+
+       if (ptr) {
+               /* do wee need some codec deinit here, too ???? */
+
+               zrdev_dbg(zr, "%s: finished codec #%d\n", ptr->name,
+                         ptr->num);
+               kfree(ptr);
+               codec->data = NULL;
+
+               zr36050_codecs--;
+               return 0;
+       }
+
+       return -EFAULT;
+}
+
+/*
+ * Setup and registry function:
+ *
+ * Initializes Zoran's JPEG processor
+ *
+ * Also sets pixel size, average code size, mode (compr./decompr.)
+ * (the given size is determined by the processor with the video interface)
+ */
+
+static int zr36050_setup(struct videocodec *codec)
+{
+       struct zr36050 *ptr;
+       struct zoran *zr = videocodec_to_zoran(codec);
+       int res;
+
+       zrdev_dbg(zr, "zr36050: initializing MJPEG subsystem #%d.\n",
+                 zr36050_codecs);
+
+       if (zr36050_codecs == MAX_CODECS) {
+               zrdev_err(zr,
+                         "zr36050: Can't attach more codecs!\n");
+               return -ENOSPC;
+       }
+       //mem structure init
+       ptr = kzalloc(sizeof(*ptr), GFP_KERNEL);
+       codec->data = ptr;
+       if (!ptr)
+               return -ENOMEM;
+
+       snprintf(ptr->name, sizeof(ptr->name), "zr36050[%d]",
+                zr36050_codecs);
+       ptr->num = zr36050_codecs++;
+       ptr->codec = codec;
+
+       //testing
+       res = zr36050_basic_test(ptr);
+       if (res < 0) {
+               zr36050_unset(codec);
+               return res;
+       }
+       //final setup
+       memcpy(ptr->h_samp_ratio, zr36050_decimation_h, 8);
+       memcpy(ptr->v_samp_ratio, zr36050_decimation_v, 8);
+
+       /* 0 or 1 - fixed file size flag (what is the difference?) */
+       ptr->bitrate_ctrl = 0;
+       ptr->mode = CODEC_DO_COMPRESSION;
+       ptr->width = 384;
+       ptr->height = 288;
+       ptr->total_code_vol = 16000;
+       ptr->max_block_vol = 240;
+       ptr->scalefact = 0x100;
+       ptr->dri = 1;
+
+       /* no app/com marker by default */
+       ptr->app.appn = 0;
+       ptr->app.len = 0;
+       ptr->com.len = 0;
+
+       zr36050_init(ptr);
+
+       zrdev_info(zr, "%s: codec attached and running\n",
+                  ptr->name);
+
+       return 0;
+}
+
+static const struct videocodec zr36050_codec = {
+       .name = "zr36050",
+       .magic = 0L,            // magic not used
+       .flags =
+           CODEC_FLAG_JPEG | CODEC_FLAG_HARDWARE | CODEC_FLAG_ENCODER |
+           CODEC_FLAG_DECODER,
+       .type = CODEC_TYPE_ZR36050,
+       .setup = zr36050_setup, // functionality
+       .unset = zr36050_unset,
+       .set_mode = zr36050_set_mode,
+       .set_video = zr36050_set_video,
+       .control = zr36050_control,
+       // others are not used
+};
+
+/* HOOK IN DRIVER AS KERNEL MODULE */
+
+int zr36050_init_module(void)
+{
+       zr36050_codecs = 0;
+       return videocodec_register(&zr36050_codec);
+}
+
+void zr36050_cleanup_module(void)
+{
+       if (zr36050_codecs) {
+               pr_debug("zr36050: something's wrong - %d codecs left somehow.\n",
+                        zr36050_codecs);
+       }
+       videocodec_unregister(&zr36050_codec);
+}
 
--- /dev/null
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Zoran ZR36050 basic configuration functions - header file
+ *
+ * Copyright (C) 2001 Wolfgang Scherr <scherr@net4you.at>
+ */
+
+#ifndef ZR36050_H
+#define ZR36050_H
+
+#include "videocodec.h"
+
+/* data stored for each zoran jpeg codec chip */
+struct zr36050 {
+       char name[32];
+       int num;
+       /* io datastructure */
+       struct videocodec *codec;
+       // last coder status
+       __u8 status1;
+       // actual coder setup
+       int mode;
+
+       __u16 width;
+       __u16 height;
+
+       __u16 bitrate_ctrl;
+
+       __u32 total_code_vol;
+       __u32 real_code_vol;
+       __u16 max_block_vol;
+
+       __u8 h_samp_ratio[8];
+       __u8 v_samp_ratio[8];
+       __u16 scalefact;
+       __u16 dri;
+
+       /* com/app marker */
+       struct jpeg_com_marker com;
+       struct jpeg_app_marker app;
+};
+
+/* zr36050 register addresses */
+#define ZR050_GO                  0x000
+#define ZR050_HARDWARE            0x002
+#define ZR050_MODE                0x003
+#define ZR050_OPTIONS             0x004
+#define ZR050_MBCV                0x005
+#define ZR050_MARKERS_EN          0x006
+#define ZR050_INT_REQ_0           0x007
+#define ZR050_INT_REQ_1           0x008
+#define ZR050_TCV_NET_HI          0x009
+#define ZR050_TCV_NET_MH          0x00a
+#define ZR050_TCV_NET_ML          0x00b
+#define ZR050_TCV_NET_LO          0x00c
+#define ZR050_TCV_DATA_HI         0x00d
+#define ZR050_TCV_DATA_MH         0x00e
+#define ZR050_TCV_DATA_ML         0x00f
+#define ZR050_TCV_DATA_LO         0x010
+#define ZR050_SF_HI               0x011
+#define ZR050_SF_LO               0x012
+#define ZR050_AF_HI               0x013
+#define ZR050_AF_M                0x014
+#define ZR050_AF_LO               0x015
+#define ZR050_ACV_HI              0x016
+#define ZR050_ACV_MH              0x017
+#define ZR050_ACV_ML              0x018
+#define ZR050_ACV_LO              0x019
+#define ZR050_ACT_HI              0x01a
+#define ZR050_ACT_MH              0x01b
+#define ZR050_ACT_ML              0x01c
+#define ZR050_ACT_LO              0x01d
+#define ZR050_ACV_TURN_HI         0x01e
+#define ZR050_ACV_TURN_MH         0x01f
+#define ZR050_ACV_TURN_ML         0x020
+#define ZR050_ACV_TURN_LO         0x021
+#define ZR050_STATUS_0            0x02e
+#define ZR050_STATUS_1            0x02f
+
+#define ZR050_SOF_IDX             0x040
+#define ZR050_SOS1_IDX            0x07a
+#define ZR050_SOS2_IDX            0x08a
+#define ZR050_SOS3_IDX            0x09a
+#define ZR050_SOS4_IDX            0x0aa
+#define ZR050_DRI_IDX             0x0c0
+#define ZR050_DNL_IDX             0x0c6
+#define ZR050_DQT_IDX             0x0cc
+#define ZR050_DHT_IDX             0x1d4
+#define ZR050_APP_IDX             0x380
+#define ZR050_COM_IDX             0x3c0
+
+/* zr36050 hardware register bits */
+
+#define ZR050_HW_BSWD                0x80
+#define ZR050_HW_MSTR                0x40
+#define ZR050_HW_DMA                 0x20
+#define ZR050_HW_CFIS_1_CLK          0x00
+#define ZR050_HW_CFIS_2_CLK          0x04
+#define ZR050_HW_CFIS_3_CLK          0x08
+#define ZR050_HW_CFIS_4_CLK          0x0C
+#define ZR050_HW_CFIS_5_CLK          0x10
+#define ZR050_HW_CFIS_6_CLK          0x14
+#define ZR050_HW_CFIS_7_CLK          0x18
+#define ZR050_HW_CFIS_8_CLK          0x1C
+#define ZR050_HW_BELE                0x01
+
+/* zr36050 mode register bits */
+
+#define ZR050_MO_COMP                0x80
+#define ZR050_MO_ATP                 0x40
+#define ZR050_MO_PASS2               0x20
+#define ZR050_MO_TLM                 0x10
+#define ZR050_MO_DCONLY              0x08
+#define ZR050_MO_BRC                 0x04
+
+#define ZR050_MO_ATP                 0x40
+#define ZR050_MO_PASS2               0x20
+#define ZR050_MO_TLM                 0x10
+#define ZR050_MO_DCONLY              0x08
+
+/* zr36050 option register bits */
+
+#define ZR050_OP_NSCN_1              0x00
+#define ZR050_OP_NSCN_2              0x20
+#define ZR050_OP_NSCN_3              0x40
+#define ZR050_OP_NSCN_4              0x60
+#define ZR050_OP_NSCN_5              0x80
+#define ZR050_OP_NSCN_6              0xA0
+#define ZR050_OP_NSCN_7              0xC0
+#define ZR050_OP_NSCN_8              0xE0
+#define ZR050_OP_OVF                 0x10
+
+/* zr36050 markers-enable register bits */
+
+#define ZR050_ME_APP                 0x80
+#define ZR050_ME_COM                 0x40
+#define ZR050_ME_DRI                 0x20
+#define ZR050_ME_DQT                 0x10
+#define ZR050_ME_DHT                 0x08
+#define ZR050_ME_DNL                 0x04
+#define ZR050_ME_DQTI                0x02
+#define ZR050_ME_DHTI                0x01
+
+/* zr36050 status0/1 register bit masks */
+
+#define ZR050_ST_RST_MASK            0x20
+#define ZR050_ST_SOF_MASK            0x02
+#define ZR050_ST_SOS_MASK            0x02
+#define ZR050_ST_DATRDY_MASK         0x80
+#define ZR050_ST_MRKDET_MASK         0x40
+#define ZR050_ST_RFM_MASK            0x10
+#define ZR050_ST_RFD_MASK            0x08
+#define ZR050_ST_END_MASK            0x04
+#define ZR050_ST_TCVOVF_MASK         0x02
+#define ZR050_ST_DATOVF_MASK         0x01
+
+/* pixel component idx */
+
+#define ZR050_Y_COMPONENT         0
+#define ZR050_U_COMPONENT         1
+#define ZR050_V_COMPONENT         2
+
+int zr36050_init_module(void);
+void zr36050_cleanup_module(void);
+#endif                         /*fndef ZR36050_H */
 
--- /dev/null
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * zr36057.h - zr36057 register offsets
+ *
+ * Copyright (C) 1998 Dave Perks <dperks@ibm.net>
+ */
+
+#ifndef _ZR36057_H_
+#define _ZR36057_H_
+
+/* Zoran ZR36057 registers */
+
+#define ZR36057_VFEHCR          0x000  /* Video Front End, Horizontal Configuration Register */
+#define ZR36057_VFEHCR_HS_POL           BIT(30)
+#define ZR36057_VFEHCR_H_START          10
+#define ZR36057_VFEHCR_H_END           0
+#define ZR36057_VFEHCR_HMASK           0x3ff
+
+#define ZR36057_VFEVCR          0x004  /* Video Front End, Vertical Configuration Register */
+#define ZR36057_VFEVCR_VS_POL           BIT(30)
+#define ZR36057_VFEVCR_V_START          10
+#define ZR36057_VFEVCR_V_END           0
+#define ZR36057_VFEVCR_VMASK           0x3ff
+
+#define ZR36057_VFESPFR         0x008  /* Video Front End, Scaler and Pixel Format Register */
+#define ZR36057_VFESPFR_EXT_FL          BIT(26)
+#define ZR36057_VFESPFR_TOP_FIELD       BIT(25)
+#define ZR36057_VFESPFR_VCLK_POL        BIT(24)
+#define ZR36057_VFESPFR_H_FILTER        21
+#define ZR36057_VFESPFR_HOR_DCM         14
+#define ZR36057_VFESPFR_VER_DCM         8
+#define ZR36057_VFESPFR_DISP_MODE       6
+#define ZR36057_VFESPFR_YUV422          (0 << 3)
+#define ZR36057_VFESPFR_RGB888          (1 << 3)
+#define ZR36057_VFESPFR_RGB565          (2 << 3)
+#define ZR36057_VFESPFR_RGB555          (3 << 3)
+#define ZR36057_VFESPFR_ERR_DIF         BIT(2)
+#define ZR36057_VFESPFR_PACK24          BIT(1)
+#define ZR36057_VFESPFR_LITTLE_ENDIAN   BIT(0)
+
+#define ZR36057_VDTR            0x00c  /* Video Display "Top" Register */
+
+#define ZR36057_VDBR            0x010  /* Video Display "Bottom" Register */
+
+#define ZR36057_VSSFGR          0x014  /* Video Stride, Status, and Frame Grab Register */
+#define ZR36057_VSSFGR_DISP_STRIDE      16
+#define ZR36057_VSSFGR_VID_OVF          BIT(8)
+#define ZR36057_VSSFGR_SNAP_SHOT        BIT(1)
+#define ZR36057_VSSFGR_FRAME_GRAB       BIT(0)
+
+#define ZR36057_VDCR            0x018  /* Video Display Configuration Register */
+#define ZR36057_VDCR_VID_EN             BIT(31)
+#define ZR36057_VDCR_MIN_PIX            24
+#define ZR36057_VDCR_TRITON             BIT(24)
+#define ZR36057_VDCR_VID_WIN_HT         12
+#define ZR36057_VDCR_VID_WIN_WID        0
+
+#define ZR36057_MMTR            0x01c  /* Masking Map "Top" Register */
+
+#define ZR36057_MMBR            0x020  /* Masking Map "Bottom" Register */
+
+#define ZR36057_OCR             0x024  /* Overlay Control Register */
+#define ZR36057_OCR_OVL_ENABLE          BIT(15)
+#define ZR36057_OCR_MASK_STRIDE         0
+
+#define ZR36057_SPGPPCR         0x028  /* System, PCI, and General Purpose Pins Control Register */
+#define ZR36057_SPGPPCR_SOFT_RESET     BIT(24)
+
+#define ZR36057_GPPGCR1         0x02c  /* General Purpose Pins and GuestBus Control Register (1) */
+
+#define ZR36057_MCSAR           0x030  /* MPEG Code Source Address Register */
+
+#define ZR36057_MCTCR           0x034  /* MPEG Code Transfer Control Register */
+#define ZR36057_MCTCR_COD_TIME          BIT(30)
+#define ZR36057_MCTCR_C_EMPTY           BIT(29)
+#define ZR36057_MCTCR_C_FLUSH           BIT(28)
+#define ZR36057_MCTCR_COD_GUEST_ID     20
+#define ZR36057_MCTCR_COD_GUEST_REG    16
+
+#define ZR36057_MCMPR           0x038  /* MPEG Code Memory Pointer Register */
+
+#define ZR36057_ISR             0x03c  /* Interrupt Status Register */
+#define ZR36057_ISR_GIRQ1               BIT(30)
+#define ZR36057_ISR_GIRQ0               BIT(29)
+#define ZR36057_ISR_COD_REP_IRQ         BIT(28)
+#define ZR36057_ISR_JPEG_REP_IRQ        BIT(27)
+
+#define ZR36057_ICR             0x040  /* Interrupt Control Register */
+#define ZR36057_ICR_GIRQ1               BIT(30)
+#define ZR36057_ICR_GIRQ0               BIT(29)
+#define ZR36057_ICR_COD_REP_IRQ         BIT(28)
+#define ZR36057_ICR_JPEG_REP_IRQ        BIT(27)
+#define ZR36057_ICR_INT_PIN_EN          BIT(24)
+
+#define ZR36057_I2CBR           0x044  /* I2C Bus Register */
+#define ZR36057_I2CBR_SDA              BIT(1)
+#define ZR36057_I2CBR_SCL              BIT(0)
+
+#define ZR36057_JMC             0x100  /* JPEG Mode and Control */
+#define ZR36057_JMC_JPG                 BIT(31)
+#define ZR36057_JMC_JPG_EXP_MODE        (0 << 29)
+#define ZR36057_JMC_JPG_CMP_MODE        BIT(29)
+#define ZR36057_JMC_MJPG_EXP_MODE       (2 << 29)
+#define ZR36057_JMC_MJPG_CMP_MODE       (3 << 29)
+#define ZR36057_JMC_RTBUSY_FB           BIT(6)
+#define ZR36057_JMC_GO_EN               BIT(5)
+#define ZR36057_JMC_SYNC_MSTR           BIT(4)
+#define ZR36057_JMC_FLD_PER_BUFF        BIT(3)
+#define ZR36057_JMC_VFIFO_FB            BIT(2)
+#define ZR36057_JMC_CFIFO_FB            BIT(1)
+#define ZR36057_JMC_STLL_LIT_ENDIAN     BIT(0)
+
+#define ZR36057_JPC             0x104  /* JPEG Process Control */
+#define ZR36057_JPC_P_RESET             BIT(7)
+#define ZR36057_JPC_COD_TRNS_EN         BIT(5)
+#define ZR36057_JPC_ACTIVE              BIT(0)
+
+#define ZR36057_VSP             0x108  /* Vertical Sync Parameters */
+#define ZR36057_VSP_VSYNC_SIZE          16
+#define ZR36057_VSP_FRM_TOT             0
+
+#define ZR36057_HSP             0x10c  /* Horizontal Sync Parameters */
+#define ZR36057_HSP_HSYNC_START         16
+#define ZR36057_HSP_LINE_TOT            0
+
+#define ZR36057_FHAP            0x110  /* Field Horizontal Active Portion */
+#define ZR36057_FHAP_NAX                16
+#define ZR36057_FHAP_PAX                0
+
+#define ZR36057_FVAP            0x114  /* Field Vertical Active Portion */
+#define ZR36057_FVAP_NAY                16
+#define ZR36057_FVAP_PAY                0
+
+#define ZR36057_FPP             0x118  /* Field Process Parameters */
+#define ZR36057_FPP_ODD_EVEN            BIT(0)
+
+#define ZR36057_JCBA            0x11c  /* JPEG Code Base Address */
+
+#define ZR36057_JCFT            0x120  /* JPEG Code FIFO Threshold */
+
+#define ZR36057_JCGI            0x124  /* JPEG Codec Guest ID */
+#define ZR36057_JCGI_JPE_GUEST_ID       4
+#define ZR36057_JCGI_JPE_GUEST_REG      0
+
+#define ZR36057_GCR2            0x12c  /* GuestBus Control Register (2) */
+
+#define ZR36057_POR             0x200  /* Post Office Register */
+#define ZR36057_POR_PO_PEN              BIT(25)
+#define ZR36057_POR_PO_TIME             BIT(24)
+#define ZR36057_POR_PO_DIR              BIT(23)
+
+#define ZR36057_STR             0x300  /* "Still" Transfer Register */
+
+#endif
 
--- /dev/null
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Zoran ZR36060 basic configuration functions
+ *
+ * Copyright (C) 2002 Laurent Pinchart <laurent.pinchart@skynet.be>
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+
+#include <linux/types.h>
+#include <linux/wait.h>
+
+/* I/O commands, error codes */
+#include <linux/io.h>
+
+/* headerfile of this module */
+#include "zr36060.h"
+
+/* codec io API */
+#include "videocodec.h"
+
+/* it doesn't make sense to have more than 20 or so, just to prevent some unwanted loops */
+#define MAX_CODECS 20
+
+/* amount of chips attached via this driver */
+static int zr36060_codecs;
+
+static bool low_bitrate;
+module_param(low_bitrate, bool, 0);
+MODULE_PARM_DESC(low_bitrate, "Buz compatibility option, halves bitrate");
+
+/* =========================================================================
+ * Local hardware I/O functions:
+ * read/write via codec layer (registers are located in the master device)
+ * =========================================================================
+ */
+
+static u8 zr36060_read(struct zr36060 *ptr, u16 reg)
+{
+       u8 value = 0;
+       struct zoran *zr = videocodec_to_zoran(ptr->codec);
+
+       // just in case something is wrong...
+       if (ptr->codec->master_data->readreg)
+               value = (ptr->codec->master_data->readreg(ptr->codec, reg)) & 0xff;
+       else
+               zrdev_err(zr, "%s: invalid I/O setup, nothing read!\n", ptr->name);
+
+       return value;
+}
+
+static void zr36060_write(struct zr36060 *ptr, u16 reg, u8 value)
+{
+       struct zoran *zr = videocodec_to_zoran(ptr->codec);
+
+       zrdev_dbg(zr, "0x%02x @0x%04x\n", value, reg);
+
+       // just in case something is wrong...
+       if (ptr->codec->master_data->writereg)
+               ptr->codec->master_data->writereg(ptr->codec, reg, value);
+       else
+               zrdev_err(zr, "%s: invalid I/O setup, nothing written!\n", ptr->name);
+}
+
+/* =========================================================================
+ * Local helper function:
+ * status read
+ * =========================================================================
+ */
+
+/* status is kept in datastructure */
+static u8 zr36060_read_status(struct zr36060 *ptr)
+{
+       ptr->status = zr36060_read(ptr, ZR060_CFSR);
+
+       zr36060_read(ptr, 0);
+       return ptr->status;
+}
+
+/* scale factor is kept in datastructure */
+static u16 zr36060_read_scalefactor(struct zr36060 *ptr)
+{
+       ptr->scalefact = (zr36060_read(ptr, ZR060_SF_HI) << 8) |
+                        (zr36060_read(ptr, ZR060_SF_LO) & 0xFF);
+
+       /* leave 0 selected for an eventually GO from master */
+       zr36060_read(ptr, 0);
+       return ptr->scalefact;
+}
+
+/* wait if codec is ready to proceed (end of processing) or time is over */
+static void zr36060_wait_end(struct zr36060 *ptr)
+{
+       struct zoran *zr = videocodec_to_zoran(ptr->codec);
+       int i = 0;
+
+       while (zr36060_read_status(ptr) & ZR060_CFSR_BUSY) {
+               udelay(1);
+               if (i++ > 200000) {     // 200ms, there is for sure something wrong!!!
+                       zrdev_dbg(zr,
+                                 "%s: timeout at wait_end (last status: 0x%02x)\n",
+                                 ptr->name, ptr->status);
+                       break;
+               }
+       }
+}
+
+/* Basic test of "connectivity", writes/reads to/from memory the SOF marker */
+static int zr36060_basic_test(struct zr36060 *ptr)
+{
+       struct zoran *zr = videocodec_to_zoran(ptr->codec);
+
+       if ((zr36060_read(ptr, ZR060_IDR_DEV) != 0x33) &&
+           (zr36060_read(ptr, ZR060_IDR_REV) != 0x01)) {
+               zrdev_err(zr, "%s: attach failed, can't connect to jpeg processor!\n", ptr->name);
+               return -ENXIO;
+       }
+
+       zr36060_wait_end(ptr);
+       if (ptr->status & ZR060_CFSR_BUSY) {
+               zrdev_err(zr, "%s: attach failed, jpeg processor failed (end flag)!\n", ptr->name);
+               return -EBUSY;
+       }
+
+       return 0;               /* looks good! */
+}
+
+/* simple loop for pushing the init datasets */
+static int zr36060_pushit(struct zr36060 *ptr, u16 startreg, u16 len, const char *data)
+{
+       struct zoran *zr = videocodec_to_zoran(ptr->codec);
+       int i = 0;
+
+       zrdev_dbg(zr, "%s: write data block to 0x%04x (len=%d)\n", ptr->name,
+                 startreg, len);
+       while (i < len)
+               zr36060_write(ptr, startreg++, data[i++]);
+
+       return i;
+}
+
+/* =========================================================================
+ * Basic datasets:
+ * jpeg baseline setup data (you find it on lots places in internet, or just
+ * extract it from any regular .jpg image...)
+ *
+ * Could be variable, but until it's not needed it they are just fixed to save
+ * memory. Otherwise expand zr36060 structure with arrays, push the values to
+ * it and initialize from there, as e.g. the linux zr36057/60 driver does it.
+ * =========================================================================
+ */
+static const char zr36060_dqt[0x86] = {
+       0xff, 0xdb,             //Marker: DQT
+       0x00, 0x84,             //Length: 2*65+2
+       0x00,                   //Pq,Tq first table
+       0x10, 0x0b, 0x0c, 0x0e, 0x0c, 0x0a, 0x10, 0x0e,
+       0x0d, 0x0e, 0x12, 0x11, 0x10, 0x13, 0x18, 0x28,
+       0x1a, 0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25,
+       0x1d, 0x28, 0x3a, 0x33, 0x3d, 0x3c, 0x39, 0x33,
+       0x38, 0x37, 0x40, 0x48, 0x5c, 0x4e, 0x40, 0x44,
+       0x57, 0x45, 0x37, 0x38, 0x50, 0x6d, 0x51, 0x57,
+       0x5f, 0x62, 0x67, 0x68, 0x67, 0x3e, 0x4d, 0x71,
+       0x79, 0x70, 0x64, 0x78, 0x5c, 0x65, 0x67, 0x63,
+       0x01,                   //Pq,Tq second table
+       0x11, 0x12, 0x12, 0x18, 0x15, 0x18, 0x2f, 0x1a,
+       0x1a, 0x2f, 0x63, 0x42, 0x38, 0x42, 0x63, 0x63,
+       0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
+       0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
+       0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
+       0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
+       0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
+       0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63
+};
+
+static const char zr36060_dht[0x1a4] = {
+       0xff, 0xc4,             //Marker: DHT
+       0x01, 0xa2,             //Length: 2*AC, 2*DC
+       0x00,                   //DC first table
+       0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01,
+       0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+       0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,
+       0x01,                   //DC second table
+       0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+       0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+       0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,
+       0x10,                   //AC first table
+       0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03,
+       0x05, 0x05, 0x04, 0x04, 0x00, 0x00,
+       0x01, 0x7D, 0x01, 0x02, 0x03, 0x00, 0x04, 0x11,
+       0x05, 0x12, 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61,
+       0x07, 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xA1,
+       0x08, 0x23, 0x42, 0xB1, 0xC1, 0x15, 0x52, 0xD1, 0xF0, 0x24,
+       0x33, 0x62, 0x72, 0x82, 0x09, 0x0A, 0x16, 0x17,
+       0x18, 0x19, 0x1A, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x34,
+       0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x43, 0x44,
+       0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56,
+       0x57, 0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66,
+       0x67, 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
+       0x79, 0x7A, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88,
+       0x89, 0x8A, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99,
+       0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8,
+       0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9,
+       0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8,
+       0xC9, 0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9,
+       0xDA, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
+       0xE8, 0xE9, 0xEA, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
+       0xF8, 0xF9, 0xFA,
+       0x11,                   //AC second table
+       0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04,
+       0x07, 0x05, 0x04, 0x04, 0x00, 0x01,
+       0x02, 0x77, 0x00, 0x01, 0x02, 0x03, 0x11, 0x04,
+       0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
+       0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
+       0xA1, 0xB1, 0xC1, 0x09, 0x23, 0x33, 0x52, 0xF0, 0x15, 0x62,
+       0x72, 0xD1, 0x0A, 0x16, 0x24, 0x34, 0xE1, 0x25,
+       0xF1, 0x17, 0x18, 0x19, 0x1A, 0x26, 0x27, 0x28, 0x29, 0x2A,
+       0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x43, 0x44,
+       0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56,
+       0x57, 0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66,
+       0x67, 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
+       0x79, 0x7A, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
+       0x88, 0x89, 0x8A, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
+       0x99, 0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7,
+       0xA8, 0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8,
+       0xB9, 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
+       0xC8, 0xC9, 0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8,
+       0xD9, 0xDA, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
+       0xE8, 0xE9, 0xEA, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8,
+       0xF9, 0xFA
+};
+
+/* jpeg baseline setup, this is just fixed in this driver (YUV pictures) */
+#define NO_OF_COMPONENTS          0x3  //Y,U,V
+#define BASELINE_PRECISION        0x8  //MCU size (?)
+static const char zr36060_tq[8] = { 0, 1, 1, 0, 0, 0, 0, 0 };  //table idx's QT
+static const char zr36060_td[8] = { 0, 1, 1, 0, 0, 0, 0, 0 };  //table idx's DC
+static const char zr36060_ta[8] = { 0, 1, 1, 0, 0, 0, 0, 0 };  //table idx's AC
+
+/* horizontal 422 decimation setup (maybe we support 411 or so later, too) */
+static const char zr36060_decimation_h[8] = { 2, 1, 1, 0, 0, 0, 0, 0 };
+static const char zr36060_decimation_v[8] = { 1, 1, 1, 0, 0, 0, 0, 0 };
+
+/*
+ * SOF (start of frame) segment depends on width, height and sampling ratio
+ * of each color component
+ */
+static int zr36060_set_sof(struct zr36060 *ptr)
+{
+       struct zoran *zr = videocodec_to_zoran(ptr->codec);
+       char sof_data[34];      // max. size of register set
+       int i;
+
+       zrdev_dbg(zr, "%s: write SOF (%dx%d, %d components)\n", ptr->name,
+                 ptr->width, ptr->height, NO_OF_COMPONENTS);
+       sof_data[0] = 0xff;
+       sof_data[1] = 0xc0;
+       sof_data[2] = 0x00;
+       sof_data[3] = (3 * NO_OF_COMPONENTS) + 8;
+       sof_data[4] = BASELINE_PRECISION;       // only '8' possible with zr36060
+       sof_data[5] = (ptr->height) >> 8;
+       sof_data[6] = (ptr->height) & 0xff;
+       sof_data[7] = (ptr->width) >> 8;
+       sof_data[8] = (ptr->width) & 0xff;
+       sof_data[9] = NO_OF_COMPONENTS;
+       for (i = 0; i < NO_OF_COMPONENTS; i++) {
+               sof_data[10 + (i * 3)] = i;     // index identifier
+               sof_data[11 + (i * 3)] = (ptr->h_samp_ratio[i] << 4) |
+                                        (ptr->v_samp_ratio[i]); // sampling ratios
+               sof_data[12 + (i * 3)] = zr36060_tq[i]; // Q table selection
+       }
+       return zr36060_pushit(ptr, ZR060_SOF_IDX,
+                             (3 * NO_OF_COMPONENTS) + 10, sof_data);
+}
+
+/* SOS (start of scan) segment depends on the used scan components of each color component */
+static int zr36060_set_sos(struct zr36060 *ptr)
+{
+       struct zoran *zr = videocodec_to_zoran(ptr->codec);
+       char sos_data[16];      // max. size of register set
+       int i;
+
+       zrdev_dbg(zr, "%s: write SOS\n", ptr->name);
+       sos_data[0] = 0xff;
+       sos_data[1] = 0xda;
+       sos_data[2] = 0x00;
+       sos_data[3] = 2 + 1 + (2 * NO_OF_COMPONENTS) + 3;
+       sos_data[4] = NO_OF_COMPONENTS;
+       for (i = 0; i < NO_OF_COMPONENTS; i++) {
+               sos_data[5 + (i * 2)] = i;      // index
+               sos_data[6 + (i * 2)] = (zr36060_td[i] << 4) |
+                                       zr36060_ta[i]; // AC/DC tbl.sel.
+       }
+       sos_data[2 + 1 + (2 * NO_OF_COMPONENTS) + 2] = 00;      // scan start
+       sos_data[2 + 1 + (2 * NO_OF_COMPONENTS) + 3] = 0x3f;
+       sos_data[2 + 1 + (2 * NO_OF_COMPONENTS) + 4] = 00;
+       return zr36060_pushit(ptr, ZR060_SOS_IDX,
+                             4 + 1 + (2 * NO_OF_COMPONENTS) + 3,
+                             sos_data);
+}
+
+/* DRI (define restart interval) */
+static int zr36060_set_dri(struct zr36060 *ptr)
+{
+       struct zoran *zr = videocodec_to_zoran(ptr->codec);
+       char dri_data[6];       // max. size of register set
+
+       zrdev_dbg(zr, "%s: write DRI\n", ptr->name);
+       dri_data[0] = 0xff;
+       dri_data[1] = 0xdd;
+       dri_data[2] = 0x00;
+       dri_data[3] = 0x04;
+       dri_data[4] = (ptr->dri) >> 8;
+       dri_data[5] = (ptr->dri) & 0xff;
+       return zr36060_pushit(ptr, ZR060_DRI_IDX, 6, dri_data);
+}
+
+/* Setup compression/decompression of Zoran's JPEG processor ( see also zoran 36060 manual )
+ * ... sorry for the spaghetti code ...
+ */
+static void zr36060_init(struct zr36060 *ptr)
+{
+       int sum = 0;
+       long bitcnt, tmp;
+       struct zoran *zr = videocodec_to_zoran(ptr->codec);
+
+       if (ptr->mode == CODEC_DO_COMPRESSION) {
+               zrdev_dbg(zr, "%s: COMPRESSION SETUP\n", ptr->name);
+
+               zr36060_write(ptr, ZR060_LOAD, ZR060_LOAD_SYNC_RST);
+
+               /* 060 communicates with 067 in master mode */
+               zr36060_write(ptr, ZR060_CIR, ZR060_CIR_CODE_MSTR);
+
+               /* Compression with or without variable scale factor */
+               /*FIXME: What about ptr->bitrate_ctrl? */
+               zr36060_write(ptr, ZR060_CMR, ZR060_CMR_COMP | ZR060_CMR_PASS2 | ZR060_CMR_BRB);
+
+               /* Must be zero */
+               zr36060_write(ptr, ZR060_MBZ, 0x00);
+               zr36060_write(ptr, ZR060_TCR_HI, 0x00);
+               zr36060_write(ptr, ZR060_TCR_LO, 0x00);
+
+               /* Disable all IRQs - no DataErr means autoreset */
+               zr36060_write(ptr, ZR060_IMR, 0);
+
+               /* volume control settings */
+               zr36060_write(ptr, ZR060_SF_HI, ptr->scalefact >> 8);
+               zr36060_write(ptr, ZR060_SF_LO, ptr->scalefact & 0xff);
+
+               zr36060_write(ptr, ZR060_AF_HI, 0xff);
+               zr36060_write(ptr, ZR060_AF_M, 0xff);
+               zr36060_write(ptr, ZR060_AF_LO, 0xff);
+
+               /* setup the variable jpeg tables */
+               sum += zr36060_set_sof(ptr);
+               sum += zr36060_set_sos(ptr);
+               sum += zr36060_set_dri(ptr);
+
+/* setup the fixed jpeg tables - maybe variable, though - (see table init section above) */
+               sum += zr36060_pushit(ptr, ZR060_DQT_IDX, sizeof(zr36060_dqt), zr36060_dqt);
+               sum += zr36060_pushit(ptr, ZR060_DHT_IDX, sizeof(zr36060_dht), zr36060_dht);
+               zr36060_write(ptr, ZR060_APP_IDX, 0xff);
+               zr36060_write(ptr, ZR060_APP_IDX + 1, 0xe0 + ptr->app.appn);
+               zr36060_write(ptr, ZR060_APP_IDX + 2, 0x00);
+               zr36060_write(ptr, ZR060_APP_IDX + 3, ptr->app.len + 2);
+               sum += zr36060_pushit(ptr, ZR060_APP_IDX + 4, 60, ptr->app.data) + 4;
+               zr36060_write(ptr, ZR060_COM_IDX, 0xff);
+               zr36060_write(ptr, ZR060_COM_IDX + 1, 0xfe);
+               zr36060_write(ptr, ZR060_COM_IDX + 2, 0x00);
+               zr36060_write(ptr, ZR060_COM_IDX + 3, ptr->com.len + 2);
+               sum += zr36060_pushit(ptr, ZR060_COM_IDX + 4, 60, ptr->com.data) + 4;
+
+               /* setup misc. data for compression (target code sizes) */
+
+               /* size of compressed code to reach without header data */
+               sum = ptr->real_code_vol - sum;
+               bitcnt = sum << 3;      /* need the size in bits */
+
+               tmp = bitcnt >> 16;
+               zrdev_dbg(zr,
+                         "%s: code: csize=%d, tot=%d, bit=%ld, highbits=%ld\n",
+                         ptr->name, sum, ptr->real_code_vol, bitcnt, tmp);
+               zr36060_write(ptr, ZR060_TCV_NET_HI, tmp >> 8);
+               zr36060_write(ptr, ZR060_TCV_NET_MH, tmp & 0xff);
+               tmp = bitcnt & 0xffff;
+               zr36060_write(ptr, ZR060_TCV_NET_ML, tmp >> 8);
+               zr36060_write(ptr, ZR060_TCV_NET_LO, tmp & 0xff);
+
+               bitcnt -= bitcnt >> 7;  // bits without stuffing
+               bitcnt -= ((bitcnt * 5) >> 6);  // bits without eob
+
+               tmp = bitcnt >> 16;
+               zrdev_dbg(zr, "%s: code: nettobit=%ld, highnettobits=%ld\n",
+                         ptr->name, bitcnt, tmp);
+               zr36060_write(ptr, ZR060_TCV_DATA_HI, tmp >> 8);
+               zr36060_write(ptr, ZR060_TCV_DATA_MH, tmp & 0xff);
+               tmp = bitcnt & 0xffff;
+               zr36060_write(ptr, ZR060_TCV_DATA_ML, tmp >> 8);
+               zr36060_write(ptr, ZR060_TCV_DATA_LO, tmp & 0xff);
+
+               /* JPEG markers to be included in the compressed stream */
+               zr36060_write(ptr, ZR060_MER,
+                             ZR060_MER_DQT | ZR060_MER_DHT |
+                             ((ptr->com.len > 0) ? ZR060_MER_COM : 0) |
+                             ((ptr->app.len > 0) ? ZR060_MER_APP : 0));
+
+               /* Setup the Video Frontend */
+               /* Limit pixel range to 16..235 as per CCIR-601 */
+               zr36060_write(ptr, ZR060_VCR, ZR060_VCR_RANGE);
+
+       } else {
+               zrdev_dbg(zr, "%s: EXPANSION SETUP\n", ptr->name);
+
+               zr36060_write(ptr, ZR060_LOAD, ZR060_LOAD_SYNC_RST);
+
+               /* 060 communicates with 067 in master mode */
+               zr36060_write(ptr, ZR060_CIR, ZR060_CIR_CODE_MSTR);
+
+               /* Decompression */
+               zr36060_write(ptr, ZR060_CMR, 0);
+
+               /* Must be zero */
+               zr36060_write(ptr, ZR060_MBZ, 0x00);
+               zr36060_write(ptr, ZR060_TCR_HI, 0x00);
+               zr36060_write(ptr, ZR060_TCR_LO, 0x00);
+
+               /* Disable all IRQs - no DataErr means autoreset */
+               zr36060_write(ptr, ZR060_IMR, 0);
+
+               /* setup misc. data for expansion */
+               zr36060_write(ptr, ZR060_MER, 0);
+
+/* setup the fixed jpeg tables - maybe variable, though - (see table init section above) */
+               zr36060_pushit(ptr, ZR060_DHT_IDX, sizeof(zr36060_dht), zr36060_dht);
+
+               /* Setup the Video Frontend */
+               //zr36060_write(ptr, ZR060_VCR, ZR060_VCR_FI_EXT);
+               //this doesn't seem right and doesn't work...
+               zr36060_write(ptr, ZR060_VCR, ZR060_VCR_RANGE);
+       }
+
+       /* Load the tables */
+       zr36060_write(ptr, ZR060_LOAD, ZR060_LOAD_SYNC_RST | ZR060_LOAD_LOAD);
+       zr36060_wait_end(ptr);
+       zrdev_dbg(zr, "%s: Status after table preload: 0x%02x\n",
+                 ptr->name, ptr->status);
+
+       if (ptr->status & ZR060_CFSR_BUSY) {
+               zrdev_err(zr, "%s: init aborted!\n", ptr->name);
+               return;         // something is wrong, its timed out!!!!
+       }
+}
+
+/* =========================================================================
+ * CODEC API FUNCTIONS
+ * this functions are accessed by the master via the API structure
+ * =========================================================================
+ */
+
+/* set compressiion/expansion mode and launches codec -
+ * this should be the last call from the master before starting processing
+ */
+static int zr36060_set_mode(struct videocodec *codec, int mode)
+{
+       struct zr36060 *ptr = (struct zr36060 *)codec->data;
+       struct zoran *zr = videocodec_to_zoran(codec);
+
+       zrdev_dbg(zr, "%s: set_mode %d call\n", ptr->name, mode);
+
+       if (mode != CODEC_DO_EXPANSION && mode != CODEC_DO_COMPRESSION)
+               return -EINVAL;
+
+       ptr->mode = mode;
+       zr36060_init(ptr);
+
+       return 0;
+}
+
+/* set picture size (norm is ignored as the codec doesn't know about it) */
+static int zr36060_set_video(struct videocodec *codec, const struct tvnorm *norm,
+                            struct vfe_settings *cap, struct vfe_polarity *pol)
+{
+       struct zr36060 *ptr = (struct zr36060 *)codec->data;
+       struct zoran *zr = videocodec_to_zoran(codec);
+       u32 reg;
+       int size;
+
+       zrdev_dbg(zr, "%s: set_video %d/%d-%dx%d (%%%d) call\n", ptr->name,
+                 cap->x, cap->y, cap->width, cap->height, cap->decimation);
+
+       /* if () return -EINVAL;
+        * trust the master driver that it knows what it does - so
+        * we allow invalid startx/y and norm for now ...
+        */
+       ptr->width = cap->width / (cap->decimation & 0xff);
+       ptr->height = cap->height / (cap->decimation >> 8);
+
+       zr36060_write(ptr, ZR060_LOAD, ZR060_LOAD_SYNC_RST);
+
+       /* Note that VSPol/HSPol bits in zr36060 have the opposite
+        * meaning of their zr360x7 counterparts with the same names
+        * N.b. for VSPol this is only true if FIVEdge = 0 (default,
+        * left unchanged here - in accordance with datasheet).
+        */
+       reg = (!pol->vsync_pol ? ZR060_VPR_VS_POL : 0)
+           | (!pol->hsync_pol ? ZR060_VPR_HS_POL : 0)
+           | (pol->field_pol ? ZR060_VPR_FI_POL : 0)
+           | (pol->blank_pol ? ZR060_VPR_BL_POL : 0)
+           | (pol->subimg_pol ? ZR060_VPR_S_IMG_POL : 0)
+           | (pol->poe_pol ? ZR060_VPR_POE_POL : 0)
+           | (pol->pvalid_pol ? ZR060_VPR_P_VAL_POL : 0)
+           | (pol->vclk_pol ? ZR060_VPR_VCLK_POL : 0);
+       zr36060_write(ptr, ZR060_VPR, reg);
+
+       reg = 0;
+       switch (cap->decimation & 0xff) {
+       default:
+       case 1:
+               break;
+
+       case 2:
+               reg |= ZR060_SR_H_SCALE2;
+               break;
+
+       case 4:
+               reg |= ZR060_SR_H_SCALE4;
+               break;
+       }
+
+       switch (cap->decimation >> 8) {
+       default:
+       case 1:
+               break;
+
+       case 2:
+               reg |= ZR060_SR_V_SCALE;
+               break;
+       }
+       zr36060_write(ptr, ZR060_SR, reg);
+
+       zr36060_write(ptr, ZR060_BCR_Y, 0x00);
+       zr36060_write(ptr, ZR060_BCR_U, 0x80);
+       zr36060_write(ptr, ZR060_BCR_V, 0x80);
+
+       /* sync generator */
+
+       reg = norm->ht - 1;     /* Vtotal */
+       zr36060_write(ptr, ZR060_SGR_VTOTAL_HI, (reg >> 8) & 0xff);
+       zr36060_write(ptr, ZR060_SGR_VTOTAL_LO, (reg >> 0) & 0xff);
+
+       reg = norm->wt - 1;     /* Htotal */
+       zr36060_write(ptr, ZR060_SGR_HTOTAL_HI, (reg >> 8) & 0xff);
+       zr36060_write(ptr, ZR060_SGR_HTOTAL_LO, (reg >> 0) & 0xff);
+
+       reg = 6 - 1;            /* VsyncSize */
+       zr36060_write(ptr, ZR060_SGR_VSYNC, reg);
+
+       reg = 68;
+       zr36060_write(ptr, ZR060_SGR_HSYNC, reg);
+
+       reg = norm->v_start - 1;        /* BVstart */
+       zr36060_write(ptr, ZR060_SGR_BVSTART, reg);
+
+       reg += norm->ha / 2;    /* BVend */
+       zr36060_write(ptr, ZR060_SGR_BVEND_HI, (reg >> 8) & 0xff);
+       zr36060_write(ptr, ZR060_SGR_BVEND_LO, (reg >> 0) & 0xff);
+
+       reg = norm->h_start - 1;        /* BHstart */
+       zr36060_write(ptr, ZR060_SGR_BHSTART, reg);
+
+       reg += norm->wa;        /* BHend */
+       zr36060_write(ptr, ZR060_SGR_BHEND_HI, (reg >> 8) & 0xff);
+       zr36060_write(ptr, ZR060_SGR_BHEND_LO, (reg >> 0) & 0xff);
+
+       /* active area */
+       reg = cap->y + norm->v_start;   /* Vstart */
+       zr36060_write(ptr, ZR060_AAR_VSTART_HI, (reg >> 8) & 0xff);
+       zr36060_write(ptr, ZR060_AAR_VSTART_LO, (reg >> 0) & 0xff);
+
+       reg += cap->height;     /* Vend */
+       zr36060_write(ptr, ZR060_AAR_VEND_HI, (reg >> 8) & 0xff);
+       zr36060_write(ptr, ZR060_AAR_VEND_LO, (reg >> 0) & 0xff);
+
+       reg = cap->x + norm->h_start;   /* Hstart */
+       zr36060_write(ptr, ZR060_AAR_HSTART_HI, (reg >> 8) & 0xff);
+       zr36060_write(ptr, ZR060_AAR_HSTART_LO, (reg >> 0) & 0xff);
+
+       reg += cap->width;      /* Hend */
+       zr36060_write(ptr, ZR060_AAR_HEND_HI, (reg >> 8) & 0xff);
+       zr36060_write(ptr, ZR060_AAR_HEND_LO, (reg >> 0) & 0xff);
+
+       /* subimage area */
+       reg = norm->v_start - 4;        /* SVstart */
+       zr36060_write(ptr, ZR060_SWR_VSTART_HI, (reg >> 8) & 0xff);
+       zr36060_write(ptr, ZR060_SWR_VSTART_LO, (reg >> 0) & 0xff);
+
+       reg += norm->ha / 2 + 8;        /* SVend */
+       zr36060_write(ptr, ZR060_SWR_VEND_HI, (reg >> 8) & 0xff);
+       zr36060_write(ptr, ZR060_SWR_VEND_LO, (reg >> 0) & 0xff);
+
+       reg = norm->h_start /*+ 64 */  - 4;     /* SHstart */
+       zr36060_write(ptr, ZR060_SWR_HSTART_HI, (reg >> 8) & 0xff);
+       zr36060_write(ptr, ZR060_SWR_HSTART_LO, (reg >> 0) & 0xff);
+
+       reg += norm->wa + 8;    /* SHend */
+       zr36060_write(ptr, ZR060_SWR_HEND_HI, (reg >> 8) & 0xff);
+       zr36060_write(ptr, ZR060_SWR_HEND_LO, (reg >> 0) & 0xff);
+
+       size = ptr->width * ptr->height;
+       /* Target compressed field size in bits: */
+       size = size * 16;       /* uncompressed size in bits */
+       /* (Ronald) by default, quality = 100 is a compression
+        * ratio 1:2. Setting low_bitrate (insmod option) sets
+        * it to 1:4 (instead of 1:2, zr36060 max) as limit because the
+        * buz can't handle more at decimation=1... Use low_bitrate if
+        * you have a Buz, unless you know what you're doing
+        */
+       size = size * cap->quality / (low_bitrate ? 400 : 200);
+       /* Lower limit (arbitrary, 1 KB) */
+       if (size < 8192)
+               size = 8192;
+       /* Upper limit: 7/8 of the code buffers */
+       if (size > ptr->total_code_vol * 7)
+               size = ptr->total_code_vol * 7;
+
+       ptr->real_code_vol = size >> 3; /* in bytes */
+
+       /* the MBCVR is the *maximum* block volume, according to the
+        * JPEG ISO specs, this shouldn't be used, since that allows
+        * for the best encoding quality. So set it to it's max value
+        */
+       reg = ptr->max_block_vol;
+       zr36060_write(ptr, ZR060_MBCVR, reg);
+
+       return 0;
+}
+
+/* additional control functions */
+static int zr36060_control(struct videocodec *codec, int type, int size, void *data)
+{
+       struct zr36060 *ptr = (struct zr36060 *)codec->data;
+       struct zoran *zr = videocodec_to_zoran(codec);
+       int *ival = (int *)data;
+
+       zrdev_dbg(zr, "%s: control %d call with %d byte\n", ptr->name, type,
+                 size);
+
+       switch (type) {
+       case CODEC_G_STATUS:    /* get last status */
+               if (size != sizeof(int))
+                       return -EFAULT;
+               zr36060_read_status(ptr);
+               *ival = ptr->status;
+               break;
+
+       case CODEC_G_CODEC_MODE:
+               if (size != sizeof(int))
+                       return -EFAULT;
+               *ival = CODEC_MODE_BJPG;
+               break;
+
+       case CODEC_S_CODEC_MODE:
+               if (size != sizeof(int))
+                       return -EFAULT;
+               if (*ival != CODEC_MODE_BJPG)
+                       return -EINVAL;
+               /* not needed, do nothing */
+               return 0;
+
+       case CODEC_G_VFE:
+       case CODEC_S_VFE:
+               /* not needed, do nothing */
+               return 0;
+
+       case CODEC_S_MMAP:
+               /* not available, give an error */
+               return -ENXIO;
+
+       case CODEC_G_JPEG_TDS_BYTE:     /* get target volume in byte */
+               if (size != sizeof(int))
+                       return -EFAULT;
+               *ival = ptr->total_code_vol;
+               break;
+
+       case CODEC_S_JPEG_TDS_BYTE:     /* get target volume in byte */
+               if (size != sizeof(int))
+                       return -EFAULT;
+               ptr->total_code_vol = *ival;
+               ptr->real_code_vol = (ptr->total_code_vol * 6) >> 3;
+               break;
+
+       case CODEC_G_JPEG_SCALE:        /* get scaling factor */
+               if (size != sizeof(int))
+                       return -EFAULT;
+               *ival = zr36060_read_scalefactor(ptr);
+               break;
+
+       case CODEC_S_JPEG_SCALE:        /* set scaling factor */
+               if (size != sizeof(int))
+                       return -EFAULT;
+               ptr->scalefact = *ival;
+               break;
+
+       case CODEC_G_JPEG_APP_DATA: {   /* get appn marker data */
+               struct jpeg_app_marker *app = data;
+
+               if (size != sizeof(struct jpeg_app_marker))
+                       return -EFAULT;
+
+               *app = ptr->app;
+               break;
+       }
+
+       case CODEC_S_JPEG_APP_DATA: {   /* set appn marker data */
+               struct jpeg_app_marker *app = data;
+
+               if (size != sizeof(struct jpeg_app_marker))
+                       return -EFAULT;
+
+               ptr->app = *app;
+               break;
+       }
+
+       case CODEC_G_JPEG_COM_DATA: {   /* get comment marker data */
+               struct jpeg_com_marker *com = data;
+
+               if (size != sizeof(struct jpeg_com_marker))
+                       return -EFAULT;
+
+               *com = ptr->com;
+               break;
+       }
+
+       case CODEC_S_JPEG_COM_DATA: {   /* set comment marker data */
+               struct jpeg_com_marker *com = data;
+
+               if (size != sizeof(struct jpeg_com_marker))
+                       return -EFAULT;
+
+               ptr->com = *com;
+               break;
+       }
+
+       default:
+               return -EINVAL;
+       }
+
+       return size;
+}
+
+/* =========================================================================
+ * Exit and unregister function:
+ * Deinitializes Zoran's JPEG processor
+ * =========================================================================
+ */
+static int zr36060_unset(struct videocodec *codec)
+{
+       struct zr36060 *ptr = codec->data;
+       struct zoran *zr = videocodec_to_zoran(codec);
+
+       if (ptr) {
+               /* do wee need some codec deinit here, too ???? */
+
+               zrdev_dbg(zr, "%s: finished codec #%d\n", ptr->name, ptr->num);
+               kfree(ptr);
+               codec->data = NULL;
+
+               zr36060_codecs--;
+               return 0;
+       }
+
+       return -EFAULT;
+}
+
+/* =========================================================================
+ * Setup and registry function:
+ * Initializes Zoran's JPEG processor
+ * Also sets pixel size, average code size, mode (compr./decompr.)
+ * (the given size is determined by the processor with the video interface)
+ * =========================================================================
+ */
+static int zr36060_setup(struct videocodec *codec)
+{
+       struct zr36060 *ptr;
+       struct zoran *zr = videocodec_to_zoran(codec);
+       int res;
+
+       zrdev_dbg(zr, "zr36060: initializing MJPEG subsystem #%d.\n",
+                 zr36060_codecs);
+
+       if (zr36060_codecs == MAX_CODECS) {
+               zrdev_err(zr, "zr36060: Can't attach more codecs!\n");
+               return -ENOSPC;
+       }
+       //mem structure init
+       ptr = kzalloc(sizeof(*ptr), GFP_KERNEL);
+       codec->data = ptr;
+       if (!ptr)
+               return -ENOMEM;
+
+       snprintf(ptr->name, sizeof(ptr->name), "zr36060[%d]", zr36060_codecs);
+       ptr->num = zr36060_codecs++;
+       ptr->codec = codec;
+
+       //testing
+       res = zr36060_basic_test(ptr);
+       if (res < 0) {
+               zr36060_unset(codec);
+               return res;
+       }
+       //final setup
+       memcpy(ptr->h_samp_ratio, zr36060_decimation_h, 8);
+       memcpy(ptr->v_samp_ratio, zr36060_decimation_v, 8);
+
+       ptr->bitrate_ctrl = 0;  /* 0 or 1 - fixed file size flag (what is the difference?) */
+       ptr->mode = CODEC_DO_COMPRESSION;
+       ptr->width = 384;
+       ptr->height = 288;
+       ptr->total_code_vol = 16000;    /* CHECKME */
+       ptr->real_code_vol = (ptr->total_code_vol * 6) >> 3;
+       ptr->max_block_vol = 240;       /* CHECKME, was 120 is 240 */
+       ptr->scalefact = 0x100;
+       ptr->dri = 1;           /* CHECKME, was 8 is 1 */
+
+       /* by default, no COM or APP markers - app should set those */
+       ptr->com.len = 0;
+       ptr->app.appn = 0;
+       ptr->app.len = 0;
+
+       zr36060_init(ptr);
+
+       zrdev_info(zr, "%s: codec attached and running\n", ptr->name);
+
+       return 0;
+}
+
+static const struct videocodec zr36060_codec = {
+       .name = "zr36060",
+       .magic = 0L,            // magic not used
+       .flags =
+           CODEC_FLAG_JPEG | CODEC_FLAG_HARDWARE | CODEC_FLAG_ENCODER |
+           CODEC_FLAG_DECODER | CODEC_FLAG_VFE,
+       .type = CODEC_TYPE_ZR36060,
+       .setup = zr36060_setup, // functionality
+       .unset = zr36060_unset,
+       .set_mode = zr36060_set_mode,
+       .set_video = zr36060_set_video,
+       .control = zr36060_control,
+       // others are not used
+};
+
+int zr36060_init_module(void)
+{
+       zr36060_codecs = 0;
+       return videocodec_register(&zr36060_codec);
+}
+
+void zr36060_cleanup_module(void)
+{
+       if (zr36060_codecs) {
+               pr_debug("zr36060: something's wrong - %d codecs left somehow.\n",
+                        zr36060_codecs);
+       }
+
+       /* however, we can't just stay alive */
+       videocodec_unregister(&zr36060_codec);
+}
 
--- /dev/null
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Zoran ZR36060 basic configuration functions - header file
+ *
+ * Copyright (C) 2002 Laurent Pinchart <laurent.pinchart@skynet.be>
+ */
+
+#ifndef ZR36060_H
+#define ZR36060_H
+
+#include "videocodec.h"
+
+/* data stored for each zoran jpeg codec chip */
+struct zr36060 {
+       char name[32];
+       int num;
+       /* io datastructure */
+       struct videocodec *codec;
+       // last coder status
+       __u8 status;
+       // actual coder setup
+       int mode;
+
+       __u16 width;
+       __u16 height;
+
+       __u16 bitrate_ctrl;
+
+       __u32 total_code_vol;
+       __u32 real_code_vol;
+       __u16 max_block_vol;
+
+       __u8 h_samp_ratio[8];
+       __u8 v_samp_ratio[8];
+       __u16 scalefact;
+       __u16 dri;
+
+       /* app/com marker data */
+       struct jpeg_app_marker app;
+       struct jpeg_com_marker com;
+};
+
+/* ZR36060 register addresses */
+#define ZR060_LOAD                     0x000
+#define ZR060_CFSR                     0x001
+#define ZR060_CIR                      0x002
+#define ZR060_CMR                      0x003
+#define ZR060_MBZ                      0x004
+#define ZR060_MBCVR                    0x005
+#define ZR060_MER                      0x006
+#define ZR060_IMR                      0x007
+#define ZR060_ISR                      0x008
+#define ZR060_TCV_NET_HI               0x009
+#define ZR060_TCV_NET_MH               0x00a
+#define ZR060_TCV_NET_ML               0x00b
+#define ZR060_TCV_NET_LO               0x00c
+#define ZR060_TCV_DATA_HI              0x00d
+#define ZR060_TCV_DATA_MH              0x00e
+#define ZR060_TCV_DATA_ML              0x00f
+#define ZR060_TCV_DATA_LO              0x010
+#define ZR060_SF_HI                    0x011
+#define ZR060_SF_LO                    0x012
+#define ZR060_AF_HI                    0x013
+#define ZR060_AF_M                     0x014
+#define ZR060_AF_LO                    0x015
+#define ZR060_ACV_HI                   0x016
+#define ZR060_ACV_MH                   0x017
+#define ZR060_ACV_ML                   0x018
+#define ZR060_ACV_LO                   0x019
+#define ZR060_ACT_HI                   0x01a
+#define ZR060_ACT_MH                   0x01b
+#define ZR060_ACT_ML                   0x01c
+#define ZR060_ACT_LO                   0x01d
+#define ZR060_ACV_TURN_HI              0x01e
+#define ZR060_ACV_TURN_MH              0x01f
+#define ZR060_ACV_TURN_ML              0x020
+#define ZR060_ACV_TURN_LO              0x021
+#define ZR060_IDR_DEV                  0x022
+#define ZR060_IDR_REV                  0x023
+#define ZR060_TCR_HI                   0x024
+#define ZR060_TCR_LO                   0x025
+#define ZR060_VCR                      0x030
+#define ZR060_VPR                      0x031
+#define ZR060_SR                       0x032
+#define ZR060_BCR_Y                    0x033
+#define ZR060_BCR_U                    0x034
+#define ZR060_BCR_V                    0x035
+#define ZR060_SGR_VTOTAL_HI            0x036
+#define ZR060_SGR_VTOTAL_LO            0x037
+#define ZR060_SGR_HTOTAL_HI            0x038
+#define ZR060_SGR_HTOTAL_LO            0x039
+#define ZR060_SGR_VSYNC                        0x03a
+#define ZR060_SGR_HSYNC                        0x03b
+#define ZR060_SGR_BVSTART              0x03c
+#define ZR060_SGR_BHSTART              0x03d
+#define ZR060_SGR_BVEND_HI             0x03e
+#define ZR060_SGR_BVEND_LO             0x03f
+#define ZR060_SGR_BHEND_HI             0x040
+#define ZR060_SGR_BHEND_LO             0x041
+#define ZR060_AAR_VSTART_HI            0x042
+#define ZR060_AAR_VSTART_LO            0x043
+#define ZR060_AAR_VEND_HI              0x044
+#define ZR060_AAR_VEND_LO              0x045
+#define ZR060_AAR_HSTART_HI            0x046
+#define ZR060_AAR_HSTART_LO            0x047
+#define ZR060_AAR_HEND_HI              0x048
+#define ZR060_AAR_HEND_LO              0x049
+#define ZR060_SWR_VSTART_HI            0x04a
+#define ZR060_SWR_VSTART_LO            0x04b
+#define ZR060_SWR_VEND_HI              0x04c
+#define ZR060_SWR_VEND_LO              0x04d
+#define ZR060_SWR_HSTART_HI            0x04e
+#define ZR060_SWR_HSTART_LO            0x04f
+#define ZR060_SWR_HEND_HI              0x050
+#define ZR060_SWR_HEND_LO              0x051
+
+#define ZR060_SOF_IDX                  0x060
+#define ZR060_SOS_IDX                  0x07a
+#define ZR060_DRI_IDX                  0x0c0
+#define ZR060_DQT_IDX                  0x0cc
+#define ZR060_DHT_IDX                  0x1d4
+#define ZR060_APP_IDX                  0x380
+#define ZR060_COM_IDX                  0x3c0
+
+/* ZR36060 LOAD register bits */
+
+#define ZR060_LOAD_LOAD                        BIT(7)
+#define ZR060_LOAD_SYNC_RST            BIT(0)
+
+/* ZR36060 Code FIFO Status register bits */
+
+#define ZR060_CFSR_BUSY                        BIT(7)
+#define ZR060_CFSR_C_BUSY              BIT(2)
+#define ZR060_CFSR_CFIFO               (3 << 0)
+
+/* ZR36060 Code Interface register */
+
+#define ZR060_CIR_CODE16               BIT(7)
+#define ZR060_CIR_ENDIAN               BIT(6)
+#define ZR060_CIR_CFIS                 BIT(2)
+#define ZR060_CIR_CODE_MSTR            BIT(0)
+
+/* ZR36060 Codec Mode register */
+
+#define ZR060_CMR_COMP                 BIT(7)
+#define ZR060_CMR_ATP                  BIT(6)
+#define ZR060_CMR_PASS2                        BIT(5)
+#define ZR060_CMR_TLM                  BIT(4)
+#define ZR060_CMR_BRB                  BIT(2)
+#define ZR060_CMR_FSF                  BIT(1)
+
+/* ZR36060 Markers Enable register */
+
+#define ZR060_MER_APP                  BIT(7)
+#define ZR060_MER_COM                  BIT(6)
+#define ZR060_MER_DRI                  BIT(5)
+#define ZR060_MER_DQT                  BIT(4)
+#define ZR060_MER_DHT                  BIT(3)
+
+/* ZR36060 Interrupt Mask register */
+
+#define ZR060_IMR_EOAV                 BIT(3)
+#define ZR060_IMR_EOI                  BIT(2)
+#define ZR060_IMR_END                  BIT(1)
+#define ZR060_IMR_DATA_ERR             BIT(0)
+
+/* ZR36060 Interrupt Status register */
+
+#define ZR060_ISR_PRO_CNT              (3 << 6)
+#define ZR060_ISR_EOAV                 BIT(3)
+#define ZR060_ISR_EOI                  BIT(2)
+#define ZR060_ISR_END                  BIT(1)
+#define ZR060_ISR_DATA_ERR             BIT(0)
+
+/* ZR36060 Video Control register */
+
+#define ZR060_VCR_VIDEO8               BIT(7)
+#define ZR060_VCR_RANGE                        BIT(6)
+#define ZR060_VCR_FI_DET               BIT(3)
+#define ZR060_VCR_FI_VEDGE             BIT(2)
+#define ZR060_VCR_FI_EXT               BIT(1)
+#define ZR060_VCR_SYNC_MSTR            BIT(0)
+
+/* ZR36060 Video Polarity register */
+
+#define ZR060_VPR_VCLK_POL             BIT(7)
+#define ZR060_VPR_P_VAL_POL            BIT(6)
+#define ZR060_VPR_POE_POL              BIT(5)
+#define ZR060_VPR_S_IMG_POL            BIT(4)
+#define ZR060_VPR_BL_POL               BIT(3)
+#define ZR060_VPR_FI_POL               BIT(2)
+#define ZR060_VPR_HS_POL               BIT(1)
+#define ZR060_VPR_VS_POL               BIT(0)
+
+/* ZR36060 Scaling register */
+
+#define ZR060_SR_V_SCALE               BIT(2)
+#define ZR060_SR_H_SCALE2              BIT(0)
+#define ZR060_SR_H_SCALE4              (2 << 0)
+
+int zr36060_init_module(void);
+void zr36060_cleanup_module(void);
+#endif                         /*fndef ZR36060_H */
 
 
 source "drivers/staging/media/tegra-video/Kconfig"
 
-source "drivers/staging/media/zoran/Kconfig"
-
 endif
 
 obj-$(CONFIG_VIDEO_TEGRA)      += tegra-video/
 obj-$(CONFIG_VIDEO_HANTRO)     += hantro/
 obj-$(CONFIG_VIDEO_IPU3_IMGU)  += ipu3/
-obj-$(CONFIG_VIDEO_ZORAN)      += zoran/
 obj-$(CONFIG_DVB_AV7110)       += av7110/
 
+++ /dev/null
-config VIDEO_ZORAN
-       tristate "Zoran ZR36057/36067 Video For Linux (Deprecated)"
-       depends on PCI && I2C_ALGOBIT && VIDEO_DEV
-       depends on !ALPHA
-       depends on DEBUG_FS
-       select VIDEOBUF2_DMA_CONTIG
-       select VIDEO_ADV7170 if VIDEO_ZORAN_LML33R10
-       select VIDEO_ADV7175 if VIDEO_ZORAN_DC10 || VIDEO_ZORAN_DC30
-       select VIDEO_BT819 if VIDEO_ZORAN_LML33
-       select VIDEO_BT856 if VIDEO_ZORAN_LML33 || VIDEO_ZORAN_AVS6EYES
-       select VIDEO_BT866 if VIDEO_ZORAN_AVS6EYES
-       select VIDEO_KS0127 if VIDEO_ZORAN_AVS6EYES
-       select VIDEO_SAA711X if VIDEO_ZORAN_BUZ || VIDEO_ZORAN_LML33R10
-       select VIDEO_SAA7110 if VIDEO_ZORAN_DC10
-       select VIDEO_SAA7185 if VIDEO_ZORAN_BUZ
-       select VIDEO_VPX3220 if VIDEO_ZORAN_DC30
-       help
-         Say Y for support for MJPEG capture cards based on the Zoran
-         36057/36067 PCI controller chipset. This includes the Iomega
-         Buz, Pinnacle DC10+ and the Linux Media Labs LML33. There is
-         a driver homepage at <http://mjpeg.sf.net/driver-zoran/>. For
-         more information, check <file:Documentation/driver-api/media/drivers/zoran.rst>.
-
-         To compile this driver as a module, choose M here: the
-         module will be called zr36067.
-
-config VIDEO_ZORAN_DC30
-       bool "Pinnacle/Miro DC30(+) support"
-       depends on VIDEO_ZORAN
-       help
-         Support for the Pinnacle/Miro DC30(+) MJPEG capture/playback
-         card. This also supports really old DC10 cards based on the
-         zr36050 MJPEG codec and zr36016 VFE.
-
-config VIDEO_ZORAN_ZR36060
-       bool "Zoran ZR36060"
-       depends on VIDEO_ZORAN
-       help
-         Say Y to support Zoran boards based on 36060 chips.
-         This includes Iomega Buz, Pinnacle DC10, Linux media Labs 33
-         and 33 R10 and AverMedia 6 boards.
-
-config VIDEO_ZORAN_BUZ
-       bool "Iomega Buz support"
-       depends on VIDEO_ZORAN_ZR36060
-       help
-         Support for the Iomega Buz MJPEG capture/playback card.
-
-config VIDEO_ZORAN_DC10
-       bool "Pinnacle/Miro DC10(+) support"
-       depends on VIDEO_ZORAN_ZR36060
-       help
-         Support for the Pinnacle/Miro DC10(+) MJPEG capture/playback
-         card.
-
-config VIDEO_ZORAN_LML33
-       bool "Linux Media Labs LML33 support"
-       depends on VIDEO_ZORAN_ZR36060
-       help
-         Support for the Linux Media Labs LML33 MJPEG capture/playback
-         card.
-
-config VIDEO_ZORAN_LML33R10
-       bool "Linux Media Labs LML33R10 support"
-       depends on VIDEO_ZORAN_ZR36060
-       help
-         support for the Linux Media Labs LML33R10 MJPEG capture/playback
-         card.
-
-config VIDEO_ZORAN_AVS6EYES
-       bool "AverMedia 6 Eyes support"
-       depends on VIDEO_ZORAN_ZR36060
-       help
-         Support for the AverMedia 6 Eyes video surveillance card.
 
+++ /dev/null
-# SPDX-License-Identifier: GPL-2.0
-zr36067-objs   :=      zoran_device.o \
-                       zoran_driver.o zoran_card.o videocodec.o
-
-obj-$(CONFIG_VIDEO_ZORAN) += zr36067.o
-zr36067-$(CONFIG_VIDEO_ZORAN_DC30) += zr36050.o zr36016.o
-zr36067-$(CONFIG_VIDEO_ZORAN_ZR36060) += zr36060.o
 
+++ /dev/null
-
-How to test the zoran driver:
-- RAW capture
-       mplayer tv:///dev/video0 -tv driver=v4l2
-
-- MJPEG capture (compression)
-       mplayer tv:///dev/video0 -tv driver=v4l2:outfmt=mjpeg
-       TODO: need two test for both Dcim path
-
-- MJPEG play (decompression)
-       ffmpeg -i test.avi -vcodec mjpeg -an -f v4l2 /dev/video0
-       Note: only recent ffmpeg has the ability of sending non-raw video via v4l2
-
-       The original way of sending video was via mplayer vo_zr/vo_zr2, but it does not compile
-       anymore and is a dead end (usage of some old private ffmpeg structures).
-
-TODO
-- fix the v4l compliance "TRY_FMT cannot handle an invalid pixelformat"
-- Filter JPEG data to made output work
 
+++ /dev/null
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * VIDEO MOTION CODECs internal API for video devices
- *
- * Interface for MJPEG (and maybe later MPEG/WAVELETS) codec's
- * bound to a master device.
- *
- * (c) 2002 Wolfgang Scherr <scherr@net4you.at>
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/types.h>
-#include <linux/slab.h>
-
-#include "videocodec.h"
-
-struct attached_list {
-       struct videocodec *codec;
-       struct attached_list *next;
-};
-
-struct codec_list {
-       const struct videocodec *codec;
-       int attached;
-       struct attached_list *list;
-       struct codec_list *next;
-};
-
-static struct codec_list *codeclist_top;
-
-/* ================================================= */
-/* function prototypes of the master/slave interface */
-/* ================================================= */
-
-struct videocodec *videocodec_attach(struct videocodec_master *master)
-{
-       struct codec_list *h = codeclist_top;
-       struct zoran *zr;
-       struct attached_list *a, *ptr;
-       struct videocodec *codec;
-       int res;
-
-       if (!master) {
-               pr_err("%s: no data\n", __func__);
-               return NULL;
-       }
-
-       zr = videocodec_master_to_zoran(master);
-
-       zrdev_dbg(zr, "%s: '%s', flags %lx, magic %lx\n", __func__,
-                 master->name, master->flags, master->magic);
-
-       if (!h) {
-               zrdev_err(zr, "%s: no device available\n", __func__);
-               return NULL;
-       }
-
-       while (h) {
-               // attach only if the slave has at least the flags
-               // expected by the master
-               if ((master->flags & h->codec->flags) == master->flags) {
-                       zrdev_dbg(zr, "%s: try '%s'\n", __func__, h->codec->name);
-
-                       codec = kmemdup(h->codec, sizeof(struct videocodec), GFP_KERNEL);
-                       if (!codec)
-                               goto out_kfree;
-
-                       res = strlen(codec->name);
-                       snprintf(codec->name + res, sizeof(codec->name) - res, "[%d]", h->attached);
-                       codec->master_data = master;
-                       res = codec->setup(codec);
-                       if (res == 0) {
-                               zrdev_dbg(zr, "%s: '%s'\n", __func__, codec->name);
-                               ptr = kzalloc(sizeof(*ptr), GFP_KERNEL);
-                               if (!ptr)
-                                       goto out_kfree;
-                               ptr->codec = codec;
-
-                               a = h->list;
-                               if (!a) {
-                                       h->list = ptr;
-                                       zrdev_dbg(zr, "videocodec: first element\n");
-                               } else {
-                                       while (a->next)
-                                               a = a->next;    // find end
-                                       a->next = ptr;
-                                       zrdev_dbg(zr, "videocodec: in after '%s'\n",
-                                                 h->codec->name);
-                               }
-
-                               h->attached += 1;
-                               return codec;
-                       }
-                       kfree(codec);
-               }
-               h = h->next;
-       }
-
-       zrdev_err(zr, "%s: no codec found!\n", __func__);
-       return NULL;
-
- out_kfree:
-       kfree(codec);
-       return NULL;
-}
-
-int videocodec_detach(struct videocodec *codec)
-{
-       struct codec_list *h = codeclist_top;
-       struct zoran *zr;
-       struct attached_list *a, *prev;
-       int res;
-
-       if (!codec) {
-               pr_err("%s: no data\n", __func__);
-               return -EINVAL;
-       }
-
-       zr = videocodec_to_zoran(codec);
-
-       zrdev_dbg(zr, "%s: '%s', type: %x, flags %lx, magic %lx\n", __func__,
-                 codec->name, codec->type, codec->flags, codec->magic);
-
-       if (!h) {
-               zrdev_err(zr, "%s: no device left...\n", __func__);
-               return -ENXIO;
-       }
-
-       while (h) {
-               a = h->list;
-               prev = NULL;
-               while (a) {
-                       if (codec == a->codec) {
-                               res = a->codec->unset(a->codec);
-                               if (res >= 0) {
-                                       zrdev_dbg(zr, "%s: '%s'\n", __func__,
-                                                 a->codec->name);
-                                       a->codec->master_data = NULL;
-                               } else {
-                                       zrdev_err(zr, "%s: '%s'\n", __func__, a->codec->name);
-                                       a->codec->master_data = NULL;
-                               }
-                               if (!prev) {
-                                       h->list = a->next;
-                                       zrdev_dbg(zr, "videocodec: delete first\n");
-                               } else {
-                                       prev->next = a->next;
-                                       zrdev_dbg(zr, "videocodec: delete middle\n");
-                               }
-                               kfree(a->codec);
-                               kfree(a);
-                               h->attached -= 1;
-                               return 0;
-                       }
-                       prev = a;
-                       a = a->next;
-               }
-               h = h->next;
-       }
-
-       zrdev_err(zr, "%s: given codec not found!\n", __func__);
-       return -EINVAL;
-}
-
-int videocodec_register(const struct videocodec *codec)
-{
-       struct codec_list *ptr, *h = codeclist_top;
-       struct zoran *zr;
-
-       if (!codec) {
-               pr_err("%s: no data!\n", __func__);
-               return -EINVAL;
-       }
-
-       zr = videocodec_to_zoran((struct videocodec *)codec);
-
-       zrdev_dbg(zr,
-                 "videocodec: register '%s', type: %x, flags %lx, magic %lx\n",
-                 codec->name, codec->type, codec->flags, codec->magic);
-
-       ptr = kzalloc(sizeof(*ptr), GFP_KERNEL);
-       if (!ptr)
-               return -ENOMEM;
-       ptr->codec = codec;
-
-       if (!h) {
-               codeclist_top = ptr;
-               zrdev_dbg(zr, "videocodec: hooked in as first element\n");
-       } else {
-               while (h->next)
-                       h = h->next;    // find the end
-               h->next = ptr;
-               zrdev_dbg(zr, "videocodec: hooked in after '%s'\n",
-                         h->codec->name);
-       }
-
-       return 0;
-}
-
-int videocodec_unregister(const struct videocodec *codec)
-{
-       struct codec_list *prev = NULL, *h = codeclist_top;
-       struct zoran *zr;
-
-       if (!codec) {
-               pr_err("%s: no data!\n", __func__);
-               return -EINVAL;
-       }
-
-       zr = videocodec_to_zoran((struct videocodec *)codec);
-
-       zrdev_dbg(zr,
-                 "videocodec: unregister '%s', type: %x, flags %lx, magic %lx\n",
-                 codec->name, codec->type, codec->flags, codec->magic);
-
-       if (!h) {
-               zrdev_err(zr, "%s: no device left...\n", __func__);
-               return -ENXIO;
-       }
-
-       while (h) {
-               if (codec == h->codec) {
-                       if (h->attached) {
-                               zrdev_err(zr, "videocodec: '%s' is used\n",
-                                         h->codec->name);
-                               return -EBUSY;
-                       }
-                       zrdev_dbg(zr, "videocodec: unregister '%s' is ok.\n",
-                                 h->codec->name);
-                       if (!prev) {
-                               codeclist_top = h->next;
-                               zrdev_dbg(zr,
-                                         "videocodec: delete first element\n");
-                       } else {
-                               prev->next = h->next;
-                               zrdev_dbg(zr,
-                                         "videocodec: delete middle element\n");
-                       }
-                       kfree(h);
-                       return 0;
-               }
-               prev = h;
-               h = h->next;
-       }
-
-       zrdev_err(zr, "%s: given codec not found!\n", __func__);
-       return -EINVAL;
-}
-
-int videocodec_debugfs_show(struct seq_file *m)
-{
-       struct codec_list *h = codeclist_top;
-       struct attached_list *a;
-
-       seq_puts(m, "<S>lave or attached <M>aster name  type flags    magic    ");
-       seq_puts(m, "(connected as)\n");
-
-       while (h) {
-               seq_printf(m, "S %32s %04x %08lx %08lx (TEMPLATE)\n",
-                          h->codec->name, h->codec->type,
-                             h->codec->flags, h->codec->magic);
-               a = h->list;
-               while (a) {
-                       seq_printf(m, "M %32s %04x %08lx %08lx (%s)\n",
-                                  a->codec->master_data->name,
-                                     a->codec->master_data->type,
-                                     a->codec->master_data->flags,
-                                     a->codec->master_data->magic,
-                                     a->codec->name);
-                       a = a->next;
-               }
-               h = h->next;
-       }
-
-       return 0;
-}
 
+++ /dev/null
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * VIDEO MOTION CODECs internal API for video devices
- *
- * Interface for MJPEG (and maybe later MPEG/WAVELETS) codec's
- * bound to a master device.
- *
- * (c) 2002 Wolfgang Scherr <scherr@net4you.at>
- */
-
-/* =================== */
-/* general description */
-/* =================== */
-
-/*
- * Should ease the (re-)usage of drivers supporting cards with (different)
- * video codecs. The codecs register to this module their functionality,
- * and the processors (masters) can attach to them if they fit.
- *
- * The codecs are typically have a "strong" binding to their master - so I
- * don't think it makes sense to have a full blown interfacing as with e.g.
- * i2c. If you have an other opinion, let's discuss & implement it :-)))
- *
- * Usage:
- *
- * The slave has just to setup the videocodec structure and use two functions:
- * videocodec_register(codecdata);
- * videocodec_unregister(codecdata);
- * The best is just calling them at module (de-)initialisation.
- *
- * The master sets up the structure videocodec_master and calls:
- * codecdata=videocodec_attach(master_codecdata);
- * videocodec_detach(codecdata);
- *
- * The slave is called during attach/detach via functions setup previously
- * during register. At that time, the master_data pointer is set up
- * and the slave can access any io registers of the master device (in the case
- * the slave is bound to it). Otherwise it doesn't need this functions and
- * therefor they may not be initialized.
- *
- * The other functions are just for convenience, as they are for sure used by
- * most/all of the codecs. The last ones may be omitted, too.
- *
- * See the structure declaration below for more information and which data has
- * to be set up for the master and the slave.
- *
- * ----------------------------------------------------------------------------
- * The master should have "knowledge" of the slave and vice versa.  So the data
- * structures sent to/from slave via set_data/get_data set_image/get_image are
- * device dependent and vary between MJPEG/MPEG/WAVELET/... devices. (!!!!)
- * ----------------------------------------------------------------------------
- */
-
-/* ========================================== */
-/* description of the videocodec_io structure */
-/* ========================================== */
-
-/*
- * ==== master setup ====
- * name -> name of the device structure for reference and debugging
- * master_data ->  data ref. for the master (e.g. the zr36055,57,67)
- * readreg -> ref. to read-fn from register (setup by master, used by slave)
- * writereg -> ref. to write-fn to register (setup by master, used by slave)
- *            this two functions do the lowlevel I/O job
- *
- * ==== slave functionality setup ====
- * slave_data -> data ref. for the slave (e.g. the zr36050,60)
- * check -> fn-ref. checks availability of an device, returns -EIO on failure or
- *         the type on success
- *         this makes espcecially sense if a driver module supports more than
- *         one codec which may be quite similar to access, nevertheless it
- *         is good for a first functionality check
- *
- * -- main functions you always need for compression/decompression --
- *
- * set_mode -> this fn-ref. resets the entire codec, and sets up the mode
- *            with the last defined norm/size (or device default if not
- *            available) - it returns 0 if the mode is possible
- * set_size -> this fn-ref. sets the norm and image size for
- *            compression/decompression (returns 0 on success)
- *            the norm param is defined in videodev2.h (V4L2_STD_*)
- *
- * additional setup may be available, too - but the codec should work with
- * some default values even without this
- *
- * set_data -> sets device-specific data (tables, quality etc.)
- * get_data -> query device-specific data (tables, quality etc.)
- *
- * if the device delivers interrupts, they may be setup/handled here
- * setup_interrupt -> codec irq setup (not needed for 36050/60)
- * handle_interrupt -> codec irq handling (not needed for 36050/60)
-
- * if the device delivers pictures, they may be handled here
- * put_image -> puts image data to the codec (not needed for 36050/60)
- * get_image -> gets image data from the codec (not needed for 36050/60)
- *             the calls include frame numbers and flags (even/odd/...)
- *             if needed and a flag which allows blocking until its ready
- */
-
-/* ============== */
-/* user interface */
-/* ============== */
-
-/*
- * Currently there is only a information display planned, as the layer
- * is not visible for the user space at all.
- *
- * Information is available via procfs. The current entry is "/proc/videocodecs"
- * but it makes sense to "hide" it in the /proc/video tree of v4l(2) --TODO--.
- *
- * A example for such an output is:
- *
- * <S>lave or attached <M>aster name  type flags    magic    (connected as)
- * S                          zr36050 0002 0000d001 00000000 (TEMPLATE)
- * M                       zr36055[0] 0001 0000c001 00000000 (zr36050[0])
- * M                       zr36055[1] 0001 0000c001 00000000 (zr36050[1])
- */
-
-/* =============================================== */
-/* special defines for the videocodec_io structure */
-/* =============================================== */
-
-#ifndef __LINUX_VIDEOCODEC_H
-#define __LINUX_VIDEOCODEC_H
-
-#include <linux/debugfs.h>
-#include <linux/videodev2.h>
-
-#define CODEC_DO_COMPRESSION 0
-#define CODEC_DO_EXPANSION   1
-
-/* this are the current codec flags I think they are needed */
-/*  -> type value in structure */
-#define CODEC_FLAG_JPEG      0x00000001L       // JPEG codec
-#define CODEC_FLAG_MPEG      0x00000002L       // MPEG1/2/4 codec
-#define CODEC_FLAG_DIVX      0x00000004L       // DIVX codec
-#define CODEC_FLAG_WAVELET   0x00000008L       // WAVELET codec
-                                         // room for other types
-
-#define CODEC_FLAG_MAGIC     0x00000800L       // magic key must match
-#define CODEC_FLAG_HARDWARE  0x00001000L       // is a hardware codec
-#define CODEC_FLAG_VFE       0x00002000L       // has direct video frontend
-#define CODEC_FLAG_ENCODER   0x00004000L       // compression capability
-#define CODEC_FLAG_DECODER   0x00008000L       // decompression capability
-#define CODEC_FLAG_NEEDIRQ   0x00010000L       // needs irq handling
-#define CODEC_FLAG_RDWRPIC   0x00020000L       // handles picture I/O
-
-/* a list of modes, some are just examples (is there any HW?) */
-#define CODEC_MODE_BJPG      0x0001    // Baseline JPEG
-#define CODEC_MODE_LJPG      0x0002    // Lossless JPEG
-#define CODEC_MODE_MPEG1     0x0003    // MPEG 1
-#define CODEC_MODE_MPEG2     0x0004    // MPEG 2
-#define CODEC_MODE_MPEG4     0x0005    // MPEG 4
-#define CODEC_MODE_MSDIVX    0x0006    // MS DivX
-#define CODEC_MODE_ODIVX     0x0007    // Open DivX
-#define CODEC_MODE_WAVELET   0x0008    // Wavelet
-
-/* this are the current codec types I want to implement */
-/*  -> type value in structure */
-#define CODEC_TYPE_NONE    0
-#define CODEC_TYPE_L64702  1
-#define CODEC_TYPE_ZR36050 2
-#define CODEC_TYPE_ZR36016 3
-#define CODEC_TYPE_ZR36060 4
-
-/* the type of data may be enhanced by future implementations (data-fn.'s) */
-/*  -> used in command                                                     */
-#define CODEC_G_STATUS         0x0000  /* codec status (query only) */
-#define CODEC_S_CODEC_MODE     0x0001  /* codec mode (baseline JPEG, MPEG1,... */
-#define CODEC_G_CODEC_MODE     0x8001
-#define CODEC_S_VFE            0x0002  /* additional video frontend setup */
-#define CODEC_G_VFE            0x8002
-#define CODEC_S_MMAP           0x0003  /* MMAP setup (if available) */
-
-#define CODEC_S_JPEG_TDS_BYTE  0x0010  /* target data size in bytes */
-#define CODEC_G_JPEG_TDS_BYTE  0x8010
-#define CODEC_S_JPEG_SCALE     0x0011  /* scaling factor for quant. tables */
-#define CODEC_G_JPEG_SCALE     0x8011
-#define CODEC_S_JPEG_HDT_DATA  0x0018  /* huffman-tables */
-#define CODEC_G_JPEG_HDT_DATA  0x8018
-#define CODEC_S_JPEG_QDT_DATA  0x0019  /* quantizing-tables */
-#define CODEC_G_JPEG_QDT_DATA  0x8019
-#define CODEC_S_JPEG_APP_DATA  0x001A  /* APP marker */
-#define CODEC_G_JPEG_APP_DATA  0x801A
-#define CODEC_S_JPEG_COM_DATA  0x001B  /* COM marker */
-#define CODEC_G_JPEG_COM_DATA  0x801B
-
-#define CODEC_S_PRIVATE        0x1000  /* "private" commands start here */
-#define CODEC_G_PRIVATE        0x9000
-
-#define CODEC_G_FLAG           0x8000  /* this is how 'get' is detected */
-
-/* types of transfer, directly user space or a kernel buffer (image-fn.'s) */
-/*  -> used in get_image, put_image */
-#define CODEC_TRANSFER_KERNEL 0        /* use "memcopy" */
-#define CODEC_TRANSFER_USER   1        /* use "to/from_user" */
-
-/* ========================= */
-/* the structures itself ... */
-/* ========================= */
-
-struct vfe_polarity {
-       unsigned int vsync_pol:1;
-       unsigned int hsync_pol:1;
-       unsigned int field_pol:1;
-       unsigned int blank_pol:1;
-       unsigned int subimg_pol:1;
-       unsigned int poe_pol:1;
-       unsigned int pvalid_pol:1;
-       unsigned int vclk_pol:1;
-};
-
-struct vfe_settings {
-       __u32 x, y;             /* Offsets into image */
-       __u32 width, height;    /* Area to capture */
-       __u16 decimation;       /* Decimation divider */
-       __u16 flags;            /* Flags for capture */
-       __u16 quality;          /* quality of the video */
-};
-
-struct tvnorm {
-       u16 wt, wa, h_start, h_sync_start, ht, ha, v_start;
-};
-
-struct jpeg_com_marker {
-       int len; /* number of usable bytes in data */
-       char data[60];
-};
-
-struct jpeg_app_marker {
-       int appn; /* number app segment */
-       int len; /* number of usable bytes in data */
-       char data[60];
-};
-
-struct videocodec {
-       /* -- filled in by slave device during register -- */
-       char name[32];
-       unsigned long magic;    /* may be used for client<->master attaching */
-       unsigned long flags;    /* functionality flags */
-       unsigned int type;      /* codec type */
-
-       /* -- these is filled in later during master device attach -- */
-
-       struct videocodec_master *master_data;
-
-       /* -- these are filled in by the slave device during register -- */
-
-       void *data;             /* private slave data */
-
-       /* attach/detach client functions (indirect call) */
-       int (*setup)(struct videocodec *codec);
-       int (*unset)(struct videocodec *codec);
-
-       /* main functions, every client needs them for sure! */
-       // set compression or decompression (or freeze, stop, standby, etc)
-       int (*set_mode)(struct videocodec *codec, int mode);
-       // setup picture size and norm (for the codec's video frontend)
-       int (*set_video)(struct videocodec *codec, const struct tvnorm *norm,
-                        struct vfe_settings *cap, struct vfe_polarity *pol);
-       // other control commands, also mmap setup etc.
-       int (*control)(struct videocodec *codec, int type, int size, void *data);
-
-       /* additional setup/query/processing (may be NULL pointer) */
-       // interrupt setup / handling (for irq's delivered by master)
-       int (*setup_interrupt)(struct videocodec *codec, long mode);
-       int (*handle_interrupt)(struct videocodec *codec, int source, long flag);
-       // picture interface (if any)
-       long (*put_image)(struct videocodec *codec, int tr_type, int block,
-                         long *fr_num, long *flag, long size, void *buf);
-       long (*get_image)(struct videocodec *codec, int tr_type, int block,
-                         long *fr_num, long *flag, long size, void *buf);
-};
-
-struct videocodec_master {
-       /* -- filled in by master device for registration -- */
-       char name[32];
-       unsigned long magic;    /* may be used for client<->master attaching */
-       unsigned long flags;    /* functionality flags */
-       unsigned int type;      /* master type */
-
-       void *data;             /* private master data */
-
-       __u32 (*readreg)(struct videocodec *codec, __u16 reg);
-       void (*writereg)(struct videocodec *codec, __u16 reg, __u32 value);
-};
-
-/* ================================================= */
-/* function prototypes of the master/slave interface */
-/* ================================================= */
-
-/* attach and detach commands for the master */
-// * master structure needs to be kmalloc'ed before calling attach
-//   and free'd after calling detach
-// * returns pointer on success, NULL on failure
-struct videocodec *videocodec_attach(struct videocodec_master *master);
-// * 0 on success, <0 (errno) on failure
-int videocodec_detach(struct videocodec *codec);
-
-/* register and unregister commands for the slaves */
-// * 0 on success, <0 (errno) on failure
-int videocodec_register(const struct videocodec *codec);
-// * 0 on success, <0 (errno) on failure
-int videocodec_unregister(const struct videocodec *codec);
-
-/* the other calls are directly done via the videocodec structure! */
-
-int videocodec_debugfs_show(struct seq_file *m);
-
-#include "zoran.h"
-static inline struct zoran *videocodec_master_to_zoran(struct videocodec_master *master)
-{
-       struct zoran *zr = master->data;
-
-       return zr;
-}
-
-static inline struct zoran *videocodec_to_zoran(struct videocodec *codec)
-{
-       struct videocodec_master *master = codec->master_data;
-
-       return videocodec_master_to_zoran(master);
-}
-
-#endif                         /*ifndef __LINUX_VIDEOCODEC_H */
 
+++ /dev/null
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * zoran - Iomega Buz driver
- *
- * Copyright (C) 1999 Rainer Johanni <Rainer@Johanni.de>
- *
- * based on
- *
- * zoran.0.0.3 Copyright (C) 1998 Dave Perks <dperks@ibm.net>
- *
- * and
- *
- * bttv - Bt848 frame grabber driver
- * Copyright (C) 1996,97,98 Ralph  Metzler (rjkm@thp.uni-koeln.de)
- *                        & Marcus Metzler (mocm@thp.uni-koeln.de)
- */
-
-#ifndef _BUZ_H_
-#define _BUZ_H_
-
-#include <linux/debugfs.h>
-#include <linux/pci.h>
-#include <linux/i2c-algo-bit.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-ctrls.h>
-#include <media/videobuf2-core.h>
-#include <media/videobuf2-v4l2.h>
-#include <media/videobuf2-dma-contig.h>
-
-#define ZR_NORM_PAL 0
-#define ZR_NORM_NTSC 1
-#define ZR_NORM_SECAM 2
-
-struct zr_buffer {
-       /* common v4l buffer stuff -- must be first */
-       struct vb2_v4l2_buffer          vbuf;
-       struct list_head                queue;
-};
-
-static inline struct zr_buffer *vb2_to_zr_buffer(struct vb2_buffer *vb)
-{
-       struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
-
-       return container_of(vbuf, struct zr_buffer, vbuf);
-}
-
-#define ZORAN_NAME    "ZORAN"  /* name of the device */
-
-#define ZR_DEVNAME(zr) ((zr)->name)
-
-#define   BUZ_MAX_WIDTH   (zr->timing->wa)
-#define   BUZ_MAX_HEIGHT  (zr->timing->ha)
-#define   BUZ_MIN_WIDTH    32  /* never display less than 32 pixels */
-#define   BUZ_MIN_HEIGHT   24  /* never display less than 24 rows */
-
-#define BUZ_NUM_STAT_COM    4
-#define BUZ_MASK_STAT_COM   3
-
-#define BUZ_MAX_INPUT       16
-
-#include "zr36057.h"
-
-enum card_type {
-       UNKNOWN = -1,
-
-       /* Pinnacle/Miro */
-       DC10_OLD,               /* DC30 like */
-       DC10_NEW,               /* DC10_PLUS like */
-       DC10_PLUS,
-       DC30,
-       DC30_PLUS,
-
-       /* Linux Media Labs */
-       LML33,
-       LML33R10,
-
-       /* Iomega */
-       BUZ,
-
-       /* AverMedia */
-       AVS6EYES,
-
-       /* total number of cards */
-       NUM_CARDS
-};
-
-enum zoran_codec_mode {
-       BUZ_MODE_IDLE,          /* nothing going on */
-       BUZ_MODE_MOTION_COMPRESS,       /* grabbing frames */
-       BUZ_MODE_MOTION_DECOMPRESS,     /* playing frames */
-       BUZ_MODE_STILL_COMPRESS,        /* still frame conversion */
-       BUZ_MODE_STILL_DECOMPRESS       /* still frame conversion */
-};
-
-enum zoran_map_mode {
-       ZORAN_MAP_MODE_NONE,
-       ZORAN_MAP_MODE_RAW,
-       ZORAN_MAP_MODE_JPG_REC,
-       ZORAN_MAP_MODE_JPG_PLAY,
-};
-
-enum gpio_type {
-       ZR_GPIO_JPEG_SLEEP = 0,
-       ZR_GPIO_JPEG_RESET,
-       ZR_GPIO_JPEG_FRAME,
-       ZR_GPIO_VID_DIR,
-       ZR_GPIO_VID_EN,
-       ZR_GPIO_VID_RESET,
-       ZR_GPIO_CLK_SEL1,
-       ZR_GPIO_CLK_SEL2,
-       ZR_GPIO_MAX,
-};
-
-enum gpcs_type {
-       GPCS_JPEG_RESET = 0,
-       GPCS_JPEG_START,
-       GPCS_MAX,
-};
-
-struct zoran_format {
-       char *name;
-       __u32 fourcc;
-       int colorspace;
-       int depth;
-       __u32 flags;
-       __u32 vfespfr;
-};
-
-/* flags */
-#define ZORAN_FORMAT_COMPRESSED BIT(0)
-#define ZORAN_FORMAT_OVERLAY BIT(1)
-#define ZORAN_FORMAT_CAPTURE BIT(2)
-#define ZORAN_FORMAT_PLAYBACK BIT(3)
-
-/* v4l-capture settings */
-struct zoran_v4l_settings {
-       int width, height, bytesperline;        /* capture size */
-       const struct zoran_format *format;      /* capture format */
-};
-
-/* jpg-capture/-playback settings */
-struct zoran_jpg_settings {
-       /* this bit is used to set everything to default */
-       int decimation;
-       /* capture decimation settings (tmp_dcm=1 means both fields) */
-       int hor_dcm, ver_dcm, tmp_dcm;
-       /* field-settings (odd_even=1 (+tmp_dcm=1) means top-field-first) */
-       int field_per_buff, odd_even;
-       /* crop settings (subframe capture) */
-       int img_x, img_y, img_width, img_height;
-       /* JPEG-specific capture settings */
-       struct v4l2_jpegcompression jpg_comp;
-};
-
-struct zoran;
-
-/* zoran_fh contains per-open() settings */
-struct zoran_fh {
-       struct v4l2_fh fh;
-       struct zoran *zr;
-};
-
-struct card_info {
-       enum card_type type;
-       char name[32];
-       const char *i2c_decoder;        /* i2c decoder device */
-       const unsigned short *addrs_decoder;
-       const char *i2c_encoder;        /* i2c encoder device */
-       const unsigned short *addrs_encoder;
-       u16 video_vfe, video_codec;                     /* videocodec types */
-       u16 audio_chip;                                 /* audio type */
-
-       int inputs;             /* number of video inputs */
-       struct input {
-               int muxsel;
-               char name[32];
-       } input[BUZ_MAX_INPUT];
-
-       v4l2_std_id norms;
-       const struct tvnorm *tvn[3];    /* supported TV norms */
-
-       u32 jpeg_int;           /* JPEG interrupt */
-       u32 vsync_int;          /* VSYNC interrupt */
-       s8 gpio[ZR_GPIO_MAX];
-       u8 gpcs[GPCS_MAX];
-
-       struct vfe_polarity vfe_pol;
-       u8 gpio_pol[ZR_GPIO_MAX];
-
-       /* is the /GWS line connected? */
-       u8 gws_not_connected;
-
-       /* avs6eyes mux setting */
-       u8 input_mux;
-
-       void (*init)(struct zoran *zr);
-};
-
-struct zoran {
-       struct v4l2_device v4l2_dev;
-       struct v4l2_ctrl_handler hdl;
-       struct video_device *video_dev;
-       struct vb2_queue vq;
-
-       struct i2c_adapter i2c_adapter; /* */
-       struct i2c_algo_bit_data i2c_algo;      /* */
-       u32 i2cbr;
-
-       struct v4l2_subdev *decoder;    /* video decoder sub-device */
-       struct v4l2_subdev *encoder;    /* video encoder sub-device */
-
-       struct videocodec *codec;       /* video codec */
-       struct videocodec *vfe; /* video front end */
-
-       struct mutex lock;      /* file ops serialize lock */
-
-       u8 initialized;         /* flag if zoran has been correctly initialized */
-       struct card_info card;
-       const struct tvnorm *timing;
-
-       unsigned short id;      /* number of this device */
-       char name[32];          /* name of this device */
-       struct pci_dev *pci_dev;        /* PCI device */
-       unsigned char revision; /* revision of zr36057 */
-       unsigned char __iomem *zr36057_mem;/* pointer to mapped IO memory */
-
-       spinlock_t spinlock;    /* Spinlock */
-
-       /* Video for Linux parameters */
-       int input;      /* card's norm and input */
-       v4l2_std_id norm;
-
-       /* Current buffer params */
-       unsigned int buffer_size;
-
-       struct zoran_v4l_settings v4l_settings; /* structure with a lot of things to play with */
-
-       /* Buz MJPEG parameters */
-       enum zoran_codec_mode codec_mode;       /* status of codec */
-       struct zoran_jpg_settings jpg_settings; /* structure with a lot of things to play with */
-
-       /* grab queue counts/indices, mask with BUZ_MASK_STAT_COM before using as index */
-       /* (dma_head - dma_tail) is number active in DMA, must be <= BUZ_NUM_STAT_COM */
-       /* (value & BUZ_MASK_STAT_COM) corresponds to index in stat_com table */
-       unsigned long jpg_que_head;     /* Index where to put next buffer which is queued */
-       unsigned long jpg_dma_head;     /* Index of next buffer which goes into stat_com */
-       unsigned long jpg_dma_tail;     /* Index of last buffer in stat_com */
-       unsigned long jpg_que_tail;     /* Index of last buffer in queue */
-       unsigned long jpg_seq_num;      /* count of frames since grab/play started */
-       unsigned long jpg_err_seq;      /* last seq_num before error */
-       unsigned long jpg_err_shift;
-       unsigned long jpg_queued_num;   /* count of frames queued since grab/play started */
-       unsigned long vbseq;
-
-       /* zr36057's code buffer table */
-       /* stat_com[i] is indexed by dma_head/tail & BUZ_MASK_STAT_COM */
-       __le32 *stat_com;
-
-       /* Additional stuff for testing */
-       unsigned int ghost_int;
-       int intr_counter_GIRQ1;
-       int intr_counter_GIRQ0;
-       int intr_counter_cod_rep_irq;
-       int intr_counter_jpeg_rep_irq;
-       int field_counter;
-       int irq1_in;
-       int irq1_out;
-       int jpeg_in;
-       int jpeg_out;
-       int JPEG_0;
-       int JPEG_1;
-       int end_event_missed;
-       int jpeg_missed;
-       int jpeg_error;
-       int num_errors;
-       int jpeg_max_missed;
-       int jpeg_min_missed;
-       unsigned int prepared;
-       unsigned int queued;
-
-       u32 last_isr;
-       unsigned long frame_num;
-       int running;
-       int buf_in_reserve;
-
-       dma_addr_t p_sc;
-       __le32 *stat_comb;
-       dma_addr_t p_scb;
-       enum zoran_map_mode map_mode;
-       struct list_head queued_bufs;
-       spinlock_t queued_bufs_lock; /* Protects queued_bufs */
-       struct zr_buffer *inuse[BUZ_NUM_STAT_COM * 2];
-       struct dentry *dbgfs_dir;
-};
-
-static inline struct zoran *to_zoran(struct v4l2_device *v4l2_dev)
-{
-       return container_of(v4l2_dev, struct zoran, v4l2_dev);
-}
-
-/*
- * There was something called _ALPHA_BUZ that used the PCI address instead of
- * the kernel iomapped address for btread/btwrite.
- */
-#define btwrite(dat, adr)    writel((dat), zr->zr36057_mem + (adr))
-#define btread(adr)         readl(zr->zr36057_mem + (adr))
-
-#define btand(dat, adr)      btwrite((dat) & btread(adr), (adr))
-#define btor(dat, adr)       btwrite((dat) | btread(adr), (adr))
-#define btaor(dat, mask, adr) btwrite((dat) | ((mask) & btread(adr)), (adr))
-
-#endif
-
-/*
- * Debugging macros
- */
-#define zrdev_dbg(zr, format, args...) \
-       pci_dbg((zr)->pci_dev, format, ##args) \
-
-#define zrdev_err(zr, format, args...) \
-       pci_err((zr)->pci_dev, format, ##args) \
-
-#define zrdev_info(zr, format, args...) \
-       pci_info((zr)->pci_dev, format, ##args) \
-
-int zoran_queue_init(struct zoran *zr, struct vb2_queue *vq, int dir);
-void zoran_queue_exit(struct zoran *zr);
-int zr_set_buf(struct zoran *zr);
 
+++ /dev/null
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Zoran zr36057/zr36067 PCI controller driver, for the
- * Pinnacle/Miro DC10/DC10+/DC30/DC30+, Iomega Buz, Linux
- * Media Labs LML33/LML33R10.
- *
- * This part handles card-specific data and detection
- *
- * Copyright (C) 2000 Serguei Miridonov <mirsev@cicese.mx>
- */
-
-#include <linux/delay.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-
-#include <linux/i2c.h>
-#include <linux/i2c-algo-bit.h>
-#include <linux/videodev2.h>
-#include <linux/spinlock.h>
-
-#include <linux/pci.h>
-#include <linux/interrupt.h>
-#include <linux/io.h>
-#include <media/v4l2-common.h>
-#include <media/i2c/bt819.h>
-
-#include "videocodec.h"
-#include "zoran.h"
-#include "zoran_card.h"
-#include "zoran_device.h"
-#include "zr36016.h"
-#include "zr36050.h"
-#include "zr36060.h"
-
-extern const struct zoran_format zoran_formats[];
-
-static int card[BUZ_MAX] = { [0 ... (BUZ_MAX - 1)] = -1 };
-module_param_array(card, int, NULL, 0444);
-MODULE_PARM_DESC(card, "Card type");
-
-/* Default input and video norm at startup of the driver. */
-
-static unsigned int default_input;     /* default 0 = Composite, 1 = S-Video */
-module_param(default_input, uint, 0444);
-MODULE_PARM_DESC(default_input,
-                "Default input (0=Composite, 1=S-Video, 2=Internal)");
-
-static int default_mux = 1;    /* 6 Eyes input selection */
-module_param(default_mux, int, 0644);
-MODULE_PARM_DESC(default_mux,
-                "Default 6 Eyes mux setting (Input selection)");
-
-static int default_norm;       /* default 0 = PAL, 1 = NTSC 2 = SECAM */
-module_param(default_norm, int, 0444);
-MODULE_PARM_DESC(default_norm, "Default norm (0=PAL, 1=NTSC, 2=SECAM)");
-
-/* /dev/videoN, -1 for autodetect */
-static int video_nr[BUZ_MAX] = { [0 ... (BUZ_MAX - 1)] = -1 };
-module_param_array(video_nr, int, NULL, 0444);
-MODULE_PARM_DESC(video_nr, "Video device number (-1=Auto)");
-
-/* 1=Pass through TV signal when device is not used */
-/* 0=Show color bar when device is not used (LML33: only if lml33dpath=1) */
-int pass_through;
-module_param(pass_through, int, 0644);
-MODULE_PARM_DESC(pass_through,
-                "Pass TV signal through to TV-out when idling");
-
-int zr36067_debug = 1;
-module_param_named(debug, zr36067_debug, int, 0644);
-MODULE_PARM_DESC(debug, "Debug level (0-5)");
-
-#define ZORAN_VERSION "0.10.1"
-
-MODULE_DESCRIPTION("Zoran-36057/36067 JPEG codec driver");
-MODULE_AUTHOR("Serguei Miridonov");
-MODULE_LICENSE("GPL");
-MODULE_VERSION(ZORAN_VERSION);
-
-#define ZR_DEVICE(subven, subdev, data)        { \
-       .vendor = PCI_VENDOR_ID_ZORAN, .device = PCI_DEVICE_ID_ZORAN_36057, \
-       .subvendor = (subven), .subdevice = (subdev), .driver_data = (data) }
-
-static const struct pci_device_id zr36067_pci_tbl[] = {
-       ZR_DEVICE(PCI_VENDOR_ID_MIRO, PCI_DEVICE_ID_MIRO_DC10PLUS, DC10_PLUS),
-       ZR_DEVICE(PCI_VENDOR_ID_MIRO, PCI_DEVICE_ID_MIRO_DC30PLUS, DC30_PLUS),
-       ZR_DEVICE(PCI_VENDOR_ID_ELECTRONICDESIGNGMBH, PCI_DEVICE_ID_LML_33R10, LML33R10),
-       ZR_DEVICE(PCI_VENDOR_ID_IOMEGA, PCI_DEVICE_ID_IOMEGA_BUZ, BUZ),
-       ZR_DEVICE(PCI_ANY_ID, PCI_ANY_ID, NUM_CARDS),
-       {0}
-};
-MODULE_DEVICE_TABLE(pci, zr36067_pci_tbl);
-
-static unsigned int zoran_num;         /* number of cards found */
-
-/* videocodec bus functions ZR36060 */
-static u32 zr36060_read(struct videocodec *codec, u16 reg)
-{
-       struct zoran *zr = (struct zoran *)codec->master_data->data;
-       __u32 data;
-
-       if (post_office_wait(zr) || post_office_write(zr, 0, 1, reg >> 8) ||
-           post_office_write(zr, 0, 2, reg & 0xff))
-               return -1;
-
-       data = post_office_read(zr, 0, 3) & 0xff;
-       return data;
-}
-
-static void zr36060_write(struct videocodec *codec, u16 reg, u32 val)
-{
-       struct zoran *zr = (struct zoran *)codec->master_data->data;
-
-       if (post_office_wait(zr) || post_office_write(zr, 0, 1, reg >> 8) ||
-           post_office_write(zr, 0, 2, reg & 0xff))
-               return;
-
-       post_office_write(zr, 0, 3, val & 0xff);
-}
-
-/* videocodec bus functions ZR36050 */
-static u32 zr36050_read(struct videocodec *codec, u16 reg)
-{
-       struct zoran *zr = (struct zoran *)codec->master_data->data;
-       __u32 data;
-
-       if (post_office_wait(zr) || post_office_write(zr, 1, 0, reg >> 2))      // reg. HIGHBYTES
-               return -1;
-
-       data = post_office_read(zr, 0, reg & 0x03) & 0xff;      // reg. LOWBYTES + read
-       return data;
-}
-
-static void zr36050_write(struct videocodec *codec, u16 reg, u32 val)
-{
-       struct zoran *zr = (struct zoran *)codec->master_data->data;
-
-       if (post_office_wait(zr) || post_office_write(zr, 1, 0, reg >> 2))      // reg. HIGHBYTES
-               return;
-
-       post_office_write(zr, 0, reg & 0x03, val & 0xff);       // reg. LOWBYTES + wr. data
-}
-
-/* videocodec bus functions ZR36016 */
-static u32 zr36016_read(struct videocodec *codec, u16 reg)
-{
-       struct zoran *zr = (struct zoran *)codec->master_data->data;
-       __u32 data;
-
-       if (post_office_wait(zr))
-               return -1;
-
-       data = post_office_read(zr, 2, reg & 0x03) & 0xff;      // read
-       return data;
-}
-
-/* hack for in zoran_device.c */
-void zr36016_write(struct videocodec *codec, u16 reg, u32 val)
-{
-       struct zoran *zr = (struct zoran *)codec->master_data->data;
-
-       if (post_office_wait(zr))
-               return;
-
-       post_office_write(zr, 2, reg & 0x03, val & 0x0ff);      // wr. data
-}
-
-/*
- * Board specific information
- */
-
-static void dc10_init(struct zoran *zr)
-{
-       /* Pixel clock selection */
-       GPIO(zr, 4, 0);
-       GPIO(zr, 5, 1);
-       /* Enable the video bus sync signals */
-       GPIO(zr, 7, 0);
-}
-
-static void dc10plus_init(struct zoran *zr)
-{
-}
-
-static void buz_init(struct zoran *zr)
-{
-       /* some stuff from Iomega */
-       pci_write_config_dword(zr->pci_dev, 0xfc, 0x90680f15);
-       pci_write_config_dword(zr->pci_dev, 0x0c, 0x00012020);
-       pci_write_config_dword(zr->pci_dev, 0xe8, 0xc0200000);
-}
-
-static void lml33_init(struct zoran *zr)
-{
-       GPIO(zr, 2, 1);         // Set Composite input/output
-}
-
-static void avs6eyes_init(struct zoran *zr)
-{
-       // AverMedia 6-Eyes original driver by Christer Weinigel
-
-       // Lifted straight from Christer's old driver and
-       // modified slightly by Martin Samuelsson.
-
-       int mux = default_mux; /* 1 = BT866, 7 = VID1 */
-
-       GPIO(zr, 4, 1); /* Bt866 SLEEP on */
-       udelay(2);
-
-       GPIO(zr, 0, 1); /* ZR36060 /RESET on */
-       GPIO(zr, 1, 0); /* ZR36060 /SLEEP on */
-       GPIO(zr, 2, mux & 1);   /* MUX S0 */
-       GPIO(zr, 3, 0); /* /FRAME on */
-       GPIO(zr, 4, 0); /* Bt866 SLEEP off */
-       GPIO(zr, 5, mux & 2);   /* MUX S1 */
-       GPIO(zr, 6, 0); /* ? */
-       GPIO(zr, 7, mux & 4);   /* MUX S2 */
-}
-
-static const char *codecid_to_modulename(u16 codecid)
-{
-       const char *name = NULL;
-
-       switch (codecid) {
-       case CODEC_TYPE_ZR36060:
-               name = "zr36060";
-               break;
-       case CODEC_TYPE_ZR36050:
-               name = "zr36050";
-               break;
-       case CODEC_TYPE_ZR36016:
-               name = "zr36016";
-               break;
-       }
-
-       return name;
-}
-
-static int codec_init(struct zoran *zr, u16 codecid)
-{
-       switch (codecid) {
-       case CODEC_TYPE_ZR36060:
-#ifdef CONFIG_VIDEO_ZORAN_ZR36060
-               return zr36060_init_module();
-#else
-               pci_err(zr->pci_dev, "ZR36060 support is not enabled\n");
-               return -EINVAL;
-#endif
-               break;
-       case CODEC_TYPE_ZR36050:
-#ifdef CONFIG_VIDEO_ZORAN_DC30
-               return zr36050_init_module();
-#else
-               pci_err(zr->pci_dev, "ZR36050 support is not enabled\n");
-               return -EINVAL;
-#endif
-               break;
-       case CODEC_TYPE_ZR36016:
-#ifdef CONFIG_VIDEO_ZORAN_DC30
-               return zr36016_init_module();
-#else
-               pci_err(zr->pci_dev, "ZR36016 support is not enabled\n");
-               return -EINVAL;
-#endif
-               break;
-       }
-
-       pci_err(zr->pci_dev, "unknown codec id %x\n", codecid);
-       return -EINVAL;
-}
-
-static void codec_exit(struct zoran *zr, u16 codecid)
-{
-       switch (codecid) {
-       case CODEC_TYPE_ZR36060:
-#ifdef CONFIG_VIDEO_ZORAN_ZR36060
-               zr36060_cleanup_module();
-#endif
-               break;
-       case CODEC_TYPE_ZR36050:
-#ifdef CONFIG_VIDEO_ZORAN_DC30
-               zr36050_cleanup_module();
-#endif
-               break;
-       case CODEC_TYPE_ZR36016:
-#ifdef CONFIG_VIDEO_ZORAN_DC30
-               zr36016_cleanup_module();
-#endif
-               break;
-       }
-}
-
-static int videocodec_init(struct zoran *zr)
-{
-       const char *codec_name, *vfe_name;
-       int result;
-
-       codec_name = codecid_to_modulename(zr->card.video_codec);
-       if (codec_name) {
-               result = codec_init(zr, zr->card.video_codec);
-               if (result < 0) {
-                       pci_err(zr->pci_dev, "failed to load video codec %s: %d\n",
-                               codec_name, result);
-                       return result;
-               }
-       }
-       vfe_name = codecid_to_modulename(zr->card.video_vfe);
-       if (vfe_name) {
-               result = codec_init(zr, zr->card.video_vfe);
-               if (result < 0) {
-                       pci_err(zr->pci_dev, "failed to load video vfe %s: %d\n",
-                               vfe_name, result);
-                       if (codec_name)
-                               codec_exit(zr, zr->card.video_codec);
-                       return result;
-               }
-       }
-       return 0;
-}
-
-static void videocodec_exit(struct zoran *zr)
-{
-       if (zr->card.video_codec != CODEC_TYPE_NONE)
-               codec_exit(zr, zr->card.video_codec);
-       if (zr->card.video_vfe != CODEC_TYPE_NONE)
-               codec_exit(zr, zr->card.video_vfe);
-}
-
-static const struct tvnorm f50sqpixel = { 944, 768, 83, 880, 625, 576, 16 };
-static const struct tvnorm f60sqpixel = { 780, 640, 51, 716, 525, 480, 12 };
-static const struct tvnorm f50ccir601 = { 864, 720, 75, 804, 625, 576, 18 };
-static const struct tvnorm f60ccir601 = { 858, 720, 57, 788, 525, 480, 16 };
-
-static const struct tvnorm f50ccir601_lml33 = { 864, 720, 75 + 34, 804, 625, 576, 18 };
-static const struct tvnorm f60ccir601_lml33 = { 858, 720, 57 + 34, 788, 525, 480, 16 };
-
-/* The DC10 (57/16/50) uses VActive as HSync, so h_start must be 0 */
-static const struct tvnorm f50sqpixel_dc10 = { 944, 768, 0, 880, 625, 576, 0 };
-static const struct tvnorm f60sqpixel_dc10 = { 780, 640, 0, 716, 525, 480, 12 };
-
-/*
- * FIXME: I cannot swap U and V in saa7114, so i do one pixel left shift in zoran (75 -> 74)
- * (Maxim Yevtyushkin <max@linuxmedialabs.com>)
- */
-static const struct tvnorm f50ccir601_lm33r10 = { 864, 720, 74 + 54, 804, 625, 576, 18 };
-static const struct tvnorm f60ccir601_lm33r10 = { 858, 720, 56 + 54, 788, 525, 480, 16 };
-
-/*
- * FIXME: The ks0127 seem incapable of swapping U and V, too, which is why I copy Maxim's left
- * shift hack for the 6 Eyes.
- *
- * Christer's driver used the unshifted norms, though...
- * /Sam
- */
-static const struct tvnorm f50ccir601_avs6eyes = { 864, 720, 74, 804, 625, 576, 18 };
-static const struct tvnorm f60ccir601_avs6eyes = { 858, 720, 56, 788, 525, 480, 16 };
-
-static const unsigned short vpx3220_addrs[] = { 0x43, 0x47, I2C_CLIENT_END };
-static const unsigned short saa7110_addrs[] = { 0x4e, 0x4f, I2C_CLIENT_END };
-static const unsigned short saa7111_addrs[] = { 0x25, 0x24, I2C_CLIENT_END };
-static const unsigned short saa7114_addrs[] = { 0x21, 0x20, I2C_CLIENT_END };
-static const unsigned short adv717x_addrs[] = { 0x6a, 0x6b, 0x2a, 0x2b, I2C_CLIENT_END };
-static const unsigned short ks0127_addrs[] = { 0x6c, 0x6d, I2C_CLIENT_END };
-static const unsigned short saa7185_addrs[] = { 0x44, I2C_CLIENT_END };
-static const unsigned short bt819_addrs[] = { 0x45, I2C_CLIENT_END };
-static const unsigned short bt856_addrs[] = { 0x44, I2C_CLIENT_END };
-static const unsigned short bt866_addrs[] = { 0x44, I2C_CLIENT_END };
-
-static struct card_info zoran_cards[NUM_CARDS] = {
-       {
-               .type = DC10_OLD,
-               .name = "DC10(old)",
-               .i2c_decoder = "vpx3220a",
-               .addrs_decoder = vpx3220_addrs,
-               .video_codec = CODEC_TYPE_ZR36050,
-               .video_vfe = CODEC_TYPE_ZR36016,
-
-               .inputs = 3,
-               .input = {
-                       { 1, "Composite" },
-                       { 2, "S-Video" },
-                       { 0, "Internal/comp" }
-               },
-               .norms = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM,
-               .tvn = {
-                       &f50sqpixel_dc10,
-                       &f60sqpixel_dc10,
-                       &f50sqpixel_dc10
-               },
-               .jpeg_int = 0,
-               .vsync_int = ZR36057_ISR_GIRQ1,
-               .gpio = { 2, 1, -1, 3, 7, 0, 4, 5 },
-               .gpio_pol = { 0, 0, 0, 1, 0, 0, 0, 0 },
-               .gpcs = { -1, 0 },
-               .vfe_pol = { 0, 0, 0, 0, 0, 0, 0, 0 },
-               .gws_not_connected = 0,
-               .input_mux = 0,
-               .init = &dc10_init,
-       }, {
-               .type = DC10_NEW,
-               .name = "DC10(new)",
-               .i2c_decoder = "saa7110",
-               .addrs_decoder = saa7110_addrs,
-               .i2c_encoder = "adv7175",
-               .addrs_encoder = adv717x_addrs,
-               .video_codec = CODEC_TYPE_ZR36060,
-
-               .inputs = 3,
-               .input = {
-                               { 0, "Composite" },
-                               { 7, "S-Video" },
-                               { 5, "Internal/comp" }
-                       },
-               .norms = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM,
-               .tvn = {
-                               &f50sqpixel,
-                               &f60sqpixel,
-                               &f50sqpixel},
-               .jpeg_int = ZR36057_ISR_GIRQ0,
-               .vsync_int = ZR36057_ISR_GIRQ1,
-               .gpio = { 3, 0, 6, 1, 2, -1, 4, 5 },
-               .gpio_pol = { 0, 0, 0, 0, 0, 0, 0, 0 },
-               .gpcs = { -1, 1},
-               .vfe_pol = { 1, 1, 1, 1, 0, 0, 0, 0 },
-               .gws_not_connected = 0,
-               .input_mux = 0,
-               .init = &dc10plus_init,
-       }, {
-               .type = DC10_PLUS,
-               .name = "DC10_PLUS",
-               .i2c_decoder = "saa7110",
-               .addrs_decoder = saa7110_addrs,
-               .i2c_encoder = "adv7175",
-               .addrs_encoder = adv717x_addrs,
-               .video_codec = CODEC_TYPE_ZR36060,
-
-               .inputs = 3,
-               .input = {
-                       { 0, "Composite" },
-                       { 7, "S-Video" },
-                       { 5, "Internal/comp" }
-               },
-               .norms = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM,
-               .tvn = {
-                       &f50sqpixel,
-                       &f60sqpixel,
-                       &f50sqpixel
-               },
-               .jpeg_int = ZR36057_ISR_GIRQ0,
-               .vsync_int = ZR36057_ISR_GIRQ1,
-               .gpio = { 3, 0, 6, 1, 2, -1, 4, 5 },
-               .gpio_pol = { 0, 0, 0, 0, 0, 0, 0, 0 },
-               .gpcs = { -1, 1 },
-               .vfe_pol = { 1, 1, 1, 1, 0, 0, 0, 0 },
-               .gws_not_connected = 0,
-               .input_mux = 0,
-               .init = &dc10plus_init,
-       }, {
-               .type = DC30,
-               .name = "DC30",
-               .i2c_decoder = "vpx3220a",
-               .addrs_decoder = vpx3220_addrs,
-               .i2c_encoder = "adv7175",
-               .addrs_encoder = adv717x_addrs,
-               .video_codec = CODEC_TYPE_ZR36050,
-               .video_vfe = CODEC_TYPE_ZR36016,
-
-               .inputs = 3,
-               .input = {
-                       { 1, "Composite" },
-                       { 2, "S-Video" },
-                       { 0, "Internal/comp" }
-               },
-               .norms = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM,
-               .tvn = {
-                       &f50sqpixel_dc10,
-                       &f60sqpixel_dc10,
-                       &f50sqpixel_dc10
-               },
-               .jpeg_int = 0,
-               .vsync_int = ZR36057_ISR_GIRQ1,
-               .gpio = { 2, 1, -1, 3, 7, 0, 4, 5 },
-               .gpio_pol = { 0, 0, 0, 1, 0, 0, 0, 0 },
-               .gpcs = { -1, 0 },
-               .vfe_pol = { 0, 0, 0, 0, 0, 0, 0, 0 },
-               .gws_not_connected = 0,
-               .input_mux = 0,
-               .init = &dc10_init,
-       }, {
-               .type = DC30_PLUS,
-               .name = "DC30_PLUS",
-               .i2c_decoder = "vpx3220a",
-               .addrs_decoder = vpx3220_addrs,
-               .i2c_encoder = "adv7175",
-               .addrs_encoder = adv717x_addrs,
-               .video_codec = CODEC_TYPE_ZR36050,
-               .video_vfe = CODEC_TYPE_ZR36016,
-
-               .inputs = 3,
-               .input = {
-                       { 1, "Composite" },
-                       { 2, "S-Video" },
-                       { 0, "Internal/comp" }
-               },
-               .norms = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM,
-               .tvn = {
-                       &f50sqpixel_dc10,
-                       &f60sqpixel_dc10,
-                       &f50sqpixel_dc10
-               },
-               .jpeg_int = 0,
-               .vsync_int = ZR36057_ISR_GIRQ1,
-               .gpio = { 2, 1, -1, 3, 7, 0, 4, 5 },
-               .gpio_pol = { 0, 0, 0, 1, 0, 0, 0, 0 },
-               .gpcs = { -1, 0 },
-               .vfe_pol = { 0, 0, 0, 0, 0, 0, 0, 0 },
-               .gws_not_connected = 0,
-               .input_mux = 0,
-               .init = &dc10_init,
-       }, {
-               .type = LML33,
-               .name = "LML33",
-               .i2c_decoder = "bt819a",
-               .addrs_decoder = bt819_addrs,
-               .i2c_encoder = "bt856",
-               .addrs_encoder = bt856_addrs,
-               .video_codec = CODEC_TYPE_ZR36060,
-
-               .inputs = 2,
-               .input = {
-                       { 0, "Composite" },
-                       { 7, "S-Video" }
-               },
-               .norms = V4L2_STD_NTSC | V4L2_STD_PAL,
-               .tvn = {
-                       &f50ccir601_lml33,
-                       &f60ccir601_lml33,
-                       NULL
-               },
-               .jpeg_int = ZR36057_ISR_GIRQ1,
-               .vsync_int = ZR36057_ISR_GIRQ0,
-               .gpio = { 1, -1, 3, 5, 7, -1, -1, -1 },
-               .gpio_pol = { 0, 0, 0, 0, 1, 0, 0, 0 },
-               .gpcs = { 3, 1 },
-               .vfe_pol = { 1, 1, 0, 0, 0, 1, 0, 0 },
-               .gws_not_connected = 1,
-               .input_mux = 0,
-               .init = &lml33_init,
-       }, {
-               .type = LML33R10,
-               .name = "LML33R10",
-               .i2c_decoder = "saa7114",
-               .addrs_decoder = saa7114_addrs,
-               .i2c_encoder = "adv7170",
-               .addrs_encoder = adv717x_addrs,
-               .video_codec = CODEC_TYPE_ZR36060,
-
-               .inputs = 2,
-               .input = {
-                       { 0, "Composite" },
-                       { 7, "S-Video" }
-               },
-               .norms = V4L2_STD_NTSC | V4L2_STD_PAL,
-               .tvn = {
-                       &f50ccir601_lm33r10,
-                       &f60ccir601_lm33r10,
-                       NULL
-               },
-               .jpeg_int = ZR36057_ISR_GIRQ1,
-               .vsync_int = ZR36057_ISR_GIRQ0,
-               .gpio = { 1, -1, 3, 5, 7, -1, -1, -1 },
-               .gpio_pol = { 0, 0, 0, 0, 1, 0, 0, 0 },
-               .gpcs = { 3, 1 },
-               .vfe_pol = { 1, 1, 0, 0, 0, 1, 0, 0 },
-               .gws_not_connected = 1,
-               .input_mux = 0,
-               .init = &lml33_init,
-       }, {
-               .type = BUZ,
-               .name = "Buz",
-               .i2c_decoder = "saa7111",
-               .addrs_decoder = saa7111_addrs,
-               .i2c_encoder = "saa7185",
-               .addrs_encoder = saa7185_addrs,
-               .video_codec = CODEC_TYPE_ZR36060,
-
-               .inputs = 2,
-               .input = {
-                       { 3, "Composite" },
-                       { 7, "S-Video" }
-               },
-               .norms = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM,
-               .tvn = {
-                       &f50ccir601,
-                       &f60ccir601,
-                       &f50ccir601
-               },
-               .jpeg_int = ZR36057_ISR_GIRQ1,
-               .vsync_int = ZR36057_ISR_GIRQ0,
-               .gpio = { 1, -1, 3, -1, -1, -1, -1, -1 },
-               .gpio_pol = { 0, 0, 0, 0, 0, 0, 0, 0 },
-               .gpcs = { 3, 1 },
-               .vfe_pol = { 1, 1, 0, 0, 0, 1, 0, 0 },
-               .gws_not_connected = 1,
-               .input_mux = 0,
-               .init = &buz_init,
-       }, {
-               .type = AVS6EYES,
-               .name = "6-Eyes",
-               /*
-                * AverMedia chose not to brand the 6-Eyes. Thus it can't be
-                * autodetected, and requires card=x.
-                */
-               .i2c_decoder = "ks0127",
-               .addrs_decoder = ks0127_addrs,
-               .i2c_encoder = "bt866",
-               .addrs_encoder = bt866_addrs,
-               .video_codec = CODEC_TYPE_ZR36060,
-
-               .inputs = 10,
-               .input = {
-                       { 0, "Composite 1" },
-                       { 1, "Composite 2" },
-                       { 2, "Composite 3" },
-                       { 4, "Composite 4" },
-                       { 5, "Composite 5" },
-                       { 6, "Composite 6" },
-                       { 8, "S-Video 1" },
-                       { 9, "S-Video 2" },
-                       {10, "S-Video 3" },
-                       {15, "YCbCr" }
-               },
-               .norms = V4L2_STD_NTSC | V4L2_STD_PAL,
-               .tvn = {
-                       &f50ccir601_avs6eyes,
-                       &f60ccir601_avs6eyes,
-                       NULL
-               },
-               .jpeg_int = ZR36057_ISR_GIRQ1,
-               .vsync_int = ZR36057_ISR_GIRQ0,
-               .gpio = { 1, 0, 3, -1, -1, -1, -1, -1 },// Validity unknown /Sam
-               .gpio_pol = { 0, 0, 0, 0, 0, 0, 0, 0 }, // Validity unknown /Sam
-               .gpcs = { 3, 1 },                       // Validity unknown /Sam
-               .vfe_pol = { 1, 0, 0, 0, 0, 1, 0, 0 },  // Validity unknown /Sam
-               .gws_not_connected = 1,
-               .input_mux = 1,
-               .init = &avs6eyes_init,
-       }
-
-};
-
-/*
- * I2C functions
- */
-/* software I2C functions */
-static int zoran_i2c_getsda(void *data)
-{
-       struct zoran *zr = (struct zoran *)data;
-
-       return (btread(ZR36057_I2CBR) >> 1) & 1;
-}
-
-static int zoran_i2c_getscl(void *data)
-{
-       struct zoran *zr = (struct zoran *)data;
-
-       return btread(ZR36057_I2CBR) & 1;
-}
-
-static void zoran_i2c_setsda(void *data, int state)
-{
-       struct zoran *zr = (struct zoran *)data;
-
-       if (state)
-               zr->i2cbr |= 2;
-       else
-               zr->i2cbr &= ~2;
-       btwrite(zr->i2cbr, ZR36057_I2CBR);
-}
-
-static void zoran_i2c_setscl(void *data, int state)
-{
-       struct zoran *zr = (struct zoran *)data;
-
-       if (state)
-               zr->i2cbr |= 1;
-       else
-               zr->i2cbr &= ~1;
-       btwrite(zr->i2cbr, ZR36057_I2CBR);
-}
-
-static const struct i2c_algo_bit_data zoran_i2c_bit_data_template = {
-       .setsda = zoran_i2c_setsda,
-       .setscl = zoran_i2c_setscl,
-       .getsda = zoran_i2c_getsda,
-       .getscl = zoran_i2c_getscl,
-       .udelay = 10,
-       .timeout = 100,
-};
-
-static int zoran_register_i2c(struct zoran *zr)
-{
-       zr->i2c_algo = zoran_i2c_bit_data_template;
-       zr->i2c_algo.data = zr;
-       strscpy(zr->i2c_adapter.name, ZR_DEVNAME(zr),
-               sizeof(zr->i2c_adapter.name));
-       i2c_set_adapdata(&zr->i2c_adapter, &zr->v4l2_dev);
-       zr->i2c_adapter.algo_data = &zr->i2c_algo;
-       zr->i2c_adapter.dev.parent = &zr->pci_dev->dev;
-       return i2c_bit_add_bus(&zr->i2c_adapter);
-}
-
-static void zoran_unregister_i2c(struct zoran *zr)
-{
-       i2c_del_adapter(&zr->i2c_adapter);
-}
-
-/* Check a zoran_params struct for correctness, insert default params */
-int zoran_check_jpg_settings(struct zoran *zr,
-                            struct zoran_jpg_settings *settings, int try)
-{
-       int err = 0, err0 = 0;
-
-       pci_dbg(zr->pci_dev, "%s - dec: %d, Hdcm: %d, Vdcm: %d, Tdcm: %d\n",
-               __func__, settings->decimation, settings->hor_dcm,
-               settings->ver_dcm, settings->tmp_dcm);
-       pci_dbg(zr->pci_dev, "%s - x: %d, y: %d, w: %d, y: %d\n", __func__,
-               settings->img_x, settings->img_y,
-               settings->img_width, settings->img_height);
-       /* Check decimation, set default values for decimation = 1, 2, 4 */
-       switch (settings->decimation) {
-       case 1:
-
-               settings->hor_dcm = 1;
-               settings->ver_dcm = 1;
-               settings->tmp_dcm = 1;
-               settings->field_per_buff = 2;
-               settings->img_x = 0;
-               settings->img_y = 0;
-               settings->img_width = BUZ_MAX_WIDTH;
-               settings->img_height = BUZ_MAX_HEIGHT / 2;
-               break;
-       case 2:
-
-               settings->hor_dcm = 2;
-               settings->ver_dcm = 1;
-               settings->tmp_dcm = 2;
-               settings->field_per_buff = 1;
-               settings->img_x = (BUZ_MAX_WIDTH == 720) ? 8 : 0;
-               settings->img_y = 0;
-               settings->img_width =
-                   (BUZ_MAX_WIDTH == 720) ? 704 : BUZ_MAX_WIDTH;
-               settings->img_height = BUZ_MAX_HEIGHT / 2;
-               break;
-       case 4:
-
-               if (zr->card.type == DC10_NEW) {
-                       pci_dbg(zr->pci_dev,
-                               "%s - HDec by 4 is not supported on the DC10\n",
-                               __func__);
-                       err0++;
-                       break;
-               }
-
-               settings->hor_dcm = 4;
-               settings->ver_dcm = 2;
-               settings->tmp_dcm = 2;
-               settings->field_per_buff = 1;
-               settings->img_x = (BUZ_MAX_WIDTH == 720) ? 8 : 0;
-               settings->img_y = 0;
-               settings->img_width =
-                   (BUZ_MAX_WIDTH == 720) ? 704 : BUZ_MAX_WIDTH;
-               settings->img_height = BUZ_MAX_HEIGHT / 2;
-               break;
-       case 0:
-
-               /* We have to check the data the user has set */
-
-               if (settings->hor_dcm != 1 && settings->hor_dcm != 2 &&
-                   (zr->card.type == DC10_NEW || settings->hor_dcm != 4)) {
-                       settings->hor_dcm = clamp(settings->hor_dcm, 1, 2);
-                       err0++;
-               }
-               if (settings->ver_dcm != 1 && settings->ver_dcm != 2) {
-                       settings->ver_dcm = clamp(settings->ver_dcm, 1, 2);
-                       err0++;
-               }
-               if (settings->tmp_dcm != 1 && settings->tmp_dcm != 2) {
-                       settings->tmp_dcm = clamp(settings->tmp_dcm, 1, 2);
-                       err0++;
-               }
-               if (settings->field_per_buff != 1 &&
-                   settings->field_per_buff != 2) {
-                       settings->field_per_buff = clamp(settings->field_per_buff, 1, 2);
-                       err0++;
-               }
-               if (settings->img_x < 0) {
-                       settings->img_x = 0;
-                       err0++;
-               }
-               if (settings->img_y < 0) {
-                       settings->img_y = 0;
-                       err0++;
-               }
-               if (settings->img_width < 0 || settings->img_width > BUZ_MAX_WIDTH) {
-                       settings->img_width = clamp(settings->img_width, 0, (int)BUZ_MAX_WIDTH);
-                       err0++;
-               }
-               if (settings->img_height < 0 || settings->img_height > BUZ_MAX_HEIGHT / 2) {
-                       settings->img_height = clamp(settings->img_height, 0, BUZ_MAX_HEIGHT / 2);
-                       err0++;
-               }
-               if (settings->img_x + settings->img_width > BUZ_MAX_WIDTH) {
-                       settings->img_x = BUZ_MAX_WIDTH - settings->img_width;
-                       err0++;
-               }
-               if (settings->img_y + settings->img_height > BUZ_MAX_HEIGHT / 2) {
-                       settings->img_y = BUZ_MAX_HEIGHT / 2 - settings->img_height;
-                       err0++;
-               }
-               if (settings->img_width % (16 * settings->hor_dcm) != 0) {
-                       settings->img_width -= settings->img_width % (16 * settings->hor_dcm);
-                       if (settings->img_width == 0)
-                               settings->img_width = 16 * settings->hor_dcm;
-                       err0++;
-               }
-               if (settings->img_height % (8 * settings->ver_dcm) != 0) {
-                       settings->img_height -= settings->img_height % (8 * settings->ver_dcm);
-                       if (settings->img_height == 0)
-                               settings->img_height = 8 * settings->ver_dcm;
-                       err0++;
-               }
-
-               if (!try && err0) {
-                       pci_err(zr->pci_dev, "%s - error in params for decimation = 0\n", __func__);
-                       err++;
-               }
-               break;
-       default:
-               pci_err(zr->pci_dev, "%s - decimation = %d, must be 0, 1, 2 or 4\n",
-                       __func__, settings->decimation);
-               err++;
-               break;
-       }
-
-       if (settings->jpg_comp.quality > 100)
-               settings->jpg_comp.quality = 100;
-       if (settings->jpg_comp.quality < 5)
-               settings->jpg_comp.quality = 5;
-       if (settings->jpg_comp.APPn < 0)
-               settings->jpg_comp.APPn = 0;
-       if (settings->jpg_comp.APPn > 15)
-               settings->jpg_comp.APPn = 15;
-       if (settings->jpg_comp.APP_len < 0)
-               settings->jpg_comp.APP_len = 0;
-       if (settings->jpg_comp.APP_len > 60)
-               settings->jpg_comp.APP_len = 60;
-       if (settings->jpg_comp.COM_len < 0)
-               settings->jpg_comp.COM_len = 0;
-       if (settings->jpg_comp.COM_len > 60)
-               settings->jpg_comp.COM_len = 60;
-       if (err)
-               return -EINVAL;
-       return 0;
-}
-
-static int zoran_init_video_device(struct zoran *zr, struct video_device *video_dev, int dir)
-{
-       int err;
-
-       /* Now add the template and register the device unit. */
-       *video_dev = zoran_template;
-       video_dev->v4l2_dev = &zr->v4l2_dev;
-       video_dev->lock = &zr->lock;
-       video_dev->device_caps = V4L2_CAP_STREAMING | dir;
-
-       strscpy(video_dev->name, ZR_DEVNAME(zr), sizeof(video_dev->name));
-       video_dev->vfl_dir = VFL_DIR_RX;
-       zoran_queue_init(zr, &zr->vq, V4L2_BUF_TYPE_VIDEO_CAPTURE);
-
-       err = video_register_device(video_dev, VFL_TYPE_VIDEO, video_nr[zr->id]);
-       if (err < 0)
-               return err;
-       video_set_drvdata(video_dev, zr);
-       return 0;
-}
-
-static void zoran_exit_video_devices(struct zoran *zr)
-{
-       video_unregister_device(zr->video_dev);
-       kfree(zr->video_dev);
-}
-
-static int zoran_init_video_devices(struct zoran *zr)
-{
-       int err;
-
-       zr->video_dev = video_device_alloc();
-       if (!zr->video_dev)
-               return -ENOMEM;
-
-       err = zoran_init_video_device(zr, zr->video_dev, V4L2_CAP_VIDEO_CAPTURE);
-       if (err)
-               kfree(zr->video_dev);
-       return err;
-}
-
-/*
- * v4l2_device_unregister() will care about removing zr->encoder/zr->decoder
- * via v4l2_i2c_subdev_unregister()
- */
-static int zoran_i2c_init(struct zoran *zr)
-{
-       int err;
-
-       pci_info(zr->pci_dev, "Initializing i2c bus...\n");
-
-       err = zoran_register_i2c(zr);
-       if (err) {
-               pci_err(zr->pci_dev, "%s - cannot initialize i2c bus\n", __func__);
-               return err;
-       }
-
-       zr->decoder = v4l2_i2c_new_subdev(&zr->v4l2_dev, &zr->i2c_adapter,
-                                         zr->card.i2c_decoder, 0,
-                                         zr->card.addrs_decoder);
-       if (!zr->decoder) {
-               pci_err(zr->pci_dev, "Fail to get decoder %s\n", zr->card.i2c_decoder);
-               err = -EINVAL;
-               goto error_decoder;
-       }
-
-       if (zr->card.i2c_encoder) {
-               zr->encoder = v4l2_i2c_new_subdev(&zr->v4l2_dev, &zr->i2c_adapter,
-                                                 zr->card.i2c_encoder, 0,
-                                                 zr->card.addrs_encoder);
-               if (!zr->encoder) {
-                       pci_err(zr->pci_dev, "Fail to get encoder %s\n", zr->card.i2c_encoder);
-                       err = -EINVAL;
-                       goto error_decoder;
-               }
-       }
-       return 0;
-
-error_decoder:
-       zoran_unregister_i2c(zr);
-       return err;
-}
-
-static void zoran_i2c_exit(struct zoran *zr)
-{
-       zoran_unregister_i2c(zr);
-}
-
-void zoran_open_init_params(struct zoran *zr)
-{
-       int i;
-
-       zr->v4l_settings.width = 192;
-       zr->v4l_settings.height = 144;
-       zr->v4l_settings.format = &zoran_formats[7];    /* YUY2 - YUV-4:2:2 packed */
-       zr->v4l_settings.bytesperline = zr->v4l_settings.width *
-               ((zr->v4l_settings.format->depth + 7) / 8);
-
-       /* Set necessary params and call zoran_check_jpg_settings to set the defaults */
-       zr->jpg_settings.decimation = 1;
-       zr->jpg_settings.jpg_comp.quality = 50; /* default compression factor 8 */
-       if (zr->card.type != BUZ)
-               zr->jpg_settings.odd_even = 1;
-       else
-               zr->jpg_settings.odd_even = 0;
-       zr->jpg_settings.jpg_comp.APPn = 0;
-       zr->jpg_settings.jpg_comp.APP_len = 0;  /* No APPn marker */
-       memset(zr->jpg_settings.jpg_comp.APP_data, 0,
-              sizeof(zr->jpg_settings.jpg_comp.APP_data));
-       zr->jpg_settings.jpg_comp.COM_len = 0;  /* No COM marker */
-       memset(zr->jpg_settings.jpg_comp.COM_data, 0,
-              sizeof(zr->jpg_settings.jpg_comp.COM_data));
-       zr->jpg_settings.jpg_comp.jpeg_markers =
-           V4L2_JPEG_MARKER_DHT | V4L2_JPEG_MARKER_DQT;
-       i = zoran_check_jpg_settings(zr, &zr->jpg_settings, 0);
-       if (i)
-               pci_err(zr->pci_dev, "%s internal error\n", __func__);
-
-       zr->buffer_size = zr->v4l_settings.bytesperline * zr->v4l_settings.height;
-
-       clear_interrupt_counters(zr);
-}
-
-static int zr36057_init(struct zoran *zr)
-{
-       int j, err;
-
-       pci_info(zr->pci_dev, "initializing card[%d]\n", zr->id);
-
-       /* Avoid nonsense settings from user for default input/norm */
-       if (default_norm < 0 || default_norm > 2)
-               default_norm = 0;
-       if (default_norm == 0) {
-               zr->norm = V4L2_STD_PAL;
-               zr->timing = zr->card.tvn[ZR_NORM_PAL];
-       } else if (default_norm == 1) {
-               zr->norm = V4L2_STD_NTSC;
-               zr->timing = zr->card.tvn[ZR_NORM_NTSC];
-       } else {
-               zr->norm = V4L2_STD_SECAM;
-               zr->timing = zr->card.tvn[ZR_NORM_SECAM];
-       }
-       if (!zr->timing) {
-               pci_warn(zr->pci_dev,
-                        "%s - default TV standard not supported by hardware. PAL will be used.\n",
-                        __func__);
-               zr->norm = V4L2_STD_PAL;
-               zr->timing = zr->card.tvn[ZR_NORM_PAL];
-       }
-
-       if (default_input > zr->card.inputs - 1) {
-               pci_warn(zr->pci_dev, "default_input value %d out of range (0-%d)\n",
-                        default_input, zr->card.inputs - 1);
-               default_input = 0;
-       }
-       zr->input = default_input;
-
-       /* default setup (will be repeated at every open) */
-       zoran_open_init_params(zr);
-
-       /* allocate memory *before* doing anything to the hardware in case allocation fails */
-       zr->stat_com = dma_alloc_coherent(&zr->pci_dev->dev,
-                                         BUZ_NUM_STAT_COM * sizeof(u32),
-                                         &zr->p_sc, GFP_KERNEL);
-       if (!zr->stat_com)
-               return -ENOMEM;
-
-       for (j = 0; j < BUZ_NUM_STAT_COM; j++)
-               zr->stat_com[j] = cpu_to_le32(1); /* mark as unavailable to zr36057 */
-
-       zr->stat_comb = dma_alloc_coherent(&zr->pci_dev->dev,
-                                          BUZ_NUM_STAT_COM * sizeof(u32) * 2,
-                                          &zr->p_scb, GFP_KERNEL);
-       if (!zr->stat_comb) {
-               err = -ENOMEM;
-               goto exit_statcom;
-       }
-
-       err = zoran_init_video_devices(zr);
-       if (err)
-               goto exit_statcomb;
-
-       zoran_init_hardware(zr);
-       if (!pass_through) {
-               decoder_call(zr, video, s_stream, 0);
-               encoder_call(zr, video, s_routing, 2, 0, 0);
-       }
-
-       zr->initialized = 1;
-       return 0;
-
-exit_statcomb:
-       dma_free_coherent(&zr->pci_dev->dev, BUZ_NUM_STAT_COM * sizeof(u32) * 2,
-                         zr->stat_comb, zr->p_scb);
-exit_statcom:
-       dma_free_coherent(&zr->pci_dev->dev, BUZ_NUM_STAT_COM * sizeof(u32),
-                         zr->stat_com, zr->p_sc);
-       return err;
-}
-
-static void zoran_remove(struct pci_dev *pdev)
-{
-       struct v4l2_device *v4l2_dev = dev_get_drvdata(&pdev->dev);
-       struct zoran *zr = to_zoran(v4l2_dev);
-
-       if (!zr->initialized)
-               goto exit_free;
-
-       debugfs_remove_recursive(zr->dbgfs_dir);
-
-       zoran_queue_exit(zr);
-
-       /* unregister videocodec bus */
-       if (zr->codec)
-               videocodec_detach(zr->codec);
-       if (zr->vfe)
-               videocodec_detach(zr->vfe);
-       videocodec_exit(zr);
-
-       /* unregister i2c bus */
-       zoran_i2c_exit(zr);
-       /* disable PCI bus-mastering */
-       zoran_set_pci_master(zr, 0);
-       /* put chip into reset */
-       btwrite(0, ZR36057_SPGPPCR);
-       pci_free_irq(zr->pci_dev, 0, zr);
-       /* unmap and free memory */
-       dma_free_coherent(&zr->pci_dev->dev, BUZ_NUM_STAT_COM * sizeof(u32),
-                         zr->stat_com, zr->p_sc);
-       dma_free_coherent(&zr->pci_dev->dev, BUZ_NUM_STAT_COM * sizeof(u32) * 2,
-                         zr->stat_comb, zr->p_scb);
-       pci_release_regions(pdev);
-       pci_disable_device(zr->pci_dev);
-       zoran_exit_video_devices(zr);
-exit_free:
-       v4l2_ctrl_handler_free(&zr->hdl);
-       v4l2_device_unregister(&zr->v4l2_dev);
-}
-
-void zoran_vdev_release(struct video_device *vdev)
-{
-       kfree(vdev);
-}
-
-static struct videocodec_master *zoran_setup_videocodec(struct zoran *zr,
-                                                       int type)
-{
-       struct videocodec_master *m = NULL;
-
-       m = devm_kmalloc(&zr->pci_dev->dev, sizeof(*m), GFP_KERNEL);
-       if (!m)
-               return m;
-
-       /*
-        * magic and type are unused for master struct. Makes sense only at codec structs.
-        * In the past, .type were initialized to the old V4L1 .hardware value,
-        * as VID_HARDWARE_ZR36067
-        */
-       m->magic = 0L;
-       m->type = 0;
-
-       m->flags = CODEC_FLAG_ENCODER | CODEC_FLAG_DECODER;
-       strscpy(m->name, ZR_DEVNAME(zr), sizeof(m->name));
-       m->data = zr;
-
-       switch (type) {
-       case CODEC_TYPE_ZR36060:
-               m->readreg = zr36060_read;
-               m->writereg = zr36060_write;
-               m->flags |= CODEC_FLAG_JPEG | CODEC_FLAG_VFE;
-               break;
-       case CODEC_TYPE_ZR36050:
-               m->readreg = zr36050_read;
-               m->writereg = zr36050_write;
-               m->flags |= CODEC_FLAG_JPEG;
-               break;
-       case CODEC_TYPE_ZR36016:
-               m->readreg = zr36016_read;
-               m->writereg = zr36016_write;
-               m->flags |= CODEC_FLAG_VFE;
-               break;
-       }
-
-       return m;
-}
-
-static void zoran_subdev_notify(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
-{
-       struct zoran *zr = to_zoran(sd->v4l2_dev);
-
-       /*
-        * Bt819 needs to reset its FIFO buffer using #FRST pin and
-        * LML33 card uses GPIO(7) for that.
-        */
-       if (cmd == BT819_FIFO_RESET_LOW)
-               GPIO(zr, 7, 0);
-       else if (cmd == BT819_FIFO_RESET_HIGH)
-               GPIO(zr, 7, 1);
-}
-
-static int zoran_video_set_ctrl(struct v4l2_ctrl *ctrl)
-{
-       struct zoran *zr = container_of(ctrl->handler, struct zoran, hdl);
-
-       switch (ctrl->id) {
-       case V4L2_CID_JPEG_COMPRESSION_QUALITY:
-               zr->jpg_settings.jpg_comp.quality = ctrl->val;
-               return zoran_check_jpg_settings(zr, &zr->jpg_settings, 0);
-       default:
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-static const struct v4l2_ctrl_ops zoran_video_ctrl_ops = {
-       .s_ctrl = zoran_video_set_ctrl,
-};
-
-static int zoran_debugfs_show(struct seq_file *seq, void *v)
-{
-       struct zoran *zr = seq->private;
-
-       seq_printf(seq, "Running mode %x\n", zr->running);
-       seq_printf(seq, "Codec mode %x\n", zr->codec_mode);
-       seq_printf(seq, "Norm %llx\n", zr->norm);
-       seq_printf(seq, "Input %d\n", zr->input);
-       seq_printf(seq, "Buffersize %d\n", zr->buffer_size);
-
-       seq_printf(seq, "V4L width %dx%d\n", zr->v4l_settings.width, zr->v4l_settings.height);
-       seq_printf(seq, "V4L bytesperline %d\n", zr->v4l_settings.bytesperline);
-
-       seq_printf(seq, "JPG decimation %u\n", zr->jpg_settings.decimation);
-       seq_printf(seq, "JPG hor_dcm %u\n", zr->jpg_settings.hor_dcm);
-       seq_printf(seq, "JPG ver_dcm %u\n", zr->jpg_settings.ver_dcm);
-       seq_printf(seq, "JPG tmp_dcm %u\n", zr->jpg_settings.tmp_dcm);
-       seq_printf(seq, "JPG odd_even %u\n", zr->jpg_settings.odd_even);
-       seq_printf(seq, "JPG crop %dx%d %d %d\n",
-                  zr->jpg_settings.img_x,
-                  zr->jpg_settings.img_y,
-                  zr->jpg_settings.img_width,
-                  zr->jpg_settings.img_height);
-
-       seq_printf(seq, "Prepared %u\n", zr->prepared);
-       seq_printf(seq, "Queued %u\n", zr->queued);
-
-       videocodec_debugfs_show(seq);
-       return 0;
-}
-
-DEFINE_SHOW_ATTRIBUTE(zoran_debugfs);
-
-/*
- *   Scan for a Buz card (actually for the PCI controller ZR36057),
- *   request the irq and map the io memory
- */
-static int zoran_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
-{
-       unsigned char latency, need_latency;
-       struct zoran *zr;
-       int result;
-       struct videocodec_master *master_vfe = NULL;
-       struct videocodec_master *master_codec = NULL;
-       int card_num;
-       unsigned int nr;
-       int err;
-
-       pci_info(pdev, "Zoran MJPEG board driver version %s\n", ZORAN_VERSION);
-
-       /* some mainboards might not do PCI-PCI data transfer well */
-       if (pci_pci_problems & (PCIPCI_FAIL | PCIAGP_FAIL | PCIPCI_ALIMAGIK))
-               pci_warn(pdev, "%s: chipset does not support reliable PCI-PCI DMA\n",
-                        ZORAN_NAME);
-
-       err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
-       if (err)
-               return err;
-       err = vb2_dma_contig_set_max_seg_size(&pdev->dev, U32_MAX);
-       if (err)
-               return err;
-
-       nr = zoran_num++;
-       if (nr >= BUZ_MAX) {
-               pci_err(pdev, "driver limited to %d card(s) maximum\n", BUZ_MAX);
-               return -ENOENT;
-       }
-
-       zr = devm_kzalloc(&pdev->dev, sizeof(*zr), GFP_KERNEL);
-       if (!zr)
-               return -ENOMEM;
-
-       zr->v4l2_dev.notify = zoran_subdev_notify;
-       if (v4l2_device_register(&pdev->dev, &zr->v4l2_dev))
-               goto zr_free_mem;
-       zr->pci_dev = pdev;
-       zr->id = nr;
-       snprintf(ZR_DEVNAME(zr), sizeof(ZR_DEVNAME(zr)), "MJPEG[%u]", zr->id);
-       if (v4l2_ctrl_handler_init(&zr->hdl, 10))
-               goto zr_unreg;
-       zr->v4l2_dev.ctrl_handler = &zr->hdl;
-       v4l2_ctrl_new_std(&zr->hdl, &zoran_video_ctrl_ops,
-                         V4L2_CID_JPEG_COMPRESSION_QUALITY, 0,
-                         100, 1, 50);
-       spin_lock_init(&zr->spinlock);
-       mutex_init(&zr->lock);
-       if (pci_enable_device(pdev))
-               goto zr_unreg;
-       zr->revision = zr->pci_dev->revision;
-
-       pci_info(zr->pci_dev, "Zoran ZR360%c7 (rev %d), irq: %d, memory: 0x%08llx\n",
-                zr->revision < 2 ? '5' : '6', zr->revision,
-                zr->pci_dev->irq, (uint64_t)pci_resource_start(zr->pci_dev, 0));
-       if (zr->revision >= 2)
-               pci_info(zr->pci_dev, "Subsystem vendor=0x%04x id=0x%04x\n",
-                        zr->pci_dev->subsystem_vendor, zr->pci_dev->subsystem_device);
-
-       /* Use auto-detected card type? */
-       if (card[nr] == -1) {
-               if (zr->revision < 2) {
-                       pci_err(pdev, "No card type specified, please use the card=X module parameter\n");
-                       pci_err(pdev, "It is not possible to auto-detect ZR36057 based cards\n");
-                       goto zr_unreg;
-               }
-
-               card_num = ent->driver_data;
-               if (card_num >= NUM_CARDS) {
-                       pci_err(pdev, "Unknown card, try specifying card=X module parameter\n");
-                       goto zr_unreg;
-               }
-               pci_info(zr->pci_dev, "%s() - card %s detected\n", __func__,
-                        zoran_cards[card_num].name);
-       } else {
-               card_num = card[nr];
-               if (card_num >= NUM_CARDS || card_num < 0) {
-                       pci_err(pdev, "User specified card type %d out of range (0 .. %d)\n",
-                               card_num, NUM_CARDS - 1);
-                       goto zr_unreg;
-               }
-       }
-
-       /*
-        * even though we make this a non pointer and thus
-        * theoretically allow for making changes to this struct
-        * on a per-individual card basis at runtime, this is
-        * strongly discouraged. This structure is intended to
-        * keep general card information, no settings or anything
-        */
-       zr->card = zoran_cards[card_num];
-       snprintf(ZR_DEVNAME(zr), sizeof(ZR_DEVNAME(zr)), "%s[%u]",
-                zr->card.name, zr->id);
-
-       err = pci_request_regions(pdev, ZR_DEVNAME(zr));
-       if (err)
-               goto zr_unreg;
-
-       zr->zr36057_mem = devm_ioremap(&pdev->dev, pci_resource_start(pdev, 0),
-                                      pci_resource_len(pdev, 0));
-       if (!zr->zr36057_mem) {
-               pci_err(pdev, "%s() - ioremap failed\n", __func__);
-               goto zr_pci_release;
-       }
-
-       result = pci_request_irq(pdev, 0, zoran_irq, NULL, zr, ZR_DEVNAME(zr));
-       if (result < 0) {
-               if (result == -EINVAL) {
-                       pci_err(pdev, "%s - bad IRQ number or handler\n", __func__);
-               } else if (result == -EBUSY) {
-                       pci_err(pdev, "%s - IRQ %d busy, change your PnP config in BIOS\n",
-                               __func__, zr->pci_dev->irq);
-               } else {
-                       pci_err(pdev, "%s - cannot assign IRQ, error code %d\n", __func__, result);
-               }
-               goto zr_pci_release;
-       }
-
-       /* set PCI latency timer */
-       pci_read_config_byte(zr->pci_dev, PCI_LATENCY_TIMER,
-                            &latency);
-       need_latency = zr->revision > 1 ? 32 : 48;
-       if (latency != need_latency) {
-               pci_info(zr->pci_dev, "Changing PCI latency from %d to %d\n",
-                        latency, need_latency);
-               pci_write_config_byte(zr->pci_dev, PCI_LATENCY_TIMER, need_latency);
-       }
-
-       zr36057_restart(zr);
-
-       err = zoran_i2c_init(zr);
-       if (err)
-               goto zr_free_irq;
-
-       pci_info(zr->pci_dev, "Initializing videocodec bus...\n");
-       err = videocodec_init(zr);
-       if (err)
-               goto zr_unreg_i2c;
-
-       /* reset JPEG codec */
-       jpeg_codec_sleep(zr, 1);
-       jpeg_codec_reset(zr);
-       /* video bus enabled */
-       /* display codec revision */
-       if (zr->card.video_codec != 0) {
-               master_codec = zoran_setup_videocodec(zr, zr->card.video_codec);
-               if (!master_codec)
-                       goto zr_unreg_videocodec;
-               zr->codec = videocodec_attach(master_codec);
-               if (!zr->codec) {
-                       pci_err(pdev, "%s - no codec found\n", __func__);
-                       goto zr_unreg_videocodec;
-               }
-               if (zr->codec->type != zr->card.video_codec) {
-                       pci_err(pdev, "%s - wrong codec\n", __func__);
-                       goto zr_unreg_videocodec;
-               }
-       }
-       if (zr->card.video_vfe != 0) {
-               master_vfe = zoran_setup_videocodec(zr, zr->card.video_vfe);
-               if (!master_vfe)
-                       goto zr_detach_codec;
-               zr->vfe = videocodec_attach(master_vfe);
-               if (!zr->vfe) {
-                       pci_err(pdev, "%s - no VFE found\n", __func__);
-                       goto zr_detach_codec;
-               }
-               if (zr->vfe->type != zr->card.video_vfe) {
-                       pci_err(pdev, "%s = wrong VFE\n", __func__);
-                       goto zr_detach_vfe;
-               }
-       }
-
-       /* take care of Natoma chipset and a revision 1 zr36057 */
-       if ((pci_pci_problems & PCIPCI_NATOMA) && zr->revision <= 1)
-               pci_info(zr->pci_dev, "ZR36057/Natoma bug, max. buffer size is 128K\n");
-
-       if (zr36057_init(zr) < 0)
-               goto zr_detach_vfe;
-
-       zr->map_mode = ZORAN_MAP_MODE_RAW;
-
-       zr->dbgfs_dir = debugfs_create_dir(ZR_DEVNAME(zr), NULL);
-       debugfs_create_file("debug", 0444, zr->dbgfs_dir, zr,
-                           &zoran_debugfs_fops);
-       return 0;
-
-zr_detach_vfe:
-       videocodec_detach(zr->vfe);
-zr_detach_codec:
-       videocodec_detach(zr->codec);
-zr_unreg_videocodec:
-       videocodec_exit(zr);
-zr_unreg_i2c:
-       zoran_i2c_exit(zr);
-zr_free_irq:
-       btwrite(0, ZR36057_SPGPPCR);
-       pci_free_irq(zr->pci_dev, 0, zr);
-zr_pci_release:
-       pci_release_regions(pdev);
-zr_unreg:
-       v4l2_ctrl_handler_free(&zr->hdl);
-       v4l2_device_unregister(&zr->v4l2_dev);
-zr_free_mem:
-
-       return -ENODEV;
-}
-
-static struct pci_driver zoran_driver = {
-       .name = "zr36067",
-       .id_table = zr36067_pci_tbl,
-       .probe = zoran_probe,
-       .remove = zoran_remove,
-};
-
-module_pci_driver(zoran_driver);
 
+++ /dev/null
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * Zoran zr36057/zr36067 PCI controller driver, for the
- * Pinnacle/Miro DC10/DC10+/DC30/DC30+, Iomega Buz, Linux
- * Media Labs LML33/LML33R10.
- *
- * This part handles card-specific data and detection
- *
- * Copyright (C) 2000 Serguei Miridonov <mirsev@cicese.mx>
- */
-
-#ifndef __ZORAN_CARD_H__
-#define __ZORAN_CARD_H__
-
-extern int zr36067_debug;
-
-/* Anybody who uses more than four? */
-#define BUZ_MAX 4
-
-extern const struct video_device zoran_template;
-
-int zoran_check_jpg_settings(struct zoran *zr,
-                            struct zoran_jpg_settings *settings, int try);
-void zoran_open_init_params(struct zoran *zr);
-void zoran_vdev_release(struct video_device *vdev);
-
-void zr36016_write(struct videocodec *codec, u16 reg, u32 val);
-
-#endif                         /* __ZORAN_CARD_H__ */
 
+++ /dev/null
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Zoran zr36057/zr36067 PCI controller driver, for the
- * Pinnacle/Miro DC10/DC10+/DC30/DC30+, Iomega Buz, Linux
- * Media Labs LML33/LML33R10.
- *
- * This part handles device access (PCI/I2C/codec/...)
- *
- * Copyright (C) 2000 Serguei Miridonov <mirsev@cicese.mx>
- */
-
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-
-#include <linux/interrupt.h>
-#include <linux/i2c.h>
-#include <linux/i2c-algo-bit.h>
-#include <linux/videodev2.h>
-#include <media/v4l2-common.h>
-#include <linux/spinlock.h>
-
-#include <linux/pci.h>
-#include <linux/delay.h>
-#include <linux/wait.h>
-#include <linux/dma-mapping.h>
-
-#include <linux/io.h>
-
-#include "videocodec.h"
-#include "zoran.h"
-#include "zoran_device.h"
-#include "zoran_card.h"
-
-#define IRQ_MASK (ZR36057_ISR_GIRQ0 | \
-                 ZR36057_ISR_GIRQ1 | \
-                 ZR36057_ISR_JPEG_REP_IRQ)
-
-static bool lml33dpath;                /* default = 0
-                                * 1 will use digital path in capture
-                                * mode instead of analog. It can be
-                                * used for picture adjustments using
-                                * tool like xawtv while watching image
-                                * on TV monitor connected to the output.
-                                * However, due to absence of 75 Ohm
-                                * load on Bt819 input, there will be
-                                * some image imperfections
-                                */
-
-module_param(lml33dpath, bool, 0644);
-MODULE_PARM_DESC(lml33dpath, "Use digital path capture mode (on LML33 cards)");
-
-/*
- * initialize video front end
- */
-static void zr36057_init_vfe(struct zoran *zr)
-{
-       u32 reg;
-
-       reg = btread(ZR36057_VFESPFR);
-       reg |= ZR36057_VFESPFR_LITTLE_ENDIAN;
-       reg &= ~ZR36057_VFESPFR_VCLK_POL;
-       reg |= ZR36057_VFESPFR_EXT_FL;
-       reg |= ZR36057_VFESPFR_TOP_FIELD;
-       btwrite(reg, ZR36057_VFESPFR);
-       reg = btread(ZR36057_VDCR);
-       if (pci_pci_problems & PCIPCI_TRITON)
-               // || zr->revision < 1) // Revision 1 has also Triton support
-               reg &= ~ZR36057_VDCR_TRITON;
-       else
-               reg |= ZR36057_VDCR_TRITON;
-       btwrite(reg, ZR36057_VDCR);
-}
-
-/*
- * General Purpose I/O and Guest bus access
- */
-
-/*
- * This is a bit tricky. When a board lacks a GPIO function, the corresponding
- * GPIO bit number in the card_info structure is set to 0.
- */
-
-void GPIO(struct zoran *zr, int bit, unsigned int value)
-{
-       u32 reg;
-       u32 mask;
-
-       /* Make sure the bit number is legal
-        * A bit number of -1 (lacking) gives a mask of 0,
-        * making it harmless
-        */
-       mask = (1 << (24 + bit)) & 0xff000000;
-       reg = btread(ZR36057_GPPGCR1) & ~mask;
-       if (value)
-               reg |= mask;
-
-       btwrite(reg, ZR36057_GPPGCR1);
-       udelay(1);
-}
-
-/*
- * Wait til post office is no longer busy
- */
-
-int post_office_wait(struct zoran *zr)
-{
-       u32 por;
-
-       while ((por = btread(ZR36057_POR)) & ZR36057_POR_PO_PEN) {
-               /* wait for something to happen */
-               /* TODO add timeout */
-       }
-       if ((por & ZR36057_POR_PO_TIME) && !zr->card.gws_not_connected) {
-               /* In LML33/BUZ \GWS line is not connected, so it has always timeout set */
-               pci_info(zr->pci_dev, "pop timeout %08x\n", por);
-               return -1;
-       }
-
-       return 0;
-}
-
-int post_office_write(struct zoran *zr, unsigned int guest,
-                     unsigned int reg, unsigned int value)
-{
-       u32 por;
-
-       por =
-           ZR36057_POR_PO_DIR | ZR36057_POR_PO_TIME | ((guest & 7) << 20) |
-           ((reg & 7) << 16) | (value & 0xFF);
-       btwrite(por, ZR36057_POR);
-
-       return post_office_wait(zr);
-}
-
-int post_office_read(struct zoran *zr, unsigned int guest, unsigned int reg)
-{
-       u32 por;
-
-       por = ZR36057_POR_PO_TIME | ((guest & 7) << 20) | ((reg & 7) << 16);
-       btwrite(por, ZR36057_POR);
-       if (post_office_wait(zr) < 0)
-               return -1;
-
-       return btread(ZR36057_POR) & 0xFF;
-}
-
-/*
- * JPEG Codec access
- */
-
-void jpeg_codec_sleep(struct zoran *zr, int sleep)
-{
-       GPIO(zr, zr->card.gpio[ZR_GPIO_JPEG_SLEEP], !sleep);
-       if (!sleep) {
-               pci_dbg(zr->pci_dev, "%s() - wake GPIO=0x%08x\n",
-                       __func__, btread(ZR36057_GPPGCR1));
-               usleep_range(500, 1000);
-       } else {
-               pci_dbg(zr->pci_dev, "%s() - sleep GPIO=0x%08x\n",
-                       __func__, btread(ZR36057_GPPGCR1));
-               udelay(2);
-       }
-}
-
-int jpeg_codec_reset(struct zoran *zr)
-{
-       /* Take the codec out of sleep */
-       jpeg_codec_sleep(zr, 0);
-
-       if (zr->card.gpcs[GPCS_JPEG_RESET] != 0xff) {
-               post_office_write(zr, zr->card.gpcs[GPCS_JPEG_RESET], 0,
-                                 0);
-               udelay(2);
-       } else {
-               GPIO(zr, zr->card.gpio[ZR_GPIO_JPEG_RESET], 0);
-               udelay(2);
-               GPIO(zr, zr->card.gpio[ZR_GPIO_JPEG_RESET], 1);
-               udelay(2);
-       }
-
-       return 0;
-}
-
-/*
- *   Set the registers for the size we have specified. Don't bother
- *   trying to understand this without the ZR36057 manual in front of
- *   you [AC].
- */
-static void zr36057_adjust_vfe(struct zoran *zr, enum zoran_codec_mode mode)
-{
-       u32 reg;
-
-       switch (mode) {
-       case BUZ_MODE_MOTION_DECOMPRESS:
-               btand(~ZR36057_VFESPFR_EXT_FL, ZR36057_VFESPFR);
-               reg = btread(ZR36057_VFEHCR);
-               if ((reg & (1 << 10)) && zr->card.type != LML33R10)
-                       reg += ((1 << 10) | 1);
-
-               btwrite(reg, ZR36057_VFEHCR);
-               break;
-       case BUZ_MODE_MOTION_COMPRESS:
-       case BUZ_MODE_IDLE:
-       default:
-               if ((zr->norm & V4L2_STD_NTSC) ||
-                   (zr->card.type == LML33R10 &&
-                    (zr->norm & V4L2_STD_PAL)))
-                       btand(~ZR36057_VFESPFR_EXT_FL, ZR36057_VFESPFR);
-               else
-                       btor(ZR36057_VFESPFR_EXT_FL, ZR36057_VFESPFR);
-               reg = btread(ZR36057_VFEHCR);
-               if (!(reg & (1 << 10)) && zr->card.type != LML33R10)
-                       reg -= ((1 << 10) | 1);
-
-               btwrite(reg, ZR36057_VFEHCR);
-               break;
-       }
-}
-
-/*
- * set geometry
- */
-
-static void zr36057_set_vfe(struct zoran *zr, int video_width, int video_height,
-                           const struct zoran_format *format)
-{
-       const struct tvnorm *tvn;
-       unsigned int h_start, h_end, v_start, v_end;
-       unsigned int disp_mode;
-       unsigned int vid_win_wid, vid_win_ht;
-       unsigned int hcrop1, hcrop2, vcrop1, vcrop2;
-       unsigned int wa, we, ha, he;
-       unsigned int X, Y, hor_dcm, ver_dcm;
-       u32 reg;
-
-       tvn = zr->timing;
-
-       wa = tvn->wa;
-       ha = tvn->ha;
-
-       pci_dbg(zr->pci_dev, "set_vfe() - width = %d, height = %d\n", video_width, video_height);
-
-       if (video_width < BUZ_MIN_WIDTH ||
-           video_height < BUZ_MIN_HEIGHT ||
-           video_width > wa || video_height > ha) {
-               pci_err(zr->pci_dev, "set_vfe: w=%d h=%d not valid\n", video_width, video_height);
-               return;
-       }
-
-       /**** zr36057 ****/
-
-       /* horizontal */
-       vid_win_wid = video_width;
-       X = DIV_ROUND_UP(vid_win_wid * 64, tvn->wa);
-       we = (vid_win_wid * 64) / X;
-       hor_dcm = 64 - X;
-       hcrop1 = 2 * ((tvn->wa - we) / 4);
-       hcrop2 = tvn->wa - we - hcrop1;
-       h_start = tvn->h_start ? tvn->h_start : 1;
-       /* (Ronald) Original comment:
-        * "| 1 Doesn't have any effect, tested on both a DC10 and a DC10+"
-        * this is false. It inverses chroma values on the LML33R10 (so Cr
-        * suddenly is shown as Cb and reverse, really cool effect if you
-        * want to see blue faces, not useful otherwise). So don't use |1.
-        * However, the DC10 has '0' as h_start, but does need |1, so we
-        * use a dirty check...
-        */
-       h_end = h_start + tvn->wa - 1;
-       h_start += hcrop1;
-       h_end -= hcrop2;
-       reg = ((h_start & ZR36057_VFEHCR_HMASK) << ZR36057_VFEHCR_H_START)
-           | ((h_end & ZR36057_VFEHCR_HMASK) << ZR36057_VFEHCR_H_END);
-       if (zr->card.vfe_pol.hsync_pol)
-               reg |= ZR36057_VFEHCR_HS_POL;
-       btwrite(reg, ZR36057_VFEHCR);
-
-       /* Vertical */
-       disp_mode = !(video_height > BUZ_MAX_HEIGHT / 2);
-       vid_win_ht = disp_mode ? video_height : video_height / 2;
-       Y = DIV_ROUND_UP(vid_win_ht * 64 * 2, tvn->ha);
-       he = (vid_win_ht * 64) / Y;
-       ver_dcm = 64 - Y;
-       vcrop1 = (tvn->ha / 2 - he) / 2;
-       vcrop2 = tvn->ha / 2 - he - vcrop1;
-       v_start = tvn->v_start;
-       // FIXME SnapShot times out with -1 in 768*576 on the DC10 - LP
-       v_end = v_start + tvn->ha / 2;  // - 1;
-       v_start += vcrop1;
-       v_end -= vcrop2;
-       reg = ((v_start & ZR36057_VFEVCR_VMASK) << ZR36057_VFEVCR_V_START)
-           | ((v_end & ZR36057_VFEVCR_VMASK) << ZR36057_VFEVCR_V_END);
-       if (zr->card.vfe_pol.vsync_pol)
-               reg |= ZR36057_VFEVCR_VS_POL;
-       btwrite(reg, ZR36057_VFEVCR);
-
-       /* scaler and pixel format */
-       reg = 0;
-       reg |= (hor_dcm << ZR36057_VFESPFR_HOR_DCM);
-       reg |= (ver_dcm << ZR36057_VFESPFR_VER_DCM);
-       reg |= (disp_mode << ZR36057_VFESPFR_DISP_MODE);
-       /*
-        * RJ: I don't know, why the following has to be the opposite
-        * of the corresponding ZR36060 setting, but only this way
-        * we get the correct colors when uncompressing to the screen
-        */
-       //reg |= ZR36057_VFESPFR_VCLK_POL;
-       /* RJ: Don't know if that is needed for NTSC also */
-       if (!(zr->norm & V4L2_STD_NTSC))
-               reg |= ZR36057_VFESPFR_EXT_FL;  // NEEDED!!!!!!! Wolfgang
-       reg |= ZR36057_VFESPFR_TOP_FIELD;
-       if (hor_dcm >= 48)
-               reg |= 3 << ZR36057_VFESPFR_H_FILTER;   /* 5 tap filter */
-       else if (hor_dcm >= 32)
-               reg |= 2 << ZR36057_VFESPFR_H_FILTER;   /* 4 tap filter */
-       else if (hor_dcm >= 16)
-               reg |= 1 << ZR36057_VFESPFR_H_FILTER;   /* 3 tap filter */
-
-       reg |= format->vfespfr;
-       btwrite(reg, ZR36057_VFESPFR);
-
-       /* display configuration */
-       reg = (16 << ZR36057_VDCR_MIN_PIX)
-           | (vid_win_ht << ZR36057_VDCR_VID_WIN_HT)
-           | (vid_win_wid << ZR36057_VDCR_VID_WIN_WID);
-       if (pci_pci_problems & PCIPCI_TRITON)
-               // || zr->revision < 1) // Revision 1 has also Triton support
-               reg &= ~ZR36057_VDCR_TRITON;
-       else
-               reg |= ZR36057_VDCR_TRITON;
-       btwrite(reg, ZR36057_VDCR);
-
-       zr36057_adjust_vfe(zr, zr->codec_mode);
-}
-
-/* Enable/Disable uncompressed memory grabbing of the 36057 */
-void zr36057_set_memgrab(struct zoran *zr, int mode)
-{
-       if (mode) {
-               /* We only check SnapShot and not FrameGrab here.  SnapShot==1
-                * means a capture is already in progress, but FrameGrab==1
-                * doesn't necessary mean that.  It's more correct to say a 1
-                * to 0 transition indicates a capture completed.  If a
-                * capture is pending when capturing is tuned off, FrameGrab
-                * will be stuck at 1 until capturing is turned back on.
-                */
-               if (btread(ZR36057_VSSFGR) & ZR36057_VSSFGR_SNAP_SHOT)
-                       pci_warn(zr->pci_dev, "%s(1) with SnapShot on!?\n", __func__);
-
-               /* switch on VSync interrupts */
-               btwrite(IRQ_MASK, ZR36057_ISR); // Clear Interrupts
-               btor(zr->card.vsync_int, ZR36057_ICR);  // SW
-
-               /* enable SnapShot */
-               btor(ZR36057_VSSFGR_SNAP_SHOT, ZR36057_VSSFGR);
-
-               /* Set zr36057 video front end  and enable video */
-               zr36057_set_vfe(zr, zr->v4l_settings.width,
-                               zr->v4l_settings.height,
-                               zr->v4l_settings.format);
-       } else {
-               /* switch off VSync interrupts */
-               btand(~zr->card.vsync_int, ZR36057_ICR);        // SW
-
-               /* re-enable grabbing to screen if it was running */
-               btand(~ZR36057_VDCR_VID_EN, ZR36057_VDCR);
-               btand(~ZR36057_VSSFGR_SNAP_SHOT, ZR36057_VSSFGR);
-       }
-}
-
-/*****************************************************************************
- *                                                                           *
- *  Set up the Buz-specific MJPEG part                                       *
- *                                                                           *
- *****************************************************************************/
-
-static inline void set_frame(struct zoran *zr, int val)
-{
-       GPIO(zr, zr->card.gpio[ZR_GPIO_JPEG_FRAME], val);
-}
-
-static void set_videobus_dir(struct zoran *zr, int val)
-{
-       switch (zr->card.type) {
-       case LML33:
-       case LML33R10:
-               if (!lml33dpath)
-                       GPIO(zr, 5, val);
-               else
-                       GPIO(zr, 5, 1);
-               break;
-       default:
-               GPIO(zr, zr->card.gpio[ZR_GPIO_VID_DIR],
-                    zr->card.gpio_pol[ZR_GPIO_VID_DIR] ? !val : val);
-               break;
-       }
-}
-
-static void init_jpeg_queue(struct zoran *zr)
-{
-       int i;
-
-       /* re-initialize DMA ring stuff */
-       zr->jpg_que_head = 0;
-       zr->jpg_dma_head = 0;
-       zr->jpg_dma_tail = 0;
-       zr->jpg_que_tail = 0;
-       zr->jpg_seq_num = 0;
-       zr->jpeg_error = 0;
-       zr->num_errors = 0;
-       zr->jpg_err_seq = 0;
-       zr->jpg_err_shift = 0;
-       zr->jpg_queued_num = 0;
-       for (i = 0; i < BUZ_NUM_STAT_COM; i++)
-               zr->stat_com[i] = cpu_to_le32(1);       /* mark as unavailable to zr36057 */
-}
-
-static void zr36057_set_jpg(struct zoran *zr, enum zoran_codec_mode mode)
-{
-       const struct tvnorm *tvn;
-       u32 reg;
-
-       tvn = zr->timing;
-
-       /* assert P_Reset, disable code transfer, deassert Active */
-       btwrite(0, ZR36057_JPC);
-
-       /* MJPEG compression mode */
-       switch (mode) {
-       case BUZ_MODE_MOTION_COMPRESS:
-       default:
-               reg = ZR36057_JMC_MJPG_CMP_MODE;
-               break;
-
-       case BUZ_MODE_MOTION_DECOMPRESS:
-               reg = ZR36057_JMC_MJPG_EXP_MODE;
-               reg |= ZR36057_JMC_SYNC_MSTR;
-               /* RJ: The following is experimental - improves the output to screen */
-               //if(zr->jpg_settings.VFIFO_FB) reg |= ZR36057_JMC_VFIFO_FB; // No, it doesn't. SM
-               break;
-
-       case BUZ_MODE_STILL_COMPRESS:
-               reg = ZR36057_JMC_JPG_CMP_MODE;
-               break;
-
-       case BUZ_MODE_STILL_DECOMPRESS:
-               reg = ZR36057_JMC_JPG_EXP_MODE;
-               break;
-       }
-       reg |= ZR36057_JMC_JPG;
-       if (zr->jpg_settings.field_per_buff == 1)
-               reg |= ZR36057_JMC_FLD_PER_BUFF;
-       btwrite(reg, ZR36057_JMC);
-
-       /* vertical */
-       btor(ZR36057_VFEVCR_VS_POL, ZR36057_VFEVCR);
-       reg = (6 << ZR36057_VSP_VSYNC_SIZE) |
-             (tvn->ht << ZR36057_VSP_FRM_TOT);
-       btwrite(reg, ZR36057_VSP);
-       reg = ((zr->jpg_settings.img_y + tvn->v_start) << ZR36057_FVAP_NAY) |
-             (zr->jpg_settings.img_height << ZR36057_FVAP_PAY);
-       btwrite(reg, ZR36057_FVAP);
-
-       /* horizontal */
-       if (zr->card.vfe_pol.hsync_pol)
-               btor(ZR36057_VFEHCR_HS_POL, ZR36057_VFEHCR);
-       else
-               btand(~ZR36057_VFEHCR_HS_POL, ZR36057_VFEHCR);
-       reg = ((tvn->h_sync_start) << ZR36057_HSP_HSYNC_START) |
-             (tvn->wt << ZR36057_HSP_LINE_TOT);
-       btwrite(reg, ZR36057_HSP);
-       reg = ((zr->jpg_settings.img_x +
-               tvn->h_start + 4) << ZR36057_FHAP_NAX) |
-             (zr->jpg_settings.img_width << ZR36057_FHAP_PAX);
-       btwrite(reg, ZR36057_FHAP);
-
-       /* field process parameters */
-       if (zr->jpg_settings.odd_even)
-               reg = ZR36057_FPP_ODD_EVEN;
-       else
-               reg = 0;
-
-       btwrite(reg, ZR36057_FPP);
-
-       /* Set proper VCLK Polarity, else colors will be wrong during playback */
-       //btor(ZR36057_VFESPFR_VCLK_POL, ZR36057_VFESPFR);
-
-       /* code base address */
-       btwrite(zr->p_sc, ZR36057_JCBA);
-
-       /* FIFO threshold (FIFO is 160. double words) */
-       /* NOTE: decimal values here */
-       switch (mode) {
-       case BUZ_MODE_STILL_COMPRESS:
-       case BUZ_MODE_MOTION_COMPRESS:
-               if (zr->card.type != BUZ)
-                       reg = 140;
-               else
-                       reg = 60;
-               break;
-
-       case BUZ_MODE_STILL_DECOMPRESS:
-       case BUZ_MODE_MOTION_DECOMPRESS:
-               reg = 20;
-               break;
-
-       default:
-               reg = 80;
-               break;
-       }
-       btwrite(reg, ZR36057_JCFT);
-       zr36057_adjust_vfe(zr, mode);
-}
-
-void clear_interrupt_counters(struct zoran *zr)
-{
-       zr->intr_counter_GIRQ1 = 0;
-       zr->intr_counter_GIRQ0 = 0;
-       zr->intr_counter_cod_rep_irq = 0;
-       zr->intr_counter_jpeg_rep_irq = 0;
-       zr->field_counter = 0;
-       zr->irq1_in = 0;
-       zr->irq1_out = 0;
-       zr->jpeg_in = 0;
-       zr->jpeg_out = 0;
-       zr->JPEG_0 = 0;
-       zr->JPEG_1 = 0;
-       zr->end_event_missed = 0;
-       zr->jpeg_missed = 0;
-       zr->jpeg_max_missed = 0;
-       zr->jpeg_min_missed = 0x7fffffff;
-}
-
-static u32 count_reset_interrupt(struct zoran *zr)
-{
-       u32 isr;
-
-       isr = btread(ZR36057_ISR) & 0x78000000;
-       if (isr) {
-               if (isr & ZR36057_ISR_GIRQ1) {
-                       btwrite(ZR36057_ISR_GIRQ1, ZR36057_ISR);
-                       zr->intr_counter_GIRQ1++;
-               }
-               if (isr & ZR36057_ISR_GIRQ0) {
-                       btwrite(ZR36057_ISR_GIRQ0, ZR36057_ISR);
-                       zr->intr_counter_GIRQ0++;
-               }
-               if (isr & ZR36057_ISR_COD_REP_IRQ) {
-                       btwrite(ZR36057_ISR_COD_REP_IRQ, ZR36057_ISR);
-                       zr->intr_counter_cod_rep_irq++;
-               }
-               if (isr & ZR36057_ISR_JPEG_REP_IRQ) {
-                       btwrite(ZR36057_ISR_JPEG_REP_IRQ, ZR36057_ISR);
-                       zr->intr_counter_jpeg_rep_irq++;
-               }
-       }
-       return isr;
-}
-
-void jpeg_start(struct zoran *zr)
-{
-       int reg;
-
-       zr->frame_num = 0;
-
-       /* deassert P_reset, disable code transfer, deassert Active */
-       btwrite(ZR36057_JPC_P_RESET, ZR36057_JPC);
-       /* stop flushing the internal code buffer */
-       btand(~ZR36057_MCTCR_C_FLUSH, ZR36057_MCTCR);
-       /* enable code transfer */
-       btor(ZR36057_JPC_COD_TRNS_EN, ZR36057_JPC);
-
-       /* clear IRQs */
-       btwrite(IRQ_MASK, ZR36057_ISR);
-       /* enable the JPEG IRQs */
-       btwrite(zr->card.jpeg_int | ZR36057_ICR_JPEG_REP_IRQ | ZR36057_ICR_INT_PIN_EN,
-               ZR36057_ICR);
-
-       set_frame(zr, 0);       // \FRAME
-
-       /* set the JPEG codec guest ID */
-       reg = (zr->card.gpcs[1] << ZR36057_JCGI_JPE_GUEST_ID) |
-              (0 << ZR36057_JCGI_JPE_GUEST_REG);
-       btwrite(reg, ZR36057_JCGI);
-
-       if (zr->card.video_vfe == CODEC_TYPE_ZR36016 &&
-           zr->card.video_codec == CODEC_TYPE_ZR36050) {
-               /* Enable processing on the ZR36016 */
-               if (zr->vfe)
-                       zr36016_write(zr->vfe, 0, 1);
-
-               /* load the address of the GO register in the ZR36050 latch */
-               post_office_write(zr, 0, 0, 0);
-       }
-
-       /* assert Active */
-       btor(ZR36057_JPC_ACTIVE, ZR36057_JPC);
-
-       /* enable the Go generation */
-       btor(ZR36057_JMC_GO_EN, ZR36057_JMC);
-       usleep_range(30, 100);
-
-       set_frame(zr, 1);       // /FRAME
-}
-
-void zr36057_enable_jpg(struct zoran *zr, enum zoran_codec_mode mode)
-{
-       struct vfe_settings cap;
-       int field_size = zr->buffer_size / zr->jpg_settings.field_per_buff;
-
-       zr->codec_mode = mode;
-
-       cap.x = zr->jpg_settings.img_x;
-       cap.y = zr->jpg_settings.img_y;
-       cap.width = zr->jpg_settings.img_width;
-       cap.height = zr->jpg_settings.img_height;
-       cap.decimation =
-           zr->jpg_settings.hor_dcm | (zr->jpg_settings.ver_dcm << 8);
-       cap.quality = zr->jpg_settings.jpg_comp.quality;
-
-       switch (mode) {
-       case BUZ_MODE_MOTION_COMPRESS: {
-               struct jpeg_app_marker app;
-               struct jpeg_com_marker com;
-
-               /* In motion compress mode, the decoder output must be enabled, and
-                * the video bus direction set to input.
-                */
-               set_videobus_dir(zr, 0);
-               decoder_call(zr, video, s_stream, 1);
-               encoder_call(zr, video, s_routing, 0, 0, 0);
-
-               /* Take the JPEG codec and the VFE out of sleep */
-               jpeg_codec_sleep(zr, 0);
-
-               /* set JPEG app/com marker */
-               app.appn = zr->jpg_settings.jpg_comp.APPn;
-               app.len = zr->jpg_settings.jpg_comp.APP_len;
-               memcpy(app.data, zr->jpg_settings.jpg_comp.APP_data, 60);
-               zr->codec->control(zr->codec, CODEC_S_JPEG_APP_DATA,
-                                  sizeof(struct jpeg_app_marker), &app);
-
-               com.len = zr->jpg_settings.jpg_comp.COM_len;
-               memcpy(com.data, zr->jpg_settings.jpg_comp.COM_data, 60);
-               zr->codec->control(zr->codec, CODEC_S_JPEG_COM_DATA,
-                                  sizeof(struct jpeg_com_marker), &com);
-
-               /* Setup the JPEG codec */
-               zr->codec->control(zr->codec, CODEC_S_JPEG_TDS_BYTE,
-                                  sizeof(int), &field_size);
-               zr->codec->set_video(zr->codec, zr->timing, &cap,
-                                    &zr->card.vfe_pol);
-               zr->codec->set_mode(zr->codec, CODEC_DO_COMPRESSION);
-
-               /* Setup the VFE */
-               if (zr->vfe) {
-                       zr->vfe->control(zr->vfe, CODEC_S_JPEG_TDS_BYTE,
-                                        sizeof(int), &field_size);
-                       zr->vfe->set_video(zr->vfe, zr->timing, &cap,
-                                          &zr->card.vfe_pol);
-                       zr->vfe->set_mode(zr->vfe, CODEC_DO_COMPRESSION);
-               }
-
-               init_jpeg_queue(zr);
-               zr36057_set_jpg(zr, mode);      // \P_Reset, ... Video param, FIFO
-
-               clear_interrupt_counters(zr);
-               pci_dbg(zr->pci_dev, "enable_jpg(MOTION_COMPRESS)\n");
-               break;
-       }
-
-       case BUZ_MODE_MOTION_DECOMPRESS:
-               /* In motion decompression mode, the decoder output must be disabled, and
-                * the video bus direction set to output.
-                */
-               decoder_call(zr, video, s_stream, 0);
-               set_videobus_dir(zr, 1);
-               encoder_call(zr, video, s_routing, 1, 0, 0);
-
-               /* Take the JPEG codec and the VFE out of sleep */
-               jpeg_codec_sleep(zr, 0);
-               /* Setup the VFE */
-               if (zr->vfe) {
-                       zr->vfe->set_video(zr->vfe, zr->timing, &cap,
-                                          &zr->card.vfe_pol);
-                       zr->vfe->set_mode(zr->vfe, CODEC_DO_EXPANSION);
-               }
-               /* Setup the JPEG codec */
-               zr->codec->set_video(zr->codec, zr->timing, &cap,
-                                    &zr->card.vfe_pol);
-               zr->codec->set_mode(zr->codec, CODEC_DO_EXPANSION);
-
-               init_jpeg_queue(zr);
-               zr36057_set_jpg(zr, mode);      // \P_Reset, ... Video param, FIFO
-
-               clear_interrupt_counters(zr);
-               pci_dbg(zr->pci_dev, "enable_jpg(MOTION_DECOMPRESS)\n");
-               break;
-
-       case BUZ_MODE_IDLE:
-       default:
-               /* shut down processing */
-               btand(~(zr->card.jpeg_int | ZR36057_ICR_JPEG_REP_IRQ),
-                     ZR36057_ICR);
-               btwrite(zr->card.jpeg_int | ZR36057_ICR_JPEG_REP_IRQ,
-                       ZR36057_ISR);
-               btand(~ZR36057_JMC_GO_EN, ZR36057_JMC); // \Go_en
-
-               msleep(50);
-
-               set_videobus_dir(zr, 0);
-               set_frame(zr, 1);       // /FRAME
-               btor(ZR36057_MCTCR_C_FLUSH, ZR36057_MCTCR);     // /CFlush
-               btwrite(0, ZR36057_JPC);        // \P_Reset,\CodTrnsEn,\Active
-               btand(~ZR36057_JMC_VFIFO_FB, ZR36057_JMC);
-               btand(~ZR36057_JMC_SYNC_MSTR, ZR36057_JMC);
-               jpeg_codec_reset(zr);
-               jpeg_codec_sleep(zr, 1);
-               zr36057_adjust_vfe(zr, mode);
-
-               decoder_call(zr, video, s_stream, 1);
-               encoder_call(zr, video, s_routing, 0, 0, 0);
-
-               pci_dbg(zr->pci_dev, "enable_jpg(IDLE)\n");
-               break;
-       }
-}
-
-/* when this is called the spinlock must be held */
-void zoran_feed_stat_com(struct zoran *zr)
-{
-       /* move frames from pending queue to DMA */
-
-       int i, max_stat_com;
-       struct zr_buffer *buf;
-       struct vb2_v4l2_buffer *vbuf;
-       dma_addr_t phys_addr = 0;
-       unsigned long flags;
-       unsigned long payload;
-
-       max_stat_com =
-           (zr->jpg_settings.tmp_dcm ==
-            1) ? BUZ_NUM_STAT_COM : (BUZ_NUM_STAT_COM >> 1);
-
-       spin_lock_irqsave(&zr->queued_bufs_lock, flags);
-       while ((zr->jpg_dma_head - zr->jpg_dma_tail) < max_stat_com) {
-               buf = list_first_entry_or_null(&zr->queued_bufs, struct zr_buffer, queue);
-               if (!buf) {
-                       pci_err(zr->pci_dev, "No buffer available to queue\n");
-                       spin_unlock_irqrestore(&zr->queued_bufs_lock, flags);
-                       return;
-               }
-               list_del(&buf->queue);
-               zr->buf_in_reserve--;
-               vbuf = &buf->vbuf;
-               vbuf->vb2_buf.state = VB2_BUF_STATE_ACTIVE;
-               phys_addr = vb2_dma_contig_plane_dma_addr(&vbuf->vb2_buf, 0);
-               payload = vb2_get_plane_payload(&vbuf->vb2_buf, 0);
-               if (payload == 0)
-                       payload = zr->buffer_size;
-               if (zr->jpg_settings.tmp_dcm == 1) {
-                       /* fill 1 stat_com entry */
-                       i = (zr->jpg_dma_head -
-                            zr->jpg_err_shift) & BUZ_MASK_STAT_COM;
-                       if (!(zr->stat_com[i] & cpu_to_le32(1)))
-                               break;
-                       zr->stat_comb[i * 2] = cpu_to_le32(phys_addr);
-                       zr->stat_comb[i * 2 + 1] = cpu_to_le32((payload >> 1) | 1);
-                       zr->inuse[i] = buf;
-                       zr->stat_com[i] = cpu_to_le32(zr->p_scb + i * 2 * 4);
-               } else {
-                       /* fill 2 stat_com entries */
-                       i = ((zr->jpg_dma_head -
-                             zr->jpg_err_shift) & 1) * 2;
-                       if (!(zr->stat_com[i] & cpu_to_le32(1)))
-                               break;
-                       zr->stat_com[i] = cpu_to_le32(zr->p_scb + i * 2 * 4);
-                       zr->stat_com[i + 1] = cpu_to_le32(zr->p_scb + i * 2 * 4);
-
-                       zr->stat_comb[i * 2] = cpu_to_le32(phys_addr);
-                       zr->stat_comb[i * 2 + 1] = cpu_to_le32((payload >> 1) | 1);
-
-                       zr->inuse[i] = buf;
-                       zr->inuse[i + 1] = NULL;
-               }
-               zr->jpg_dma_head++;
-       }
-       spin_unlock_irqrestore(&zr->queued_bufs_lock, flags);
-       if (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS)
-               zr->jpg_queued_num++;
-}
-
-/* when this is called the spinlock must be held */
-static void zoran_reap_stat_com(struct zoran *zr)
-{
-       /* move frames from DMA queue to done queue */
-
-       int i;
-       u32 stat_com;
-       unsigned int seq;
-       unsigned int dif;
-       unsigned long flags;
-       struct zr_buffer *buf;
-       unsigned int size = 0;
-       u32 fcnt;
-
-       /*
-        * In motion decompress we don't have a hardware frame counter,
-        * we just count the interrupts here
-        */
-
-       if (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS)
-               zr->jpg_seq_num++;
-
-       spin_lock_irqsave(&zr->queued_bufs_lock, flags);
-       while (zr->jpg_dma_tail < zr->jpg_dma_head) {
-               if (zr->jpg_settings.tmp_dcm == 1)
-                       i = (zr->jpg_dma_tail - zr->jpg_err_shift) & BUZ_MASK_STAT_COM;
-               else
-                       i = ((zr->jpg_dma_tail - zr->jpg_err_shift) & 1) * 2;
-
-               stat_com = le32_to_cpu(zr->stat_com[i]);
-               if ((stat_com & 1) == 0) {
-                       spin_unlock_irqrestore(&zr->queued_bufs_lock, flags);
-                       return;
-               }
-
-               fcnt = (stat_com & GENMASK(31, 24)) >> 24;
-               size = (stat_com & GENMASK(22, 1)) >> 1;
-
-               buf = zr->inuse[i];
-               if (!buf) {
-                       spin_unlock_irqrestore(&zr->queued_bufs_lock, flags);
-                       pci_err(zr->pci_dev, "No buffer at slot %d\n", i);
-                       return;
-               }
-               buf->vbuf.vb2_buf.timestamp = ktime_get_ns();
-
-               if (zr->codec_mode == BUZ_MODE_MOTION_COMPRESS) {
-                       vb2_set_plane_payload(&buf->vbuf.vb2_buf, 0, size);
-
-                       /* update sequence number with the help of the counter in stat_com */
-                       seq = (fcnt + zr->jpg_err_seq) & 0xff;
-                       dif = (seq - zr->jpg_seq_num) & 0xff;
-                       zr->jpg_seq_num += dif;
-               }
-               buf->vbuf.sequence = zr->jpg_settings.tmp_dcm ==
-                   2 ? (zr->jpg_seq_num >> 1) : zr->jpg_seq_num;
-               zr->inuse[i] = NULL;
-               if (zr->jpg_settings.tmp_dcm != 1)
-                       buf->vbuf.field = zr->jpg_settings.odd_even ?
-                               V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM;
-               else
-                       buf->vbuf.field = zr->jpg_settings.odd_even ?
-                               V4L2_FIELD_SEQ_TB : V4L2_FIELD_SEQ_BT;
-               vb2_buffer_done(&buf->vbuf.vb2_buf, VB2_BUF_STATE_DONE);
-
-               zr->jpg_dma_tail++;
-       }
-       spin_unlock_irqrestore(&zr->queued_bufs_lock, flags);
-}
-
-irqreturn_t zoran_irq(int irq, void *dev_id)
-{
-       struct zoran *zr = dev_id;
-       u32 stat, astat;
-
-       stat = count_reset_interrupt(zr);
-       astat = stat & IRQ_MASK;
-       if (astat & zr->card.vsync_int) {
-               if (zr->running == ZORAN_MAP_MODE_RAW) {
-                       if ((btread(ZR36057_VSSFGR) & ZR36057_VSSFGR_SNAP_SHOT) == 0)
-                               pci_warn(zr->pci_dev, "BuzIRQ with SnapShot off ???\n");
-                       if ((btread(ZR36057_VSSFGR) & ZR36057_VSSFGR_FRAME_GRAB) == 0)
-                               zr_set_buf(zr);
-                       return IRQ_HANDLED;
-               }
-               if (astat & ZR36057_ISR_JPEG_REP_IRQ) {
-                       if (zr->codec_mode != BUZ_MODE_MOTION_DECOMPRESS &&
-                           zr->codec_mode != BUZ_MODE_MOTION_COMPRESS) {
-                               pci_err(zr->pci_dev, "JPG IRQ when not in good mode\n");
-                               return IRQ_HANDLED;
-                       }
-                       zr->frame_num++;
-                       zoran_reap_stat_com(zr);
-                       zoran_feed_stat_com(zr);
-                       return IRQ_HANDLED;
-               }
-               /* unused interrupts */
-       }
-       zr->ghost_int++;
-       return IRQ_HANDLED;
-}
-
-void zoran_set_pci_master(struct zoran *zr, int set_master)
-{
-       if (set_master) {
-               pci_set_master(zr->pci_dev);
-       } else {
-               u16 command;
-
-               pci_read_config_word(zr->pci_dev, PCI_COMMAND, &command);
-               command &= ~PCI_COMMAND_MASTER;
-               pci_write_config_word(zr->pci_dev, PCI_COMMAND, command);
-       }
-}
-
-void zoran_init_hardware(struct zoran *zr)
-{
-       /* Enable bus-mastering */
-       zoran_set_pci_master(zr, 1);
-
-       /* Initialize the board */
-       if (zr->card.init)
-               zr->card.init(zr);
-
-       decoder_call(zr, core, init, 0);
-       decoder_call(zr, video, s_std, zr->norm);
-       decoder_call(zr, video, s_routing,
-                    zr->card.input[zr->input].muxsel, 0, 0);
-
-       encoder_call(zr, core, init, 0);
-       encoder_call(zr, video, s_std_output, zr->norm);
-       encoder_call(zr, video, s_routing, 0, 0, 0);
-
-       /* toggle JPEG codec sleep to sync PLL */
-       jpeg_codec_sleep(zr, 1);
-       jpeg_codec_sleep(zr, 0);
-
-       /*
-        * set individual interrupt enables (without GIRQ1)
-        * but don't global enable until zoran_open()
-        */
-       zr36057_init_vfe(zr);
-
-       zr36057_enable_jpg(zr, BUZ_MODE_IDLE);
-
-       btwrite(IRQ_MASK, ZR36057_ISR); // Clears interrupts
-}
-
-void zr36057_restart(struct zoran *zr)
-{
-       btwrite(0, ZR36057_SPGPPCR);
-       usleep_range(1000, 2000);
-       btor(ZR36057_SPGPPCR_SOFT_RESET, ZR36057_SPGPPCR);
-       usleep_range(1000, 2000);
-
-       /* assert P_Reset */
-       btwrite(0, ZR36057_JPC);
-       /* set up GPIO direction - all output */
-       btwrite(ZR36057_SPGPPCR_SOFT_RESET | 0, ZR36057_SPGPPCR);
-
-       /* set up GPIO pins and guest bus timing */
-       btwrite((0x81 << 24) | 0x8888, ZR36057_GPPGCR1);
-}
-
 
+++ /dev/null
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * Zoran zr36057/zr36067 PCI controller driver, for the
- * Pinnacle/Miro DC10/DC10+/DC30/DC30+, Iomega Buz, Linux
- * Media Labs LML33/LML33R10.
- *
- * This part handles card-specific data and detection
- *
- * Copyright (C) 2000 Serguei Miridonov <mirsev@cicese.mx>
- */
-
-#ifndef __ZORAN_DEVICE_H__
-#define __ZORAN_DEVICE_H__
-
-/* general purpose I/O */
-void GPIO(struct zoran *zr, int bit, unsigned int value);
-
-/* codec (or actually: guest bus) access */
-int post_office_wait(struct zoran *zr);
-int post_office_write(struct zoran *zr, unsigned int guest, unsigned int reg,
-                     unsigned int value);
-int post_office_read(struct zoran *zr, unsigned int guest, unsigned int reg);
-
-void jpeg_codec_sleep(struct zoran *zr, int sleep);
-int jpeg_codec_reset(struct zoran *zr);
-
-/* zr360x7 access to raw capture */
-void zr36057_overlay(struct zoran *zr, int on);
-void write_overlay_mask(struct zoran_fh *fh, struct v4l2_clip *vp, int count);
-void zr36057_set_memgrab(struct zoran *zr, int mode);
-int wait_grab_pending(struct zoran *zr);
-
-/* interrupts */
-void print_interrupts(struct zoran *zr);
-void clear_interrupt_counters(struct zoran *zr);
-irqreturn_t zoran_irq(int irq, void *dev_id);
-
-/* JPEG codec access */
-void jpeg_start(struct zoran *zr);
-void zr36057_enable_jpg(struct zoran *zr, enum zoran_codec_mode mode);
-void zoran_feed_stat_com(struct zoran *zr);
-
-/* general */
-void zoran_set_pci_master(struct zoran *zr, int set_master);
-void zoran_init_hardware(struct zoran *zr);
-void zr36057_restart(struct zoran *zr);
-
-extern const struct zoran_format zoran_formats[];
-
-extern int v4l_bufsize;
-extern int jpg_bufsize;
-extern int pass_through;
-
-/* i2c */
-#define decoder_call(zr, o, f, args...) \
-       v4l2_subdev_call((zr)->decoder, o, f, ##args)
-#define encoder_call(zr, o, f, args...) \
-       v4l2_subdev_call((zr)->encoder, o, f, ##args)
-
-#endif                         /* __ZORAN_DEVICE_H__ */
 
+++ /dev/null
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Zoran zr36057/zr36067 PCI controller driver, for the
- * Pinnacle/Miro DC10/DC10+/DC30/DC30+, Iomega Buz, Linux
- * Media Labs LML33/LML33R10.
- *
- * Copyright (C) 2000 Serguei Miridonov <mirsev@cicese.mx>
- *
- * Changes for BUZ by Wolfgang Scherr <scherr@net4you.net>
- *
- * Changes for DC10/DC30 by Laurent Pinchart <laurent.pinchart@skynet.be>
- *
- * Changes for LML33R10 by Maxim Yevtyushkin <max@linuxmedialabs.com>
- *
- * Changes for videodev2/v4l2 by Ronald Bultje <rbultje@ronald.bitfreak.net>
- *
- * Based on
- *
- * Miro DC10 driver
- * Copyright (C) 1999 Wolfgang Scherr <scherr@net4you.net>
- *
- * Iomega Buz driver version 1.0
- * Copyright (C) 1999 Rainer Johanni <Rainer@Johanni.de>
- *
- * buz.0.0.3
- * Copyright (C) 1998 Dave Perks <dperks@ibm.net>
- *
- * bttv - Bt848 frame grabber driver
- * Copyright (C) 1996,97,98 Ralph  Metzler (rjkm@thp.uni-koeln.de)
- *                        & Marcus Metzler (mocm@thp.uni-koeln.de)
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <linux/pci.h>
-#include <linux/wait.h>
-
-#include <linux/interrupt.h>
-#include <linux/i2c.h>
-#include <linux/i2c-algo-bit.h>
-
-#include <linux/spinlock.h>
-
-#include <linux/videodev2.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-ioctl.h>
-#include <media/v4l2-event.h>
-#include "videocodec.h"
-
-#include <linux/io.h>
-#include <linux/uaccess.h>
-
-#include <linux/mutex.h>
-#include "zoran.h"
-#include "zoran_device.h"
-#include "zoran_card.h"
-
-const struct zoran_format zoran_formats[] = {
-       {
-               .name = "15-bit RGB LE",
-               .fourcc = V4L2_PIX_FMT_RGB555,
-               .colorspace = V4L2_COLORSPACE_SRGB,
-               .depth = 15,
-               .flags = ZORAN_FORMAT_CAPTURE,
-               .vfespfr = ZR36057_VFESPFR_RGB555 | ZR36057_VFESPFR_ERR_DIF |
-                          ZR36057_VFESPFR_LITTLE_ENDIAN,
-       }, {
-               .name = "15-bit RGB BE",
-               .fourcc = V4L2_PIX_FMT_RGB555X,
-               .colorspace = V4L2_COLORSPACE_SRGB,
-               .depth = 15,
-               .flags = ZORAN_FORMAT_CAPTURE,
-               .vfespfr = ZR36057_VFESPFR_RGB555 | ZR36057_VFESPFR_ERR_DIF,
-       }, {
-               .name = "16-bit RGB LE",
-               .fourcc = V4L2_PIX_FMT_RGB565,
-               .colorspace = V4L2_COLORSPACE_SRGB,
-               .depth = 16,
-               .flags = ZORAN_FORMAT_CAPTURE,
-               .vfespfr = ZR36057_VFESPFR_RGB565 | ZR36057_VFESPFR_ERR_DIF |
-                          ZR36057_VFESPFR_LITTLE_ENDIAN,
-       }, {
-               .name = "16-bit RGB BE",
-               .fourcc = V4L2_PIX_FMT_RGB565X,
-               .colorspace = V4L2_COLORSPACE_SRGB,
-               .depth = 16,
-               .flags = ZORAN_FORMAT_CAPTURE,
-               .vfespfr = ZR36057_VFESPFR_RGB565 | ZR36057_VFESPFR_ERR_DIF,
-       }, {
-               .name = "24-bit RGB",
-               .fourcc = V4L2_PIX_FMT_BGR24,
-               .colorspace = V4L2_COLORSPACE_SRGB,
-               .depth = 24,
-               .flags = ZORAN_FORMAT_CAPTURE,
-               .vfespfr = ZR36057_VFESPFR_RGB888 | ZR36057_VFESPFR_PACK24,
-       }, {
-               .name = "32-bit RGB LE",
-               .fourcc = V4L2_PIX_FMT_BGR32,
-               .colorspace = V4L2_COLORSPACE_SRGB,
-               .depth = 32,
-               .flags = ZORAN_FORMAT_CAPTURE,
-               .vfespfr = ZR36057_VFESPFR_RGB888 | ZR36057_VFESPFR_LITTLE_ENDIAN,
-       }, {
-               .name = "32-bit RGB BE",
-               .fourcc = V4L2_PIX_FMT_RGB32,
-               .colorspace = V4L2_COLORSPACE_SRGB,
-               .depth = 32,
-               .flags = ZORAN_FORMAT_CAPTURE,
-               .vfespfr = ZR36057_VFESPFR_RGB888,
-       }, {
-               .name = "4:2:2, packed, YUYV",
-               .fourcc = V4L2_PIX_FMT_YUYV,
-               .colorspace = V4L2_COLORSPACE_SMPTE170M,
-               .depth = 16,
-               .flags = ZORAN_FORMAT_CAPTURE,
-               .vfespfr = ZR36057_VFESPFR_YUV422,
-       }, {
-               .name = "4:2:2, packed, UYVY",
-               .fourcc = V4L2_PIX_FMT_UYVY,
-               .colorspace = V4L2_COLORSPACE_SMPTE170M,
-               .depth = 16,
-               .flags = ZORAN_FORMAT_CAPTURE,
-               .vfespfr = ZR36057_VFESPFR_YUV422 | ZR36057_VFESPFR_LITTLE_ENDIAN,
-       }, {
-               .name = "Hardware-encoded Motion-JPEG",
-               .fourcc = V4L2_PIX_FMT_MJPEG,
-               .colorspace = V4L2_COLORSPACE_SMPTE170M,
-               .depth = 0,
-               .flags = ZORAN_FORMAT_CAPTURE |
-                        ZORAN_FORMAT_PLAYBACK |
-                        ZORAN_FORMAT_COMPRESSED,
-       }
-};
-
-#define NUM_FORMATS ARRAY_SIZE(zoran_formats)
-
-       /*
-        * small helper function for calculating buffersizes for v4l2
-        * we calculate the nearest higher power-of-two, which
-        * will be the recommended buffersize
-        */
-static __u32 zoran_v4l2_calc_bufsize(struct zoran_jpg_settings *settings)
-{
-       __u8 div = settings->ver_dcm * settings->hor_dcm * settings->tmp_dcm;
-       __u32 num = (1024 * 512) / (div);
-       __u32 result = 2;
-
-       num--;
-       while (num) {
-               num >>= 1;
-               result <<= 1;
-       }
-
-       if (result < 8192)
-               return 8192;
-
-       return result;
-}
-
-/*
- *   V4L Buffer grabbing
- */
-static int zoran_v4l_set_format(struct zoran *zr, int width, int height,
-                               const struct zoran_format *format)
-{
-       int bpp;
-
-       /* Check size and format of the grab wanted */
-
-       if (height < BUZ_MIN_HEIGHT || width < BUZ_MIN_WIDTH ||
-           height > BUZ_MAX_HEIGHT || width > BUZ_MAX_WIDTH) {
-               pci_dbg(zr->pci_dev, "%s - wrong frame size (%dx%d)\n", __func__, width, height);
-               return -EINVAL;
-       }
-
-       bpp = (format->depth + 7) / 8;
-
-       zr->buffer_size = height * width * bpp;
-
-       /* Check against available buffer size */
-       if (height * width * bpp > zr->buffer_size) {
-               pci_dbg(zr->pci_dev, "%s - video buffer size (%d kB) is too small\n",
-                       __func__, zr->buffer_size >> 10);
-               return -EINVAL;
-       }
-
-       /* The video front end needs 4-byte alinged line sizes */
-
-       if ((bpp == 2 && (width & 1)) || (bpp == 3 && (width & 3))) {
-               pci_dbg(zr->pci_dev, "%s - wrong frame alignment\n", __func__);
-               return -EINVAL;
-       }
-
-       zr->v4l_settings.width = width;
-       zr->v4l_settings.height = height;
-       zr->v4l_settings.format = format;
-       zr->v4l_settings.bytesperline = bpp * zr->v4l_settings.width;
-
-       return 0;
-}
-
-static int zoran_set_norm(struct zoran *zr, v4l2_std_id norm)
-{
-       if (!(norm & zr->card.norms)) {
-               pci_dbg(zr->pci_dev, "%s - unsupported norm %llx\n", __func__, norm);
-               return -EINVAL;
-       }
-
-       if (norm & V4L2_STD_SECAM)
-               zr->timing = zr->card.tvn[ZR_NORM_SECAM];
-       else if (norm & V4L2_STD_NTSC)
-               zr->timing = zr->card.tvn[ZR_NORM_NTSC];
-       else
-               zr->timing = zr->card.tvn[ZR_NORM_PAL];
-
-       decoder_call(zr, video, s_std, norm);
-       encoder_call(zr, video, s_std_output, norm);
-
-       /* Make sure the changes come into effect */
-       zr->norm = norm;
-
-       return 0;
-}
-
-static int zoran_set_input(struct zoran *zr, int input)
-{
-       if (input == zr->input)
-               return 0;
-
-       if (input < 0 || input >= zr->card.inputs) {
-               pci_dbg(zr->pci_dev, "%s - unsupported input %d\n", __func__, input);
-               return -EINVAL;
-       }
-
-       zr->input = input;
-
-       decoder_call(zr, video, s_routing, zr->card.input[input].muxsel, 0, 0);
-
-       return 0;
-}
-
-/*
- *   ioctl routine
- */
-
-static int zoran_querycap(struct file *file, void *__fh, struct v4l2_capability *cap)
-{
-       struct zoran *zr = video_drvdata(file);
-
-       strscpy(cap->card, ZR_DEVNAME(zr), sizeof(cap->card));
-       strscpy(cap->driver, "zoran", sizeof(cap->driver));
-       snprintf(cap->bus_info, sizeof(cap->bus_info), "PCI:%s", pci_name(zr->pci_dev));
-       return 0;
-}
-
-static int zoran_enum_fmt(struct zoran *zr, struct v4l2_fmtdesc *fmt, int flag)
-{
-       unsigned int num, i;
-
-       if (fmt->index >= ARRAY_SIZE(zoran_formats))
-               return -EINVAL;
-       if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
-               return -EINVAL;
-
-       for (num = i = 0; i < NUM_FORMATS; i++) {
-               if (zoran_formats[i].flags & flag && num++ == fmt->index) {
-                       strscpy(fmt->description, zoran_formats[i].name,
-                               sizeof(fmt->description));
-                       /* fmt struct pre-zeroed, so adding '\0' not needed */
-                       fmt->pixelformat = zoran_formats[i].fourcc;
-                       if (zoran_formats[i].flags & ZORAN_FORMAT_COMPRESSED)
-                               fmt->flags |= V4L2_FMT_FLAG_COMPRESSED;
-                       return 0;
-               }
-       }
-       return -EINVAL;
-}
-
-static int zoran_enum_fmt_vid_cap(struct file *file, void *__fh,
-                                 struct v4l2_fmtdesc *f)
-{
-       struct zoran *zr = video_drvdata(file);
-
-       return zoran_enum_fmt(zr, f, ZORAN_FORMAT_CAPTURE);
-}
-
-static int zoran_g_fmt_vid_out(struct file *file, void *__fh,
-                              struct v4l2_format *fmt)
-{
-       struct zoran *zr = video_drvdata(file);
-
-       fmt->fmt.pix.width = zr->jpg_settings.img_width / zr->jpg_settings.hor_dcm;
-       fmt->fmt.pix.height = zr->jpg_settings.img_height * 2 /
-               (zr->jpg_settings.ver_dcm * zr->jpg_settings.tmp_dcm);
-       fmt->fmt.pix.sizeimage = zr->buffer_size;
-       fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_MJPEG;
-       if (zr->jpg_settings.tmp_dcm == 1)
-               fmt->fmt.pix.field = (zr->jpg_settings.odd_even ?
-                               V4L2_FIELD_SEQ_TB : V4L2_FIELD_SEQ_BT);
-       else
-               fmt->fmt.pix.field = (zr->jpg_settings.odd_even ?
-                               V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM);
-       fmt->fmt.pix.bytesperline = 0;
-       fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
-
-       return 0;
-}
-
-static int zoran_g_fmt_vid_cap(struct file *file, void *__fh,
-                              struct v4l2_format *fmt)
-{
-       struct zoran *zr = video_drvdata(file);
-
-       if (zr->map_mode != ZORAN_MAP_MODE_RAW)
-               return zoran_g_fmt_vid_out(file, __fh, fmt);
-       fmt->fmt.pix.width = zr->v4l_settings.width;
-       fmt->fmt.pix.height = zr->v4l_settings.height;
-       fmt->fmt.pix.sizeimage = zr->buffer_size;
-       fmt->fmt.pix.pixelformat = zr->v4l_settings.format->fourcc;
-       fmt->fmt.pix.colorspace = zr->v4l_settings.format->colorspace;
-       fmt->fmt.pix.bytesperline = zr->v4l_settings.bytesperline;
-       if (BUZ_MAX_HEIGHT < (zr->v4l_settings.height * 2))
-               fmt->fmt.pix.field = V4L2_FIELD_INTERLACED;
-       else
-               fmt->fmt.pix.field = V4L2_FIELD_TOP;
-       return 0;
-}
-
-static int zoran_try_fmt_vid_out(struct file *file, void *__fh,
-                                struct v4l2_format *fmt)
-{
-       struct zoran *zr = video_drvdata(file);
-       struct zoran_jpg_settings settings;
-       int res = 0;
-
-       if (fmt->fmt.pix.pixelformat != V4L2_PIX_FMT_MJPEG)
-               return -EINVAL;
-
-       settings = zr->jpg_settings;
-
-       /* we actually need to set 'real' parameters now */
-       if ((fmt->fmt.pix.height * 2) > BUZ_MAX_HEIGHT)
-               settings.tmp_dcm = 1;
-       else
-               settings.tmp_dcm = 2;
-       settings.decimation = 0;
-       if (fmt->fmt.pix.height <= zr->jpg_settings.img_height / 2)
-               settings.ver_dcm = 2;
-       else
-               settings.ver_dcm = 1;
-       if (fmt->fmt.pix.width <= zr->jpg_settings.img_width / 4)
-               settings.hor_dcm = 4;
-       else if (fmt->fmt.pix.width <= zr->jpg_settings.img_width / 2)
-               settings.hor_dcm = 2;
-       else
-               settings.hor_dcm = 1;
-       if (settings.tmp_dcm == 1)
-               settings.field_per_buff = 2;
-       else
-               settings.field_per_buff = 1;
-
-       if (settings.hor_dcm > 1) {
-               settings.img_x = (BUZ_MAX_WIDTH == 720) ? 8 : 0;
-               settings.img_width = (BUZ_MAX_WIDTH == 720) ? 704 : BUZ_MAX_WIDTH;
-       } else {
-               settings.img_x = 0;
-               settings.img_width = BUZ_MAX_WIDTH;
-       }
-
-       /* check */
-       res = zoran_check_jpg_settings(zr, &settings, 1);
-       if (res)
-               return res;
-
-       /* tell the user what we actually did */
-       fmt->fmt.pix.width = settings.img_width / settings.hor_dcm;
-       fmt->fmt.pix.height = settings.img_height * 2 /
-               (settings.tmp_dcm * settings.ver_dcm);
-       if (settings.tmp_dcm == 1)
-               fmt->fmt.pix.field = (zr->jpg_settings.odd_even ?
-                               V4L2_FIELD_SEQ_TB : V4L2_FIELD_SEQ_BT);
-       else
-               fmt->fmt.pix.field = (zr->jpg_settings.odd_even ?
-                               V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM);
-
-       fmt->fmt.pix.sizeimage = zoran_v4l2_calc_bufsize(&settings);
-       fmt->fmt.pix.bytesperline = 0;
-       fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
-       return res;
-}
-
-static int zoran_try_fmt_vid_cap(struct file *file, void *__fh,
-                                struct v4l2_format *fmt)
-{
-       struct zoran *zr = video_drvdata(file);
-       int bpp;
-       int i;
-
-       if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG)
-               return zoran_try_fmt_vid_out(file, __fh, fmt);
-
-       for (i = 0; i < NUM_FORMATS; i++)
-               if (zoran_formats[i].fourcc == fmt->fmt.pix.pixelformat)
-                       break;
-
-       if (i == NUM_FORMATS) {
-               /* TODO do not return here to fix the TRY_FMT cannot handle an invalid pixelformat*/
-               return -EINVAL;
-       }
-
-       fmt->fmt.pix.pixelformat = zoran_formats[i].fourcc;
-       fmt->fmt.pix.colorspace = zoran_formats[i].colorspace;
-       if (BUZ_MAX_HEIGHT < (fmt->fmt.pix.height * 2))
-               fmt->fmt.pix.field = V4L2_FIELD_INTERLACED;
-       else
-               fmt->fmt.pix.field = V4L2_FIELD_TOP;
-
-       bpp = DIV_ROUND_UP(zoran_formats[i].depth, 8);
-       v4l_bound_align_image(&fmt->fmt.pix.width, BUZ_MIN_WIDTH, BUZ_MAX_WIDTH,
-                             bpp == 2 ? 1 : 2,
-                             &fmt->fmt.pix.height, BUZ_MIN_HEIGHT, BUZ_MAX_HEIGHT,
-                             0, 0);
-       fmt->fmt.pix.bytesperline = fmt->fmt.pix.width * bpp;
-       fmt->fmt.pix.sizeimage = fmt->fmt.pix.bytesperline * fmt->fmt.pix.height;
-       return 0;
-}
-
-static int zoran_s_fmt_vid_out(struct file *file, void *__fh,
-                              struct v4l2_format *fmt)
-{
-       struct zoran *zr = video_drvdata(file);
-       __le32 printformat = __cpu_to_le32(fmt->fmt.pix.pixelformat);
-       struct zoran_jpg_settings settings;
-       int res = 0;
-
-       pci_dbg(zr->pci_dev, "size=%dx%d, fmt=0x%x (%4.4s)\n",
-               fmt->fmt.pix.width, fmt->fmt.pix.height,
-                       fmt->fmt.pix.pixelformat,
-                       (char *)&printformat);
-       if (fmt->fmt.pix.pixelformat != V4L2_PIX_FMT_MJPEG)
-               return -EINVAL;
-
-       if (!fmt->fmt.pix.height || !fmt->fmt.pix.width)
-               return -EINVAL;
-
-       settings = zr->jpg_settings;
-
-       /* we actually need to set 'real' parameters now */
-       if (fmt->fmt.pix.height * 2 > BUZ_MAX_HEIGHT)
-               settings.tmp_dcm = 1;
-       else
-               settings.tmp_dcm = 2;
-       settings.decimation = 0;
-       if (fmt->fmt.pix.height <= zr->jpg_settings.img_height / 2)
-               settings.ver_dcm = 2;
-       else
-               settings.ver_dcm = 1;
-       if (fmt->fmt.pix.width <= zr->jpg_settings.img_width / 4)
-               settings.hor_dcm = 4;
-       else if (fmt->fmt.pix.width <= zr->jpg_settings.img_width / 2)
-               settings.hor_dcm = 2;
-       else
-               settings.hor_dcm = 1;
-       if (settings.tmp_dcm == 1)
-               settings.field_per_buff = 2;
-       else
-               settings.field_per_buff = 1;
-
-       if (settings.hor_dcm > 1) {
-               settings.img_x = (BUZ_MAX_WIDTH == 720) ? 8 : 0;
-               settings.img_width = (BUZ_MAX_WIDTH == 720) ? 704 : BUZ_MAX_WIDTH;
-       } else {
-               settings.img_x = 0;
-               settings.img_width = BUZ_MAX_WIDTH;
-       }
-
-       /* check */
-       res = zoran_check_jpg_settings(zr, &settings, 0);
-       if (res)
-               return res;
-
-       /* it's ok, so set them */
-       zr->jpg_settings = settings;
-
-       if (fmt->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
-               zr->map_mode = ZORAN_MAP_MODE_JPG_REC;
-       else
-               zr->map_mode = ZORAN_MAP_MODE_JPG_PLAY;
-
-       zr->buffer_size = zoran_v4l2_calc_bufsize(&zr->jpg_settings);
-
-       /* tell the user what we actually did */
-       fmt->fmt.pix.width = settings.img_width / settings.hor_dcm;
-       fmt->fmt.pix.height = settings.img_height * 2 /
-               (settings.tmp_dcm * settings.ver_dcm);
-       if (settings.tmp_dcm == 1)
-               fmt->fmt.pix.field = (zr->jpg_settings.odd_even ?
-                               V4L2_FIELD_SEQ_TB : V4L2_FIELD_SEQ_BT);
-       else
-               fmt->fmt.pix.field = (zr->jpg_settings.odd_even ?
-                               V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM);
-       fmt->fmt.pix.bytesperline = 0;
-       fmt->fmt.pix.sizeimage = zr->buffer_size;
-       fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
-       return res;
-}
-
-static int zoran_s_fmt_vid_cap(struct file *file, void *__fh,
-                              struct v4l2_format *fmt)
-{
-       struct zoran *zr = video_drvdata(file);
-       struct zoran_fh *fh = __fh;
-       int i;
-       int res = 0;
-
-       if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG)
-               return zoran_s_fmt_vid_out(file, fh, fmt);
-
-       for (i = 0; i < NUM_FORMATS; i++)
-               if (fmt->fmt.pix.pixelformat == zoran_formats[i].fourcc)
-                       break;
-       if (i == NUM_FORMATS) {
-               pci_dbg(zr->pci_dev, "VIDIOC_S_FMT - unknown/unsupported format 0x%x\n",
-                       fmt->fmt.pix.pixelformat);
-               /* TODO do not return here to fix the TRY_FMT cannot handle an invalid pixelformat*/
-               return -EINVAL;
-       }
-
-       fmt->fmt.pix.pixelformat = zoran_formats[i].fourcc;
-       if (fmt->fmt.pix.height > BUZ_MAX_HEIGHT)
-               fmt->fmt.pix.height = BUZ_MAX_HEIGHT;
-       if (fmt->fmt.pix.width > BUZ_MAX_WIDTH)
-               fmt->fmt.pix.width = BUZ_MAX_WIDTH;
-       if (fmt->fmt.pix.height < BUZ_MIN_HEIGHT)
-               fmt->fmt.pix.height = BUZ_MIN_HEIGHT;
-       if (fmt->fmt.pix.width < BUZ_MIN_WIDTH)
-               fmt->fmt.pix.width = BUZ_MIN_WIDTH;
-
-       zr->map_mode = ZORAN_MAP_MODE_RAW;
-
-       res = zoran_v4l_set_format(zr, fmt->fmt.pix.width, fmt->fmt.pix.height,
-                                  &zoran_formats[i]);
-       if (res)
-               return res;
-
-       /* tell the user the results/missing stuff */
-       fmt->fmt.pix.bytesperline = zr->v4l_settings.bytesperline;
-       fmt->fmt.pix.sizeimage = zr->buffer_size;
-       fmt->fmt.pix.colorspace = zr->v4l_settings.format->colorspace;
-       if (BUZ_MAX_HEIGHT < (zr->v4l_settings.height * 2))
-               fmt->fmt.pix.field = V4L2_FIELD_INTERLACED;
-       else
-               fmt->fmt.pix.field = V4L2_FIELD_TOP;
-       return res;
-}
-
-static int zoran_g_std(struct file *file, void *__fh, v4l2_std_id *std)
-{
-       struct zoran *zr = video_drvdata(file);
-
-       *std = zr->norm;
-       return 0;
-}
-
-static int zoran_s_std(struct file *file, void *__fh, v4l2_std_id std)
-{
-       struct zoran *zr = video_drvdata(file);
-       int res = 0;
-
-       if (zr->norm == std)
-               return 0;
-
-       if (zr->running != ZORAN_MAP_MODE_NONE)
-               return -EBUSY;
-
-       res = zoran_set_norm(zr, std);
-       return res;
-}
-
-static int zoran_enum_input(struct file *file, void *__fh,
-                           struct v4l2_input *inp)
-{
-       struct zoran *zr = video_drvdata(file);
-
-       if (inp->index >= zr->card.inputs)
-               return -EINVAL;
-
-       strscpy(inp->name, zr->card.input[inp->index].name, sizeof(inp->name));
-       inp->type = V4L2_INPUT_TYPE_CAMERA;
-       inp->std = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM;
-
-       /* Get status of video decoder */
-       decoder_call(zr, video, g_input_status, &inp->status);
-       return 0;
-}
-
-static int zoran_g_input(struct file *file, void *__fh, unsigned int *input)
-{
-       struct zoran *zr = video_drvdata(file);
-
-       *input = zr->input;
-
-       return 0;
-}
-
-static int zoran_s_input(struct file *file, void *__fh, unsigned int input)
-{
-       struct zoran *zr = video_drvdata(file);
-       int res;
-
-       if (zr->running != ZORAN_MAP_MODE_NONE)
-               return -EBUSY;
-
-       res = zoran_set_input(zr, input);
-       return res;
-}
-
-/* cropping (sub-frame capture) */
-static int zoran_g_selection(struct file *file, void *__fh, struct v4l2_selection *sel)
-{
-       struct zoran *zr = video_drvdata(file);
-
-       if (sel->type != V4L2_BUF_TYPE_VIDEO_OUTPUT &&
-           sel->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
-               pci_dbg(zr->pci_dev, "%s invalid selection type combination\n", __func__);
-               return -EINVAL;
-       }
-
-       switch (sel->target) {
-       case V4L2_SEL_TGT_CROP:
-               sel->r.top = zr->jpg_settings.img_y;
-               sel->r.left = zr->jpg_settings.img_x;
-               sel->r.width = zr->jpg_settings.img_width;
-               sel->r.height = zr->jpg_settings.img_height;
-               break;
-       case V4L2_SEL_TGT_CROP_DEFAULT:
-               sel->r.top = 0;
-               sel->r.left = 0;
-               sel->r.width = BUZ_MIN_WIDTH;
-               sel->r.height = BUZ_MIN_HEIGHT;
-               break;
-       case V4L2_SEL_TGT_CROP_BOUNDS:
-               sel->r.top = 0;
-               sel->r.left = 0;
-               sel->r.width = BUZ_MAX_WIDTH;
-               sel->r.height = BUZ_MAX_HEIGHT;
-               break;
-       default:
-               return -EINVAL;
-       }
-       return 0;
-}
-
-static int zoran_s_selection(struct file *file, void *__fh, struct v4l2_selection *sel)
-{
-       struct zoran *zr = video_drvdata(file);
-       struct zoran_jpg_settings settings;
-       int res;
-
-       if (sel->type != V4L2_BUF_TYPE_VIDEO_OUTPUT &&
-           sel->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
-               return -EINVAL;
-
-       if (!sel->r.width || !sel->r.height)
-               return -EINVAL;
-
-       if (sel->target != V4L2_SEL_TGT_CROP)
-               return -EINVAL;
-
-       if (zr->map_mode == ZORAN_MAP_MODE_RAW) {
-               pci_dbg(zr->pci_dev, "VIDIOC_S_SELECTION - subcapture only supported for compressed capture\n");
-               return -EINVAL;
-       }
-
-       settings = zr->jpg_settings;
-
-       /* move into a form that we understand */
-       settings.img_x = sel->r.left;
-       settings.img_y = sel->r.top;
-       settings.img_width = sel->r.width;
-       settings.img_height = sel->r.height;
-
-       /* check validity */
-       res = zoran_check_jpg_settings(zr, &settings, 0);
-       if (res)
-               return res;
-
-       /* accept */
-       zr->jpg_settings = settings;
-       return res;
-}
-
-/*
- * Output is disabled temporarily
- * Zoran is picky about jpeg data it accepts. At least it seems to unsupport COM and APPn.
- * So until a way to filter data will be done, disable output.
- */
-static const struct v4l2_ioctl_ops zoran_ioctl_ops = {
-       .vidioc_querycap                    = zoran_querycap,
-       .vidioc_s_selection                 = zoran_s_selection,
-       .vidioc_g_selection                 = zoran_g_selection,
-       .vidioc_enum_input                  = zoran_enum_input,
-       .vidioc_g_input                     = zoran_g_input,
-       .vidioc_s_input                     = zoran_s_input,
-       .vidioc_g_std                       = zoran_g_std,
-       .vidioc_s_std                       = zoran_s_std,
-       .vidioc_create_bufs                 = vb2_ioctl_create_bufs,
-       .vidioc_reqbufs                     = vb2_ioctl_reqbufs,
-       .vidioc_querybuf                    = vb2_ioctl_querybuf,
-       .vidioc_qbuf                        = vb2_ioctl_qbuf,
-       .vidioc_dqbuf                       = vb2_ioctl_dqbuf,
-       .vidioc_expbuf                      = vb2_ioctl_expbuf,
-       .vidioc_streamon                    = vb2_ioctl_streamon,
-       .vidioc_streamoff                   = vb2_ioctl_streamoff,
-       .vidioc_enum_fmt_vid_cap            = zoran_enum_fmt_vid_cap,
-       .vidioc_g_fmt_vid_cap               = zoran_g_fmt_vid_cap,
-       .vidioc_s_fmt_vid_cap               = zoran_s_fmt_vid_cap,
-       .vidioc_try_fmt_vid_cap             = zoran_try_fmt_vid_cap,
-       .vidioc_subscribe_event             = v4l2_ctrl_subscribe_event,
-       .vidioc_unsubscribe_event           = v4l2_event_unsubscribe,
-};
-
-static const struct v4l2_file_operations zoran_fops = {
-       .owner = THIS_MODULE,
-       .unlocked_ioctl = video_ioctl2,
-       .open           = v4l2_fh_open,
-       .release        = vb2_fop_release,
-       .mmap           = vb2_fop_mmap,
-       .poll           = vb2_fop_poll,
-};
-
-const struct video_device zoran_template = {
-       .name = ZORAN_NAME,
-       .fops = &zoran_fops,
-       .ioctl_ops = &zoran_ioctl_ops,
-       .release = &zoran_vdev_release,
-       .tvnorms = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM,
-};
-
-static int zr_vb2_queue_setup(struct vb2_queue *vq, unsigned int *nbuffers, unsigned int *nplanes,
-                             unsigned int sizes[], struct device *alloc_devs[])
-{
-       struct zoran *zr = vb2_get_drv_priv(vq);
-       unsigned int size = zr->buffer_size;
-
-       pci_dbg(zr->pci_dev, "%s nbuf=%u nplanes=%u", __func__, *nbuffers, *nplanes);
-
-       zr->buf_in_reserve = 0;
-
-       if (*nbuffers < vq->min_buffers_needed)
-               *nbuffers = vq->min_buffers_needed;
-
-       if (*nplanes) {
-               if (sizes[0] < size)
-                       return -EINVAL;
-               else
-                       return 0;
-       }
-
-       *nplanes = 1;
-       sizes[0] = size;
-
-       return 0;
-}
-
-static void zr_vb2_queue(struct vb2_buffer *vb)
-{
-       struct zoran *zr = vb2_get_drv_priv(vb->vb2_queue);
-       struct zr_buffer *buf = vb2_to_zr_buffer(vb);
-       unsigned long flags;
-
-       spin_lock_irqsave(&zr->queued_bufs_lock, flags);
-       list_add_tail(&buf->queue, &zr->queued_bufs);
-       zr->buf_in_reserve++;
-       spin_unlock_irqrestore(&zr->queued_bufs_lock, flags);
-       if (zr->running == ZORAN_MAP_MODE_JPG_REC)
-               zoran_feed_stat_com(zr);
-       zr->queued++;
-}
-
-static int zr_vb2_prepare(struct vb2_buffer *vb)
-{
-       struct zoran *zr = vb2_get_drv_priv(vb->vb2_queue);
-
-       if (vb2_plane_size(vb, 0) < zr->buffer_size)
-               return -EINVAL;
-       zr->prepared++;
-
-       return 0;
-}
-
-int zr_set_buf(struct zoran *zr)
-{
-       struct zr_buffer *buf;
-       struct vb2_v4l2_buffer *vbuf;
-       dma_addr_t phys_addr;
-       unsigned long flags;
-       u32 reg;
-
-       if (zr->running == ZORAN_MAP_MODE_NONE)
-               return 0;
-
-       if (zr->inuse[0]) {
-               buf = zr->inuse[0];
-               buf->vbuf.vb2_buf.timestamp = ktime_get_ns();
-               buf->vbuf.sequence = zr->vbseq++;
-               vbuf = &buf->vbuf;
-
-               buf->vbuf.field = V4L2_FIELD_INTERLACED;
-               if (BUZ_MAX_HEIGHT < (zr->v4l_settings.height * 2))
-                       buf->vbuf.field = V4L2_FIELD_INTERLACED;
-               else
-                       buf->vbuf.field = V4L2_FIELD_TOP;
-               vb2_set_plane_payload(&buf->vbuf.vb2_buf, 0, zr->buffer_size);
-               vb2_buffer_done(&buf->vbuf.vb2_buf, VB2_BUF_STATE_DONE);
-               zr->inuse[0] = NULL;
-       }
-
-       spin_lock_irqsave(&zr->queued_bufs_lock, flags);
-       if (list_empty(&zr->queued_bufs)) {
-               btand(~ZR36057_ICR_INT_PIN_EN, ZR36057_ICR);
-               vb2_queue_error(zr->video_dev->queue);
-               spin_unlock_irqrestore(&zr->queued_bufs_lock, flags);
-               return -EINVAL;
-       }
-       buf = list_first_entry_or_null(&zr->queued_bufs, struct zr_buffer, queue);
-       if (!buf) {
-               btand(~ZR36057_ICR_INT_PIN_EN, ZR36057_ICR);
-               vb2_queue_error(zr->video_dev->queue);
-               spin_unlock_irqrestore(&zr->queued_bufs_lock, flags);
-               return -EINVAL;
-       }
-       list_del(&buf->queue);
-       zr->buf_in_reserve--;
-       spin_unlock_irqrestore(&zr->queued_bufs_lock, flags);
-
-       vbuf = &buf->vbuf;
-       vbuf->vb2_buf.state = VB2_BUF_STATE_ACTIVE;
-       phys_addr = vb2_dma_contig_plane_dma_addr(&vbuf->vb2_buf, 0);
-
-       if (!phys_addr)
-               return -EINVAL;
-
-       zr->inuse[0] = buf;
-
-       reg = phys_addr;
-       btwrite(reg, ZR36057_VDTR);
-       if (zr->v4l_settings.height > BUZ_MAX_HEIGHT / 2)
-               reg += zr->v4l_settings.bytesperline;
-       btwrite(reg, ZR36057_VDBR);
-
-       reg = 0;
-       if (zr->v4l_settings.height > BUZ_MAX_HEIGHT / 2)
-               reg += zr->v4l_settings.bytesperline;
-       reg = (reg << ZR36057_VSSFGR_DISP_STRIDE);
-       reg |= ZR36057_VSSFGR_VID_OVF;
-       reg |= ZR36057_VSSFGR_SNAP_SHOT;
-       reg |= ZR36057_VSSFGR_FRAME_GRAB;
-       btwrite(reg, ZR36057_VSSFGR);
-
-       btor(ZR36057_VDCR_VID_EN, ZR36057_VDCR);
-       return 0;
-}
-
-static int zr_vb2_start_streaming(struct vb2_queue *vq, unsigned int count)
-{
-       struct zoran *zr = vq->drv_priv;
-       int j;
-
-       for (j = 0; j < BUZ_NUM_STAT_COM; j++) {
-               zr->stat_com[j] = cpu_to_le32(1);
-               zr->inuse[j] = NULL;
-       }
-       zr->vbseq = 0;
-
-       if (zr->map_mode != ZORAN_MAP_MODE_RAW) {
-               pci_dbg(zr->pci_dev, "START JPG\n");
-               zr36057_restart(zr);
-               zoran_init_hardware(zr);
-               if (zr->map_mode == ZORAN_MAP_MODE_JPG_REC)
-                       zr36057_enable_jpg(zr, BUZ_MODE_MOTION_DECOMPRESS);
-               else
-                       zr36057_enable_jpg(zr, BUZ_MODE_MOTION_COMPRESS);
-               zoran_feed_stat_com(zr);
-               jpeg_start(zr);
-               zr->running = zr->map_mode;
-               btor(ZR36057_ICR_INT_PIN_EN, ZR36057_ICR);
-               return 0;
-       }
-
-       pci_dbg(zr->pci_dev, "START RAW\n");
-       zr36057_restart(zr);
-       zoran_init_hardware(zr);
-
-       zr36057_enable_jpg(zr, BUZ_MODE_IDLE);
-       zr36057_set_memgrab(zr, 1);
-       zr->running = zr->map_mode;
-       btor(ZR36057_ICR_INT_PIN_EN, ZR36057_ICR);
-       return 0;
-}
-
-static void zr_vb2_stop_streaming(struct vb2_queue *vq)
-{
-       struct zoran *zr = vq->drv_priv;
-       struct zr_buffer *buf;
-       unsigned long flags;
-       int j;
-
-       btand(~ZR36057_ICR_INT_PIN_EN, ZR36057_ICR);
-       if (zr->map_mode != ZORAN_MAP_MODE_RAW)
-               zr36057_enable_jpg(zr, BUZ_MODE_IDLE);
-       zr36057_set_memgrab(zr, 0);
-       zr->running = ZORAN_MAP_MODE_NONE;
-
-       zoran_set_pci_master(zr, 0);
-
-       if (!pass_through) {    /* Switch to color bar */
-               decoder_call(zr, video, s_stream, 0);
-               encoder_call(zr, video, s_routing, 2, 0, 0);
-       }
-
-       for (j = 0; j < BUZ_NUM_STAT_COM; j++) {
-               zr->stat_com[j] = cpu_to_le32(1);
-               if (!zr->inuse[j])
-                       continue;
-               buf = zr->inuse[j];
-               pci_dbg(zr->pci_dev, "%s clean buf %d\n", __func__, j);
-               vb2_buffer_done(&buf->vbuf.vb2_buf, VB2_BUF_STATE_ERROR);
-               zr->inuse[j] = NULL;
-       }
-
-       spin_lock_irqsave(&zr->queued_bufs_lock, flags);
-       while (!list_empty(&zr->queued_bufs)) {
-               buf = list_entry(zr->queued_bufs.next, struct zr_buffer, queue);
-               list_del(&buf->queue);
-               vb2_buffer_done(&buf->vbuf.vb2_buf, VB2_BUF_STATE_ERROR);
-               zr->buf_in_reserve--;
-       }
-       spin_unlock_irqrestore(&zr->queued_bufs_lock, flags);
-       if (zr->buf_in_reserve)
-               pci_dbg(zr->pci_dev, "Buffer remaining %d\n", zr->buf_in_reserve);
-       zr->map_mode = ZORAN_MAP_MODE_RAW;
-}
-
-static const struct vb2_ops zr_video_qops = {
-       .queue_setup            = zr_vb2_queue_setup,
-       .buf_queue              = zr_vb2_queue,
-       .buf_prepare            = zr_vb2_prepare,
-       .start_streaming        = zr_vb2_start_streaming,
-       .stop_streaming         = zr_vb2_stop_streaming,
-       .wait_prepare           = vb2_ops_wait_prepare,
-       .wait_finish            = vb2_ops_wait_finish,
-};
-
-int zoran_queue_init(struct zoran *zr, struct vb2_queue *vq, int dir)
-{
-       int err;
-
-       spin_lock_init(&zr->queued_bufs_lock);
-       INIT_LIST_HEAD(&zr->queued_bufs);
-
-       vq->dev = &zr->pci_dev->dev;
-       vq->type = dir;
-
-       vq->io_modes = VB2_DMABUF | VB2_MMAP;
-       vq->drv_priv = zr;
-       vq->buf_struct_size = sizeof(struct zr_buffer);
-       vq->ops = &zr_video_qops;
-       vq->mem_ops = &vb2_dma_contig_memops;
-       vq->gfp_flags = GFP_DMA32;
-       vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
-       vq->min_buffers_needed = 9;
-       vq->lock = &zr->lock;
-       err = vb2_queue_init(vq);
-       if (err)
-               return err;
-       zr->video_dev->queue = vq;
-       return 0;
-}
-
-void zoran_queue_exit(struct zoran *zr)
-{
-       vb2_queue_release(zr->video_dev->queue);
-}
 
+++ /dev/null
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Zoran ZR36016 basic configuration functions
- *
- * Copyright (C) 2001 Wolfgang Scherr <scherr@net4you.at>
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-
-/* headerfile of this module */
-#include "zr36016.h"
-
-/* codec io API */
-#include "videocodec.h"
-
-/*
- * it doesn't make sense to have more than 20 or so,
- * just to prevent some unwanted loops
- */
-#define MAX_CODECS 20
-
-/* amount of chips attached via this driver */
-static int zr36016_codecs;
-
-/*
- * Local hardware I/O functions: read/write via codec layer
- * (registers are located in the master device)
- */
-
-/* read and write functions */
-static u8 zr36016_read(struct zr36016 *ptr, u16 reg)
-{
-       u8 value = 0;
-       struct zoran *zr = videocodec_to_zoran(ptr->codec);
-
-       /* just in case something is wrong... */
-       if (ptr->codec->master_data->readreg)
-               value = (ptr->codec->master_data->readreg(ptr->codec, reg)) & 0xFF;
-       else
-               zrdev_err(zr, "%s: invalid I/O setup, nothing read!\n", ptr->name);
-
-       zrdev_dbg(zr, "%s: reading from 0x%04x: %02x\n", ptr->name, reg, value);
-
-       return value;
-}
-
-static void zr36016_write(struct zr36016 *ptr, u16 reg, u8 value)
-{
-       struct zoran *zr = videocodec_to_zoran(ptr->codec);
-
-       zrdev_dbg(zr, "%s: writing 0x%02x to 0x%04x\n", ptr->name, value, reg);
-
-       // just in case something is wrong...
-       if (ptr->codec->master_data->writereg)
-               ptr->codec->master_data->writereg(ptr->codec, reg, value);
-       else
-               zrdev_err(zr, "%s: invalid I/O setup, nothing written!\n", ptr->name);
-}
-
-/*
- * indirect read and write functions
- *
- * the 016 supports auto-addr-increment, but
- * writing it all time cost not much and is safer...
- */
-static u8 zr36016_readi(struct zr36016 *ptr, u16 reg)
-{
-       u8 value = 0;
-       struct zoran *zr = videocodec_to_zoran(ptr->codec);
-
-       /* just in case something is wrong... */
-       if ((ptr->codec->master_data->writereg) && (ptr->codec->master_data->readreg)) {
-               ptr->codec->master_data->writereg(ptr->codec, ZR016_IADDR, reg & 0x0F);
-               value = (ptr->codec->master_data->readreg(ptr->codec, ZR016_IDATA)) & 0xFF;
-       } else {
-               zrdev_err(zr, "%s: invalid I/O setup, nothing read (i)!\n", ptr->name);
-       }
-
-       zrdev_dbg(zr, "%s: reading indirect from 0x%04x: %02x\n",
-                 ptr->name, reg, value);
-       return value;
-}
-
-static void zr36016_writei(struct zr36016 *ptr, u16 reg, u8 value)
-{
-       struct zoran *zr = videocodec_to_zoran(ptr->codec);
-
-       zrdev_dbg(zr, "%s: writing indirect 0x%02x to 0x%04x\n", ptr->name,
-                 value, reg);
-
-       /* just in case something is wrong... */
-       if (ptr->codec->master_data->writereg) {
-               ptr->codec->master_data->writereg(ptr->codec, ZR016_IADDR, reg & 0x0F);
-               ptr->codec->master_data->writereg(ptr->codec, ZR016_IDATA, value & 0x0FF);
-       } else {
-               zrdev_err(zr, "%s: invalid I/O setup, nothing written (i)!\n", ptr->name);
-       }
-}
-
-/* Local helper function: version read */
-
-/* version kept in datastructure */
-static u8 zr36016_read_version(struct zr36016 *ptr)
-{
-       ptr->version = zr36016_read(ptr, 0) >> 4;
-       return ptr->version;
-}
-
-/*
- * Local helper function: basic test of "connectivity", writes/reads
- * to/from PAX-Lo register
- */
-
-static int zr36016_basic_test(struct zr36016 *ptr)
-{
-       struct zoran *zr = videocodec_to_zoran(ptr->codec);
-
-       if (*KERN_INFO <= CONSOLE_LOGLEVEL_DEFAULT) {
-               int i;
-
-               zr36016_writei(ptr, ZR016I_PAX_LO, 0x55);
-               zrdev_dbg(zr, "%s: registers: ", ptr->name);
-               for (i = 0; i <= 0x0b; i++)
-                       zrdev_dbg(zr, "%02x ", zr36016_readi(ptr, i));
-               zrdev_dbg(zr, "\n");
-       }
-       // for testing just write 0, then the default value to a register and read
-       // it back in both cases
-       zr36016_writei(ptr, ZR016I_PAX_LO, 0x00);
-       if (zr36016_readi(ptr, ZR016I_PAX_LO) != 0x0) {
-               zrdev_err(zr, "%s: attach failed, can't connect to vfe processor!\n", ptr->name);
-               return -ENXIO;
-       }
-       zr36016_writei(ptr, ZR016I_PAX_LO, 0x0d0);
-       if (zr36016_readi(ptr, ZR016I_PAX_LO) != 0x0d0) {
-               zrdev_err(zr, "%s: attach failed, can't connect to vfe processor!\n", ptr->name);
-               return -ENXIO;
-       }
-       // we allow version numbers from 0-3, should be enough, though
-       zr36016_read_version(ptr);
-       if (ptr->version & 0x0c) {
-               zrdev_err(zr, "%s: attach failed, suspicious version %d found...\n", ptr->name,
-                         ptr->version);
-               return -ENXIO;
-       }
-
-       return 0;               /* looks good! */
-}
-
-/* Basic datasets & init */
-
-static void zr36016_init(struct zr36016 *ptr)
-{
-       // stop any processing
-       zr36016_write(ptr, ZR016_GOSTOP, 0);
-
-       // mode setup (yuv422 in and out, compression/expansuon due to mode)
-       zr36016_write(ptr, ZR016_MODE,
-                     ZR016_YUV422 | ZR016_YUV422_YUV422 |
-                     (ptr->mode == CODEC_DO_COMPRESSION ?
-                      ZR016_COMPRESSION : ZR016_EXPANSION));
-
-       // misc setup
-       zr36016_writei(ptr, ZR016I_SETUP1,
-                      (ptr->xdec ? (ZR016_HRFL | ZR016_HORZ) : 0) |
-                      (ptr->ydec ? ZR016_VERT : 0) | ZR016_CNTI);
-       zr36016_writei(ptr, ZR016I_SETUP2, ZR016_CCIR);
-
-       // Window setup
-       // (no extra offset for now, norm defines offset, default width height)
-       zr36016_writei(ptr, ZR016I_PAX_HI, ptr->width >> 8);
-       zr36016_writei(ptr, ZR016I_PAX_LO, ptr->width & 0xFF);
-       zr36016_writei(ptr, ZR016I_PAY_HI, ptr->height >> 8);
-       zr36016_writei(ptr, ZR016I_PAY_LO, ptr->height & 0xFF);
-       zr36016_writei(ptr, ZR016I_NAX_HI, ptr->xoff >> 8);
-       zr36016_writei(ptr, ZR016I_NAX_LO, ptr->xoff & 0xFF);
-       zr36016_writei(ptr, ZR016I_NAY_HI, ptr->yoff >> 8);
-       zr36016_writei(ptr, ZR016I_NAY_LO, ptr->yoff & 0xFF);
-
-       /* shall we continue now, please? */
-       zr36016_write(ptr, ZR016_GOSTOP, 1);
-}
-
-/*
- * CODEC API FUNCTIONS
- *
- * These functions are accessed by the master via the API structure
- */
-
-/*
- * set compression/expansion mode and launches codec -
- * this should be the last call from the master before starting processing
- */
-static int zr36016_set_mode(struct videocodec *codec, int mode)
-{
-       struct zr36016 *ptr = (struct zr36016 *)codec->data;
-       struct zoran *zr = videocodec_to_zoran(codec);
-
-       zrdev_dbg(zr, "%s: set_mode %d call\n", ptr->name, mode);
-
-       if ((mode != CODEC_DO_EXPANSION) && (mode != CODEC_DO_COMPRESSION))
-               return -EINVAL;
-
-       ptr->mode = mode;
-       zr36016_init(ptr);
-
-       return 0;
-}
-
-/* set picture size */
-static int zr36016_set_video(struct videocodec *codec, const struct tvnorm *norm,
-                            struct vfe_settings *cap, struct vfe_polarity *pol)
-{
-       struct zr36016 *ptr = (struct zr36016 *)codec->data;
-       struct zoran *zr = videocodec_to_zoran(codec);
-
-       zrdev_dbg(zr, "%s: set_video %d.%d, %d/%d-%dx%d (0x%x) call\n",
-                 ptr->name, norm->h_start, norm->v_start,
-                 cap->x, cap->y, cap->width, cap->height,
-                 cap->decimation);
-
-       /*
-        * if () return -EINVAL;
-        * trust the master driver that it knows what it does - so
-        * we allow invalid startx/y for now ...
-        */
-       ptr->width = cap->width;
-       ptr->height = cap->height;
-       /*
-        * (Ronald) This is ugly. zoran_device.c, line 387
-        * already mentions what happens if h_start is even
-        * (blue faces, etc., cr/cb inversed). There's probably
-        * some good reason why h_start is 0 instead of 1, so I'm
-        * leaving it to this for now, but really... This can be
-        * done a lot simpler
-        */
-       ptr->xoff = (norm->h_start ? norm->h_start : 1) + cap->x;
-       /*
-        * Something to note here (I don't understand it), setting
-        * v_start too high will cause the codec to 'not work'. I
-        * really don't get it. values of 16 (v_start) already break
-        * it here. Just '0' seems to work. More testing needed!
-        */
-       ptr->yoff = norm->v_start + cap->y;
-       /* (Ronald) dzjeeh, can't this thing do hor_decimation = 4? */
-       ptr->xdec = ((cap->decimation & 0xff) == 1) ? 0 : 1;
-       ptr->ydec = (((cap->decimation >> 8) & 0xff) == 1) ? 0 : 1;
-
-       return 0;
-}
-
-/* additional control functions */
-static int zr36016_control(struct videocodec *codec, int type, int size, void *data)
-{
-       struct zr36016 *ptr = (struct zr36016 *)codec->data;
-       struct zoran *zr = videocodec_to_zoran(codec);
-       int *ival = (int *)data;
-
-       zrdev_dbg(zr, "%s: control %d call with %d byte\n",
-                 ptr->name, type, size);
-
-       switch (type) {
-       case CODEC_G_STATUS:    /* get last status - we don't know it ... */
-               if (size != sizeof(int))
-                       return -EFAULT;
-               *ival = 0;
-               break;
-
-       case CODEC_G_CODEC_MODE:
-               if (size != sizeof(int))
-                       return -EFAULT;
-               *ival = 0;
-               break;
-
-       case CODEC_S_CODEC_MODE:
-               if (size != sizeof(int))
-                       return -EFAULT;
-               if (*ival != 0)
-                       return -EINVAL;
-               /* not needed, do nothing */
-               return 0;
-
-       case CODEC_G_VFE:
-       case CODEC_S_VFE:
-               return 0;
-
-       case CODEC_S_MMAP:
-               /* not available, give an error */
-               return -ENXIO;
-
-       default:
-               return -EINVAL;
-       }
-
-       return size;
-}
-
-/*
- * Exit and unregister function:
- *
- * Deinitializes Zoran's JPEG processor
- */
-
-static int zr36016_unset(struct videocodec *codec)
-{
-       struct zr36016 *ptr = codec->data;
-       struct zoran *zr = videocodec_to_zoran(codec);
-
-       if (ptr) {
-               /* do wee need some codec deinit here, too ???? */
-
-               zrdev_dbg(zr, "%s: finished codec #%d\n", ptr->name, ptr->num);
-               kfree(ptr);
-               codec->data = NULL;
-
-               zr36016_codecs--;
-               return 0;
-       }
-
-       return -EFAULT;
-}
-
-/*
- * Setup and registry function:
- *
- * Initializes Zoran's JPEG processor
- *
- * Also sets pixel size, average code size, mode (compr./decompr.)
- * (the given size is determined by the processor with the video interface)
- */
-
-static int zr36016_setup(struct videocodec *codec)
-{
-       struct zr36016 *ptr;
-       struct zoran *zr = videocodec_to_zoran(codec);
-       int res;
-
-       zrdev_dbg(zr, "zr36016: initializing VFE subsystem #%d.\n", zr36016_codecs);
-
-       if (zr36016_codecs == MAX_CODECS) {
-               zrdev_err(zr, "zr36016: Can't attach more codecs!\n");
-               return -ENOSPC;
-       }
-       //mem structure init
-       ptr = kzalloc(sizeof(*ptr), GFP_KERNEL);
-       codec->data = ptr;
-       if (!ptr)
-               return -ENOMEM;
-
-       snprintf(ptr->name, sizeof(ptr->name), "zr36016[%d]", zr36016_codecs);
-       ptr->num = zr36016_codecs++;
-       ptr->codec = codec;
-
-       //testing
-       res = zr36016_basic_test(ptr);
-       if (res < 0) {
-               zr36016_unset(codec);
-               return res;
-       }
-       //final setup
-       ptr->mode = CODEC_DO_COMPRESSION;
-       ptr->width = 768;
-       ptr->height = 288;
-       ptr->xdec = 1;
-       ptr->ydec = 0;
-       zr36016_init(ptr);
-
-       zrdev_dbg(zr, "%s: codec v%d attached and running\n",
-                 ptr->name, ptr->version);
-
-       return 0;
-}
-
-static const struct videocodec zr36016_codec = {
-       .name = "zr36016",
-       .magic = 0L,            /* magic not used */
-       .flags =
-           CODEC_FLAG_HARDWARE | CODEC_FLAG_VFE | CODEC_FLAG_ENCODER |
-           CODEC_FLAG_DECODER,
-       .type = CODEC_TYPE_ZR36016,
-       .setup = zr36016_setup, /* functionality */
-       .unset = zr36016_unset,
-       .set_mode = zr36016_set_mode,
-       .set_video = zr36016_set_video,
-       .control = zr36016_control,
-       /* others are not used */
-};
-
-/* HOOK IN DRIVER AS KERNEL MODULE */
-
-int zr36016_init_module(void)
-{
-       zr36016_codecs = 0;
-       return videocodec_register(&zr36016_codec);
-}
-
-void zr36016_cleanup_module(void)
-{
-       if (zr36016_codecs) {
-               pr_debug("zr36016: something's wrong - %d codecs left somehow.\n",
-                        zr36016_codecs);
-       }
-       videocodec_unregister(&zr36016_codec);
-}
 
+++ /dev/null
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * Zoran ZR36016 basic configuration functions - header file
- *
- * Copyright (C) 2001 Wolfgang Scherr <scherr@net4you.at>
- */
-
-#ifndef ZR36016_H
-#define ZR36016_H
-
-/* data stored for each zoran jpeg codec chip */
-struct zr36016 {
-       char name[32];
-       int num;
-       /* io datastructure */
-       struct videocodec *codec;
-       // coder status
-       __u8 version;
-       // actual coder setup
-       int mode;
-
-       __u16 xoff;
-       __u16 yoff;
-       __u16 width;
-       __u16 height;
-       __u16 xdec;
-       __u16 ydec;
-};
-
-/* direct  register addresses */
-#define ZR016_GOSTOP      0x00
-#define ZR016_MODE        0x01
-#define ZR016_IADDR       0x02
-#define ZR016_IDATA       0x03
-
-/* indirect  register addresses */
-#define ZR016I_SETUP1     0x00
-#define ZR016I_SETUP2     0x01
-#define ZR016I_NAX_LO     0x02
-#define ZR016I_NAX_HI     0x03
-#define ZR016I_PAX_LO     0x04
-#define ZR016I_PAX_HI     0x05
-#define ZR016I_NAY_LO     0x06
-#define ZR016I_NAY_HI     0x07
-#define ZR016I_PAY_LO     0x08
-#define ZR016I_PAY_HI     0x09
-#define ZR016I_NOL_LO     0x0a
-#define ZR016I_NOL_HI     0x0b
-
-/* possible values for mode register */
-#define ZR016_RGB444_YUV444  0x00
-#define ZR016_RGB444_YUV422  0x01
-#define ZR016_RGB444_YUV411  0x02
-#define ZR016_RGB444_Y400    0x03
-#define ZR016_RGB444_RGB444  0x04
-#define ZR016_YUV444_YUV444  0x08
-#define ZR016_YUV444_YUV422  0x09
-#define ZR016_YUV444_YUV411  0x0a
-#define ZR016_YUV444_Y400    0x0b
-#define ZR016_YUV444_RGB444  0x0c
-#define ZR016_YUV422_YUV422  0x11
-#define ZR016_YUV422_YUV411  0x12
-#define ZR016_YUV422_Y400    0x13
-#define ZR016_YUV411_YUV411  0x16
-#define ZR016_YUV411_Y400    0x17
-#define ZR016_4444_4444      0x19
-#define ZR016_100_100        0x1b
-
-#define ZR016_RGB444         0x00
-#define ZR016_YUV444         0x20
-#define ZR016_YUV422         0x40
-
-#define ZR016_COMPRESSION    0x80
-#define ZR016_EXPANSION      0x80
-
-/* possible values for setup 1 register */
-#define ZR016_CKRT           0x80
-#define ZR016_VERT           0x40
-#define ZR016_HORZ           0x20
-#define ZR016_HRFL           0x10
-#define ZR016_DSFL           0x08
-#define ZR016_SBFL           0x04
-#define ZR016_RSTR           0x02
-#define ZR016_CNTI           0x01
-
-/* possible values for setup 2 register */
-#define ZR016_SYEN           0x40
-#define ZR016_CCIR           0x04
-#define ZR016_SIGN           0x02
-#define ZR016_YMCS           0x01
-
-int zr36016_init_module(void);
-void zr36016_cleanup_module(void);
-#endif                         /*fndef ZR36016_H */
 
+++ /dev/null
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Zoran ZR36050 basic configuration functions
- *
- * Copyright (C) 2001 Wolfgang Scherr <scherr@net4you.at>
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-
-#include <linux/types.h>
-#include <linux/wait.h>
-
-/* I/O commands, error codes */
-#include <linux/io.h>
-
-/* headerfile of this module */
-#include "zr36050.h"
-
-/* codec io API */
-#include "videocodec.h"
-
-/*
- * it doesn't make sense to have more than 20 or so,
- * just to prevent some unwanted loops
- */
-#define MAX_CODECS 20
-
-/* amount of chips attached via this driver */
-static int zr36050_codecs;
-
-/*
- * Local hardware I/O functions:
- *
- * read/write via codec layer (registers are located in the master device)
- */
-
-/* read and write functions */
-static u8 zr36050_read(struct zr36050 *ptr, u16 reg)
-{
-       struct zoran *zr = videocodec_to_zoran(ptr->codec);
-       u8 value = 0;
-
-       /* just in case something is wrong... */
-       if (ptr->codec->master_data->readreg)
-               value = (ptr->codec->master_data->readreg(ptr->codec, reg)) & 0xFF;
-       else
-               zrdev_err(zr, "%s: invalid I/O setup, nothing read!\n", ptr->name);
-
-       zrdev_dbg(zr, "%s: reading from 0x%04x: %02x\n", ptr->name, reg, value);
-
-       return value;
-}
-
-static void zr36050_write(struct zr36050 *ptr, u16 reg, u8 value)
-{
-       struct zoran *zr = videocodec_to_zoran(ptr->codec);
-
-       zrdev_dbg(zr, "%s: writing 0x%02x to 0x%04x\n", ptr->name, value, reg);
-
-       /* just in case something is wrong... */
-       if (ptr->codec->master_data->writereg)
-               ptr->codec->master_data->writereg(ptr->codec, reg, value);
-       else
-               zrdev_err(zr, "%s: invalid I/O setup, nothing written!\n",
-                         ptr->name);
-}
-
-/* status is kept in datastructure */
-static u8 zr36050_read_status1(struct zr36050 *ptr)
-{
-       ptr->status1 = zr36050_read(ptr, ZR050_STATUS_1);
-
-       zr36050_read(ptr, 0);
-       return ptr->status1;
-}
-
-/* scale factor is kept in datastructure */
-static u16 zr36050_read_scalefactor(struct zr36050 *ptr)
-{
-       ptr->scalefact = (zr36050_read(ptr, ZR050_SF_HI) << 8) |
-                        (zr36050_read(ptr, ZR050_SF_LO) & 0xFF);
-
-       /* leave 0 selected for an eventually GO from master */
-       zr36050_read(ptr, 0);
-       return ptr->scalefact;
-}
-
-/*
- * Local helper function:
- *
- * wait if codec is ready to proceed (end of processing) or time is over
- */
-
-static void zr36050_wait_end(struct zr36050 *ptr)
-{
-       struct zoran *zr = videocodec_to_zoran(ptr->codec);
-       int i = 0;
-
-       while (!(zr36050_read_status1(ptr) & 0x4)) {
-               udelay(1);
-               if (i++ > 200000) {     // 200ms, there is for sure something wrong!!!
-                       zrdev_err(zr,
-                                 "%s: timeout at wait_end (last status: 0x%02x)\n",
-                                 ptr->name, ptr->status1);
-                       break;
-               }
-       }
-}
-
-/*
- * Local helper function: basic test of "connectivity", writes/reads
- * to/from memory the SOF marker
- */
-
-static int zr36050_basic_test(struct zr36050 *ptr)
-{
-       struct zoran *zr = videocodec_to_zoran(ptr->codec);
-
-       zr36050_write(ptr, ZR050_SOF_IDX, 0x00);
-       zr36050_write(ptr, ZR050_SOF_IDX + 1, 0x00);
-       if ((zr36050_read(ptr, ZR050_SOF_IDX) |
-            zr36050_read(ptr, ZR050_SOF_IDX + 1)) != 0x0000) {
-               zrdev_err(zr,
-                         "%s: attach failed, can't connect to jpeg processor!\n",
-                         ptr->name);
-               return -ENXIO;
-       }
-       zr36050_write(ptr, ZR050_SOF_IDX, 0xff);
-       zr36050_write(ptr, ZR050_SOF_IDX + 1, 0xc0);
-       if (((zr36050_read(ptr, ZR050_SOF_IDX) << 8) |
-            zr36050_read(ptr, ZR050_SOF_IDX + 1)) != 0xffc0) {
-               zrdev_err(zr,
-                         "%s: attach failed, can't connect to jpeg processor!\n",
-                         ptr->name);
-               return -ENXIO;
-       }
-
-       zr36050_wait_end(ptr);
-       if ((ptr->status1 & 0x4) == 0) {
-               zrdev_err(zr,
-                         "%s: attach failed, jpeg processor failed (end flag)!\n",
-                         ptr->name);
-               return -EBUSY;
-       }
-
-       return 0;               /* looks good! */
-}
-
-/* Local helper function: simple loop for pushing the init datasets */
-
-static int zr36050_pushit(struct zr36050 *ptr, u16 startreg, u16 len, const char *data)
-{
-       struct zoran *zr = videocodec_to_zoran(ptr->codec);
-       int i = 0;
-
-       zrdev_dbg(zr, "%s: write data block to 0x%04x (len=%d)\n", ptr->name,
-                 startreg, len);
-       while (i < len)
-               zr36050_write(ptr, startreg++, data[i++]);
-
-       return i;
-}
-
-/*
- * Basic datasets:
- *
- * jpeg baseline setup data (you find it on lots places in internet, or just
- * extract it from any regular .jpg image...)
- *
- * Could be variable, but until it's not needed it they are just fixed to save
- * memory. Otherwise expand zr36050 structure with arrays, push the values to
- * it and initialize from there, as e.g. the linux zr36057/60 driver does it.
- */
-
-static const char zr36050_dqt[0x86] = {
-       0xff, 0xdb,             //Marker: DQT
-       0x00, 0x84,             //Length: 2*65+2
-       0x00,                   //Pq,Tq first table
-       0x10, 0x0b, 0x0c, 0x0e, 0x0c, 0x0a, 0x10, 0x0e,
-       0x0d, 0x0e, 0x12, 0x11, 0x10, 0x13, 0x18, 0x28,
-       0x1a, 0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25,
-       0x1d, 0x28, 0x3a, 0x33, 0x3d, 0x3c, 0x39, 0x33,
-       0x38, 0x37, 0x40, 0x48, 0x5c, 0x4e, 0x40, 0x44,
-       0x57, 0x45, 0x37, 0x38, 0x50, 0x6d, 0x51, 0x57,
-       0x5f, 0x62, 0x67, 0x68, 0x67, 0x3e, 0x4d, 0x71,
-       0x79, 0x70, 0x64, 0x78, 0x5c, 0x65, 0x67, 0x63,
-       0x01,                   //Pq,Tq second table
-       0x11, 0x12, 0x12, 0x18, 0x15, 0x18, 0x2f, 0x1a,
-       0x1a, 0x2f, 0x63, 0x42, 0x38, 0x42, 0x63, 0x63,
-       0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
-       0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
-       0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
-       0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
-       0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
-       0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63
-};
-
-static const char zr36050_dht[0x1a4] = {
-       0xff, 0xc4,             //Marker: DHT
-       0x01, 0xa2,             //Length: 2*AC, 2*DC
-       0x00,                   //DC first table
-       0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01,
-       0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
-       0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,
-       0x01,                   //DC second table
-       0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-       0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
-       0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,
-       0x10,                   //AC first table
-       0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03,
-       0x05, 0x05, 0x04, 0x04, 0x00, 0x00,
-       0x01, 0x7D, 0x01, 0x02, 0x03, 0x00, 0x04, 0x11,
-       0x05, 0x12, 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61,
-       0x07, 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xA1,
-       0x08, 0x23, 0x42, 0xB1, 0xC1, 0x15, 0x52, 0xD1, 0xF0, 0x24,
-       0x33, 0x62, 0x72, 0x82, 0x09, 0x0A, 0x16, 0x17,
-       0x18, 0x19, 0x1A, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x34,
-       0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x43, 0x44,
-       0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56,
-       0x57, 0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66,
-       0x67, 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
-       0x79, 0x7A, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88,
-       0x89, 0x8A, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99,
-       0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8,
-       0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9,
-       0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8,
-       0xC9, 0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9,
-       0xDA, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
-       0xE8, 0xE9, 0xEA, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
-       0xF8, 0xF9, 0xFA,
-       0x11,                   //AC second table
-       0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04,
-       0x07, 0x05, 0x04, 0x04, 0x00, 0x01,
-       0x02, 0x77, 0x00, 0x01, 0x02, 0x03, 0x11, 0x04,
-       0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
-       0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
-       0xA1, 0xB1, 0xC1, 0x09, 0x23, 0x33, 0x52, 0xF0, 0x15, 0x62,
-       0x72, 0xD1, 0x0A, 0x16, 0x24, 0x34, 0xE1, 0x25,
-       0xF1, 0x17, 0x18, 0x19, 0x1A, 0x26, 0x27, 0x28, 0x29, 0x2A,
-       0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x43, 0x44,
-       0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56,
-       0x57, 0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66,
-       0x67, 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
-       0x79, 0x7A, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
-       0x88, 0x89, 0x8A, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
-       0x99, 0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7,
-       0xA8, 0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8,
-       0xB9, 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
-       0xC8, 0xC9, 0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8,
-       0xD9, 0xDA, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
-       0xE8, 0xE9, 0xEA, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8,
-       0xF9, 0xFA
-};
-
-/* jpeg baseline setup, this is just fixed in this driver (YUV pictures) */
-#define NO_OF_COMPONENTS          0x3  //Y,U,V
-#define BASELINE_PRECISION        0x8  //MCU size (?)
-static const char zr36050_tq[8] = { 0, 1, 1, 0, 0, 0, 0, 0 };  //table idx's QT
-static const char zr36050_td[8] = { 0, 1, 1, 0, 0, 0, 0, 0 };  //table idx's DC
-static const char zr36050_ta[8] = { 0, 1, 1, 0, 0, 0, 0, 0 };  //table idx's AC
-
-/* horizontal 422 decimation setup (maybe we support 411 or so later, too) */
-static const char zr36050_decimation_h[8] = { 2, 1, 1, 0, 0, 0, 0, 0 };
-static const char zr36050_decimation_v[8] = { 1, 1, 1, 0, 0, 0, 0, 0 };
-
-/*
- * Local helper functions:
- *
- * calculation and setup of parameter-dependent JPEG baseline segments
- * (needed for compression only)
- */
-
-/* ------------------------------------------------------------------------- */
-
-/*
- * SOF (start of frame) segment depends on width, height and sampling ratio
- * of each color component
- */
-static int zr36050_set_sof(struct zr36050 *ptr)
-{
-       struct zoran *zr = videocodec_to_zoran(ptr->codec);
-       char sof_data[34];      // max. size of register set
-       int i;
-
-       zrdev_dbg(zr, "%s: write SOF (%dx%d, %d components)\n", ptr->name,
-                 ptr->width, ptr->height, NO_OF_COMPONENTS);
-       sof_data[0] = 0xff;
-       sof_data[1] = 0xc0;
-       sof_data[2] = 0x00;
-       sof_data[3] = (3 * NO_OF_COMPONENTS) + 8;
-       sof_data[4] = BASELINE_PRECISION;       // only '8' possible with zr36050
-       sof_data[5] = (ptr->height) >> 8;
-       sof_data[6] = (ptr->height) & 0xff;
-       sof_data[7] = (ptr->width) >> 8;
-       sof_data[8] = (ptr->width) & 0xff;
-       sof_data[9] = NO_OF_COMPONENTS;
-       for (i = 0; i < NO_OF_COMPONENTS; i++) {
-               sof_data[10 + (i * 3)] = i;     // index identifier
-               sof_data[11 + (i * 3)] = (ptr->h_samp_ratio[i] << 4) |
-                                        (ptr->v_samp_ratio[i]);        // sampling ratios
-               sof_data[12 + (i * 3)] = zr36050_tq[i]; // Q table selection
-       }
-       return zr36050_pushit(ptr, ZR050_SOF_IDX,
-                             (3 * NO_OF_COMPONENTS) + 10, sof_data);
-}
-
-/* ------------------------------------------------------------------------- */
-
-/*
- * SOS (start of scan) segment depends on the used scan components
- * of each color component
- */
-
-static int zr36050_set_sos(struct zr36050 *ptr)
-{
-       struct zoran *zr = videocodec_to_zoran(ptr->codec);
-       char sos_data[16];      // max. size of register set
-       int i;
-
-       zrdev_dbg(zr, "%s: write SOS\n", ptr->name);
-       sos_data[0] = 0xff;
-       sos_data[1] = 0xda;
-       sos_data[2] = 0x00;
-       sos_data[3] = 2 + 1 + (2 * NO_OF_COMPONENTS) + 3;
-       sos_data[4] = NO_OF_COMPONENTS;
-       for (i = 0; i < NO_OF_COMPONENTS; i++) {
-               sos_data[5 + (i * 2)] = i;      // index
-               sos_data[6 + (i * 2)] = (zr36050_td[i] << 4) | zr36050_ta[i];   // AC/DC tbl.sel.
-       }
-       sos_data[2 + 1 + (2 * NO_OF_COMPONENTS) + 2] = 00;      // scan start
-       sos_data[2 + 1 + (2 * NO_OF_COMPONENTS) + 3] = 0x3F;
-       sos_data[2 + 1 + (2 * NO_OF_COMPONENTS) + 4] = 00;
-       return zr36050_pushit(ptr, ZR050_SOS1_IDX,
-                             4 + 1 + (2 * NO_OF_COMPONENTS) + 3,
-                             sos_data);
-}
-
-/* ------------------------------------------------------------------------- */
-
-/* DRI (define restart interval) */
-
-static int zr36050_set_dri(struct zr36050 *ptr)
-{
-       struct zoran *zr = videocodec_to_zoran(ptr->codec);
-       char dri_data[6];       // max. size of register set
-
-       zrdev_dbg(zr, "%s: write DRI\n", ptr->name);
-       dri_data[0] = 0xff;
-       dri_data[1] = 0xdd;
-       dri_data[2] = 0x00;
-       dri_data[3] = 0x04;
-       dri_data[4] = ptr->dri >> 8;
-       dri_data[5] = ptr->dri & 0xff;
-       return zr36050_pushit(ptr, ZR050_DRI_IDX, 6, dri_data);
-}
-
-/*
- * Setup function:
- *
- * Setup compression/decompression of Zoran's JPEG processor
- * ( see also zoran 36050 manual )
- *
- * ... sorry for the spaghetti code ...
- */
-static void zr36050_init(struct zr36050 *ptr)
-{
-       int sum = 0;
-       long bitcnt, tmp;
-       struct zoran *zr = videocodec_to_zoran(ptr->codec);
-
-       if (ptr->mode == CODEC_DO_COMPRESSION) {
-               zrdev_dbg(zr, "%s: COMPRESSION SETUP\n", ptr->name);
-
-               /* 050 communicates with 057 in master mode */
-               zr36050_write(ptr, ZR050_HARDWARE, ZR050_HW_MSTR);
-
-               /* encoding table preload for compression */
-               zr36050_write(ptr, ZR050_MODE,
-                             ZR050_MO_COMP | ZR050_MO_TLM);
-               zr36050_write(ptr, ZR050_OPTIONS, 0);
-
-               /* disable all IRQs */
-               zr36050_write(ptr, ZR050_INT_REQ_0, 0);
-               zr36050_write(ptr, ZR050_INT_REQ_1, 3); // low 2 bits always 1
-
-               /* volume control settings */
-               /*zr36050_write(ptr, ZR050_MBCV, ptr->max_block_vol);*/
-               zr36050_write(ptr, ZR050_SF_HI, ptr->scalefact >> 8);
-               zr36050_write(ptr, ZR050_SF_LO, ptr->scalefact & 0xff);
-
-               zr36050_write(ptr, ZR050_AF_HI, 0xff);
-               zr36050_write(ptr, ZR050_AF_M, 0xff);
-               zr36050_write(ptr, ZR050_AF_LO, 0xff);
-
-               /* setup the variable jpeg tables */
-               sum += zr36050_set_sof(ptr);
-               sum += zr36050_set_sos(ptr);
-               sum += zr36050_set_dri(ptr);
-
-               /*
-                * setup the fixed jpeg tables - maybe variable, though -
-                * (see table init section above)
-                */
-               zrdev_dbg(zr, "%s: write DQT, DHT, APP\n", ptr->name);
-               sum += zr36050_pushit(ptr, ZR050_DQT_IDX,
-                                     sizeof(zr36050_dqt), zr36050_dqt);
-               sum += zr36050_pushit(ptr, ZR050_DHT_IDX,
-                                     sizeof(zr36050_dht), zr36050_dht);
-               zr36050_write(ptr, ZR050_APP_IDX, 0xff);
-               zr36050_write(ptr, ZR050_APP_IDX + 1, 0xe0 + ptr->app.appn);
-               zr36050_write(ptr, ZR050_APP_IDX + 2, 0x00);
-               zr36050_write(ptr, ZR050_APP_IDX + 3, ptr->app.len + 2);
-               sum += zr36050_pushit(ptr, ZR050_APP_IDX + 4, 60,
-                                     ptr->app.data) + 4;
-               zr36050_write(ptr, ZR050_COM_IDX, 0xff);
-               zr36050_write(ptr, ZR050_COM_IDX + 1, 0xfe);
-               zr36050_write(ptr, ZR050_COM_IDX + 2, 0x00);
-               zr36050_write(ptr, ZR050_COM_IDX + 3, ptr->com.len + 2);
-               sum += zr36050_pushit(ptr, ZR050_COM_IDX + 4, 60,
-                                     ptr->com.data) + 4;
-
-               /* do the internal huffman table preload */
-               zr36050_write(ptr, ZR050_MARKERS_EN, ZR050_ME_DHTI);
-
-               zr36050_write(ptr, ZR050_GO, 1);        // launch codec
-               zr36050_wait_end(ptr);
-               zrdev_dbg(zr, "%s: Status after table preload: 0x%02x\n",
-                         ptr->name, ptr->status1);
-
-               if ((ptr->status1 & 0x4) == 0) {
-                       zrdev_err(zr, "%s: init aborted!\n", ptr->name);
-                       return; // something is wrong, its timed out!!!!
-               }
-
-               /* setup misc. data for compression (target code sizes) */
-
-               /* size of compressed code to reach without header data */
-               sum = ptr->real_code_vol - sum;
-               bitcnt = sum << 3;      /* need the size in bits */
-
-               tmp = bitcnt >> 16;
-               zrdev_dbg(zr,
-                         "%s: code: csize=%d, tot=%d, bit=%ld, highbits=%ld\n",
-                         ptr->name, sum, ptr->real_code_vol, bitcnt, tmp);
-               zr36050_write(ptr, ZR050_TCV_NET_HI, tmp >> 8);
-               zr36050_write(ptr, ZR050_TCV_NET_MH, tmp & 0xff);
-               tmp = bitcnt & 0xffff;
-               zr36050_write(ptr, ZR050_TCV_NET_ML, tmp >> 8);
-               zr36050_write(ptr, ZR050_TCV_NET_LO, tmp & 0xff);
-
-               bitcnt -= bitcnt >> 7;  // bits without stuffing
-               bitcnt -= ((bitcnt * 5) >> 6);  // bits without eob
-
-               tmp = bitcnt >> 16;
-               zrdev_dbg(zr, "%s: code: nettobit=%ld, highnettobits=%ld\n",
-                         ptr->name, bitcnt, tmp);
-               zr36050_write(ptr, ZR050_TCV_DATA_HI, tmp >> 8);
-               zr36050_write(ptr, ZR050_TCV_DATA_MH, tmp & 0xff);
-               tmp = bitcnt & 0xffff;
-               zr36050_write(ptr, ZR050_TCV_DATA_ML, tmp >> 8);
-               zr36050_write(ptr, ZR050_TCV_DATA_LO, tmp & 0xff);
-
-               /* compression setup with or without bitrate control */
-               zr36050_write(ptr, ZR050_MODE,
-                             ZR050_MO_COMP | ZR050_MO_PASS2 |
-                             (ptr->bitrate_ctrl ? ZR050_MO_BRC : 0));
-
-               /* this headers seem to deliver "valid AVI" jpeg frames */
-               zr36050_write(ptr, ZR050_MARKERS_EN,
-                             ZR050_ME_DQT | ZR050_ME_DHT |
-                             ((ptr->app.len > 0) ? ZR050_ME_APP : 0) |
-                             ((ptr->com.len > 0) ? ZR050_ME_COM : 0));
-       } else {
-               zrdev_dbg(zr, "%s: EXPANSION SETUP\n", ptr->name);
-
-               /* 050 communicates with 055 in master mode */
-               zr36050_write(ptr, ZR050_HARDWARE,
-                             ZR050_HW_MSTR | ZR050_HW_CFIS_2_CLK);
-
-               /* encoding table preload */
-               zr36050_write(ptr, ZR050_MODE, ZR050_MO_TLM);
-
-               /* disable all IRQs */
-               zr36050_write(ptr, ZR050_INT_REQ_0, 0);
-               zr36050_write(ptr, ZR050_INT_REQ_1, 3); // low 2 bits always 1
-
-               zrdev_dbg(zr, "%s: write DHT\n", ptr->name);
-               zr36050_pushit(ptr, ZR050_DHT_IDX, sizeof(zr36050_dht),
-                              zr36050_dht);
-
-               /* do the internal huffman table preload */
-               zr36050_write(ptr, ZR050_MARKERS_EN, ZR050_ME_DHTI);
-
-               zr36050_write(ptr, ZR050_GO, 1);        // launch codec
-               zr36050_wait_end(ptr);
-               zrdev_dbg(zr, "%s: Status after table preload: 0x%02x\n",
-                         ptr->name, ptr->status1);
-
-               if ((ptr->status1 & 0x4) == 0) {
-                       zrdev_err(zr, "%s: init aborted!\n", ptr->name);
-                       return; // something is wrong, its timed out!!!!
-               }
-
-               /* setup misc. data for expansion */
-               zr36050_write(ptr, ZR050_MODE, 0);
-               zr36050_write(ptr, ZR050_MARKERS_EN, 0);
-       }
-
-       /* adr on selected, to allow GO from master */
-       zr36050_read(ptr, 0);
-}
-
-/*
- * CODEC API FUNCTIONS
- *
- * this functions are accessed by the master via the API structure
- */
-
-/*
- * set compression/expansion mode and launches codec -
- * this should be the last call from the master before starting processing
- */
-static int zr36050_set_mode(struct videocodec *codec, int mode)
-{
-       struct zr36050 *ptr = (struct zr36050 *)codec->data;
-       struct zoran *zr = videocodec_to_zoran(codec);
-
-       zrdev_dbg(zr, "%s: set_mode %d call\n", ptr->name, mode);
-
-       if ((mode != CODEC_DO_EXPANSION) && (mode != CODEC_DO_COMPRESSION))
-               return -EINVAL;
-
-       ptr->mode = mode;
-       zr36050_init(ptr);
-
-       return 0;
-}
-
-/* set picture size (norm is ignored as the codec doesn't know about it) */
-static int zr36050_set_video(struct videocodec *codec, const struct tvnorm *norm,
-                            struct vfe_settings *cap, struct vfe_polarity *pol)
-{
-       struct zr36050 *ptr = (struct zr36050 *)codec->data;
-       struct zoran *zr = videocodec_to_zoran(codec);
-       int size;
-
-       zrdev_dbg(zr, "%s: set_video %d.%d, %d/%d-%dx%d (0x%x) q%d call\n",
-                 ptr->name, norm->h_start, norm->v_start,
-                 cap->x, cap->y, cap->width, cap->height,
-                 cap->decimation, cap->quality);
-       /*
-        * trust the master driver that it knows what it does - so
-        * we allow invalid startx/y and norm for now ...
-        */
-       ptr->width = cap->width / (cap->decimation & 0xff);
-       ptr->height = cap->height / ((cap->decimation >> 8) & 0xff);
-
-       /* (KM) JPEG quality */
-       size = ptr->width * ptr->height;
-       size *= 16; /* size in bits */
-       /* apply quality setting */
-       size = size * cap->quality / 200;
-
-       /* Minimum: 1kb */
-       if (size < 8192)
-               size = 8192;
-       /* Maximum: 7/8 of code buffer */
-       if (size > ptr->total_code_vol * 7)
-               size = ptr->total_code_vol * 7;
-
-       ptr->real_code_vol = size >> 3; /* in bytes */
-
-       /*
-        * Set max_block_vol here (previously in zr36050_init, moved
-        * here for consistency with zr36060 code
-        */
-       zr36050_write(ptr, ZR050_MBCV, ptr->max_block_vol);
-
-       return 0;
-}
-
-/* additional control functions */
-static int zr36050_control(struct videocodec *codec, int type, int size, void *data)
-{
-       struct zr36050 *ptr = (struct zr36050 *)codec->data;
-       struct zoran *zr = videocodec_to_zoran(codec);
-       int *ival = (int *)data;
-
-       zrdev_dbg(zr, "%s: control %d call with %d byte\n", ptr->name, type,
-                 size);
-
-       switch (type) {
-       case CODEC_G_STATUS:    /* get last status */
-               if (size != sizeof(int))
-                       return -EFAULT;
-               zr36050_read_status1(ptr);
-               *ival = ptr->status1;
-               break;
-
-       case CODEC_G_CODEC_MODE:
-               if (size != sizeof(int))
-                       return -EFAULT;
-               *ival = CODEC_MODE_BJPG;
-               break;
-
-       case CODEC_S_CODEC_MODE:
-               if (size != sizeof(int))
-                       return -EFAULT;
-               if (*ival != CODEC_MODE_BJPG)
-                       return -EINVAL;
-               /* not needed, do nothing */
-               return 0;
-
-       case CODEC_G_VFE:
-       case CODEC_S_VFE:
-               /* not needed, do nothing */
-               return 0;
-
-       case CODEC_S_MMAP:
-               /* not available, give an error */
-               return -ENXIO;
-
-       case CODEC_G_JPEG_TDS_BYTE:     /* get target volume in byte */
-               if (size != sizeof(int))
-                       return -EFAULT;
-               *ival = ptr->total_code_vol;
-               break;
-
-       case CODEC_S_JPEG_TDS_BYTE:     /* get target volume in byte */
-               if (size != sizeof(int))
-                       return -EFAULT;
-               ptr->total_code_vol = *ival;
-               ptr->real_code_vol = (ptr->total_code_vol * 6) >> 3;
-               break;
-
-       case CODEC_G_JPEG_SCALE:        /* get scaling factor */
-               if (size != sizeof(int))
-                       return -EFAULT;
-               *ival = zr36050_read_scalefactor(ptr);
-               break;
-
-       case CODEC_S_JPEG_SCALE:        /* set scaling factor */
-               if (size != sizeof(int))
-                       return -EFAULT;
-               ptr->scalefact = *ival;
-               break;
-
-       case CODEC_G_JPEG_APP_DATA: {   /* get appn marker data */
-               struct jpeg_app_marker *app = data;
-
-               if (size != sizeof(struct jpeg_app_marker))
-                       return -EFAULT;
-
-               *app = ptr->app;
-               break;
-       }
-
-       case CODEC_S_JPEG_APP_DATA: {    /* set appn marker data */
-               struct jpeg_app_marker *app = data;
-
-               if (size != sizeof(struct jpeg_app_marker))
-                       return -EFAULT;
-
-               ptr->app = *app;
-               break;
-       }
-
-       case CODEC_G_JPEG_COM_DATA: {   /* get comment marker data */
-               struct jpeg_com_marker *com = data;
-
-               if (size != sizeof(struct jpeg_com_marker))
-                       return -EFAULT;
-
-               *com = ptr->com;
-               break;
-       }
-
-       case CODEC_S_JPEG_COM_DATA: {   /* set comment marker data */
-               struct jpeg_com_marker *com = data;
-
-               if (size != sizeof(struct jpeg_com_marker))
-                       return -EFAULT;
-
-               ptr->com = *com;
-               break;
-       }
-
-       default:
-               return -EINVAL;
-       }
-
-       return size;
-}
-
-/* Exit and unregister function: Deinitializes Zoran's JPEG processor */
-
-static int zr36050_unset(struct videocodec *codec)
-{
-       struct zr36050 *ptr = codec->data;
-       struct zoran *zr = videocodec_to_zoran(codec);
-
-       if (ptr) {
-               /* do wee need some codec deinit here, too ???? */
-
-               zrdev_dbg(zr, "%s: finished codec #%d\n", ptr->name,
-                         ptr->num);
-               kfree(ptr);
-               codec->data = NULL;
-
-               zr36050_codecs--;
-               return 0;
-       }
-
-       return -EFAULT;
-}
-
-/*
- * Setup and registry function:
- *
- * Initializes Zoran's JPEG processor
- *
- * Also sets pixel size, average code size, mode (compr./decompr.)
- * (the given size is determined by the processor with the video interface)
- */
-
-static int zr36050_setup(struct videocodec *codec)
-{
-       struct zr36050 *ptr;
-       struct zoran *zr = videocodec_to_zoran(codec);
-       int res;
-
-       zrdev_dbg(zr, "zr36050: initializing MJPEG subsystem #%d.\n",
-                 zr36050_codecs);
-
-       if (zr36050_codecs == MAX_CODECS) {
-               zrdev_err(zr,
-                         "zr36050: Can't attach more codecs!\n");
-               return -ENOSPC;
-       }
-       //mem structure init
-       ptr = kzalloc(sizeof(*ptr), GFP_KERNEL);
-       codec->data = ptr;
-       if (!ptr)
-               return -ENOMEM;
-
-       snprintf(ptr->name, sizeof(ptr->name), "zr36050[%d]",
-                zr36050_codecs);
-       ptr->num = zr36050_codecs++;
-       ptr->codec = codec;
-
-       //testing
-       res = zr36050_basic_test(ptr);
-       if (res < 0) {
-               zr36050_unset(codec);
-               return res;
-       }
-       //final setup
-       memcpy(ptr->h_samp_ratio, zr36050_decimation_h, 8);
-       memcpy(ptr->v_samp_ratio, zr36050_decimation_v, 8);
-
-       /* 0 or 1 - fixed file size flag (what is the difference?) */
-       ptr->bitrate_ctrl = 0;
-       ptr->mode = CODEC_DO_COMPRESSION;
-       ptr->width = 384;
-       ptr->height = 288;
-       ptr->total_code_vol = 16000;
-       ptr->max_block_vol = 240;
-       ptr->scalefact = 0x100;
-       ptr->dri = 1;
-
-       /* no app/com marker by default */
-       ptr->app.appn = 0;
-       ptr->app.len = 0;
-       ptr->com.len = 0;
-
-       zr36050_init(ptr);
-
-       zrdev_info(zr, "%s: codec attached and running\n",
-                  ptr->name);
-
-       return 0;
-}
-
-static const struct videocodec zr36050_codec = {
-       .name = "zr36050",
-       .magic = 0L,            // magic not used
-       .flags =
-           CODEC_FLAG_JPEG | CODEC_FLAG_HARDWARE | CODEC_FLAG_ENCODER |
-           CODEC_FLAG_DECODER,
-       .type = CODEC_TYPE_ZR36050,
-       .setup = zr36050_setup, // functionality
-       .unset = zr36050_unset,
-       .set_mode = zr36050_set_mode,
-       .set_video = zr36050_set_video,
-       .control = zr36050_control,
-       // others are not used
-};
-
-/* HOOK IN DRIVER AS KERNEL MODULE */
-
-int zr36050_init_module(void)
-{
-       zr36050_codecs = 0;
-       return videocodec_register(&zr36050_codec);
-}
-
-void zr36050_cleanup_module(void)
-{
-       if (zr36050_codecs) {
-               pr_debug("zr36050: something's wrong - %d codecs left somehow.\n",
-                        zr36050_codecs);
-       }
-       videocodec_unregister(&zr36050_codec);
-}
 
+++ /dev/null
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * Zoran ZR36050 basic configuration functions - header file
- *
- * Copyright (C) 2001 Wolfgang Scherr <scherr@net4you.at>
- */
-
-#ifndef ZR36050_H
-#define ZR36050_H
-
-#include "videocodec.h"
-
-/* data stored for each zoran jpeg codec chip */
-struct zr36050 {
-       char name[32];
-       int num;
-       /* io datastructure */
-       struct videocodec *codec;
-       // last coder status
-       __u8 status1;
-       // actual coder setup
-       int mode;
-
-       __u16 width;
-       __u16 height;
-
-       __u16 bitrate_ctrl;
-
-       __u32 total_code_vol;
-       __u32 real_code_vol;
-       __u16 max_block_vol;
-
-       __u8 h_samp_ratio[8];
-       __u8 v_samp_ratio[8];
-       __u16 scalefact;
-       __u16 dri;
-
-       /* com/app marker */
-       struct jpeg_com_marker com;
-       struct jpeg_app_marker app;
-};
-
-/* zr36050 register addresses */
-#define ZR050_GO                  0x000
-#define ZR050_HARDWARE            0x002
-#define ZR050_MODE                0x003
-#define ZR050_OPTIONS             0x004
-#define ZR050_MBCV                0x005
-#define ZR050_MARKERS_EN          0x006
-#define ZR050_INT_REQ_0           0x007
-#define ZR050_INT_REQ_1           0x008
-#define ZR050_TCV_NET_HI          0x009
-#define ZR050_TCV_NET_MH          0x00a
-#define ZR050_TCV_NET_ML          0x00b
-#define ZR050_TCV_NET_LO          0x00c
-#define ZR050_TCV_DATA_HI         0x00d
-#define ZR050_TCV_DATA_MH         0x00e
-#define ZR050_TCV_DATA_ML         0x00f
-#define ZR050_TCV_DATA_LO         0x010
-#define ZR050_SF_HI               0x011
-#define ZR050_SF_LO               0x012
-#define ZR050_AF_HI               0x013
-#define ZR050_AF_M                0x014
-#define ZR050_AF_LO               0x015
-#define ZR050_ACV_HI              0x016
-#define ZR050_ACV_MH              0x017
-#define ZR050_ACV_ML              0x018
-#define ZR050_ACV_LO              0x019
-#define ZR050_ACT_HI              0x01a
-#define ZR050_ACT_MH              0x01b
-#define ZR050_ACT_ML              0x01c
-#define ZR050_ACT_LO              0x01d
-#define ZR050_ACV_TURN_HI         0x01e
-#define ZR050_ACV_TURN_MH         0x01f
-#define ZR050_ACV_TURN_ML         0x020
-#define ZR050_ACV_TURN_LO         0x021
-#define ZR050_STATUS_0            0x02e
-#define ZR050_STATUS_1            0x02f
-
-#define ZR050_SOF_IDX             0x040
-#define ZR050_SOS1_IDX            0x07a
-#define ZR050_SOS2_IDX            0x08a
-#define ZR050_SOS3_IDX            0x09a
-#define ZR050_SOS4_IDX            0x0aa
-#define ZR050_DRI_IDX             0x0c0
-#define ZR050_DNL_IDX             0x0c6
-#define ZR050_DQT_IDX             0x0cc
-#define ZR050_DHT_IDX             0x1d4
-#define ZR050_APP_IDX             0x380
-#define ZR050_COM_IDX             0x3c0
-
-/* zr36050 hardware register bits */
-
-#define ZR050_HW_BSWD                0x80
-#define ZR050_HW_MSTR                0x40
-#define ZR050_HW_DMA                 0x20
-#define ZR050_HW_CFIS_1_CLK          0x00
-#define ZR050_HW_CFIS_2_CLK          0x04
-#define ZR050_HW_CFIS_3_CLK          0x08
-#define ZR050_HW_CFIS_4_CLK          0x0C
-#define ZR050_HW_CFIS_5_CLK          0x10
-#define ZR050_HW_CFIS_6_CLK          0x14
-#define ZR050_HW_CFIS_7_CLK          0x18
-#define ZR050_HW_CFIS_8_CLK          0x1C
-#define ZR050_HW_BELE                0x01
-
-/* zr36050 mode register bits */
-
-#define ZR050_MO_COMP                0x80
-#define ZR050_MO_ATP                 0x40
-#define ZR050_MO_PASS2               0x20
-#define ZR050_MO_TLM                 0x10
-#define ZR050_MO_DCONLY              0x08
-#define ZR050_MO_BRC                 0x04
-
-#define ZR050_MO_ATP                 0x40
-#define ZR050_MO_PASS2               0x20
-#define ZR050_MO_TLM                 0x10
-#define ZR050_MO_DCONLY              0x08
-
-/* zr36050 option register bits */
-
-#define ZR050_OP_NSCN_1              0x00
-#define ZR050_OP_NSCN_2              0x20
-#define ZR050_OP_NSCN_3              0x40
-#define ZR050_OP_NSCN_4              0x60
-#define ZR050_OP_NSCN_5              0x80
-#define ZR050_OP_NSCN_6              0xA0
-#define ZR050_OP_NSCN_7              0xC0
-#define ZR050_OP_NSCN_8              0xE0
-#define ZR050_OP_OVF                 0x10
-
-/* zr36050 markers-enable register bits */
-
-#define ZR050_ME_APP                 0x80
-#define ZR050_ME_COM                 0x40
-#define ZR050_ME_DRI                 0x20
-#define ZR050_ME_DQT                 0x10
-#define ZR050_ME_DHT                 0x08
-#define ZR050_ME_DNL                 0x04
-#define ZR050_ME_DQTI                0x02
-#define ZR050_ME_DHTI                0x01
-
-/* zr36050 status0/1 register bit masks */
-
-#define ZR050_ST_RST_MASK            0x20
-#define ZR050_ST_SOF_MASK            0x02
-#define ZR050_ST_SOS_MASK            0x02
-#define ZR050_ST_DATRDY_MASK         0x80
-#define ZR050_ST_MRKDET_MASK         0x40
-#define ZR050_ST_RFM_MASK            0x10
-#define ZR050_ST_RFD_MASK            0x08
-#define ZR050_ST_END_MASK            0x04
-#define ZR050_ST_TCVOVF_MASK         0x02
-#define ZR050_ST_DATOVF_MASK         0x01
-
-/* pixel component idx */
-
-#define ZR050_Y_COMPONENT         0
-#define ZR050_U_COMPONENT         1
-#define ZR050_V_COMPONENT         2
-
-int zr36050_init_module(void);
-void zr36050_cleanup_module(void);
-#endif                         /*fndef ZR36050_H */
 
+++ /dev/null
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * zr36057.h - zr36057 register offsets
- *
- * Copyright (C) 1998 Dave Perks <dperks@ibm.net>
- */
-
-#ifndef _ZR36057_H_
-#define _ZR36057_H_
-
-/* Zoran ZR36057 registers */
-
-#define ZR36057_VFEHCR          0x000  /* Video Front End, Horizontal Configuration Register */
-#define ZR36057_VFEHCR_HS_POL           BIT(30)
-#define ZR36057_VFEHCR_H_START          10
-#define ZR36057_VFEHCR_H_END           0
-#define ZR36057_VFEHCR_HMASK           0x3ff
-
-#define ZR36057_VFEVCR          0x004  /* Video Front End, Vertical Configuration Register */
-#define ZR36057_VFEVCR_VS_POL           BIT(30)
-#define ZR36057_VFEVCR_V_START          10
-#define ZR36057_VFEVCR_V_END           0
-#define ZR36057_VFEVCR_VMASK           0x3ff
-
-#define ZR36057_VFESPFR         0x008  /* Video Front End, Scaler and Pixel Format Register */
-#define ZR36057_VFESPFR_EXT_FL          BIT(26)
-#define ZR36057_VFESPFR_TOP_FIELD       BIT(25)
-#define ZR36057_VFESPFR_VCLK_POL        BIT(24)
-#define ZR36057_VFESPFR_H_FILTER        21
-#define ZR36057_VFESPFR_HOR_DCM         14
-#define ZR36057_VFESPFR_VER_DCM         8
-#define ZR36057_VFESPFR_DISP_MODE       6
-#define ZR36057_VFESPFR_YUV422          (0 << 3)
-#define ZR36057_VFESPFR_RGB888          (1 << 3)
-#define ZR36057_VFESPFR_RGB565          (2 << 3)
-#define ZR36057_VFESPFR_RGB555          (3 << 3)
-#define ZR36057_VFESPFR_ERR_DIF         BIT(2)
-#define ZR36057_VFESPFR_PACK24          BIT(1)
-#define ZR36057_VFESPFR_LITTLE_ENDIAN   BIT(0)
-
-#define ZR36057_VDTR            0x00c  /* Video Display "Top" Register */
-
-#define ZR36057_VDBR            0x010  /* Video Display "Bottom" Register */
-
-#define ZR36057_VSSFGR          0x014  /* Video Stride, Status, and Frame Grab Register */
-#define ZR36057_VSSFGR_DISP_STRIDE      16
-#define ZR36057_VSSFGR_VID_OVF          BIT(8)
-#define ZR36057_VSSFGR_SNAP_SHOT        BIT(1)
-#define ZR36057_VSSFGR_FRAME_GRAB       BIT(0)
-
-#define ZR36057_VDCR            0x018  /* Video Display Configuration Register */
-#define ZR36057_VDCR_VID_EN             BIT(31)
-#define ZR36057_VDCR_MIN_PIX            24
-#define ZR36057_VDCR_TRITON             BIT(24)
-#define ZR36057_VDCR_VID_WIN_HT         12
-#define ZR36057_VDCR_VID_WIN_WID        0
-
-#define ZR36057_MMTR            0x01c  /* Masking Map "Top" Register */
-
-#define ZR36057_MMBR            0x020  /* Masking Map "Bottom" Register */
-
-#define ZR36057_OCR             0x024  /* Overlay Control Register */
-#define ZR36057_OCR_OVL_ENABLE          BIT(15)
-#define ZR36057_OCR_MASK_STRIDE         0
-
-#define ZR36057_SPGPPCR         0x028  /* System, PCI, and General Purpose Pins Control Register */
-#define ZR36057_SPGPPCR_SOFT_RESET     BIT(24)
-
-#define ZR36057_GPPGCR1         0x02c  /* General Purpose Pins and GuestBus Control Register (1) */
-
-#define ZR36057_MCSAR           0x030  /* MPEG Code Source Address Register */
-
-#define ZR36057_MCTCR           0x034  /* MPEG Code Transfer Control Register */
-#define ZR36057_MCTCR_COD_TIME          BIT(30)
-#define ZR36057_MCTCR_C_EMPTY           BIT(29)
-#define ZR36057_MCTCR_C_FLUSH           BIT(28)
-#define ZR36057_MCTCR_COD_GUEST_ID     20
-#define ZR36057_MCTCR_COD_GUEST_REG    16
-
-#define ZR36057_MCMPR           0x038  /* MPEG Code Memory Pointer Register */
-
-#define ZR36057_ISR             0x03c  /* Interrupt Status Register */
-#define ZR36057_ISR_GIRQ1               BIT(30)
-#define ZR36057_ISR_GIRQ0               BIT(29)
-#define ZR36057_ISR_COD_REP_IRQ         BIT(28)
-#define ZR36057_ISR_JPEG_REP_IRQ        BIT(27)
-
-#define ZR36057_ICR             0x040  /* Interrupt Control Register */
-#define ZR36057_ICR_GIRQ1               BIT(30)
-#define ZR36057_ICR_GIRQ0               BIT(29)
-#define ZR36057_ICR_COD_REP_IRQ         BIT(28)
-#define ZR36057_ICR_JPEG_REP_IRQ        BIT(27)
-#define ZR36057_ICR_INT_PIN_EN          BIT(24)
-
-#define ZR36057_I2CBR           0x044  /* I2C Bus Register */
-#define ZR36057_I2CBR_SDA              BIT(1)
-#define ZR36057_I2CBR_SCL              BIT(0)
-
-#define ZR36057_JMC             0x100  /* JPEG Mode and Control */
-#define ZR36057_JMC_JPG                 BIT(31)
-#define ZR36057_JMC_JPG_EXP_MODE        (0 << 29)
-#define ZR36057_JMC_JPG_CMP_MODE        BIT(29)
-#define ZR36057_JMC_MJPG_EXP_MODE       (2 << 29)
-#define ZR36057_JMC_MJPG_CMP_MODE       (3 << 29)
-#define ZR36057_JMC_RTBUSY_FB           BIT(6)
-#define ZR36057_JMC_GO_EN               BIT(5)
-#define ZR36057_JMC_SYNC_MSTR           BIT(4)
-#define ZR36057_JMC_FLD_PER_BUFF        BIT(3)
-#define ZR36057_JMC_VFIFO_FB            BIT(2)
-#define ZR36057_JMC_CFIFO_FB            BIT(1)
-#define ZR36057_JMC_STLL_LIT_ENDIAN     BIT(0)
-
-#define ZR36057_JPC             0x104  /* JPEG Process Control */
-#define ZR36057_JPC_P_RESET             BIT(7)
-#define ZR36057_JPC_COD_TRNS_EN         BIT(5)
-#define ZR36057_JPC_ACTIVE              BIT(0)
-
-#define ZR36057_VSP             0x108  /* Vertical Sync Parameters */
-#define ZR36057_VSP_VSYNC_SIZE          16
-#define ZR36057_VSP_FRM_TOT             0
-
-#define ZR36057_HSP             0x10c  /* Horizontal Sync Parameters */
-#define ZR36057_HSP_HSYNC_START         16
-#define ZR36057_HSP_LINE_TOT            0
-
-#define ZR36057_FHAP            0x110  /* Field Horizontal Active Portion */
-#define ZR36057_FHAP_NAX                16
-#define ZR36057_FHAP_PAX                0
-
-#define ZR36057_FVAP            0x114  /* Field Vertical Active Portion */
-#define ZR36057_FVAP_NAY                16
-#define ZR36057_FVAP_PAY                0
-
-#define ZR36057_FPP             0x118  /* Field Process Parameters */
-#define ZR36057_FPP_ODD_EVEN            BIT(0)
-
-#define ZR36057_JCBA            0x11c  /* JPEG Code Base Address */
-
-#define ZR36057_JCFT            0x120  /* JPEG Code FIFO Threshold */
-
-#define ZR36057_JCGI            0x124  /* JPEG Codec Guest ID */
-#define ZR36057_JCGI_JPE_GUEST_ID       4
-#define ZR36057_JCGI_JPE_GUEST_REG      0
-
-#define ZR36057_GCR2            0x12c  /* GuestBus Control Register (2) */
-
-#define ZR36057_POR             0x200  /* Post Office Register */
-#define ZR36057_POR_PO_PEN              BIT(25)
-#define ZR36057_POR_PO_TIME             BIT(24)
-#define ZR36057_POR_PO_DIR              BIT(23)
-
-#define ZR36057_STR             0x300  /* "Still" Transfer Register */
-
-#endif
 
+++ /dev/null
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Zoran ZR36060 basic configuration functions
- *
- * Copyright (C) 2002 Laurent Pinchart <laurent.pinchart@skynet.be>
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-
-#include <linux/types.h>
-#include <linux/wait.h>
-
-/* I/O commands, error codes */
-#include <linux/io.h>
-
-/* headerfile of this module */
-#include "zr36060.h"
-
-/* codec io API */
-#include "videocodec.h"
-
-/* it doesn't make sense to have more than 20 or so, just to prevent some unwanted loops */
-#define MAX_CODECS 20
-
-/* amount of chips attached via this driver */
-static int zr36060_codecs;
-
-static bool low_bitrate;
-module_param(low_bitrate, bool, 0);
-MODULE_PARM_DESC(low_bitrate, "Buz compatibility option, halves bitrate");
-
-/* =========================================================================
- * Local hardware I/O functions:
- * read/write via codec layer (registers are located in the master device)
- * =========================================================================
- */
-
-static u8 zr36060_read(struct zr36060 *ptr, u16 reg)
-{
-       u8 value = 0;
-       struct zoran *zr = videocodec_to_zoran(ptr->codec);
-
-       // just in case something is wrong...
-       if (ptr->codec->master_data->readreg)
-               value = (ptr->codec->master_data->readreg(ptr->codec, reg)) & 0xff;
-       else
-               zrdev_err(zr, "%s: invalid I/O setup, nothing read!\n", ptr->name);
-
-       return value;
-}
-
-static void zr36060_write(struct zr36060 *ptr, u16 reg, u8 value)
-{
-       struct zoran *zr = videocodec_to_zoran(ptr->codec);
-
-       zrdev_dbg(zr, "0x%02x @0x%04x\n", value, reg);
-
-       // just in case something is wrong...
-       if (ptr->codec->master_data->writereg)
-               ptr->codec->master_data->writereg(ptr->codec, reg, value);
-       else
-               zrdev_err(zr, "%s: invalid I/O setup, nothing written!\n", ptr->name);
-}
-
-/* =========================================================================
- * Local helper function:
- * status read
- * =========================================================================
- */
-
-/* status is kept in datastructure */
-static u8 zr36060_read_status(struct zr36060 *ptr)
-{
-       ptr->status = zr36060_read(ptr, ZR060_CFSR);
-
-       zr36060_read(ptr, 0);
-       return ptr->status;
-}
-
-/* scale factor is kept in datastructure */
-static u16 zr36060_read_scalefactor(struct zr36060 *ptr)
-{
-       ptr->scalefact = (zr36060_read(ptr, ZR060_SF_HI) << 8) |
-                        (zr36060_read(ptr, ZR060_SF_LO) & 0xFF);
-
-       /* leave 0 selected for an eventually GO from master */
-       zr36060_read(ptr, 0);
-       return ptr->scalefact;
-}
-
-/* wait if codec is ready to proceed (end of processing) or time is over */
-static void zr36060_wait_end(struct zr36060 *ptr)
-{
-       struct zoran *zr = videocodec_to_zoran(ptr->codec);
-       int i = 0;
-
-       while (zr36060_read_status(ptr) & ZR060_CFSR_BUSY) {
-               udelay(1);
-               if (i++ > 200000) {     // 200ms, there is for sure something wrong!!!
-                       zrdev_dbg(zr,
-                                 "%s: timeout at wait_end (last status: 0x%02x)\n",
-                                 ptr->name, ptr->status);
-                       break;
-               }
-       }
-}
-
-/* Basic test of "connectivity", writes/reads to/from memory the SOF marker */
-static int zr36060_basic_test(struct zr36060 *ptr)
-{
-       struct zoran *zr = videocodec_to_zoran(ptr->codec);
-
-       if ((zr36060_read(ptr, ZR060_IDR_DEV) != 0x33) &&
-           (zr36060_read(ptr, ZR060_IDR_REV) != 0x01)) {
-               zrdev_err(zr, "%s: attach failed, can't connect to jpeg processor!\n", ptr->name);
-               return -ENXIO;
-       }
-
-       zr36060_wait_end(ptr);
-       if (ptr->status & ZR060_CFSR_BUSY) {
-               zrdev_err(zr, "%s: attach failed, jpeg processor failed (end flag)!\n", ptr->name);
-               return -EBUSY;
-       }
-
-       return 0;               /* looks good! */
-}
-
-/* simple loop for pushing the init datasets */
-static int zr36060_pushit(struct zr36060 *ptr, u16 startreg, u16 len, const char *data)
-{
-       struct zoran *zr = videocodec_to_zoran(ptr->codec);
-       int i = 0;
-
-       zrdev_dbg(zr, "%s: write data block to 0x%04x (len=%d)\n", ptr->name,
-                 startreg, len);
-       while (i < len)
-               zr36060_write(ptr, startreg++, data[i++]);
-
-       return i;
-}
-
-/* =========================================================================
- * Basic datasets:
- * jpeg baseline setup data (you find it on lots places in internet, or just
- * extract it from any regular .jpg image...)
- *
- * Could be variable, but until it's not needed it they are just fixed to save
- * memory. Otherwise expand zr36060 structure with arrays, push the values to
- * it and initialize from there, as e.g. the linux zr36057/60 driver does it.
- * =========================================================================
- */
-static const char zr36060_dqt[0x86] = {
-       0xff, 0xdb,             //Marker: DQT
-       0x00, 0x84,             //Length: 2*65+2
-       0x00,                   //Pq,Tq first table
-       0x10, 0x0b, 0x0c, 0x0e, 0x0c, 0x0a, 0x10, 0x0e,
-       0x0d, 0x0e, 0x12, 0x11, 0x10, 0x13, 0x18, 0x28,
-       0x1a, 0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25,
-       0x1d, 0x28, 0x3a, 0x33, 0x3d, 0x3c, 0x39, 0x33,
-       0x38, 0x37, 0x40, 0x48, 0x5c, 0x4e, 0x40, 0x44,
-       0x57, 0x45, 0x37, 0x38, 0x50, 0x6d, 0x51, 0x57,
-       0x5f, 0x62, 0x67, 0x68, 0x67, 0x3e, 0x4d, 0x71,
-       0x79, 0x70, 0x64, 0x78, 0x5c, 0x65, 0x67, 0x63,
-       0x01,                   //Pq,Tq second table
-       0x11, 0x12, 0x12, 0x18, 0x15, 0x18, 0x2f, 0x1a,
-       0x1a, 0x2f, 0x63, 0x42, 0x38, 0x42, 0x63, 0x63,
-       0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
-       0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
-       0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
-       0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
-       0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
-       0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63
-};
-
-static const char zr36060_dht[0x1a4] = {
-       0xff, 0xc4,             //Marker: DHT
-       0x01, 0xa2,             //Length: 2*AC, 2*DC
-       0x00,                   //DC first table
-       0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01,
-       0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
-       0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,
-       0x01,                   //DC second table
-       0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-       0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
-       0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,
-       0x10,                   //AC first table
-       0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03,
-       0x05, 0x05, 0x04, 0x04, 0x00, 0x00,
-       0x01, 0x7D, 0x01, 0x02, 0x03, 0x00, 0x04, 0x11,
-       0x05, 0x12, 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61,
-       0x07, 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xA1,
-       0x08, 0x23, 0x42, 0xB1, 0xC1, 0x15, 0x52, 0xD1, 0xF0, 0x24,
-       0x33, 0x62, 0x72, 0x82, 0x09, 0x0A, 0x16, 0x17,
-       0x18, 0x19, 0x1A, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x34,
-       0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x43, 0x44,
-       0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56,
-       0x57, 0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66,
-       0x67, 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
-       0x79, 0x7A, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88,
-       0x89, 0x8A, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99,
-       0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8,
-       0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9,
-       0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8,
-       0xC9, 0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9,
-       0xDA, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
-       0xE8, 0xE9, 0xEA, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
-       0xF8, 0xF9, 0xFA,
-       0x11,                   //AC second table
-       0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04,
-       0x07, 0x05, 0x04, 0x04, 0x00, 0x01,
-       0x02, 0x77, 0x00, 0x01, 0x02, 0x03, 0x11, 0x04,
-       0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
-       0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
-       0xA1, 0xB1, 0xC1, 0x09, 0x23, 0x33, 0x52, 0xF0, 0x15, 0x62,
-       0x72, 0xD1, 0x0A, 0x16, 0x24, 0x34, 0xE1, 0x25,
-       0xF1, 0x17, 0x18, 0x19, 0x1A, 0x26, 0x27, 0x28, 0x29, 0x2A,
-       0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x43, 0x44,
-       0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56,
-       0x57, 0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66,
-       0x67, 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
-       0x79, 0x7A, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
-       0x88, 0x89, 0x8A, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
-       0x99, 0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7,
-       0xA8, 0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8,
-       0xB9, 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
-       0xC8, 0xC9, 0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8,
-       0xD9, 0xDA, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
-       0xE8, 0xE9, 0xEA, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8,
-       0xF9, 0xFA
-};
-
-/* jpeg baseline setup, this is just fixed in this driver (YUV pictures) */
-#define NO_OF_COMPONENTS          0x3  //Y,U,V
-#define BASELINE_PRECISION        0x8  //MCU size (?)
-static const char zr36060_tq[8] = { 0, 1, 1, 0, 0, 0, 0, 0 };  //table idx's QT
-static const char zr36060_td[8] = { 0, 1, 1, 0, 0, 0, 0, 0 };  //table idx's DC
-static const char zr36060_ta[8] = { 0, 1, 1, 0, 0, 0, 0, 0 };  //table idx's AC
-
-/* horizontal 422 decimation setup (maybe we support 411 or so later, too) */
-static const char zr36060_decimation_h[8] = { 2, 1, 1, 0, 0, 0, 0, 0 };
-static const char zr36060_decimation_v[8] = { 1, 1, 1, 0, 0, 0, 0, 0 };
-
-/*
- * SOF (start of frame) segment depends on width, height and sampling ratio
- * of each color component
- */
-static int zr36060_set_sof(struct zr36060 *ptr)
-{
-       struct zoran *zr = videocodec_to_zoran(ptr->codec);
-       char sof_data[34];      // max. size of register set
-       int i;
-
-       zrdev_dbg(zr, "%s: write SOF (%dx%d, %d components)\n", ptr->name,
-                 ptr->width, ptr->height, NO_OF_COMPONENTS);
-       sof_data[0] = 0xff;
-       sof_data[1] = 0xc0;
-       sof_data[2] = 0x00;
-       sof_data[3] = (3 * NO_OF_COMPONENTS) + 8;
-       sof_data[4] = BASELINE_PRECISION;       // only '8' possible with zr36060
-       sof_data[5] = (ptr->height) >> 8;
-       sof_data[6] = (ptr->height) & 0xff;
-       sof_data[7] = (ptr->width) >> 8;
-       sof_data[8] = (ptr->width) & 0xff;
-       sof_data[9] = NO_OF_COMPONENTS;
-       for (i = 0; i < NO_OF_COMPONENTS; i++) {
-               sof_data[10 + (i * 3)] = i;     // index identifier
-               sof_data[11 + (i * 3)] = (ptr->h_samp_ratio[i] << 4) |
-                                        (ptr->v_samp_ratio[i]); // sampling ratios
-               sof_data[12 + (i * 3)] = zr36060_tq[i]; // Q table selection
-       }
-       return zr36060_pushit(ptr, ZR060_SOF_IDX,
-                             (3 * NO_OF_COMPONENTS) + 10, sof_data);
-}
-
-/* SOS (start of scan) segment depends on the used scan components of each color component */
-static int zr36060_set_sos(struct zr36060 *ptr)
-{
-       struct zoran *zr = videocodec_to_zoran(ptr->codec);
-       char sos_data[16];      // max. size of register set
-       int i;
-
-       zrdev_dbg(zr, "%s: write SOS\n", ptr->name);
-       sos_data[0] = 0xff;
-       sos_data[1] = 0xda;
-       sos_data[2] = 0x00;
-       sos_data[3] = 2 + 1 + (2 * NO_OF_COMPONENTS) + 3;
-       sos_data[4] = NO_OF_COMPONENTS;
-       for (i = 0; i < NO_OF_COMPONENTS; i++) {
-               sos_data[5 + (i * 2)] = i;      // index
-               sos_data[6 + (i * 2)] = (zr36060_td[i] << 4) |
-                                       zr36060_ta[i]; // AC/DC tbl.sel.
-       }
-       sos_data[2 + 1 + (2 * NO_OF_COMPONENTS) + 2] = 00;      // scan start
-       sos_data[2 + 1 + (2 * NO_OF_COMPONENTS) + 3] = 0x3f;
-       sos_data[2 + 1 + (2 * NO_OF_COMPONENTS) + 4] = 00;
-       return zr36060_pushit(ptr, ZR060_SOS_IDX,
-                             4 + 1 + (2 * NO_OF_COMPONENTS) + 3,
-                             sos_data);
-}
-
-/* DRI (define restart interval) */
-static int zr36060_set_dri(struct zr36060 *ptr)
-{
-       struct zoran *zr = videocodec_to_zoran(ptr->codec);
-       char dri_data[6];       // max. size of register set
-
-       zrdev_dbg(zr, "%s: write DRI\n", ptr->name);
-       dri_data[0] = 0xff;
-       dri_data[1] = 0xdd;
-       dri_data[2] = 0x00;
-       dri_data[3] = 0x04;
-       dri_data[4] = (ptr->dri) >> 8;
-       dri_data[5] = (ptr->dri) & 0xff;
-       return zr36060_pushit(ptr, ZR060_DRI_IDX, 6, dri_data);
-}
-
-/* Setup compression/decompression of Zoran's JPEG processor ( see also zoran 36060 manual )
- * ... sorry for the spaghetti code ...
- */
-static void zr36060_init(struct zr36060 *ptr)
-{
-       int sum = 0;
-       long bitcnt, tmp;
-       struct zoran *zr = videocodec_to_zoran(ptr->codec);
-
-       if (ptr->mode == CODEC_DO_COMPRESSION) {
-               zrdev_dbg(zr, "%s: COMPRESSION SETUP\n", ptr->name);
-
-               zr36060_write(ptr, ZR060_LOAD, ZR060_LOAD_SYNC_RST);
-
-               /* 060 communicates with 067 in master mode */
-               zr36060_write(ptr, ZR060_CIR, ZR060_CIR_CODE_MSTR);
-
-               /* Compression with or without variable scale factor */
-               /*FIXME: What about ptr->bitrate_ctrl? */
-               zr36060_write(ptr, ZR060_CMR, ZR060_CMR_COMP | ZR060_CMR_PASS2 | ZR060_CMR_BRB);
-
-               /* Must be zero */
-               zr36060_write(ptr, ZR060_MBZ, 0x00);
-               zr36060_write(ptr, ZR060_TCR_HI, 0x00);
-               zr36060_write(ptr, ZR060_TCR_LO, 0x00);
-
-               /* Disable all IRQs - no DataErr means autoreset */
-               zr36060_write(ptr, ZR060_IMR, 0);
-
-               /* volume control settings */
-               zr36060_write(ptr, ZR060_SF_HI, ptr->scalefact >> 8);
-               zr36060_write(ptr, ZR060_SF_LO, ptr->scalefact & 0xff);
-
-               zr36060_write(ptr, ZR060_AF_HI, 0xff);
-               zr36060_write(ptr, ZR060_AF_M, 0xff);
-               zr36060_write(ptr, ZR060_AF_LO, 0xff);
-
-               /* setup the variable jpeg tables */
-               sum += zr36060_set_sof(ptr);
-               sum += zr36060_set_sos(ptr);
-               sum += zr36060_set_dri(ptr);
-
-/* setup the fixed jpeg tables - maybe variable, though - (see table init section above) */
-               sum += zr36060_pushit(ptr, ZR060_DQT_IDX, sizeof(zr36060_dqt), zr36060_dqt);
-               sum += zr36060_pushit(ptr, ZR060_DHT_IDX, sizeof(zr36060_dht), zr36060_dht);
-               zr36060_write(ptr, ZR060_APP_IDX, 0xff);
-               zr36060_write(ptr, ZR060_APP_IDX + 1, 0xe0 + ptr->app.appn);
-               zr36060_write(ptr, ZR060_APP_IDX + 2, 0x00);
-               zr36060_write(ptr, ZR060_APP_IDX + 3, ptr->app.len + 2);
-               sum += zr36060_pushit(ptr, ZR060_APP_IDX + 4, 60, ptr->app.data) + 4;
-               zr36060_write(ptr, ZR060_COM_IDX, 0xff);
-               zr36060_write(ptr, ZR060_COM_IDX + 1, 0xfe);
-               zr36060_write(ptr, ZR060_COM_IDX + 2, 0x00);
-               zr36060_write(ptr, ZR060_COM_IDX + 3, ptr->com.len + 2);
-               sum += zr36060_pushit(ptr, ZR060_COM_IDX + 4, 60, ptr->com.data) + 4;
-
-               /* setup misc. data for compression (target code sizes) */
-
-               /* size of compressed code to reach without header data */
-               sum = ptr->real_code_vol - sum;
-               bitcnt = sum << 3;      /* need the size in bits */
-
-               tmp = bitcnt >> 16;
-               zrdev_dbg(zr,
-                         "%s: code: csize=%d, tot=%d, bit=%ld, highbits=%ld\n",
-                         ptr->name, sum, ptr->real_code_vol, bitcnt, tmp);
-               zr36060_write(ptr, ZR060_TCV_NET_HI, tmp >> 8);
-               zr36060_write(ptr, ZR060_TCV_NET_MH, tmp & 0xff);
-               tmp = bitcnt & 0xffff;
-               zr36060_write(ptr, ZR060_TCV_NET_ML, tmp >> 8);
-               zr36060_write(ptr, ZR060_TCV_NET_LO, tmp & 0xff);
-
-               bitcnt -= bitcnt >> 7;  // bits without stuffing
-               bitcnt -= ((bitcnt * 5) >> 6);  // bits without eob
-
-               tmp = bitcnt >> 16;
-               zrdev_dbg(zr, "%s: code: nettobit=%ld, highnettobits=%ld\n",
-                         ptr->name, bitcnt, tmp);
-               zr36060_write(ptr, ZR060_TCV_DATA_HI, tmp >> 8);
-               zr36060_write(ptr, ZR060_TCV_DATA_MH, tmp & 0xff);
-               tmp = bitcnt & 0xffff;
-               zr36060_write(ptr, ZR060_TCV_DATA_ML, tmp >> 8);
-               zr36060_write(ptr, ZR060_TCV_DATA_LO, tmp & 0xff);
-
-               /* JPEG markers to be included in the compressed stream */
-               zr36060_write(ptr, ZR060_MER,
-                             ZR060_MER_DQT | ZR060_MER_DHT |
-                             ((ptr->com.len > 0) ? ZR060_MER_COM : 0) |
-                             ((ptr->app.len > 0) ? ZR060_MER_APP : 0));
-
-               /* Setup the Video Frontend */
-               /* Limit pixel range to 16..235 as per CCIR-601 */
-               zr36060_write(ptr, ZR060_VCR, ZR060_VCR_RANGE);
-
-       } else {
-               zrdev_dbg(zr, "%s: EXPANSION SETUP\n", ptr->name);
-
-               zr36060_write(ptr, ZR060_LOAD, ZR060_LOAD_SYNC_RST);
-
-               /* 060 communicates with 067 in master mode */
-               zr36060_write(ptr, ZR060_CIR, ZR060_CIR_CODE_MSTR);
-
-               /* Decompression */
-               zr36060_write(ptr, ZR060_CMR, 0);
-
-               /* Must be zero */
-               zr36060_write(ptr, ZR060_MBZ, 0x00);
-               zr36060_write(ptr, ZR060_TCR_HI, 0x00);
-               zr36060_write(ptr, ZR060_TCR_LO, 0x00);
-
-               /* Disable all IRQs - no DataErr means autoreset */
-               zr36060_write(ptr, ZR060_IMR, 0);
-
-               /* setup misc. data for expansion */
-               zr36060_write(ptr, ZR060_MER, 0);
-
-/* setup the fixed jpeg tables - maybe variable, though - (see table init section above) */
-               zr36060_pushit(ptr, ZR060_DHT_IDX, sizeof(zr36060_dht), zr36060_dht);
-
-               /* Setup the Video Frontend */
-               //zr36060_write(ptr, ZR060_VCR, ZR060_VCR_FI_EXT);
-               //this doesn't seem right and doesn't work...
-               zr36060_write(ptr, ZR060_VCR, ZR060_VCR_RANGE);
-       }
-
-       /* Load the tables */
-       zr36060_write(ptr, ZR060_LOAD, ZR060_LOAD_SYNC_RST | ZR060_LOAD_LOAD);
-       zr36060_wait_end(ptr);
-       zrdev_dbg(zr, "%s: Status after table preload: 0x%02x\n",
-                 ptr->name, ptr->status);
-
-       if (ptr->status & ZR060_CFSR_BUSY) {
-               zrdev_err(zr, "%s: init aborted!\n", ptr->name);
-               return;         // something is wrong, its timed out!!!!
-       }
-}
-
-/* =========================================================================
- * CODEC API FUNCTIONS
- * this functions are accessed by the master via the API structure
- * =========================================================================
- */
-
-/* set compressiion/expansion mode and launches codec -
- * this should be the last call from the master before starting processing
- */
-static int zr36060_set_mode(struct videocodec *codec, int mode)
-{
-       struct zr36060 *ptr = (struct zr36060 *)codec->data;
-       struct zoran *zr = videocodec_to_zoran(codec);
-
-       zrdev_dbg(zr, "%s: set_mode %d call\n", ptr->name, mode);
-
-       if (mode != CODEC_DO_EXPANSION && mode != CODEC_DO_COMPRESSION)
-               return -EINVAL;
-
-       ptr->mode = mode;
-       zr36060_init(ptr);
-
-       return 0;
-}
-
-/* set picture size (norm is ignored as the codec doesn't know about it) */
-static int zr36060_set_video(struct videocodec *codec, const struct tvnorm *norm,
-                            struct vfe_settings *cap, struct vfe_polarity *pol)
-{
-       struct zr36060 *ptr = (struct zr36060 *)codec->data;
-       struct zoran *zr = videocodec_to_zoran(codec);
-       u32 reg;
-       int size;
-
-       zrdev_dbg(zr, "%s: set_video %d/%d-%dx%d (%%%d) call\n", ptr->name,
-                 cap->x, cap->y, cap->width, cap->height, cap->decimation);
-
-       /* if () return -EINVAL;
-        * trust the master driver that it knows what it does - so
-        * we allow invalid startx/y and norm for now ...
-        */
-       ptr->width = cap->width / (cap->decimation & 0xff);
-       ptr->height = cap->height / (cap->decimation >> 8);
-
-       zr36060_write(ptr, ZR060_LOAD, ZR060_LOAD_SYNC_RST);
-
-       /* Note that VSPol/HSPol bits in zr36060 have the opposite
-        * meaning of their zr360x7 counterparts with the same names
-        * N.b. for VSPol this is only true if FIVEdge = 0 (default,
-        * left unchanged here - in accordance with datasheet).
-        */
-       reg = (!pol->vsync_pol ? ZR060_VPR_VS_POL : 0)
-           | (!pol->hsync_pol ? ZR060_VPR_HS_POL : 0)
-           | (pol->field_pol ? ZR060_VPR_FI_POL : 0)
-           | (pol->blank_pol ? ZR060_VPR_BL_POL : 0)
-           | (pol->subimg_pol ? ZR060_VPR_S_IMG_POL : 0)
-           | (pol->poe_pol ? ZR060_VPR_POE_POL : 0)
-           | (pol->pvalid_pol ? ZR060_VPR_P_VAL_POL : 0)
-           | (pol->vclk_pol ? ZR060_VPR_VCLK_POL : 0);
-       zr36060_write(ptr, ZR060_VPR, reg);
-
-       reg = 0;
-       switch (cap->decimation & 0xff) {
-       default:
-       case 1:
-               break;
-
-       case 2:
-               reg |= ZR060_SR_H_SCALE2;
-               break;
-
-       case 4:
-               reg |= ZR060_SR_H_SCALE4;
-               break;
-       }
-
-       switch (cap->decimation >> 8) {
-       default:
-       case 1:
-               break;
-
-       case 2:
-               reg |= ZR060_SR_V_SCALE;
-               break;
-       }
-       zr36060_write(ptr, ZR060_SR, reg);
-
-       zr36060_write(ptr, ZR060_BCR_Y, 0x00);
-       zr36060_write(ptr, ZR060_BCR_U, 0x80);
-       zr36060_write(ptr, ZR060_BCR_V, 0x80);
-
-       /* sync generator */
-
-       reg = norm->ht - 1;     /* Vtotal */
-       zr36060_write(ptr, ZR060_SGR_VTOTAL_HI, (reg >> 8) & 0xff);
-       zr36060_write(ptr, ZR060_SGR_VTOTAL_LO, (reg >> 0) & 0xff);
-
-       reg = norm->wt - 1;     /* Htotal */
-       zr36060_write(ptr, ZR060_SGR_HTOTAL_HI, (reg >> 8) & 0xff);
-       zr36060_write(ptr, ZR060_SGR_HTOTAL_LO, (reg >> 0) & 0xff);
-
-       reg = 6 - 1;            /* VsyncSize */
-       zr36060_write(ptr, ZR060_SGR_VSYNC, reg);
-
-       reg = 68;
-       zr36060_write(ptr, ZR060_SGR_HSYNC, reg);
-
-       reg = norm->v_start - 1;        /* BVstart */
-       zr36060_write(ptr, ZR060_SGR_BVSTART, reg);
-
-       reg += norm->ha / 2;    /* BVend */
-       zr36060_write(ptr, ZR060_SGR_BVEND_HI, (reg >> 8) & 0xff);
-       zr36060_write(ptr, ZR060_SGR_BVEND_LO, (reg >> 0) & 0xff);
-
-       reg = norm->h_start - 1;        /* BHstart */
-       zr36060_write(ptr, ZR060_SGR_BHSTART, reg);
-
-       reg += norm->wa;        /* BHend */
-       zr36060_write(ptr, ZR060_SGR_BHEND_HI, (reg >> 8) & 0xff);
-       zr36060_write(ptr, ZR060_SGR_BHEND_LO, (reg >> 0) & 0xff);
-
-       /* active area */
-       reg = cap->y + norm->v_start;   /* Vstart */
-       zr36060_write(ptr, ZR060_AAR_VSTART_HI, (reg >> 8) & 0xff);
-       zr36060_write(ptr, ZR060_AAR_VSTART_LO, (reg >> 0) & 0xff);
-
-       reg += cap->height;     /* Vend */
-       zr36060_write(ptr, ZR060_AAR_VEND_HI, (reg >> 8) & 0xff);
-       zr36060_write(ptr, ZR060_AAR_VEND_LO, (reg >> 0) & 0xff);
-
-       reg = cap->x + norm->h_start;   /* Hstart */
-       zr36060_write(ptr, ZR060_AAR_HSTART_HI, (reg >> 8) & 0xff);
-       zr36060_write(ptr, ZR060_AAR_HSTART_LO, (reg >> 0) & 0xff);
-
-       reg += cap->width;      /* Hend */
-       zr36060_write(ptr, ZR060_AAR_HEND_HI, (reg >> 8) & 0xff);
-       zr36060_write(ptr, ZR060_AAR_HEND_LO, (reg >> 0) & 0xff);
-
-       /* subimage area */
-       reg = norm->v_start - 4;        /* SVstart */
-       zr36060_write(ptr, ZR060_SWR_VSTART_HI, (reg >> 8) & 0xff);
-       zr36060_write(ptr, ZR060_SWR_VSTART_LO, (reg >> 0) & 0xff);
-
-       reg += norm->ha / 2 + 8;        /* SVend */
-       zr36060_write(ptr, ZR060_SWR_VEND_HI, (reg >> 8) & 0xff);
-       zr36060_write(ptr, ZR060_SWR_VEND_LO, (reg >> 0) & 0xff);
-
-       reg = norm->h_start /*+ 64 */  - 4;     /* SHstart */
-       zr36060_write(ptr, ZR060_SWR_HSTART_HI, (reg >> 8) & 0xff);
-       zr36060_write(ptr, ZR060_SWR_HSTART_LO, (reg >> 0) & 0xff);
-
-       reg += norm->wa + 8;    /* SHend */
-       zr36060_write(ptr, ZR060_SWR_HEND_HI, (reg >> 8) & 0xff);
-       zr36060_write(ptr, ZR060_SWR_HEND_LO, (reg >> 0) & 0xff);
-
-       size = ptr->width * ptr->height;
-       /* Target compressed field size in bits: */
-       size = size * 16;       /* uncompressed size in bits */
-       /* (Ronald) by default, quality = 100 is a compression
-        * ratio 1:2. Setting low_bitrate (insmod option) sets
-        * it to 1:4 (instead of 1:2, zr36060 max) as limit because the
-        * buz can't handle more at decimation=1... Use low_bitrate if
-        * you have a Buz, unless you know what you're doing
-        */
-       size = size * cap->quality / (low_bitrate ? 400 : 200);
-       /* Lower limit (arbitrary, 1 KB) */
-       if (size < 8192)
-               size = 8192;
-       /* Upper limit: 7/8 of the code buffers */
-       if (size > ptr->total_code_vol * 7)
-               size = ptr->total_code_vol * 7;
-
-       ptr->real_code_vol = size >> 3; /* in bytes */
-
-       /* the MBCVR is the *maximum* block volume, according to the
-        * JPEG ISO specs, this shouldn't be used, since that allows
-        * for the best encoding quality. So set it to it's max value
-        */
-       reg = ptr->max_block_vol;
-       zr36060_write(ptr, ZR060_MBCVR, reg);
-
-       return 0;
-}
-
-/* additional control functions */
-static int zr36060_control(struct videocodec *codec, int type, int size, void *data)
-{
-       struct zr36060 *ptr = (struct zr36060 *)codec->data;
-       struct zoran *zr = videocodec_to_zoran(codec);
-       int *ival = (int *)data;
-
-       zrdev_dbg(zr, "%s: control %d call with %d byte\n", ptr->name, type,
-                 size);
-
-       switch (type) {
-       case CODEC_G_STATUS:    /* get last status */
-               if (size != sizeof(int))
-                       return -EFAULT;
-               zr36060_read_status(ptr);
-               *ival = ptr->status;
-               break;
-
-       case CODEC_G_CODEC_MODE:
-               if (size != sizeof(int))
-                       return -EFAULT;
-               *ival = CODEC_MODE_BJPG;
-               break;
-
-       case CODEC_S_CODEC_MODE:
-               if (size != sizeof(int))
-                       return -EFAULT;
-               if (*ival != CODEC_MODE_BJPG)
-                       return -EINVAL;
-               /* not needed, do nothing */
-               return 0;
-
-       case CODEC_G_VFE:
-       case CODEC_S_VFE:
-               /* not needed, do nothing */
-               return 0;
-
-       case CODEC_S_MMAP:
-               /* not available, give an error */
-               return -ENXIO;
-
-       case CODEC_G_JPEG_TDS_BYTE:     /* get target volume in byte */
-               if (size != sizeof(int))
-                       return -EFAULT;
-               *ival = ptr->total_code_vol;
-               break;
-
-       case CODEC_S_JPEG_TDS_BYTE:     /* get target volume in byte */
-               if (size != sizeof(int))
-                       return -EFAULT;
-               ptr->total_code_vol = *ival;
-               ptr->real_code_vol = (ptr->total_code_vol * 6) >> 3;
-               break;
-
-       case CODEC_G_JPEG_SCALE:        /* get scaling factor */
-               if (size != sizeof(int))
-                       return -EFAULT;
-               *ival = zr36060_read_scalefactor(ptr);
-               break;
-
-       case CODEC_S_JPEG_SCALE:        /* set scaling factor */
-               if (size != sizeof(int))
-                       return -EFAULT;
-               ptr->scalefact = *ival;
-               break;
-
-       case CODEC_G_JPEG_APP_DATA: {   /* get appn marker data */
-               struct jpeg_app_marker *app = data;
-
-               if (size != sizeof(struct jpeg_app_marker))
-                       return -EFAULT;
-
-               *app = ptr->app;
-               break;
-       }
-
-       case CODEC_S_JPEG_APP_DATA: {   /* set appn marker data */
-               struct jpeg_app_marker *app = data;
-
-               if (size != sizeof(struct jpeg_app_marker))
-                       return -EFAULT;
-
-               ptr->app = *app;
-               break;
-       }
-
-       case CODEC_G_JPEG_COM_DATA: {   /* get comment marker data */
-               struct jpeg_com_marker *com = data;
-
-               if (size != sizeof(struct jpeg_com_marker))
-                       return -EFAULT;
-
-               *com = ptr->com;
-               break;
-       }
-
-       case CODEC_S_JPEG_COM_DATA: {   /* set comment marker data */
-               struct jpeg_com_marker *com = data;
-
-               if (size != sizeof(struct jpeg_com_marker))
-                       return -EFAULT;
-
-               ptr->com = *com;
-               break;
-       }
-
-       default:
-               return -EINVAL;
-       }
-
-       return size;
-}
-
-/* =========================================================================
- * Exit and unregister function:
- * Deinitializes Zoran's JPEG processor
- * =========================================================================
- */
-static int zr36060_unset(struct videocodec *codec)
-{
-       struct zr36060 *ptr = codec->data;
-       struct zoran *zr = videocodec_to_zoran(codec);
-
-       if (ptr) {
-               /* do wee need some codec deinit here, too ???? */
-
-               zrdev_dbg(zr, "%s: finished codec #%d\n", ptr->name, ptr->num);
-               kfree(ptr);
-               codec->data = NULL;
-
-               zr36060_codecs--;
-               return 0;
-       }
-
-       return -EFAULT;
-}
-
-/* =========================================================================
- * Setup and registry function:
- * Initializes Zoran's JPEG processor
- * Also sets pixel size, average code size, mode (compr./decompr.)
- * (the given size is determined by the processor with the video interface)
- * =========================================================================
- */
-static int zr36060_setup(struct videocodec *codec)
-{
-       struct zr36060 *ptr;
-       struct zoran *zr = videocodec_to_zoran(codec);
-       int res;
-
-       zrdev_dbg(zr, "zr36060: initializing MJPEG subsystem #%d.\n",
-                 zr36060_codecs);
-
-       if (zr36060_codecs == MAX_CODECS) {
-               zrdev_err(zr, "zr36060: Can't attach more codecs!\n");
-               return -ENOSPC;
-       }
-       //mem structure init
-       ptr = kzalloc(sizeof(*ptr), GFP_KERNEL);
-       codec->data = ptr;
-       if (!ptr)
-               return -ENOMEM;
-
-       snprintf(ptr->name, sizeof(ptr->name), "zr36060[%d]", zr36060_codecs);
-       ptr->num = zr36060_codecs++;
-       ptr->codec = codec;
-
-       //testing
-       res = zr36060_basic_test(ptr);
-       if (res < 0) {
-               zr36060_unset(codec);
-               return res;
-       }
-       //final setup
-       memcpy(ptr->h_samp_ratio, zr36060_decimation_h, 8);
-       memcpy(ptr->v_samp_ratio, zr36060_decimation_v, 8);
-
-       ptr->bitrate_ctrl = 0;  /* 0 or 1 - fixed file size flag (what is the difference?) */
-       ptr->mode = CODEC_DO_COMPRESSION;
-       ptr->width = 384;
-       ptr->height = 288;
-       ptr->total_code_vol = 16000;    /* CHECKME */
-       ptr->real_code_vol = (ptr->total_code_vol * 6) >> 3;
-       ptr->max_block_vol = 240;       /* CHECKME, was 120 is 240 */
-       ptr->scalefact = 0x100;
-       ptr->dri = 1;           /* CHECKME, was 8 is 1 */
-
-       /* by default, no COM or APP markers - app should set those */
-       ptr->com.len = 0;
-       ptr->app.appn = 0;
-       ptr->app.len = 0;
-
-       zr36060_init(ptr);
-
-       zrdev_info(zr, "%s: codec attached and running\n", ptr->name);
-
-       return 0;
-}
-
-static const struct videocodec zr36060_codec = {
-       .name = "zr36060",
-       .magic = 0L,            // magic not used
-       .flags =
-           CODEC_FLAG_JPEG | CODEC_FLAG_HARDWARE | CODEC_FLAG_ENCODER |
-           CODEC_FLAG_DECODER | CODEC_FLAG_VFE,
-       .type = CODEC_TYPE_ZR36060,
-       .setup = zr36060_setup, // functionality
-       .unset = zr36060_unset,
-       .set_mode = zr36060_set_mode,
-       .set_video = zr36060_set_video,
-       .control = zr36060_control,
-       // others are not used
-};
-
-int zr36060_init_module(void)
-{
-       zr36060_codecs = 0;
-       return videocodec_register(&zr36060_codec);
-}
-
-void zr36060_cleanup_module(void)
-{
-       if (zr36060_codecs) {
-               pr_debug("zr36060: something's wrong - %d codecs left somehow.\n",
-                        zr36060_codecs);
-       }
-
-       /* however, we can't just stay alive */
-       videocodec_unregister(&zr36060_codec);
-}
 
+++ /dev/null
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * Zoran ZR36060 basic configuration functions - header file
- *
- * Copyright (C) 2002 Laurent Pinchart <laurent.pinchart@skynet.be>
- */
-
-#ifndef ZR36060_H
-#define ZR36060_H
-
-#include "videocodec.h"
-
-/* data stored for each zoran jpeg codec chip */
-struct zr36060 {
-       char name[32];
-       int num;
-       /* io datastructure */
-       struct videocodec *codec;
-       // last coder status
-       __u8 status;
-       // actual coder setup
-       int mode;
-
-       __u16 width;
-       __u16 height;
-
-       __u16 bitrate_ctrl;
-
-       __u32 total_code_vol;
-       __u32 real_code_vol;
-       __u16 max_block_vol;
-
-       __u8 h_samp_ratio[8];
-       __u8 v_samp_ratio[8];
-       __u16 scalefact;
-       __u16 dri;
-
-       /* app/com marker data */
-       struct jpeg_app_marker app;
-       struct jpeg_com_marker com;
-};
-
-/* ZR36060 register addresses */
-#define ZR060_LOAD                     0x000
-#define ZR060_CFSR                     0x001
-#define ZR060_CIR                      0x002
-#define ZR060_CMR                      0x003
-#define ZR060_MBZ                      0x004
-#define ZR060_MBCVR                    0x005
-#define ZR060_MER                      0x006
-#define ZR060_IMR                      0x007
-#define ZR060_ISR                      0x008
-#define ZR060_TCV_NET_HI               0x009
-#define ZR060_TCV_NET_MH               0x00a
-#define ZR060_TCV_NET_ML               0x00b
-#define ZR060_TCV_NET_LO               0x00c
-#define ZR060_TCV_DATA_HI              0x00d
-#define ZR060_TCV_DATA_MH              0x00e
-#define ZR060_TCV_DATA_ML              0x00f
-#define ZR060_TCV_DATA_LO              0x010
-#define ZR060_SF_HI                    0x011
-#define ZR060_SF_LO                    0x012
-#define ZR060_AF_HI                    0x013
-#define ZR060_AF_M                     0x014
-#define ZR060_AF_LO                    0x015
-#define ZR060_ACV_HI                   0x016
-#define ZR060_ACV_MH                   0x017
-#define ZR060_ACV_ML                   0x018
-#define ZR060_ACV_LO                   0x019
-#define ZR060_ACT_HI                   0x01a
-#define ZR060_ACT_MH                   0x01b
-#define ZR060_ACT_ML                   0x01c
-#define ZR060_ACT_LO                   0x01d
-#define ZR060_ACV_TURN_HI              0x01e
-#define ZR060_ACV_TURN_MH              0x01f
-#define ZR060_ACV_TURN_ML              0x020
-#define ZR060_ACV_TURN_LO              0x021
-#define ZR060_IDR_DEV                  0x022
-#define ZR060_IDR_REV                  0x023
-#define ZR060_TCR_HI                   0x024
-#define ZR060_TCR_LO                   0x025
-#define ZR060_VCR                      0x030
-#define ZR060_VPR                      0x031
-#define ZR060_SR                       0x032
-#define ZR060_BCR_Y                    0x033
-#define ZR060_BCR_U                    0x034
-#define ZR060_BCR_V                    0x035
-#define ZR060_SGR_VTOTAL_HI            0x036
-#define ZR060_SGR_VTOTAL_LO            0x037
-#define ZR060_SGR_HTOTAL_HI            0x038
-#define ZR060_SGR_HTOTAL_LO            0x039
-#define ZR060_SGR_VSYNC                        0x03a
-#define ZR060_SGR_HSYNC                        0x03b
-#define ZR060_SGR_BVSTART              0x03c
-#define ZR060_SGR_BHSTART              0x03d
-#define ZR060_SGR_BVEND_HI             0x03e
-#define ZR060_SGR_BVEND_LO             0x03f
-#define ZR060_SGR_BHEND_HI             0x040
-#define ZR060_SGR_BHEND_LO             0x041
-#define ZR060_AAR_VSTART_HI            0x042
-#define ZR060_AAR_VSTART_LO            0x043
-#define ZR060_AAR_VEND_HI              0x044
-#define ZR060_AAR_VEND_LO              0x045
-#define ZR060_AAR_HSTART_HI            0x046
-#define ZR060_AAR_HSTART_LO            0x047
-#define ZR060_AAR_HEND_HI              0x048
-#define ZR060_AAR_HEND_LO              0x049
-#define ZR060_SWR_VSTART_HI            0x04a
-#define ZR060_SWR_VSTART_LO            0x04b
-#define ZR060_SWR_VEND_HI              0x04c
-#define ZR060_SWR_VEND_LO              0x04d
-#define ZR060_SWR_HSTART_HI            0x04e
-#define ZR060_SWR_HSTART_LO            0x04f
-#define ZR060_SWR_HEND_HI              0x050
-#define ZR060_SWR_HEND_LO              0x051
-
-#define ZR060_SOF_IDX                  0x060
-#define ZR060_SOS_IDX                  0x07a
-#define ZR060_DRI_IDX                  0x0c0
-#define ZR060_DQT_IDX                  0x0cc
-#define ZR060_DHT_IDX                  0x1d4
-#define ZR060_APP_IDX                  0x380
-#define ZR060_COM_IDX                  0x3c0
-
-/* ZR36060 LOAD register bits */
-
-#define ZR060_LOAD_LOAD                        BIT(7)
-#define ZR060_LOAD_SYNC_RST            BIT(0)
-
-/* ZR36060 Code FIFO Status register bits */
-
-#define ZR060_CFSR_BUSY                        BIT(7)
-#define ZR060_CFSR_C_BUSY              BIT(2)
-#define ZR060_CFSR_CFIFO               (3 << 0)
-
-/* ZR36060 Code Interface register */
-
-#define ZR060_CIR_CODE16               BIT(7)
-#define ZR060_CIR_ENDIAN               BIT(6)
-#define ZR060_CIR_CFIS                 BIT(2)
-#define ZR060_CIR_CODE_MSTR            BIT(0)
-
-/* ZR36060 Codec Mode register */
-
-#define ZR060_CMR_COMP                 BIT(7)
-#define ZR060_CMR_ATP                  BIT(6)
-#define ZR060_CMR_PASS2                        BIT(5)
-#define ZR060_CMR_TLM                  BIT(4)
-#define ZR060_CMR_BRB                  BIT(2)
-#define ZR060_CMR_FSF                  BIT(1)
-
-/* ZR36060 Markers Enable register */
-
-#define ZR060_MER_APP                  BIT(7)
-#define ZR060_MER_COM                  BIT(6)
-#define ZR060_MER_DRI                  BIT(5)
-#define ZR060_MER_DQT                  BIT(4)
-#define ZR060_MER_DHT                  BIT(3)
-
-/* ZR36060 Interrupt Mask register */
-
-#define ZR060_IMR_EOAV                 BIT(3)
-#define ZR060_IMR_EOI                  BIT(2)
-#define ZR060_IMR_END                  BIT(1)
-#define ZR060_IMR_DATA_ERR             BIT(0)
-
-/* ZR36060 Interrupt Status register */
-
-#define ZR060_ISR_PRO_CNT              (3 << 6)
-#define ZR060_ISR_EOAV                 BIT(3)
-#define ZR060_ISR_EOI                  BIT(2)
-#define ZR060_ISR_END                  BIT(1)
-#define ZR060_ISR_DATA_ERR             BIT(0)
-
-/* ZR36060 Video Control register */
-
-#define ZR060_VCR_VIDEO8               BIT(7)
-#define ZR060_VCR_RANGE                        BIT(6)
-#define ZR060_VCR_FI_DET               BIT(3)
-#define ZR060_VCR_FI_VEDGE             BIT(2)
-#define ZR060_VCR_FI_EXT               BIT(1)
-#define ZR060_VCR_SYNC_MSTR            BIT(0)
-
-/* ZR36060 Video Polarity register */
-
-#define ZR060_VPR_VCLK_POL             BIT(7)
-#define ZR060_VPR_P_VAL_POL            BIT(6)
-#define ZR060_VPR_POE_POL              BIT(5)
-#define ZR060_VPR_S_IMG_POL            BIT(4)
-#define ZR060_VPR_BL_POL               BIT(3)
-#define ZR060_VPR_FI_POL               BIT(2)
-#define ZR060_VPR_HS_POL               BIT(1)
-#define ZR060_VPR_VS_POL               BIT(0)
-
-/* ZR36060 Scaling register */
-
-#define ZR060_SR_V_SCALE               BIT(2)
-#define ZR060_SR_H_SCALE2              BIT(0)
-#define ZR060_SR_H_SCALE4              (2 << 0)
-
-int zr36060_init_module(void);
-void zr36060_cleanup_module(void);
-#endif                         /*fndef ZR36060_H */