linux/drivers/media/i2c/ds90ub960.c

// SPDX-License-Identifier: GPL-2.0
/*
 * Driver for the Texas Instruments DS90UB960-Q1 video deserializer
 *
 * Copyright (c) 2019 Luca Ceresoli <[email protected]>
 * Copyright (c) 2023 Tomi Valkeinen <[email protected]>
 */

/*
 * (Possible) TODOs:
 *
 * - PM for serializer and remote peripherals. We need to manage:
 *   - VPOC
 *     - Power domain? Regulator? Somehow any remote device should be able to
 *       cause the VPOC to be turned on.
 *   - Link between the deserializer and the serializer
 *     - Related to VPOC management. We probably always want to turn on the VPOC
 *       and then enable the link.
 *   - Serializer's services: i2c, gpios, power
 *     - The serializer needs to resume before the remote peripherals can
 *       e.g. use the i2c.
 *     - How to handle gpios? Reserving a gpio essentially keeps the provider
 *       (serializer) always powered on.
 * - Do we need a new bus for the FPD-Link? At the moment the serializers
 *   are children of the same i2c-adapter where the deserializer resides.
 * - i2c-atr could be made embeddable instead of allocatable.
 */

#include <linux/bitops.h>
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/fwnode.h>
#include <linux/gpio/consumer.h>
#include <linux/i2c-atr.h>
#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/kthread.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/property.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
#include <linux/slab.h>
#include <linux/workqueue.h>

#include <media/i2c/ds90ub9xx.h>
#include <media/mipi-csi2.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-event.h>
#include <media/v4l2-fwnode.h>
#include <media/v4l2-subdev.h>

#define MHZ(v)

#define UB960_POLL_TIME_MS

#define UB960_MAX_RX_NPORTS
#define UB960_MAX_TX_NPORTS
#define UB960_MAX_NPORTS

#define UB960_MAX_PORT_ALIASES

#define UB960_NUM_BC_GPIOS

/*
 * Register map
 *
 * 0x00-0x32   Shared (UB960_SR)
 * 0x33-0x3a   CSI-2 TX (per-port paged on DS90UB960, shared on 954) (UB960_TR)
 * 0x4c        Shared (UB960_SR)
 * 0x4d-0x7f   FPD-Link RX, per-port paged (UB960_RR)
 * 0xb0-0xbf   Shared (UB960_SR)
 * 0xd0-0xdf   FPD-Link RX, per-port paged (UB960_RR)
 * 0xf0-0xf5   Shared (UB960_SR)
 * 0xf8-0xfb   Shared (UB960_SR)
 * All others  Reserved
 *
 * Register prefixes:
 * UB960_SR_* = Shared register
 * UB960_RR_* = FPD-Link RX, per-port paged register
 * UB960_TR_* = CSI-2 TX, per-port paged register
 * UB960_XR_* = Reserved register
 * UB960_IR_* = Indirect register
 */

#define UB960_SR_I2C_DEV_ID
#define UB960_SR_RESET
#define UB960_SR_RESET_DIGITAL_RESET1
#define UB960_SR_RESET_DIGITAL_RESET0
#define UB960_SR_RESET_GPIO_LOCK_RELEASE

#define UB960_SR_GEN_CONFIG
#define UB960_SR_REV_MASK
#define UB960_SR_DEVICE_STS
#define UB960_SR_PAR_ERR_THOLD_HI
#define UB960_SR_PAR_ERR_THOLD_LO
#define UB960_SR_BCC_WDOG_CTL
#define UB960_SR_I2C_CTL1
#define UB960_SR_I2C_CTL2
#define UB960_SR_SCL_HIGH_TIME
#define UB960_SR_SCL_LOW_TIME
#define UB960_SR_RX_PORT_CTL
#define UB960_SR_IO_CTL
#define UB960_SR_GPIO_PIN_STS
#define UB960_SR_GPIO_INPUT_CTL
#define UB960_SR_GPIO_PIN_CTL(n)
#define UB960_SR_GPIO_PIN_CTL_GPIO_OUT_SEL
#define UB960_SR_GPIO_PIN_CTL_GPIO_OUT_SRC_SHIFT
#define UB960_SR_GPIO_PIN_CTL_GPIO_OUT_EN

