diff options
Diffstat (limited to 'drivers/media/pci/mgb4')
-rw-r--r-- | drivers/media/pci/mgb4/mgb4_cmt.c | 8 | ||||
-rw-r--r-- | drivers/media/pci/mgb4/mgb4_core.c | 13 | ||||
-rw-r--r-- | drivers/media/pci/mgb4/mgb4_core.h | 8 | ||||
-rw-r--r-- | drivers/media/pci/mgb4/mgb4_regs.c | 1 | ||||
-rw-r--r-- | drivers/media/pci/mgb4/mgb4_vin.c | 21 |
5 files changed, 35 insertions, 16 deletions
diff --git a/drivers/media/pci/mgb4/mgb4_cmt.c b/drivers/media/pci/mgb4/mgb4_cmt.c index a25b68403bc6..c22ef51436ed 100644 --- a/drivers/media/pci/mgb4/mgb4_cmt.c +++ b/drivers/media/pci/mgb4/mgb4_cmt.c @@ -135,8 +135,8 @@ static const u16 cmt_vals_out[][15] = { }; static const u16 cmt_vals_in[][13] = { - {0x1082, 0x0000, 0x5104, 0x0000, 0x11C7, 0x0000, 0x1041, 0x02BC, 0x7C01, 0xFFE9, 0x9900, 0x9908, 0x8100}, {0x1104, 0x0000, 0x9208, 0x0000, 0x138E, 0x0000, 0x1041, 0x015E, 0x7C01, 0xFFE9, 0x0100, 0x0908, 0x1000}, + {0x1082, 0x0000, 0x5104, 0x0000, 0x11C7, 0x0000, 0x1041, 0x02BC, 0x7C01, 0xFFE9, 0x9900, 0x9908, 0x8100}, }; static const u32 cmt_addrs_out[][15] = { @@ -206,10 +206,11 @@ u32 mgb4_cmt_set_vout_freq(struct mgb4_vout_dev *voutdev, unsigned int freq) mgb4_write_reg(video, regs->config, 0x1 | (config & ~0x3)); + mgb4_mask_reg(video, regs->config, 0x100, 0x100); + for (i = 0; i < ARRAY_SIZE(cmt_addrs_out[0]); i++) mgb4_write_reg(&voutdev->mgbdev->cmt, addr[i], reg_set[i]); - mgb4_mask_reg(video, regs->config, 0x100, 0x100); mgb4_mask_reg(video, regs->config, 0x100, 0x0); mgb4_write_reg(video, regs->config, config & ~0x1); @@ -236,10 +237,11 @@ void mgb4_cmt_set_vin_freq_range(struct mgb4_vin_dev *vindev, mgb4_write_reg(video, regs->config, 0x1 | (config & ~0x3)); + mgb4_mask_reg(video, regs->config, 0x1000, 0x1000); + for (i = 0; i < ARRAY_SIZE(cmt_addrs_in[0]); i++) mgb4_write_reg(&vindev->mgbdev->cmt, addr[i], reg_set[i]); - mgb4_mask_reg(video, regs->config, 0x1000, 0x1000); mgb4_mask_reg(video, regs->config, 0x1000, 0x0); mgb4_write_reg(video, regs->config, config & ~0x1); diff --git a/drivers/media/pci/mgb4/mgb4_core.c b/drivers/media/pci/mgb4/mgb4_core.c index f90ffc4dad52..3ce6b717ca32 100644 --- a/drivers/media/pci/mgb4/mgb4_core.c +++ b/drivers/media/pci/mgb4/mgb4_core.c @@ -406,8 +406,9 @@ static int get_module_version(struct mgb4_dev *mgbdev) dev_err(dev, "unknown module type\n"); return -EINVAL; } - fw_version = mgb4_read_reg(&mgbdev->video, 0xC4); - if (fw_version >> 24 != mgbdev->module_version >> 4) { + fw_version = mgb4_read_reg(&mgbdev->video, 0xC4) >> 24; + if ((MGB4_IS_FPDL3(mgbdev) && fw_version != 1) || + (MGB4_IS_GMSL(mgbdev) && fw_version != 2)) { dev_err(dev, "module/firmware type mismatch\n"); return -EINVAL; } @@ -599,14 +600,18 @@ static int mgb4_probe(struct pci_dev *pdev, const struct pci_device_id *id) rv = get_module_version(mgbdev); if (rv < 0) goto exit; + /* Propagate the module type(version) to the FPGA */ + mgb4_write_reg(&mgbdev->video, 0xD4, mgbdev->module_version); /* Video input v4l2 devices */ for (i = 0; i < MGB4_VIN_DEVICES; i++) mgbdev->vin[i] = mgb4_vin_create(mgbdev, i); /* Video output v4l2 devices */ - for (i = 0; i < MGB4_VOUT_DEVICES; i++) - mgbdev->vout[i] = mgb4_vout_create(mgbdev, i); + if (MGB4_HAS_VOUT(mgbdev)) { + for (i = 0; i < MGB4_VOUT_DEVICES; i++) + mgbdev->vout[i] = mgb4_vout_create(mgbdev, i); + } /* Triggers */ mgbdev->indio_dev = mgb4_trigger_create(mgbdev); diff --git a/drivers/media/pci/mgb4/mgb4_core.h b/drivers/media/pci/mgb4/mgb4_core.h index e86742d7b6c4..cc24068400a2 100644 --- a/drivers/media/pci/mgb4/mgb4_core.h +++ b/drivers/media/pci/mgb4/mgb4_core.h @@ -19,9 +19,13 @@ #define MGB4_VOUT_DEVICES 2 #define MGB4_IS_GMSL(mgbdev) \ - ((mgbdev)->module_version >> 4 == 2) + ((((mgbdev)->module_version >> 4) >= 2) && \ + (((mgbdev)->module_version >> 4) <= 4)) #define MGB4_IS_FPDL3(mgbdev) \ - ((mgbdev)->module_version >> 4 == 1) + (((mgbdev)->module_version >> 4) == 1) +#define MGB4_HAS_VOUT(mgbdev) \ + ((((mgbdev)->module_version >> 4) >= 1) && \ + (((mgbdev)->module_version >> 4) <= 3)) struct mgb4_dma_channel { struct dma_chan *chan; diff --git a/drivers/media/pci/mgb4/mgb4_regs.c b/drivers/media/pci/mgb4/mgb4_regs.c index 31befd722d72..b45537dbfafa 100644 --- a/drivers/media/pci/mgb4/mgb4_regs.c +++ b/drivers/media/pci/mgb4/mgb4_regs.c @@ -5,6 +5,7 @@ */ #include <linux/ioport.h> +#include <linux/errno.h> #include "mgb4_regs.h" int mgb4_regs_map(struct resource *res, struct mgb4_regs *regs) diff --git a/drivers/media/pci/mgb4/mgb4_vin.c b/drivers/media/pci/mgb4/mgb4_vin.c index 434eaf0440e2..989e93f67f75 100644 --- a/drivers/media/pci/mgb4/mgb4_vin.c +++ b/drivers/media/pci/mgb4/mgb4_vin.c @@ -641,7 +641,14 @@ static int vidioc_query_dv_timings(struct file *file, void *fh, static int vidioc_enum_dv_timings(struct file *file, void *fh, struct v4l2_enum_dv_timings *timings) { - return v4l2_enum_dv_timings_cap(timings, &video_timings_cap, NULL, NULL); + struct mgb4_vin_dev *vindev = video_drvdata(file); + + if (timings->index != 0) + return -EINVAL; + if (get_timings(vindev, &timings->timings) < 0) + return -ENODATA; + + return 0; } static int vidioc_dv_timings_cap(struct file *file, void *fh, @@ -749,14 +756,14 @@ static void signal_change(struct work_struct *work) u32 width = resolution >> 16; u32 height = resolution & 0xFFFF; - if (timings->width != width || timings->height != height) { - static const struct v4l2_event ev = { - .type = V4L2_EVENT_SOURCE_CHANGE, - .u.src_change.changes = V4L2_EVENT_SRC_CH_RESOLUTION, - }; + static const struct v4l2_event ev = { + .type = V4L2_EVENT_SOURCE_CHANGE, + .u.src_change.changes = V4L2_EVENT_SRC_CH_RESOLUTION, + }; - v4l2_event_queue(&vindev->vdev, &ev); + v4l2_event_queue(&vindev->vdev, &ev); + if (timings->width != width || timings->height != height) { if (vb2_is_streaming(&vindev->queue)) vb2_queue_error(&vindev->queue); } |