summaryrefslogtreecommitdiff
path: root/drivers/media/pci/mgb4/mgb4_vout.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/pci/mgb4/mgb4_vout.c')
-rw-r--r--drivers/media/pci/mgb4/mgb4_vout.c64
1 files changed, 45 insertions, 19 deletions
diff --git a/drivers/media/pci/mgb4/mgb4_vout.c b/drivers/media/pci/mgb4/mgb4_vout.c
index fd93fbbaf755..44e9565d4d06 100644
--- a/drivers/media/pci/mgb4/mgb4_vout.c
+++ b/drivers/media/pci/mgb4/mgb4_vout.c
@@ -25,7 +25,8 @@
#include "mgb4_vout.h"
ATTRIBUTE_GROUPS(mgb4_fpdl3_out);
-ATTRIBUTE_GROUPS(mgb4_gmsl_out);
+ATTRIBUTE_GROUPS(mgb4_gmsl3_out);
+ATTRIBUTE_GROUPS(mgb4_gmsl1_out);
static const struct mgb4_vout_config vout_cfg[] = {
{0, 0, 8, {0x78, 0x60, 0x64, 0x68, 0x74, 0x6C, 0x70, 0x7C, 0xE0}},
@@ -37,10 +38,18 @@ static const struct i2c_board_info fpdl3_ser_info[] = {
{I2C_BOARD_INFO("serializer2", 0x16)},
};
+static const struct i2c_board_info gmsl1_ser_info[] = {
+ {I2C_BOARD_INFO("serializer1", 0x24)},
+ {I2C_BOARD_INFO("serializer2", 0x22)},
+};
+
static const struct mgb4_i2c_kv fpdl3_i2c[] = {
{0x05, 0xFF, 0x04}, {0x06, 0xFF, 0x01}, {0xC2, 0xFF, 0x80}
};
+static const struct mgb4_i2c_kv gmsl1_i2c[] = {
+};
+
static const struct v4l2_dv_timings_cap video_timings_cap = {
.type = V4L2_DV_BT_656_1120,
.bt = {
@@ -634,12 +643,24 @@ static irqreturn_t handler(int irq, void *ctx)
static int ser_init(struct mgb4_vout_dev *voutdev, int id)
{
- int rv;
- const struct i2c_board_info *info = &fpdl3_ser_info[id];
struct mgb4_i2c_client *ser = &voutdev->ser;
struct device *dev = &voutdev->mgbdev->pdev->dev;
+ const struct i2c_board_info *info = NULL;
+ const struct mgb4_i2c_kv *values = NULL;
+ size_t count = 0;
+ int rv;
+
+ if (MGB4_IS_FPDL3(voutdev->mgbdev)) {
+ info = &fpdl3_ser_info[id];
+ values = fpdl3_i2c;
+ count = ARRAY_SIZE(fpdl3_i2c);
+ } else if (MGB4_IS_GMSL1(voutdev->mgbdev)) {
+ info = &gmsl1_ser_info[id];
+ values = gmsl1_i2c;
+ count = ARRAY_SIZE(gmsl1_i2c);
+ }
- if (MGB4_IS_GMSL(voutdev->mgbdev))
+ if (!info)
return 0;
rv = mgb4_i2c_init(ser, voutdev->mgbdev->i2c_adap, info, 8);
@@ -647,7 +668,7 @@ static int ser_init(struct mgb4_vout_dev *voutdev, int id)
dev_err(dev, "failed to create serializer\n");
return rv;
}
- rv = mgb4_i2c_configure(ser, fpdl3_i2c, ARRAY_SIZE(fpdl3_i2c));
+ rv = mgb4_i2c_configure(ser, values, count);
if (rv < 0) {
dev_err(dev, "failed to configure serializer\n");
goto err_i2c_dev;
@@ -665,18 +686,19 @@ static void fpga_init(struct mgb4_vout_dev *voutdev)
{
struct mgb4_regs *video = &voutdev->mgbdev->video;
const struct mgb4_vout_regs *regs = &voutdev->config->regs;
+ int dp = MGB4_IS_GMSL1(voutdev->mgbdev) ? 0 : 1;
+ u32 source = (voutdev->config->id + MGB4_VIN_DEVICES) << 2;
- mgb4_write_reg(video, regs->config, 0x00000011);
+ mgb4_write_reg(video, regs->config, 0x00000001);
mgb4_write_reg(video, regs->resolution, (1280 << 16) | 640);
mgb4_write_reg(video, regs->hsync, 0x00283232);
mgb4_write_reg(video, regs->vsync, 0x40141F1E);
mgb4_write_reg(video, regs->frame_limit, MGB4_HW_FREQ / 60);
mgb4_write_reg(video, regs->padding, 0x00000000);
- voutdev->freq = mgb4_cmt_set_vout_freq(voutdev, 61150 >> 1) << 1;
+ voutdev->freq = mgb4_cmt_set_vout_freq(voutdev, 61150 >> dp) << dp;
- mgb4_write_reg(video, regs->config,
- (voutdev->config->id + MGB4_VIN_DEVICES) << 2 | 1 << 4);
+ mgb4_write_reg(video, regs->config, source | dp << 4);
}
static void create_debugfs(struct mgb4_vout_dev *voutdev)
@@ -720,10 +742,21 @@ static void create_debugfs(struct mgb4_vout_dev *voutdev)
#endif
}
+static const struct attribute_group **module_groups(struct mgb4_dev *mgbdev)
+{
+ if (MGB4_IS_FPDL3(mgbdev))
+ return mgb4_fpdl3_out_groups;
+ else if (MGB4_IS_GMSL3(mgbdev))
+ return mgb4_gmsl3_out_groups;
+ else if (MGB4_IS_GMSL1(mgbdev))
+ return mgb4_gmsl1_out_groups;
+ else
+ return NULL;
+}
+
struct mgb4_vout_dev *mgb4_vout_create(struct mgb4_dev *mgbdev, int id)
{
int rv, irq;
- const struct attribute_group **groups;
struct mgb4_vout_dev *voutdev;
struct pci_dev *pdev = mgbdev->pdev;
struct device *dev = &pdev->dev;
@@ -804,9 +837,7 @@ struct mgb4_vout_dev *mgb4_vout_create(struct mgb4_dev *mgbdev, int id)
}
/* Module sysfs attributes */
- groups = MGB4_IS_GMSL(mgbdev)
- ? mgb4_gmsl_out_groups : mgb4_fpdl3_out_groups;
- rv = device_add_groups(&voutdev->vdev.dev, groups);
+ rv = device_add_groups(&voutdev->vdev.dev, module_groups(mgbdev));
if (rv) {
dev_err(dev, "failed to create sysfs attributes\n");
goto err_video_dev;
@@ -830,15 +861,10 @@ err_alloc:
void mgb4_vout_free(struct mgb4_vout_dev *voutdev)
{
- const struct attribute_group **groups;
int irq = xdma_get_user_irq(voutdev->mgbdev->xdev, voutdev->config->irq);
free_irq(irq, voutdev);
-
- groups = MGB4_IS_GMSL(voutdev->mgbdev)
- ? mgb4_gmsl_out_groups : mgb4_fpdl3_out_groups;
- device_remove_groups(&voutdev->vdev.dev, groups);
-
+ device_remove_groups(&voutdev->vdev.dev, module_groups(voutdev->mgbdev));
mgb4_i2c_free(&voutdev->ser);
video_unregister_device(&voutdev->vdev);
v4l2_device_unregister(&voutdev->v4l2dev);