#define UB960_SR_FS_CTL
#define UB960_SR_FS_HIGH_TIME_1
#define UB960_SR_FS_HIGH_TIME_0
#define UB960_SR_FS_LOW_TIME_1
#define UB960_SR_FS_LOW_TIME_0
#define UB960_SR_MAX_FRM_HI
#define UB960_SR_MAX_FRM_LO
#define UB960_SR_CSI_PLL_CTL

#define UB960_SR_FWD_CTL1
#define UB960_SR_FWD_CTL1_PORT_DIS(n)

#define UB960_SR_FWD_CTL2
#define UB960_SR_FWD_STS

#define UB960_SR_INTERRUPT_CTL
#define UB960_SR_INTERRUPT_CTL_INT_EN
#define UB960_SR_INTERRUPT_CTL_IE_CSI_TX0
#define UB960_SR_INTERRUPT_CTL_IE_RX(n)

#define UB960_SR_INTERRUPT_STS
#define UB960_SR_INTERRUPT_STS_INT
#define UB960_SR_INTERRUPT_STS_IS_CSI_TX(n)
#define UB960_SR_INTERRUPT_STS_IS_RX(n)

#define UB960_SR_TS_CONFIG
#define UB960_SR_TS_CONTROL
#define UB960_SR_TS_LINE_HI
#define UB960_SR_TS_LINE_LO
#define UB960_SR_TS_STATUS
#define UB960_SR_TIMESTAMP_P0_HI
#define UB960_SR_TIMESTAMP_P0_LO
#define UB960_SR_TIMESTAMP_P1_HI
#define UB960_SR_TIMESTAMP_P1_LO

#define UB960_SR_CSI_PORT_SEL

#define UB960_TR_CSI_CTL
#define UB960_TR_CSI_CTL_CSI_CAL_EN
#define UB960_TR_CSI_CTL_CSI_CONTS_CLOCK
#define UB960_TR_CSI_CTL_CSI_ENABLE

#define UB960_TR_CSI_CTL2
#define UB960_TR_CSI_STS
#define UB960_TR_CSI_TX_ICR

#define UB960_TR_CSI_TX_ISR
#define UB960_TR_CSI_TX_ISR_IS_CSI_SYNC_ERROR
#define UB960_TR_CSI_TX_ISR_IS_CSI_PASS_ERROR

#define UB960_TR_CSI_TEST_CTL
#define UB960_TR_CSI_TEST_PATT_HI
#define UB960_TR_CSI_TEST_PATT_LO

#define UB960_XR_SFILTER_CFG
#define UB960_XR_SFILTER_CFG_SFILTER_MAX_SHIFT
#define UB960_XR_SFILTER_CFG_SFILTER_MIN_SHIFT

#define UB960_XR_AEQ_CTL1
#define UB960_XR_AEQ_CTL1_AEQ_ERR_CTL_FPD_CLK
#define UB960_XR_AEQ_CTL1_AEQ_ERR_CTL_ENCODING
#define UB960_XR_AEQ_CTL1_AEQ_ERR_CTL_PARITY
#define UB960_XR_AEQ_CTL1_AEQ_ERR_CTL_MASK
#define UB960_XR_AEQ_CTL1_AEQ_SFILTER_EN

#define UB960_XR_AEQ_ERR_THOLD

#define UB960_RR_BCC_ERR_CTL
#define UB960_RR_BCC_STATUS
#define UB960_RR_BCC_STATUS_SEQ_ERROR
#define UB960_RR_BCC_STATUS_MASTER_ERR
#define UB960_RR_BCC_STATUS_MASTER_TO
#define UB960_RR_BCC_STATUS_SLAVE_ERR
#define UB960_RR_BCC_STATUS_SLAVE_TO
#define UB960_RR_BCC_STATUS_RESP_ERR
#define UB960_RR_BCC_STATUS_ERROR_MASK

