mirror of
https://github.com/linux-msm/laptops-kernel.git
synced 2026-08-13 14:19:53 -07:00
media: pci: mgb4: Added Digiteq Automotive MGB4 driver
Digiteq Automotive MGB4 is a modular frame grabber PCIe card for automotive video interfaces. As for now, two modules - FPD-Link and GMSL - are available and supported by the driver. The card has two inputs and two outputs (FPD-Link only). In addition to the video interfaces it also provides a trigger signal interface and a MTD interface for FPGA firmware upload. Signed-off-by: Martin Tůma <martin.tuma@digiteqautomotive.com> Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
This commit is contained in:
committed by
Hans Verkuil
parent
fd6627cb82
commit
0ab13674a9
@@ -6087,6 +6087,13 @@ L: linux-gpio@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/gpio/gpio-gpio-mm.c
|
||||
|
||||
DIGITEQ AUTOMOTIVE MGB4 V4L2 DRIVER
|
||||
M: Martin Tuma <martin.tuma@digiteqautomotive.com>
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Maintained
|
||||
F: Documentation/admin-guide/media/mgb4.rst
|
||||
F: drivers/media/pci/mgb4/
|
||||
|
||||
DIOLAN U2C-12 I2C DRIVER
|
||||
M: Guenter Roeck <linux@roeck-us.net>
|
||||
L: linux-i2c@vger.kernel.org
|
||||
|
||||
@@ -13,6 +13,7 @@ if MEDIA_PCI_SUPPORT
|
||||
if MEDIA_CAMERA_SUPPORT
|
||||
comment "Media capture support"
|
||||
|
||||
source "drivers/media/pci/mgb4/Kconfig"
|
||||
source "drivers/media/pci/solo6x10/Kconfig"
|
||||
source "drivers/media/pci/sta2x11/Kconfig"
|
||||
source "drivers/media/pci/tw5864/Kconfig"
|
||||
|
||||
@@ -32,6 +32,7 @@ obj-$(CONFIG_VIDEO_CX25821) += cx25821/
|
||||
obj-$(CONFIG_VIDEO_CX88) += cx88/
|
||||
obj-$(CONFIG_VIDEO_DT3155) += dt3155/
|
||||
obj-$(CONFIG_VIDEO_IVTV) += ivtv/
|
||||
obj-$(CONFIG_VIDEO_MGB4) += mgb4/
|
||||
obj-$(CONFIG_VIDEO_SAA7134) += saa7134/
|
||||
obj-$(CONFIG_VIDEO_SAA7164) += saa7164/
|
||||
obj-$(CONFIG_VIDEO_SOLO6X10) += solo6x10/
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
config VIDEO_MGB4
|
||||
tristate "Digiteq Automotive MGB4 support"
|
||||
depends on VIDEO_DEV && PCI && I2C && DMADEVICES && SPI && MTD && IIO
|
||||
select VIDEOBUF2_DMA_SG
|
||||
select IIO_BUFFER
|
||||
select IIO_TRIGGERED_BUFFER
|
||||
select I2C_XILINX
|
||||
select SPI_XILINX
|
||||
select MTD_SPI_NOR
|
||||
select XILINX_XDMA
|
||||
help
|
||||
This is a video4linux driver for Digiteq Automotive MGB4 grabber
|
||||
cards.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called mgb4.
|
||||
@@ -0,0 +1,6 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
mgb4-objs := mgb4_regs.o mgb4_core.o mgb4_vin.o mgb4_vout.o \
|
||||
mgb4_sysfs_pci.o mgb4_sysfs_in.o mgb4_sysfs_out.o \
|
||||
mgb4_i2c.o mgb4_cmt.o mgb4_trigger.o mgb4_dma.o
|
||||
|
||||
obj-$(CONFIG_VIDEO_MGB4) += mgb4.o
|
||||
@@ -0,0 +1,244 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (C) 2021-2023 Digiteq Automotive
|
||||
* author: Martin Tuma <martin.tuma@digiteqautomotive.com>
|
||||
*
|
||||
* The CMT module configures the FPGA Clock Management Tile (CMT) registers. For
|
||||
* different video signal frequencies (FPGA input signal frequencies), the FPGA
|
||||
* CMT registers need to be adjusted for the FPGA to work properly. The values
|
||||
* are precomputed based on formulas given by Xilinx in their FPGA documentation
|
||||
* (which are in turn full of some magic values/tables...).
|
||||
*/
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/kernel.h>
|
||||
#include "mgb4_core.h"
|
||||
#include "mgb4_cmt.h"
|
||||
|
||||
static const u16 cmt_vals_out[][15] = {
|
||||
{0x1208, 0x0000, 0x171C, 0x0000, 0x1E38, 0x0000, 0x11C7, 0x0000, 0x1041, 0x01BC, 0x7C01, 0x7DE9, 0xFFFF, 0x9900, 0x8100, },
|
||||
{0x11C7, 0x0000, 0x1619, 0x0080, 0x1C71, 0x0000, 0x130D, 0x0080, 0x0041, 0x0090, 0x7C01, 0x7DE9, 0xFFFF, 0x1100, 0x9000, },
|
||||
{0x11C7, 0x0000, 0x1619, 0x0080, 0x1C71, 0x0000, 0x165A, 0x0080, 0x0082, 0x00FA, 0x7C01, 0x7DE9, 0xFFFF, 0x1000, 0x9000, },
|
||||
{0x11C7, 0x0000, 0x1619, 0x0080, 0x1C71, 0x0000, 0x1187, 0x0080, 0x1041, 0x01EE, 0x7C01, 0x7DE9, 0xFFFF, 0x9900, 0x8100, },
|
||||
{0x1186, 0x0000, 0x1555, 0x0000, 0x1AAA, 0x0000, 0x1451, 0x0000, 0x0042, 0x0013, 0x7C01, 0x7DE9, 0xFFFF, 0x0900, 0x1000, },
|
||||
{0x11C7, 0x0000, 0x1619, 0x0080, 0x1C71, 0x0000, 0x134E, 0x0080, 0x0041, 0x005E, 0x7C01, 0x7DE9, 0xFFFF, 0x0900, 0x1000, },
|
||||
{0x1145, 0x0000, 0x1452, 0x0080, 0x18E3, 0x0000, 0x1619, 0x0080, 0x0083, 0x00FA, 0x7C01, 0x7DE9, 0xFFFF, 0x1000, 0x9000, },
|
||||
{0x1145, 0x0000, 0x1452, 0x0080, 0x18E3, 0x0000, 0x179E, 0x0000, 0x00C3, 0x00FA, 0x7C01, 0x7DE9, 0xFFFF, 0x0800, 0x1000, },
|
||||
{0x1145, 0x0000, 0x1452, 0x0080, 0x18E3, 0x0000, 0x179F, 0x0080, 0x00C3, 0x00FA, 0x7C01, 0x7DE9, 0xFFFF, 0x0800, 0x1000, },
|
||||
{0x1145, 0x0000, 0x1452, 0x0080, 0x18E3, 0x0000, 0x17DF, 0x0000, 0x00C3, 0x00FA, 0x7C01, 0x7DE9, 0xFFFF, 0x1000, 0x8800, },
|
||||
{0x1145, 0x0000, 0x1452, 0x0080, 0x18E3, 0x0000, 0x128B, 0x0080, 0x0041, 0x00DB, 0x7C01, 0x7DE9, 0xFFFF, 0x9000, 0x0100, },
|
||||
{0x1186, 0x0000, 0x1555, 0x0000, 0x1AAA, 0x0000, 0x1820, 0x0000, 0x0083, 0x00FA, 0x7DE9, 0x7DE8, 0xFFFF, 0x0900, 0x9000, },
|
||||
{0x1186, 0x0000, 0x1555, 0x0000, 0x1AAA, 0x0000, 0x1187, 0x0080, 0x1041, 0x01EE, 0x7C01, 0x7DE9, 0xFFFF, 0x9900, 0x8100, },
|
||||
{0x1104, 0x0000, 0x138E, 0x0000, 0x171C, 0x0000, 0x169B, 0x0080, 0x00C3, 0x00FA, 0x7C01, 0x7DE9, 0xFFFF, 0x1800, 0x0100, },
|
||||
{0x1145, 0x0000, 0x1452, 0x0080, 0x18E3, 0x0000, 0x171C, 0x0000, 0x0083, 0x00FA, 0x7C01, 0x7DE9, 0xFFFF, 0x1100, 0x1800, },
|
||||
{0x1186, 0x0000, 0x1555, 0x0000, 0x1AAA, 0x0000, 0x1515, 0x0080, 0x0042, 0x00FA, 0x7C01, 0x7DE9, 0xFFFF, 0x0900, 0x1000, },
|
||||
{0x1104, 0x0000, 0x138E, 0x0000, 0x171C, 0x0000, 0x1493, 0x0080, 0x0082, 0x00FA, 0x7C01, 0x7DE9, 0xFFFF, 0x0900, 0x1000, },
|
||||
{0x1145, 0x0000, 0x1452, 0x0080, 0x18E3, 0x0000, 0x15D8, 0x0080, 0x0082, 0x00FA, 0x7C01, 0x7DE9, 0xFFFF, 0x1900, 0x0100, },
|
||||
{0x1104, 0x0000, 0x138E, 0x0000, 0x171C, 0x0000, 0x124A, 0x0080, 0x0041, 0x010D, 0x7C01, 0x7DE9, 0xFFFF, 0x9000, 0x0100, },
|
||||
{0x1104, 0x0000, 0x138E, 0x0000, 0x171C, 0x0000, 0x175D, 0x0000, 0x00C3, 0x00FA, 0x7C01, 0x7DE9, 0xFFFF, 0x0800, 0x1000, },
|
||||
{0x1145, 0x0000, 0x1452, 0x0080, 0x18E3, 0x0000, 0x1619, 0x0080, 0x0082, 0x00FA, 0x7C01, 0x7DE9, 0xFFFF, 0x1000, 0x9000, },
|
||||
{0x1145, 0x0000, 0x1452, 0x0080, 0x18E3, 0x0000, 0x17DF, 0x0000, 0x0083, 0x00FA, 0x7C01, 0x7DE9, 0xFFFF, 0x1000, 0x8800, },
|
||||
{0x1145, 0x0000, 0x1452, 0x0080, 0x18E3, 0x0000, 0x17E0, 0x0080, 0x0083, 0x00FA, 0x7C01, 0x7DE9, 0xFFFF, 0x0900, 0x9000, },
|
||||
{0x1145, 0x0000, 0x1452, 0x0080, 0x18E3, 0x0000, 0x1820, 0x0000, 0x0083, 0x00FA, 0x7DE9, 0x7DE8, 0xFFFF, 0x0900, 0x9000, },
|
||||
{0x1104, 0x0000, 0x138E, 0x0000, 0x171C, 0x0000, 0x13D0, 0x0080, 0x0042, 0x002C, 0x7C01, 0x7DE9, 0xFFFF, 0x0900, 0x1000, },
|
||||
{0x1104, 0x0000, 0x138E, 0x0000, 0x171C, 0x0000, 0x128B, 0x0080, 0x0041, 0x00DB, 0x7C01, 0x7DE9, 0xFFFF, 0x9000, 0x0100, },
|
||||
{0x1104, 0x0000, 0x138E, 0x0000, 0x171C, 0x0000, 0x1820, 0x0000, 0x00C3, 0x00FA, 0x7DE9, 0x7DE8, 0xFFFF, 0x0900, 0x9000, },
|
||||
{0x1145, 0x0000, 0x1452, 0x0080, 0x18E3, 0x0000, 0x134E, 0x0080, 0x0041, 0x005E, 0x7C01, 0x7DE9, 0xFFFF, 0x0900, 0x1000, },
|
||||
{0x1145, 0x0000, 0x1452, 0x0080, 0x18E3, 0x0000, 0x1515, 0x0080, 0x0042, 0x00FA, 0x7C01, 0x7DE9, 0xFFFF, 0x0900, 0x1000, },
|
||||
{0x10C3, 0x0000, 0x128B, 0x0080, 0x1555, 0x0000, 0x175D, 0x0000, 0x00C4, 0x00FA, 0x7C01, 0x7DE9, 0xFFFF, 0x0800, 0x1000, },
|
||||
{0x1145, 0x0000, 0x1452, 0x0080, 0x18E3, 0x0000, 0x11C7, 0x0000, 0x1041, 0x01BC, 0x7C01, 0x7DE9, 0xFFFF, 0x9900, 0x8100, },
|
||||
{0x10C3, 0x0000, 0x128B, 0x0080, 0x1555, 0x0000, 0x1209, 0x0080, 0x0041, 0x013F, 0x7C01, 0x7DE9, 0xFFFF, 0x9900, 0x1100, },
|
||||
{0x10C3, 0x0000, 0x128B, 0x0080, 0x1555, 0x0000, 0x1556, 0x0080, 0x0083, 0x00FA, 0x7C01, 0x7DE9, 0xFFFF, 0x0800, 0x8000, },
|
||||
{0x10C3, 0x0000, 0x128B, 0x0080, 0x1555, 0x0000, 0x179F, 0x0080, 0x00C4, 0x00FA, 0x7C01, 0x7DE9, 0xFFFF, 0x0800, 0x1000, },
|
||||
{0x1104, 0x0000, 0x138E, 0x0000, 0x171C, 0x0000, 0x15D8, 0x0080, 0x0082, 0x00FA, 0x7C01, 0x7DE9, 0xFFFF, 0x1900, 0x0100, },
|
||||
{0x10C3, 0x0000, 0x128B, 0x0080, 0x1555, 0x0000, 0x1105, 0x0080, 0x1041, 0x01E8, 0x6401, 0x65E9, 0xFFFF, 0x9800, 0x1100, },
|
||||
{0x10C3, 0x0000, 0x128B, 0x0080, 0x1555, 0x0000, 0x1820, 0x0000, 0x00C4, 0x00FA, 0x7DE9, 0x7DE8, 0xFFFF, 0x0900, 0x9000, },
|
||||
{0x1104, 0x0000, 0x138E, 0x0000, 0x171C, 0x0000, 0x1493, 0x0080, 0x0042, 0x00FA, 0x7C01, 0x7DE9, 0xFFFF, 0x0900, 0x1000, },
|
||||
{0x10C3, 0x0000, 0x128B, 0x0080, 0x1555, 0x0000, 0x138E, 0x0000, 0x0042, 0x005E, 0x7C01, 0x7DE9, 0xFFFF, 0x0900, 0x1000, },
|
||||
{0x1104, 0x0000, 0x138E, 0x0000, 0x171C, 0x0000, 0x17E0, 0x0080, 0x0083, 0x00FA, 0x7C01, 0x7DE9, 0xFFFF, 0x0900, 0x9000, },
|
||||
{0x1104, 0x0000, 0x138E, 0x0000, 0x171C, 0x0000, 0x165A, 0x0080, 0x0082, 0x00FA, 0x7C01, 0x7DE9, 0xFFFF, 0x1000, 0x9000, },
|
||||
{0x10C3, 0x0000, 0x128B, 0x0080, 0x1555, 0x0000, 0x175D, 0x0000, 0x00C3, 0x00FA, 0x7C01, 0x7DE9, 0xFFFF, 0x0800, 0x1000, },
|
||||
{0x1104, 0x0000, 0x138E, 0x0000, 0x171C, 0x0000, 0x1187, 0x0080, 0x1041, 0x01EE, 0x7C01, 0x7DE9, 0xFFFF, 0x9900, 0x8100, },
|
||||
{0x10C3, 0x0000, 0x128B, 0x0080, 0x1555, 0x0000, 0x175E, 0x0080, 0x00C3, 0x00FA, 0x7C01, 0x7DE9, 0xFFFF, 0x0800, 0x1000, },
|
||||
{0x10C3, 0x0000, 0x128B, 0x0080, 0x1555, 0x0000, 0x179E, 0x0000, 0x00C3, 0x00FA, 0x7C01, 0x7DE9, 0xFFFF, 0x0800, 0x1000, },
|
||||
{0x1104, 0x0000, 0x138E, 0x0000, 0x171C, 0x0000, 0x134E, 0x0080, 0x0041, 0x005E, 0x7C01, 0x7DE9, 0xFFFF, 0x0900, 0x1000, },
|
||||
{0x10C3, 0x0000, 0x128B, 0x0080, 0x1555, 0x0000, 0x165A, 0x0080, 0x0083, 0x00FA, 0x7C01, 0x7DE9, 0xFFFF, 0x1000, 0x9000, },
|
||||
{0x1104, 0x0000, 0x138E, 0x0000, 0x171C, 0x0000, 0x16DC, 0x0080, 0x0082, 0x00FA, 0x7C01, 0x7DE9, 0xFFFF, 0x1100, 0x1800, },
|
||||
{0x10C3, 0x0000, 0x128B, 0x0080, 0x1555, 0x0000, 0x169A, 0x0000, 0x0083, 0x00FA, 0x7C01, 0x7DE9, 0xFFFF, 0x1000, 0x9000, },
|
||||
{0x1104, 0x0000, 0x138E, 0x0000, 0x171C, 0x0000, 0x11C7, 0x0000, 0x1041, 0x01BC, 0x7C01, 0x7DE9, 0xFFFF, 0x9900, 0x8100, },
|
||||
{0x10C3, 0x0000, 0x128B, 0x0080, 0x1555, 0x0000, 0x169B, 0x0080, 0x0083, 0x00FA, 0x7C01, 0x7DE9, 0xFFFF, 0x1800, 0x0100, },
|
||||
{0x1104, 0x0000, 0x138E, 0x0000, 0x171C, 0x0000, 0x171D, 0x0080, 0x0082, 0x00FA, 0x7C01, 0x7DE9, 0xFFFF, 0x1100, 0x1800, },
|
||||
{0x10C3, 0x0000, 0x128B, 0x0080, 0x1555, 0x0000, 0x16DB, 0x0000, 0x0083, 0x00FA, 0x7C01, 0x7DE9, 0xFFFF, 0x1800, 0x0100, },
|
||||
{0x10C3, 0x0000, 0x128B, 0x0080, 0x1555, 0x0000, 0x1146, 0x0080, 0x1041, 0x0184, 0x7C01, 0x7DE9, 0xFFFF, 0x9900, 0x8100, },
|
||||
{0x10C3, 0x0000, 0x128B, 0x0080, 0x1555, 0x0000, 0x171C, 0x0000, 0x0083, 0x00FA, 0x7C01, 0x7DE9, 0xFFFF, 0x1100, 0x1800, },
|
||||
{0x10C3, 0x0000, 0x128B, 0x0080, 0x1555, 0x0000, 0x1451, 0x0000, 0x0042, 0x0013, 0x7C01, 0x7DE9, 0xFFFF, 0x0900, 0x1000, },
|
||||
{0x10C3, 0x0000, 0x128B, 0x0080, 0x1555, 0x0000, 0x171D, 0x0080, 0x0083, 0x00FA, 0x7C01, 0x7DE9, 0xFFFF, 0x1100, 0x1800, },
|
||||
{0x10C3, 0x0000, 0x128B, 0x0080, 0x1555, 0x0000, 0x175D, 0x0000, 0x0083, 0x00FA, 0x7C01, 0x7DE9, 0xFFFF, 0x0800, 0x1000, },
|
||||
{0x10C3, 0x0000, 0x128B, 0x0080, 0x1555, 0x0000, 0x1452, 0x0080, 0x0042, 0x0013, 0x7C01, 0x7DE9, 0xFFFF, 0x0900, 0x1000, },
|
||||
{0x10C3, 0x0000, 0x128B, 0x0080, 0x1555, 0x0000, 0x15D8, 0x0080, 0x0082, 0x00FA, 0x7C01, 0x7DE9, 0xFFFF, 0x1900, 0x0100, },
|
||||
{0x1082, 0x0000, 0x11C7, 0x0000, 0x138E, 0x0000, 0x1104, 0x0000, 0x1041, 0x01E8, 0x5801, 0x59E9, 0xFFFF, 0x9900, 0x0900, },
|
||||
{0x10C3, 0x0000, 0x128B, 0x0080, 0x1555, 0x0000, 0x179F, 0x0080, 0x0083, 0x00FA, 0x7C01, 0x7DE9, 0xFFFF, 0x0800, 0x1000, },
|
||||
{0x1082, 0x0000, 0x11C7, 0x0000, 0x138E, 0x0000, 0x1515, 0x0080, 0x0083, 0x00FA, 0x7C01, 0x7DE9, 0xFFFF, 0x0900, 0x1000, },
|
||||
{0x10C3, 0x0000, 0x128B, 0x0080, 0x1555, 0x0000, 0x17DF, 0x0000, 0x0083, 0x00FA, 0x7C01, 0x7DE9, 0xFFFF, 0x1000, 0x8800, },
|
||||
{0x1082, 0x0000, 0x11C7, 0x0000, 0x138E, 0x0000, 0x1659, 0x0000, 0x00C3, 0x00FA, 0x7C01, 0x7DE9, 0xFFFF, 0x1000, 0x9000, },
|
||||
{0x1082, 0x0000, 0x11C7, 0x0000, 0x138E, 0x0000, 0x1555, 0x0000, 0x0083, 0x00FA, 0x7C01, 0x7DE9, 0xFFFF, 0x0800, 0x8000, },
|
||||
{0x10C3, 0x0000, 0x128B, 0x0080, 0x1555, 0x0000, 0x14D3, 0x0000, 0x0042, 0x00FA, 0x7C01, 0x7DE9, 0xFFFF, 0x0900, 0x1000, },
|
||||
{0x10C3, 0x0000, 0x128B, 0x0080, 0x1555, 0x0000, 0x1820, 0x0000, 0x0083, 0x00FA, 0x7DE9, 0x7DE8, 0xFFFF, 0x0900, 0x9000, },
|
||||
{0x1082, 0x0000, 0x11C7, 0x0000, 0x138E, 0x0000, 0x1556, 0x0080, 0x0083, 0x00FA, 0x7C01, 0x7DE9, 0xFFFF, 0x0800, 0x8000, },
|
||||
{0x10C3, 0x0000, 0x128B, 0x0080, 0x1555, 0x0000, 0x1187, 0x0080, 0x1041, 0x01EE, 0x7C01, 0x7DE9, 0xFFFF, 0x9900, 0x8100, },
|
||||
{0x1082, 0x0000, 0x11C7, 0x0000, 0x138E, 0x0000, 0x1452, 0x0080, 0x0082, 0x0013, 0x7C01, 0x7DE9, 0xFFFF, 0x0900, 0x1000, },
|
||||
{0x1082, 0x0000, 0x11C7, 0x0000, 0x138E, 0x0000, 0x169B, 0x0080, 0x00C3, 0x00FA, 0x7C01, 0x7DE9, 0xFFFF, 0x1800, 0x0100, },
|
||||
{0x10C3, 0x0000, 0x128B, 0x0080, 0x1555, 0x0000, 0x1514, 0x0000, 0x0042, 0x00FA, 0x7C01, 0x7DE9, 0xFFFF, 0x0900, 0x1000, },
|
||||
{0x1082, 0x0000, 0x11C7, 0x0000, 0x138E, 0x0000, 0x17E0, 0x0080, 0x00C4, 0x00FA, 0x7C01, 0x7DE9, 0xFFFF, 0x0900, 0x9000, },
|
||||
{0x10C3, 0x0000, 0x128B, 0x0080, 0x1555, 0x0000, 0x1515, 0x0080, 0x0042, 0x00FA, 0x7C01, 0x7DE9, 0xFFFF, 0x0900, 0x1000, },
|
||||
{0x10C3, 0x0000, 0x128B, 0x0080, 0x1555, 0x0000, 0x16DC, 0x0080, 0x0082, 0x00FA, 0x7C01, 0x7DE9, 0xFFFF, 0x1100, 0x1800, },
|
||||
{0x1082, 0x0000, 0x11C7, 0x0000, 0x138E, 0x0000, 0x1493, 0x0080, 0x0082, 0x00FA, 0x7C01, 0x7DE9, 0xFFFF, 0x0900, 0x1000, },
|
||||
{0x1082, 0x0000, 0x11C7, 0x0000, 0x138E, 0x0000, 0x171C, 0x0000, 0x00C3, 0x00FA, 0x7C01, 0x7DE9, 0xFFFF, 0x1100, 0x1800, },
|
||||
{0x1082, 0x0000, 0x11C7, 0x0000, 0x138E, 0x0000, 0x15D8, 0x0080, 0x0083, 0x00FA, 0x7C01, 0x7DE9, 0xFFFF, 0x1900, 0x0100, },
|
||||
{0x1082, 0x0000, 0x11C7, 0x0000, 0x138E, 0x0000, 0x171D, 0x0080, 0x00C3, 0x00FA, 0x7C01, 0x7DE9, 0xFFFF, 0x1100, 0x1800, },
|
||||
{0x1082, 0x0000, 0x11C7, 0x0000, 0x138E, 0x0000, 0x1618, 0x0000, 0x0083, 0x00FA, 0x7C01, 0x7DE9, 0xFFFF, 0x1900, 0x0100, },
|
||||
{0x1082, 0x0000, 0x11C7, 0x0000, 0x138E, 0x0000, 0x175D, 0x0000, 0x00C3, 0x00FA, 0x7C01, 0x7DE9, 0xFFFF, 0x0800, 0x1000, },
|
||||
{0x1082, 0x0000, 0x11C7, 0x0000, 0x138E, 0x0000, 0x14D4, 0x0080, 0x0082, 0x00FA, 0x7C01, 0x7DE9, 0xFFFF, 0x0900, 0x1000, },
|
||||
{0x1082, 0x0000, 0x11C7, 0x0000, 0x138E, 0x0000, 0x1619, 0x0080, 0x0083, 0x00FA, 0x7C01, 0x7DE9, 0xFFFF, 0x1000, 0x9000, },
|
||||
{0x1082, 0x0000, 0x11C7, 0x0000, 0x138E, 0x0000, 0x179E, 0x0000, 0x00C3, 0x00FA, 0x7C01, 0x7DE9, 0xFFFF, 0x0800, 0x1000, },
|
||||
{0x1082, 0x0000, 0x11C7, 0x0000, 0x138E, 0x0000, 0x179F, 0x0080, 0x00C3, 0x00FA, 0x7C01, 0x7DE9, 0xFFFF, 0x0800, 0x1000, },
|
||||
{0x1082, 0x0000, 0x11C7, 0x0000, 0x138E, 0x0000, 0x1515, 0x0080, 0x0082, 0x00FA, 0x7C01, 0x7DE9, 0xFFFF, 0x0900, 0x1000, },
|
||||
{0x1082, 0x0000, 0x11C7, 0x0000, 0x138E, 0x0000, 0x13D0, 0x0080, 0x0042, 0x002C, 0x7C01, 0x7DE9, 0xFFFF, 0x0900, 0x1000, },
|
||||
{0x1082, 0x0000, 0x11C7, 0x0000, 0x138E, 0x0000, 0x169A, 0x0000, 0x0083, 0x00FA, 0x7C01, 0x7DE9, 0xFFFF, 0x1000, 0x9000, },
|
||||
{0x1082, 0x0000, 0x11C7, 0x0000, 0x138E, 0x0000, 0x128B, 0x0080, 0x0041, 0x00DB, 0x7C01, 0x7DE9, 0xFFFF, 0x9000, 0x0100, },
|
||||
{0x1082, 0x0000, 0x11C7, 0x0000, 0x138E, 0x0000, 0x169B, 0x0080, 0x0083, 0x00FA, 0x7C01, 0x7DE9, 0xFFFF, 0x1800, 0x0100, },
|
||||
{0x1082, 0x0000, 0x11C7, 0x0000, 0x138E, 0x0000, 0x1820, 0x0000, 0x00C3, 0x00FA, 0x7DE9, 0x7DE8, 0xFFFF, 0x0900, 0x9000, },
|
||||
{0x1082, 0x0000, 0x11C7, 0x0000, 0x138E, 0x0000, 0x1556, 0x0080, 0x0082, 0x00FA, 0x7C01, 0x7DE9, 0xFFFF, 0x0800, 0x8000, },
|
||||
{0x1082, 0x0000, 0x11C7, 0x0000, 0x138E, 0x0000, 0x16DB, 0x0000, 0x0083, 0x00FA, 0x7C01, 0x7DE9, 0xFFFF, 0x1800, 0x0100, },
|
||||
{0x1082, 0x0000, 0x11C7, 0x0000, 0x138E, 0x0000, 0x1411, 0x0080, 0x0042, 0x002C, 0x7C01, 0x7DE9, 0xFFFF, 0x0900, 0x1000, },
|
||||
{0x1082, 0x0000, 0x11C7, 0x0000, 0x138E, 0x0000, 0x171C, 0x0000, 0x0083, 0x00FA, 0x7C01, 0x7DE9, 0xFFFF, 0x1100, 0x1800, },
|
||||
{0x1082, 0x0000, 0x11C7, 0x0000, 0x138E, 0x0000, 0x1597, 0x0080, 0x0082, 0x00FA, 0x7C01, 0x7DE9, 0xFFFF, 0x0800, 0x8000, },
|
||||
{0x1082, 0x0000, 0x11C7, 0x0000, 0x138E, 0x0000, 0x1451, 0x0000, 0x0042, 0x0013, 0x7C01, 0x7DE9, 0xFFFF, 0x0900, 0x1000, },
|
||||
{0x1082, 0x0000, 0x11C7, 0x0000, 0x138E, 0x0000, 0x171D, 0x0080, 0x0083, 0x00FA, 0x7C01, 0x7DE9, 0xFFFF, 0x1100, 0x1800, },
|
||||
{0x1082, 0x0000, 0x11C7, 0x0000, 0x138E, 0x0000, 0x12CC, 0x0080, 0x0041, 0x00A9, 0x7C01, 0x7DE9, 0xFFFF, 0x1100, 0x9000, },
|
||||
{0x1082, 0x0000, 0x11C7, 0x0000, 0x138E, 0x0000, 0x175D, 0x0000, 0x0083, 0x00FA, 0x7C01, 0x7DE9, 0xFFFF, 0x0800, 0x1000, },
|
||||
{0x1082, 0x0000, 0x11C7, 0x0000, 0x138E, 0x0000, 0x1452, 0x0080, 0x0042, 0x0013, 0x7C01, 0x7DE9, 0xFFFF, 0x0900, 0x1000, },
|
||||
{0x1082, 0x0000, 0x11C7, 0x0000, 0x138E, 0x0000, 0x15D8, 0x0080, 0x0082, 0x00FA, 0x7C01, 0x7DE9, 0xFFFF, 0x1900, 0x0100, },
|
||||
{0x1082, 0x0000, 0x11C7, 0x0000, 0x138E, 0x0000, 0x175E, 0x0080, 0x0083, 0x00FA, 0x7C01, 0x7DE9, 0xFFFF, 0x0800, 0x1000, },
|
||||
{0x1082, 0x0000, 0x11C7, 0x0000, 0x138E, 0x0000, 0x1492, 0x0000, 0x0042, 0x0013, 0x7C01, 0x7DE9, 0xFFFF, 0x0900, 0x1000, },
|
||||
{0x1082, 0x0000, 0x11C7, 0x0000, 0x138E, 0x0000, 0x179F, 0x0080, 0x0083, 0x00FA, 0x7C01, 0x7DE9, 0xFFFF, 0x0800, 0x1000, },
|
||||
{0x1082, 0x0000, 0x11C7, 0x0000, 0x138E, 0x0000, 0x1619, 0x0080, 0x0082, 0x00FA, 0x7C01, 0x7DE9, 0xFFFF, 0x1000, 0x9000, },
|
||||
{0x1082, 0x0000, 0x11C7, 0x0000, 0x138E, 0x0000, 0x1493, 0x0080, 0x0042, 0x00FA, 0x7C01, 0x7DE9, 0xFFFF, 0x0900, 0x1000, },
|
||||
{0x1082, 0x0000, 0x11C7, 0x0000, 0x138E, 0x0000, 0x17DF, 0x0000, 0x0083, 0x00FA, 0x7C01, 0x7DE9, 0xFFFF, 0x1000, 0x8800, },
|
||||
{0x1082, 0x0000, 0x11C7, 0x0000, 0x138E, 0x0000, 0x130D, 0x0080, 0x0041, 0x0090, 0x7C01, 0x7DE9, 0xFFFF, 0x1100, 0x9000, },
|
||||
{0x1082, 0x0000, 0x11C7, 0x0000, 0x138E, 0x0000, 0x17E0, 0x0080, 0x0083, 0x00FA, 0x7C01, 0x7DE9, 0xFFFF, 0x0900, 0x9000, },
|
||||
{0x1082, 0x0000, 0x11C7, 0x0000, 0x138E, 0x0000, 0x14D3, 0x0000, 0x0042, 0x00FA, 0x7C01, 0x7DE9, 0xFFFF, 0x0900, 0x1000, },
|
||||
{0x1082, 0x0000, 0x11C7, 0x0000, 0x138E, 0x0000, 0x165A, 0x0080, 0x0082, 0x00FA, 0x7C01, 0x7DE9, 0xFFFF, 0x1000, 0x9000, },
|
||||
{0x1082, 0x0000, 0x11C7, 0x0000, 0x138E, 0x0000, 0x1820, 0x0000, 0x0083, 0x00FA, 0x7DE9, 0x7DE8, 0xFFFF, 0x0900, 0x9000, },
|
||||
{0x1082, 0x0000, 0x11C7, 0x0000, 0x138E, 0x0000, 0x14D4, 0x0080, 0x0042, 0x00FA, 0x7C01, 0x7DE9, 0xFFFF, 0x0900, 0x1000, },
|
||||
{0x1082, 0x0000, 0x11C7, 0x0000, 0x138E, 0x0000, 0x169B, 0x0080, 0x0082, 0x00FA, 0x7C01, 0x7DE9, 0xFFFF, 0x1800, 0x0100, },
|
||||
};
|
||||
|
||||
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},
|
||||
};
|
||||
|
||||
static const u32 cmt_addrs_out[][15] = {
|
||||
{0x420, 0x424, 0x428, 0x42C, 0x430, 0x434, 0x450, 0x454, 0x458, 0x460, 0x464, 0x468, 0x4A0, 0x538, 0x53C},
|
||||
{0x620, 0x624, 0x628, 0x62C, 0x630, 0x634, 0x650, 0x654, 0x658, 0x660, 0x664, 0x668, 0x6A0, 0x738, 0x73C},
|
||||
};
|
||||
|
||||
static const u32 cmt_addrs_in[][13] = {
|
||||
{0x020, 0x024, 0x028, 0x02C, 0x050, 0x054, 0x058, 0x060, 0x064, 0x068, 0x0A0, 0x138, 0x13C},
|
||||
{0x220, 0x224, 0x228, 0x22C, 0x250, 0x254, 0x258, 0x260, 0x264, 0x268, 0x2A0, 0x338, 0x33C},
|
||||
};
|
||||
|
||||
static const u32 cmt_freq[] = {
|
||||
25000, 25510, 26020, 26530, 26983, 27551, 28000, 28570,
|
||||
29046, 29522, 30000, 30476, 30952, 31546, 32000, 32539,
|
||||
33035, 33571, 33928, 34522, 35000, 35428, 36000, 36571,
|
||||
36904, 37500, 38093, 38571, 39047, 39453, 40000, 40476,
|
||||
40952, 41494, 41964, 42857, 43535, 44047, 44444, 45000,
|
||||
45535, 46029, 46428, 46823, 47617, 48214, 48571, 49107,
|
||||
49523, 50000, 50476, 50892, 51428, 52380, 53333, 53967,
|
||||
54285, 55238, 55555, 55952, 57142, 58095, 58571, 59047,
|
||||
59521, 60000, 60316, 60952, 61428, 61904, 62500, 63092,
|
||||
63491, 64282, 65078, 65476, 66071, 66664, 67142, 67854,
|
||||
68571, 69044, 69642, 70000, 71425, 72616, 73214, 73808,
|
||||
74285, 75000, 75714, 76187, 76785, 77142, 78570, 80000,
|
||||
80357, 80951, 81428, 82142, 82857, 83332, 83928, 84285,
|
||||
85713, 87142, 87500, 88094, 88571, 89285, 90000, 90475,
|
||||
91071, 91428, 92856, 94642,
|
||||
};
|
||||
|
||||
static size_t freq_srch(u32 key, const u32 *array, size_t size)
|
||||
{
|
||||
int l = 0;
|
||||
int r = size - 1;
|
||||
int m = 0;
|
||||
|
||||
while (l <= r) {
|
||||
m = (l + r) / 2;
|
||||
if (array[m] < key)
|
||||
l = m + 1;
|
||||
else if (array[m] > key)
|
||||
r = m - 1;
|
||||
else
|
||||
return m;
|
||||
}
|
||||
|
||||
if (r < 0 || l > size - 1)
|
||||
return m;
|
||||
else
|
||||
return (abs(key - array[l]) < abs(key - array[r])) ? l : r;
|
||||
}
|
||||
|
||||
u32 mgb4_cmt_set_vout_freq(struct mgb4_vout_dev *voutdev, unsigned int freq)
|
||||
{
|
||||
struct mgb4_regs *video = &voutdev->mgbdev->video;
|
||||
const struct mgb4_vout_regs *regs = &voutdev->config->regs;
|
||||
const u16 *reg_set;
|
||||
const u32 *addr;
|
||||
u32 config;
|
||||
size_t i, index;
|
||||
|
||||
index = freq_srch(freq, cmt_freq, ARRAY_SIZE(cmt_freq));
|
||||
addr = cmt_addrs_out[voutdev->config->id];
|
||||
reg_set = cmt_vals_out[index];
|
||||
|
||||
config = mgb4_read_reg(video, regs->config);
|
||||
|
||||
mgb4_write_reg(video, regs->config, 0x1 | (config & ~0x3));
|
||||
|
||||
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);
|
||||
|
||||
return cmt_freq[index];
|
||||
}
|
||||
|
||||
void mgb4_cmt_set_vin_freq_range(struct mgb4_vin_dev *vindev,
|
||||
unsigned int freq_range)
|
||||
{
|
||||
struct mgb4_regs *video = &vindev->mgbdev->video;
|
||||
const struct mgb4_vin_regs *regs = &vindev->config->regs;
|
||||
const u16 *reg_set;
|
||||
const u32 *addr;
|
||||
u32 config;
|
||||
size_t i;
|
||||
|
||||
addr = cmt_addrs_in[vindev->config->id];
|
||||
reg_set = cmt_vals_in[freq_range];
|
||||
|
||||
config = mgb4_read_reg(video, regs->config);
|
||||
|
||||
mgb4_write_reg(video, regs->config, 0x1 | (config & ~0x3));
|
||||
|
||||
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);
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (C) 2021-2023 Digiteq Automotive
|
||||
* author: Martin Tuma <martin.tuma@digiteqautomotive.com>
|
||||
*/
|
||||
|
||||
#ifndef __MGB4_CMT_H__
|
||||
#define __MGB4_CMT_H__
|
||||
|
||||
#include "mgb4_vout.h"
|
||||
#include "mgb4_vin.h"
|
||||
|
||||
u32 mgb4_cmt_set_vout_freq(struct mgb4_vout_dev *voutdev, unsigned int freq);
|
||||
void mgb4_cmt_set_vin_freq_range(struct mgb4_vin_dev *vindev,
|
||||
unsigned int freq_range);
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,74 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (C) 2021-2023 Digiteq Automotive
|
||||
* author: Martin Tuma <martin.tuma@digiteqautomotive.com>
|
||||
*/
|
||||
|
||||
#ifndef __MGB4_CORE_H__
|
||||
#define __MGB4_CORE_H__
|
||||
|
||||
#include <linux/spi/flash.h>
|
||||
#include <linux/mtd/partitions.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/dmaengine.h>
|
||||
#include "mgb4_regs.h"
|
||||
|
||||
#define MGB4_VIN_DEVICES 2
|
||||
#define MGB4_VOUT_DEVICES 2
|
||||
|
||||
#define MGB4_MGB4_BAR_ID 0
|
||||
#define MGB4_XDMA_BAR_ID 1
|
||||
|
||||
#define MGB4_IS_GMSL(mgbdev) \
|
||||
((mgbdev)->module_version >> 4 == 2)
|
||||
#define MGB4_IS_FPDL3(mgbdev) \
|
||||
((mgbdev)->module_version >> 4 == 1)
|
||||
|
||||
struct mgb4_dma_channel {
|
||||
struct dma_chan *chan;
|
||||
struct completion req_compl;
|
||||
};
|
||||
|
||||
struct mgb4_dev {
|
||||
struct pci_dev *pdev;
|
||||
struct platform_device *xdev;
|
||||
struct mgb4_vin_dev *vin[MGB4_VIN_DEVICES];
|
||||
struct mgb4_vout_dev *vout[MGB4_VOUT_DEVICES];
|
||||
|
||||
struct mgb4_dma_channel c2h_chan[MGB4_VIN_DEVICES];
|
||||
struct mgb4_dma_channel h2c_chan[MGB4_VOUT_DEVICES];
|
||||
struct dma_slave_map slave_map[MGB4_VIN_DEVICES + MGB4_VOUT_DEVICES];
|
||||
|
||||
struct mgb4_regs video;
|
||||
struct mgb4_regs cmt;
|
||||
|
||||
struct clk_hw *i2c_clk;
|
||||
struct clk_lookup *i2c_cl;
|
||||
struct platform_device *i2c_pdev;
|
||||
struct i2c_adapter *i2c_adap;
|
||||
struct mutex i2c_lock; /* I2C bus access lock */
|
||||
|
||||
struct platform_device *spi_pdev;
|
||||
struct flash_platform_data flash_data;
|
||||
struct mtd_partition partitions[2];
|
||||
char flash_name[16];
|
||||
char fw_part_name[16];
|
||||
char data_part_name[16];
|
||||
char channel_names[MGB4_VIN_DEVICES + MGB4_VOUT_DEVICES][16];
|
||||
|
||||
struct iio_dev *indio_dev;
|
||||
#if IS_REACHABLE(CONFIG_HWMON)
|
||||
struct device *hwmon_dev;
|
||||
#endif
|
||||
|
||||
unsigned long io_reconfig;
|
||||
|
||||
u8 module_version;
|
||||
u32 serial_number;
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
struct dentry *debugfs;
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,123 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (C) 2021-2022 Digiteq Automotive
|
||||
* author: Martin Tuma <martin.tuma@digiteqautomotive.com>
|
||||
*
|
||||
* This module handles the DMA transfers. A standard dmaengine API as provided
|
||||
* by the XDMA module is used.
|
||||
*/
|
||||
|
||||
#include <linux/pci.h>
|
||||
#include <linux/dma-direction.h>
|
||||
#include "mgb4_core.h"
|
||||
#include "mgb4_dma.h"
|
||||
|
||||
static void chan_irq(void *param)
|
||||
{
|
||||
struct mgb4_dma_channel *chan = param;
|
||||
|
||||
complete(&chan->req_compl);
|
||||
}
|
||||
|
||||
int mgb4_dma_transfer(struct mgb4_dev *mgbdev, u32 channel, bool write,
|
||||
u64 paddr, struct sg_table *sgt)
|
||||
{
|
||||
struct dma_slave_config cfg;
|
||||
struct mgb4_dma_channel *chan;
|
||||
struct dma_async_tx_descriptor *tx;
|
||||
struct pci_dev *pdev = mgbdev->pdev;
|
||||
int ret;
|
||||
|
||||
memset(&cfg, 0, sizeof(cfg));
|
||||
|
||||
if (write) {
|
||||
cfg.direction = DMA_MEM_TO_DEV;
|
||||
cfg.dst_addr = paddr;
|
||||
cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
|
||||
chan = &mgbdev->h2c_chan[channel];
|
||||
} else {
|
||||
cfg.direction = DMA_DEV_TO_MEM;
|
||||
cfg.src_addr = paddr;
|
||||
cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
|
||||
chan = &mgbdev->c2h_chan[channel];
|
||||
}
|
||||
|
||||
ret = dmaengine_slave_config(chan->chan, &cfg);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "failed to config dma: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
tx = dmaengine_prep_slave_sg(chan->chan, sgt->sgl, sgt->nents,
|
||||
cfg.direction, 0);
|
||||
if (!tx) {
|
||||
dev_err(&pdev->dev, "failed to prep slave sg\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
tx->callback = chan_irq;
|
||||
tx->callback_param = chan;
|
||||
|
||||
ret = dma_submit_error(dmaengine_submit(tx));
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "failed to submit sg\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
dma_async_issue_pending(chan->chan);
|
||||
|
||||
if (!wait_for_completion_timeout(&chan->req_compl,
|
||||
msecs_to_jiffies(10000))) {
|
||||
dev_err(&pdev->dev, "dma timeout\n");
|
||||
dmaengine_terminate_sync(chan->chan);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mgb4_dma_channel_init(struct mgb4_dev *mgbdev)
|
||||
{
|
||||
int i, ret;
|
||||
char name[16];
|
||||
struct pci_dev *pdev = mgbdev->pdev;
|
||||
|
||||
for (i = 0; i < MGB4_VIN_DEVICES; i++) {
|
||||
sprintf(name, "c2h%d", i);
|
||||
mgbdev->c2h_chan[i].chan = dma_request_chan(&pdev->dev, name);
|
||||
if (IS_ERR(mgbdev->c2h_chan[i].chan)) {
|
||||
dev_err(&pdev->dev, "failed to initialize %s", name);
|
||||
ret = PTR_ERR(mgbdev->c2h_chan[i].chan);
|
||||
mgbdev->c2h_chan[i].chan = NULL;
|
||||
return ret;
|
||||
}
|
||||
init_completion(&mgbdev->c2h_chan[i].req_compl);
|
||||
}
|
||||
for (i = 0; i < MGB4_VOUT_DEVICES; i++) {
|
||||
sprintf(name, "h2c%d", i);
|
||||
mgbdev->h2c_chan[i].chan = dma_request_chan(&pdev->dev, name);
|
||||
if (IS_ERR(mgbdev->h2c_chan[i].chan)) {
|
||||
dev_err(&pdev->dev, "failed to initialize %s", name);
|
||||
ret = PTR_ERR(mgbdev->h2c_chan[i].chan);
|
||||
mgbdev->h2c_chan[i].chan = NULL;
|
||||
return ret;
|
||||
}
|
||||
init_completion(&mgbdev->h2c_chan[i].req_compl);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void mgb4_dma_channel_free(struct mgb4_dev *mgbdev)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MGB4_VIN_DEVICES; i++) {
|
||||
if (mgbdev->c2h_chan[i].chan)
|
||||
dma_release_channel(mgbdev->c2h_chan[i].chan);
|
||||
}
|
||||
for (i = 0; i < MGB4_VOUT_DEVICES; i++) {
|
||||
if (mgbdev->h2c_chan[i].chan)
|
||||
dma_release_channel(mgbdev->h2c_chan[i].chan);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (C) 2021-2023 Digiteq Automotive
|
||||
* author: Martin Tuma <martin.tuma@digiteqautomotive.com>
|
||||
*/
|
||||
|
||||
#ifndef __MGB4_DMA_H__
|
||||
#define __MGB4_DMA_H__
|
||||
|
||||
#include "mgb4_core.h"
|
||||
|
||||
int mgb4_dma_channel_init(struct mgb4_dev *mgbdev);
|
||||
void mgb4_dma_channel_free(struct mgb4_dev *mgbdev);
|
||||
|
||||
int mgb4_dma_transfer(struct mgb4_dev *mgbdev, u32 channel, bool write,
|
||||
u64 paddr, struct sg_table *sgt);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,140 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (C) 2021-2023 Digiteq Automotive
|
||||
* author: Martin Tuma <martin.tuma@digiteqautomotive.com>
|
||||
*
|
||||
* The i2c module unifies the I2C access to the serializes/deserializes. The I2C
|
||||
* chips on the GMSL module use 16b addressing, the FPDL3 chips use standard
|
||||
* 8b addressing.
|
||||
*/
|
||||
|
||||
#include "mgb4_i2c.h"
|
||||
|
||||
static int read_r16(struct i2c_client *client, u16 reg, u8 *val, int len)
|
||||
{
|
||||
int ret;
|
||||
u8 buf[2];
|
||||
struct i2c_msg msg[2] = {
|
||||
{
|
||||
.addr = client->addr,
|
||||
.flags = 0,
|
||||
.len = 2,
|
||||
.buf = buf,
|
||||
}, {
|
||||
.addr = client->addr,
|
||||
.flags = I2C_M_RD,
|
||||
.len = len,
|
||||
.buf = val,
|
||||
}
|
||||
};
|
||||
|
||||
buf[0] = (reg >> 8) & 0xff;
|
||||
buf[1] = (reg >> 0) & 0xff;
|
||||
|
||||
ret = i2c_transfer(client->adapter, msg, 2);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
else if (ret != 2)
|
||||
return -EREMOTEIO;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int write_r16(struct i2c_client *client, u16 reg, const u8 *val, int len)
|
||||
{
|
||||
int ret;
|
||||
u8 buf[4];
|
||||
struct i2c_msg msg[1] = {
|
||||
{
|
||||
.addr = client->addr,
|
||||
.flags = 0,
|
||||
.len = 2 + len,
|
||||
.buf = buf,
|
||||
}
|
||||
};
|
||||
|
||||
if (2 + len > sizeof(buf))
|
||||
return -EINVAL;
|
||||
|
||||
buf[0] = (reg >> 8) & 0xff;
|
||||
buf[1] = (reg >> 0) & 0xff;
|
||||
memcpy(&buf[2], val, len);
|
||||
|
||||
ret = i2c_transfer(client->adapter, msg, 1);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
else if (ret != 1)
|
||||
return -EREMOTEIO;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mgb4_i2c_init(struct mgb4_i2c_client *client, struct i2c_adapter *adap,
|
||||
struct i2c_board_info const *info, int addr_size)
|
||||
{
|
||||
client->client = i2c_new_client_device(adap, info);
|
||||
if (IS_ERR(client->client))
|
||||
return PTR_ERR(client->client);
|
||||
|
||||
client->addr_size = addr_size;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void mgb4_i2c_free(struct mgb4_i2c_client *client)
|
||||
{
|
||||
i2c_unregister_device(client->client);
|
||||
}
|
||||
|
||||
s32 mgb4_i2c_read_byte(struct mgb4_i2c_client *client, u16 reg)
|
||||
{
|
||||
int ret;
|
||||
u8 b;
|
||||
|
||||
if (client->addr_size == 8)
|
||||
return i2c_smbus_read_byte_data(client->client, reg);
|
||||
|
||||
ret = read_r16(client->client, reg, &b, 1);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return (s32)b;
|
||||
}
|
||||
|
||||
s32 mgb4_i2c_write_byte(struct mgb4_i2c_client *client, u16 reg, u8 val)
|
||||
{
|
||||
if (client->addr_size == 8)
|
||||
return i2c_smbus_write_byte_data(client->client, reg, val);
|
||||
else
|
||||
return write_r16(client->client, reg, &val, 1);
|
||||
}
|
||||
|
||||
s32 mgb4_i2c_mask_byte(struct mgb4_i2c_client *client, u16 reg, u8 mask, u8 val)
|
||||
{
|
||||
s32 ret;
|
||||
|
||||
if (mask != 0xFF) {
|
||||
ret = mgb4_i2c_read_byte(client, reg);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
val |= (u8)ret & ~mask;
|
||||
}
|
||||
|
||||
return mgb4_i2c_write_byte(client, reg, val);
|
||||
}
|
||||
|
||||
int mgb4_i2c_configure(struct mgb4_i2c_client *client,
|
||||
const struct mgb4_i2c_kv *values, size_t count)
|
||||
{
|
||||
size_t i;
|
||||
s32 res;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
res = mgb4_i2c_mask_byte(client, values[i].reg, values[i].mask,
|
||||
values[i].val);
|
||||
if (res < 0)
|
||||
return res;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (C) 2021-2023 Digiteq Automotive
|
||||
* author: Martin Tuma <martin.tuma@digiteqautomotive.com>
|
||||
*/
|
||||
|
||||
#ifndef __MGB4_I2C_H__
|
||||
#define __MGB4_I2C_H__
|
||||
|
||||
#include <linux/i2c.h>
|
||||
|
||||
struct mgb4_i2c_client {
|
||||
struct i2c_client *client;
|
||||
int addr_size;
|
||||
};
|
||||
|
||||
struct mgb4_i2c_kv {
|
||||
u16 reg;
|
||||
u8 mask;
|
||||
u8 val;
|
||||
};
|
||||
|
||||
int mgb4_i2c_init(struct mgb4_i2c_client *client, struct i2c_adapter *adap,
|
||||
struct i2c_board_info const *info, int addr_size);
|
||||
void mgb4_i2c_free(struct mgb4_i2c_client *client);
|
||||
|
||||
s32 mgb4_i2c_read_byte(struct mgb4_i2c_client *client, u16 reg);
|
||||
s32 mgb4_i2c_write_byte(struct mgb4_i2c_client *client, u16 reg, u8 val);
|
||||
s32 mgb4_i2c_mask_byte(struct mgb4_i2c_client *client, u16 reg, u8 mask,
|
||||
u8 val);
|
||||
|
||||
int mgb4_i2c_configure(struct mgb4_i2c_client *client,
|
||||
const struct mgb4_i2c_kv *values, size_t count);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,33 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (C) 2021-2022 Digiteq Automotive
|
||||
* author: Martin Tuma <martin.tuma@digiteqautomotive.com>
|
||||
*/
|
||||
|
||||
#ifndef __MGB4_IO_H__
|
||||
#define __MGB4_IO_H__
|
||||
|
||||
#include <media/v4l2-dev.h>
|
||||
|
||||
#define MGB4_DEFAULT_WIDTH 1280
|
||||
#define MGB4_DEFAULT_HEIGHT 640
|
||||
#define MGB4_DEFAULT_PERIOD (125000000 / 60)
|
||||
|
||||
/* Register access error indication */
|
||||
#define MGB4_ERR_NO_REG 0xFFFFFFFE
|
||||
/* Frame buffer addresses greater than 0xFFFFFFFA indicate HW errors */
|
||||
#define MGB4_ERR_QUEUE_TIMEOUT 0xFFFFFFFD
|
||||
#define MGB4_ERR_QUEUE_EMPTY 0xFFFFFFFC
|
||||
#define MGB4_ERR_QUEUE_FULL 0xFFFFFFFB
|
||||
|
||||
struct mgb4_frame_buffer {
|
||||
struct vb2_v4l2_buffer vb;
|
||||
struct list_head list;
|
||||
};
|
||||
|
||||
static inline struct mgb4_frame_buffer *to_frame_buffer(struct vb2_v4l2_buffer *vbuf)
|
||||
{
|
||||
return container_of(vbuf, struct mgb4_frame_buffer, vb);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,30 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (C) 2021-2022 Digiteq Automotive
|
||||
* author: Martin Tuma <martin.tuma@digiteqautomotive.com>
|
||||
*/
|
||||
|
||||
#include <linux/ioport.h>
|
||||
#include "mgb4_regs.h"
|
||||
|
||||
int mgb4_regs_map(struct resource *res, struct mgb4_regs *regs)
|
||||
{
|
||||
regs->mapbase = res->start;
|
||||
regs->mapsize = res->end - res->start;
|
||||
|
||||
if (!request_mem_region(regs->mapbase, regs->mapsize, res->name))
|
||||
return -EINVAL;
|
||||
regs->membase = ioremap(regs->mapbase, regs->mapsize);
|
||||
if (!regs->membase) {
|
||||
release_mem_region(regs->mapbase, regs->mapsize);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void mgb4_regs_free(struct mgb4_regs *regs)
|
||||
{
|
||||
iounmap(regs->membase);
|
||||
release_mem_region(regs->mapbase, regs->mapsize);
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (C) 2021-2022 Digiteq Automotive
|
||||
* author: Martin Tuma <martin.tuma@digiteqautomotive.com>
|
||||
*/
|
||||
|
||||
#ifndef __MGB4_REGS_H__
|
||||
#define __MGB4_REGS_H__
|
||||
|
||||
#include <linux/io.h>
|
||||
|
||||
struct mgb4_regs {
|
||||
resource_size_t mapbase;
|
||||
resource_size_t mapsize;
|
||||
void __iomem *membase;
|
||||
};
|
||||
|
||||
#define mgb4_write_reg(regs, offset, val) \
|
||||
iowrite32(val, (regs)->membase + (offset))
|
||||
#define mgb4_read_reg(regs, offset) \
|
||||
ioread32((regs)->membase + (offset))
|
||||
|
||||
static inline void mgb4_mask_reg(struct mgb4_regs *regs, u32 reg, u32 mask,
|
||||
u32 val)
|
||||
{
|
||||
u32 ret = mgb4_read_reg(regs, reg);
|
||||
|
||||
val |= ret & ~mask;
|
||||
mgb4_write_reg(regs, reg, val);
|
||||
}
|
||||
|
||||
int mgb4_regs_map(struct resource *res, struct mgb4_regs *regs);
|
||||
void mgb4_regs_free(struct mgb4_regs *regs);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,18 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (C) 2021-2022 Digiteq Automotive
|
||||
* author: Martin Tuma <martin.tuma@digiteqautomotive.com>
|
||||
*/
|
||||
|
||||
#ifndef __MGB4_SYSFS_H__
|
||||
#define __MGB4_SYSFS_H__
|
||||
|
||||
#include <linux/sysfs.h>
|
||||
|
||||
extern struct attribute *mgb4_pci_attrs[];
|
||||
extern struct attribute *mgb4_fpdl3_in_attrs[];
|
||||
extern struct attribute *mgb4_gmsl_in_attrs[];
|
||||
extern struct attribute *mgb4_fpdl3_out_attrs[];
|
||||
extern struct attribute *mgb4_gmsl_out_attrs[];
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,71 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (C) 2021-2022 Digiteq Automotive
|
||||
* author: Martin Tuma <martin.tuma@digiteqautomotive.com>
|
||||
*
|
||||
* This module handles all the sysfs info/configuration that is related to the
|
||||
* PCI card device.
|
||||
*/
|
||||
|
||||
#include <linux/device.h>
|
||||
#include "mgb4_core.h"
|
||||
#include "mgb4_sysfs.h"
|
||||
|
||||
static ssize_t module_version_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct mgb4_dev *mgbdev = dev_get_drvdata(dev);
|
||||
|
||||
return sprintf(buf, "%u\n", mgbdev->module_version & 0x0F);
|
||||
}
|
||||
|
||||
static ssize_t module_type_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct mgb4_dev *mgbdev = dev_get_drvdata(dev);
|
||||
|
||||
return sprintf(buf, "%u\n", mgbdev->module_version >> 4);
|
||||
}
|
||||
|
||||
static ssize_t fw_version_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct mgb4_dev *mgbdev = dev_get_drvdata(dev);
|
||||
u32 config = mgb4_read_reg(&mgbdev->video, 0xC4);
|
||||
|
||||
return sprintf(buf, "%u\n", config & 0xFFFF);
|
||||
}
|
||||
|
||||
static ssize_t fw_type_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct mgb4_dev *mgbdev = dev_get_drvdata(dev);
|
||||
u32 config = mgb4_read_reg(&mgbdev->video, 0xC4);
|
||||
|
||||
return sprintf(buf, "%u\n", config >> 24);
|
||||
}
|
||||
|
||||
static ssize_t serial_number_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct mgb4_dev *mgbdev = dev_get_drvdata(dev);
|
||||
u32 sn = mgbdev->serial_number;
|
||||
|
||||
return sprintf(buf, "%03d-%03d-%03d-%03d\n", sn >> 24, (sn >> 16) & 0xFF,
|
||||
(sn >> 8) & 0xFF, sn & 0xFF);
|
||||
}
|
||||
|
||||
static DEVICE_ATTR_RO(module_version);
|
||||
static DEVICE_ATTR_RO(module_type);
|
||||
static DEVICE_ATTR_RO(fw_version);
|
||||
static DEVICE_ATTR_RO(fw_type);
|
||||
static DEVICE_ATTR_RO(serial_number);
|
||||
|
||||
struct attribute *mgb4_pci_attrs[] = {
|
||||
&dev_attr_module_type.attr,
|
||||
&dev_attr_module_version.attr,
|
||||
&dev_attr_fw_type.attr,
|
||||
&dev_attr_fw_version.attr,
|
||||
&dev_attr_serial_number.attr,
|
||||
NULL
|
||||
};
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user