#define UB960_RR_FPD3_CAP
#define UB960_RR_RAW_EMBED_DTYPE
#define UB960_RR_RAW_EMBED_DTYPE_LINES_SHIFT

#define UB960_SR_FPD3_PORT_SEL

#define UB960_RR_RX_PORT_STS1
#define UB960_RR_RX_PORT_STS1_BCC_CRC_ERROR
#define UB960_RR_RX_PORT_STS1_LOCK_STS_CHG
#define UB960_RR_RX_PORT_STS1_BCC_SEQ_ERROR
#define UB960_RR_RX_PORT_STS1_PARITY_ERROR
#define UB960_RR_RX_PORT_STS1_PORT_PASS
#define UB960_RR_RX_PORT_STS1_LOCK_STS
#define UB960_RR_RX_PORT_STS1_ERROR_MASK

#define UB960_RR_RX_PORT_STS2
#define UB960_RR_RX_PORT_STS2_LINE_LEN_UNSTABLE
#define UB960_RR_RX_PORT_STS2_LINE_LEN_CHG
#define UB960_RR_RX_PORT_STS2_FPD3_ENCODE_ERROR
#define UB960_RR_RX_PORT_STS2_BUFFER_ERROR
#define UB960_RR_RX_PORT_STS2_CSI_ERROR
#define UB960_RR_RX_PORT_STS2_FREQ_STABLE
#define UB960_RR_RX_PORT_STS2_CABLE_FAULT
#define UB960_RR_RX_PORT_STS2_LINE_CNT_CHG
#define UB960_RR_RX_PORT_STS2_ERROR_MASK

#define UB960_RR_RX_FREQ_HIGH
#define UB960_RR_RX_FREQ_LOW
#define UB960_RR_SENSOR_STS_0
#define UB960_RR_SENSOR_STS_1
#define UB960_RR_SENSOR_STS_2
#define UB960_RR_SENSOR_STS_3
#define UB960_RR_RX_PAR_ERR_HI
#define UB960_RR_RX_PAR_ERR_LO
#define UB960_RR_BIST_ERR_COUNT

#define UB960_RR_BCC_CONFIG
#define UB960_RR_BCC_CONFIG_I2C_PASS_THROUGH
#define UB960_RR_BCC_CONFIG_BC_FREQ_SEL_MASK

#define UB960_RR_DATAPATH_CTL1
#define UB960_RR_DATAPATH_CTL2
#define UB960_RR_SER_ID
#define UB960_RR_SER_ALIAS_ID

/* For these two register sets: n < UB960_MAX_PORT_ALIASES */
#define UB960_RR_SLAVE_ID(n)
#define UB960_RR_SLAVE_ALIAS(n)

#define UB960_RR_PORT_CONFIG
#define UB960_RR_PORT_CONFIG_FPD3_MODE_MASK

#define UB960_RR_BC_GPIO_CTL(n)
#define UB960_RR_RAW10_ID
#define UB960_RR_RAW10_ID_VC_SHIFT
#define UB960_RR_RAW10_ID_DT_SHIFT

#define UB960_RR_RAW12_ID
#define UB960_RR_CSI_VC_MAP
#define UB960_RR_CSI_VC_MAP_SHIFT(x)

#define UB960_RR_LINE_COUNT_HI
#define UB960_RR_LINE_COUNT_LO
#define UB960_RR_LINE_LEN_1
#define UB960_RR_LINE_LEN_0
#define UB960_RR_FREQ_DET_CTL
#define UB960_RR_MAILBOX_1
#define UB960_RR_MAILBOX_2

#define UB960_RR_CSI_RX_STS
#define UB960_RR_CSI_RX_STS_LENGTH_ERR
#define UB960_RR_CSI_RX_STS_CKSUM_ERR
#define UB960_RR_CSI_RX_STS_ECC2_ERR
#define UB960_RR_CSI_RX_STS_ECC1_ERR
#define UB960_RR_CSI_RX_STS_ERROR_MASK

#define UB960_RR_CSI_ERR_COUNTER
#define UB960_RR_PORT_CONFIG2
#define UB960_RR_PORT_CONFIG2_RAW10_8BIT_CTL_MASK
#define UB960_RR_PORT_CONFIG2_RAW10_8BIT_CTL_SHIFT

#define UB960_RR_PORT_CONFIG2_LV_POL_LOW
#define UB960_RR_PORT_CONFIG2_FV_POL_LOW

#define UB960_RR_PORT_PASS_CTL
#define UB960_RR_SEN_INT_RISE_CTL
#define UB960_RR_SEN_INT_FALL_CTL

#define UB960_SR_CSI_FRAME_COUNT_HI(n)
#define UB960_SR_CSI_FRAME_COUNT_LO(n)
#define UB960_SR_CSI_FRAME_ERR_COUNT_HI(n)
#define UB960_SR_CSI_FRAME_ERR_COUNT_LO(n)
#define UB960_SR_CSI_LINE_COUNT_HI(n)
#define UB960_SR_CSI_LINE_COUNT_LO(n)
#define UB960_SR_CSI_LINE_ERR_COUNT_HI(n)
#define UB960_SR_CSI_LINE_ERR_COUNT_LO(n)

#define UB960_XR_REFCLK_FREQ

#define UB960_RR_VC_ID_MAP(x)

#define UB960_SR_IND_ACC_CTL
#define UB960_SR_IND_ACC_CTL_IA_AUTO_INC

#define UB960_SR_IND_ACC_ADDR
#define UB960_SR_IND_ACC_DATA
#define UB960_SR_BIST_CONTROL
#define UB960_SR_MODE_IDX_STS
#define UB960_SR_LINK_ERROR_COUNT
#define UB960_SR_FPD3_ENC_CTL
#define UB960_SR_FV_MIN_TIME
#define UB960_SR_GPIO_PD_CTL

#define UB960_SR_FPD_RATE_CFG
#define UB960_SR_CSI_PLL_DIV

#define UB960_RR_PORT_DEBUG
#define UB960_RR_AEQ_CTL2
#define UB960_RR_AEQ_CTL2_SET_AEQ_FLOOR

#define UB960_RR_AEQ_STATUS
#define UB960_RR_AEQ_STATUS_STATUS_2
#define UB960_RR_AEQ_STATUS_STATUS_1

#define UB960_RR_AEQ_BYPASS
#define UB960_RR_AEQ_BYPASS_EQ_STAGE1_VALUE_SHIFT
#define UB960_RR_AEQ_BYPASS_EQ_STAGE1_VALUE_MASK
#define UB960_RR_AEQ_BYPASS_EQ_STAGE2_VALUE_SHIFT
#define UB960_RR_AEQ_BYPASS_EQ_STAGE2_VALUE_MASK
#define UB960_RR_AEQ_BYPASS_ENABLE

#define UB960_RR_AEQ_MIN_MAX
#define UB960_RR_AEQ_MIN_MAX_AEQ_MAX_SHIFT
#define UB960_RR_AEQ_MIN_MAX_AEQ_FLOOR_SHIFT

#define UB960_RR_SFILTER_STS_0
#define UB960_RR_SFILTER_STS_1
#define UB960_RR_PORT_ICR_HI
#define UB960_RR_PORT_ICR_LO
#define UB960_RR_PORT_ISR_HI
#define UB960_RR_PORT_ISR_LO
#define UB960_RR_FC_GPIO_STS
#define UB960_RR_FC_GPIO_ICR
#define UB960_RR_SEN_INT_RISE_STS
#define UB960_RR_SEN_INT_FALL_STS

#define UB960_RR_CHANNEL_MODE

#define UB960_SR_FPD3_RX_ID(n)
#define UB960_SR_FPD3_RX_ID_LEN

#define UB960_SR_I2C_RX_ID(n)

/* Indirect register blocks */
#define UB960_IND_TARGET_PAT_GEN
#define UB960_IND_TARGET_RX_ANA(n)
#define UB960_IND_TARGET_CSI_CSIPLL_REG_1
#define UB960_IND_TARGET_CSI_ANA

/* UB960_IR_PGEN_*: Indirect Registers for Test Pattern Generator */

#define UB960_IR_PGEN_CTL
#define UB960_IR_PGEN_CTL_PGEN_ENABLE

#define UB960_IR_PGEN_CFG
#define UB960_IR_PGEN_CSI_DI
#define UB960_IR_PGEN_LINE_SIZE1
#define UB960_IR_PGEN_LINE_SIZE0
#define UB960_IR_PGEN_BAR_SIZE1
#define UB960_IR_PGEN_BAR_SIZE0
#define UB960_IR_PGEN_ACT_LPF1
#define UB960_IR_PGEN_ACT_LPF0
#define UB960_IR_PGEN_TOT_LPF1
#define UB960_IR_PGEN_TOT_LPF0
#define UB960_IR_PGEN_LINE_PD1
#define UB960_IR_PGEN_LINE_PD0
#define UB960_IR_PGEN_VBP
#define UB960_IR_PGEN_VFP
#define UB960_IR_PGEN_COLOR(n)

#define UB960_IR_RX_ANA_STROBE_SET_CLK
#define UB960_IR_RX_ANA_STROBE_SET_CLK_NO_EXTRA_DELAY
#define UB960_IR_RX_ANA_STROBE_SET_CLK_DELAY_MASK

#define UB960_IR_RX_ANA_STROBE_SET_DATA
#define UB960_IR_RX_ANA_STROBE_SET_DATA_NO_EXTRA_DELAY
#define UB960_IR_RX_ANA_STROBE_SET_DATA_DELAY_MASK

/* EQ related */

#define UB960_MIN_AEQ_STROBE_POS
#define UB960_MAX_AEQ_STROBE_POS

#define UB960_MANUAL_STROBE_EXTRA_DELAY

#define UB960_MIN_MANUAL_STROBE_POS
#define UB960_MAX_MANUAL_STROBE_POS
#define UB960_NUM_MANUAL_STROBE_POS

#define UB960_MIN_EQ_LEVEL
#define UB960_MAX_EQ_LEVEL
#define UB960_NUM_EQ_LEVELS

struct ub960_hw_data {};

enum ub960_rxport_mode {};

enum ub960_rxport_cdr {};

struct ub960_rxport {};

struct ub960_asd {};

static inline struct ub960_asd *to_ub960_asd(struct v4l2_async_connection *asd)
{}

struct ub960_txport {};

struct ub960_data {};

static inline struct ub960_data *sd_to_ub960(struct v4l2_subdev *sd)
{}

static inline bool ub960_pad_is_sink(struct ub960_data *priv, u32 pad)
{}

static inline bool ub960_pad_is_source(struct ub960_data *priv, u32 pad)
{}

static inline unsigned int ub960_pad_to_port(struct ub960_data *priv, u32 pad)
{}

struct ub960_format_info {};

static const struct ub960_format_info ub960_formats[] =;

static const struct ub960_format_info *ub960_find_format(u32 code)
{}

/* -----------------------------------------------------------------------------
 * Basic device access
 */

static int ub960_read(struct ub960_data *priv, u8 reg, u8 *val)
{}

static int ub960_write(struct ub960_data *priv, u8 reg, u8 val)
{}

static int ub960_update_bits(struct ub960_data *priv, u8 reg, u8 mask, u8 val)
{}

static int ub960_read16(struct ub960_data *priv, u8 reg, u16 *val)
{}

static int ub960_rxport_select(struct ub960_data *priv, u8 nport)
{}

static int ub960_rxport_read(struct ub960_data *priv, u8 nport, u8 reg, u8 *val)
{}

static int ub960_rxport_write(struct ub960_data *priv, u8 nport, u8 reg, u8 val)
{}

static int ub960_rxport_update_bits(struct ub960_data *priv, u8 nport, u8 reg,
				    u8 mask, u8 val)
{}

static int ub960_rxport_read16(struct ub960_data *priv, u8 nport, u8 reg,
			       u16 *val)
{}

static int ub960_txport_select(struct ub960_data *priv, u8 nport)
{}

static int ub960_txport_read(struct ub960_data *priv, u8 nport, u8 reg, u8 *val)
{}

static int ub960_txport_write(struct ub960_data *priv, u8 nport, u8 reg, u8 val)
{}

static int ub960_txport_update_bits(struct ub960_data *priv, u8 nport, u8 reg,
				    u8 mask, u8 val)
{}

static int ub960_select_ind_reg_block(struct ub960_data *priv, u8 block)
{}

static int ub960_read_ind(struct ub960_data *priv, u8 block, u8 reg, u8 *val)
{}

static int ub960_write_ind(struct ub960_data *priv, u8 block, u8 reg, u8 val)
{}

static int ub960_ind_update_bits(struct ub960_data *priv, u8 block, u8 reg,
				 u8 mask, u8 val)
{}

/* -----------------------------------------------------------------------------
 * I2C-ATR (address translator)
 */

static int ub960_atr_attach_client(struct i2c_atr *atr, u32 chan_id,
				   const struct i2c_client *client, u16 alias)
{}

static void ub960_atr_detach_client(struct i2c_atr *atr, u32 chan_id,
				    const struct i2c_client *client)
{}

static const struct i2c_atr_ops ub960_atr_ops =;

static int ub960_init_atr(struct ub960_data *priv)
{}

static void ub960_uninit_atr(struct ub960_data *priv)
{}

/* -----------------------------------------------------------------------------
 * TX ports
 */

static int ub960_parse_dt_txport(struct ub960_data *priv,
				 struct fwnode_handle *ep_fwnode,
				 u8 nport)
{}

static void ub960_csi_handle_events(struct ub960_data *priv, u8 nport)
{}

/* -----------------------------------------------------------------------------
 * RX ports
 */

static int ub960_rxport_enable_vpocs(struct ub960_data *priv)
{}

static void ub960_rxport_disable_vpocs(struct ub960_data *priv)
{}

static void ub960_rxport_clear_errors(struct ub960_data *priv,
				      unsigned int nport)
{}

static void ub960_clear_rx_errors(struct ub960_data *priv)
{}

static int ub960_rxport_get_strobe_pos(struct ub960_data *priv,
				       unsigned int nport, s8 *strobe_pos)
{}

static void ub960_rxport_set_strobe_pos(struct ub960_data *priv,
					unsigned int nport, s8 strobe_pos)
{}

static void ub960_rxport_set_strobe_range(struct ub960_data *priv,
					  s8 strobe_min, s8 strobe_max)
{}

static int ub960_rxport_get_eq_level(struct ub960_data *priv,
				     unsigned int nport, u8 *eq_level)
{}

static void ub960_rxport_set_eq_level(struct ub960_data *priv,
				      unsigned int nport, u8 eq_level)
{}

static void ub960_rxport_set_eq_range(struct ub960_data *priv,
				      unsigned int nport, u8 eq_min, u8 eq_max)
{}

static void ub960_rxport_config_eq(struct ub960_data *priv, unsigned int nport)
{}

static int ub960_rxport_link_ok(struct ub960_data *priv, unsigned int nport,
				bool *ok)
{}

/*
 * Wait for the RX ports to lock, have no errors and have stable strobe position
 * and EQ level.
 */
static int ub960_rxport_wait_locks(struct ub960_data *priv,
				   unsigned long port_mask,
				   unsigned int *lock_mask)
{}

static unsigned long ub960_calc_bc_clk_rate_ub960(struct ub960_data *priv,
						  struct ub960_rxport *rxport)
{}

static unsigned long ub960_calc_bc_clk_rate_ub9702(struct ub960_data *priv,
						   struct ub960_rxport *rxport)
{}

static int ub960_rxport_add_serializer(struct ub960_data *priv, u8 nport)
{}

static void ub960_rxport_remove_serializer(struct ub960_data *priv, u8 nport)
{}

/* Add serializer i2c devices for all initialized ports */
static int ub960_rxport_add_serializers(struct ub960_data *priv)
{}

static void ub960_rxport_remove_serializers(struct ub960_data *priv)
{}

static void ub960_init_tx_port(struct ub960_data *priv,
			       struct ub960_txport *txport)
{}

static int ub960_init_tx_ports(struct ub960_data *priv)
{}

static void ub960_init_rx_port_ub960(struct ub960_data *priv,
				     struct ub960_rxport *rxport)
{}

static void ub960_init_rx_port_ub9702_fpd3(struct ub960_data *priv,
					   struct ub960_rxport *rxport)
{}

static void ub960_init_rx_port_ub9702_fpd4_aeq(struct ub960_data *priv,
					       struct ub960_rxport *rxport)
{}

static void ub960_init_rx_port_ub9702_fpd4(struct ub960_data *priv,
					   struct ub960_rxport *rxport)
{}

static void ub960_init_rx_port_ub9702(struct ub960_data *priv,
				      struct ub960_rxport *rxport)
{}

static int ub960_init_rx_ports(struct ub960_data *priv)
{}

static void ub960_rxport_handle_events(struct ub960_data *priv, u8 nport)
{}

/* -----------------------------------------------------------------------------
 * V4L2
 */

/*
 * The current implementation only supports a simple VC mapping, where all VCs
 * from a one RX port will be mapped to the same VC. Also, the hardware
 * dictates that all streams from an RX port must go to a single TX port.
 *
 * This function decides the target VC numbers for each RX port with a simple
 * algorithm, so that for each TX port, we get VC numbers starting from 0,
 * and counting up.
 *
 * E.g. if all four RX ports are in use, of which the first two go to the
 * first TX port and the secont two go to the second TX port, we would get
 * the following VCs for the four RX ports: 0, 1, 0, 1.
 *
 * TODO: implement a more sophisticated VC mapping. As the driver cannot know
 * what VCs the sinks expect (say, an FPGA with hardcoded VC routing), this
 * probably needs to be somehow configurable. Device tree?
 */
static void ub960_get_vc_maps(struct ub960_data *priv,
			      struct v4l2_subdev_state *state, u8 *vc)
{}

static int ub960_enable_tx_port(struct ub960_data *priv, unsigned int nport)
{}

static void ub960_disable_tx_port(struct ub960_data *priv, unsigned int nport)
{}

static int ub960_enable_rx_port(struct ub960_data *priv, unsigned int nport)
{}

static void ub960_disable_rx_port(struct ub960_data *priv, unsigned int nport)
{}

/*
 * The driver only supports using a single VC for each source. This function
 * checks that each source only provides streams using a single VC.
 */
static int ub960_validate_stream_vcs(struct ub960_data *priv)
{}

static int ub960_configure_ports_for_streaming(struct ub960_data *priv,
					       struct v4l2_subdev_state *state)
{}

static void ub960_update_streaming_status(struct ub960_data *priv)
{}

static int ub960_enable_streams(struct v4l2_subdev *sd,
				struct v4l2_subdev_state *state, u32 source_pad,
				u64 source_streams_mask)
{}

static int ub960_disable_streams(struct v4l2_subdev *sd,
				 struct v4l2_subdev_state *state,
				 u32 source_pad, u64 source_streams_mask)
{}

static int _ub960_set_routing(struct v4l2_subdev *sd,
			      struct v4l2_subdev_state *state,
			      struct v4l2_subdev_krouting *routing)
{}

static int ub960_set_routing(struct v4l2_subdev *sd,
			     struct v4l2_subdev_state *state,
			     enum v4l2_subdev_format_whence which,
			     struct v4l2_subdev_krouting *routing)
{}

static int ub960_get_frame_desc(struct v4l2_subdev *sd, unsigned int pad,
				struct v4l2_mbus_frame_desc *fd)
{}

static int ub960_set_fmt(struct v4l2_subdev *sd,
			 struct v4l2_subdev_state *state,
			 struct v4l2_subdev_format *format)
{}

static int ub960_init_state(struct v4l2_subdev *sd,
			    struct v4l2_subdev_state *state)
{}

static const struct v4l2_subdev_pad_ops ub960_pad_ops =;

static int ub960_log_status(struct v4l2_subdev *sd)
{}

static const struct v4l2_subdev_core_ops ub960_subdev_core_ops =;

static const struct v4l2_subdev_internal_ops ub960_internal_ops =;

static const struct v4l2_subdev_ops ub960_subdev_ops =;

static const struct media_entity_operations ub960_entity_ops =;

/* -----------------------------------------------------------------------------
 * Core
 */

static irqreturn_t ub960_handle_events(int irq, void *arg)
{}

static void ub960_handler_work(struct work_struct *work)
{}

static void ub960_txport_free_ports(struct ub960_data *priv)
{}

static void ub960_rxport_free_ports(struct ub960_data *priv)
{}

static int
ub960_parse_dt_rxport_link_properties(struct ub960_data *priv,
				      struct fwnode_handle *link_fwnode,
				      struct ub960_rxport *rxport)
{}

static int ub960_parse_dt_rxport_ep_properties(struct ub960_data *priv,
					       struct fwnode_handle *ep_fwnode,
					       struct ub960_rxport *rxport)
{}

static int ub960_parse_dt_rxport(struct ub960_data *priv, unsigned int nport,
				 struct fwnode_handle *link_fwnode,
				 struct fwnode_handle *ep_fwnode)
{}

static struct fwnode_handle *
ub960_fwnode_get_link_by_regs(struct fwnode_handle *links_fwnode,
			      unsigned int nport)
{}

static int ub960_parse_dt_rxports(struct ub960_data *priv)
{}

static int ub960_parse_dt_txports(struct ub960_data *priv)
{}

static int ub960_parse_dt(struct ub960_data *priv)
{}

static int ub960_notify_bound(struct v4l2_async_notifier *notifier,
			      struct v4l2_subdev *subdev,
			      struct v4l2_async_connection *asd)
{}

static void ub960_notify_unbind(struct v4l2_async_notifier *notifier,
				struct v4l2_subdev *subdev,
				struct v4l2_async_connection *asd)
{}

static const struct v4l2_async_notifier_operations ub960_notify_ops =;

static int ub960_v4l2_notifier_register(struct ub960_data *priv)
{}

static void ub960_v4l2_notifier_unregister(struct ub960_data *priv)
{}

static int ub960_create_subdev(struct ub960_data *priv)
{}

static void ub960_destroy_subdev(struct ub960_data *priv)
{}

static const struct regmap_config ub960_regmap_config =;

static void ub960_reset(struct ub960_data *priv, bool reset_regs)
{}

static int ub960_get_hw_resources(struct ub960_data *priv)
{}

static int ub960_enable_core_hw(struct ub960_data *priv)
{}

static void ub960_disable_core_hw(struct ub960_data *priv)
{}

static int ub960_probe(struct i2c_client *client)
{}

static void ub960_remove(struct i2c_client *client)
{}

static const struct ub960_hw_data ds90ub960_hw =;

static const struct ub960_hw_data ds90ub9702_hw =;

static const struct i2c_device_id ub960_id[] =;
MODULE_DEVICE_TABLE(i2c, ub960_id);

static const struct of_device_id ub960_dt_ids[] =;
MODULE_DEVICE_TABLE(of, ub960_dt_ids);

static struct i2c_driver ds90ub960_driver =;
module_i2c_driver();

MODULE_LICENSE();
MODULE_DESCRIPTION();
MODULE_AUTHOR();
MODULE_AUTHOR();
MODULE_IMPORT_NS();