// SPDX-License-Identifier: GPL-2.0
/*
* Driver for the Texas Instruments DS90UB953 video serializer
*
* Based on a driver from Luca Ceresoli <luca@lucaceresoli.net>
*
* Copyright (c) 2019 Luca Ceresoli <luca@lucaceresoli.net>
* Copyright (c) 2023 Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
*/
#include <linux/clk-provider.h>
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/gpio/driver.h>
#include <linux/i2c-atr.h>
#include <linux/i2c.h>
#include <linux/kernel.h>
#include <linux/math64.h>
#include <linux/module.h>
#include <linux/property.h>
#include <linux/rational.h>
#include <linux/regmap.h>
#include <media/i2c/ds90ub9xx.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-fwnode.h>
#include <media/v4l2-mediabus.h>
#include <media/v4l2-subdev.h>
#include "ds90ub953.h"
#define UB953_PAD_SINK 0
#define UB953_PAD_SOURCE 1
#define UB953_NUM_GPIOS 4
#define UB953_DEFAULT_CLKOUT_RATE 25000000UL
/* Note: Only sync mode supported for now */
enum ub953_mode {
/* FPD-Link III CSI-2 synchronous mode */
UB953_MODE_SYNC,
/* FPD-Link III CSI-2 non-synchronous mode, external ref clock */
UB953_MODE_NONSYNC_EXT,
/* FPD-Link III CSI-2 non-synchronous mode, internal ref clock */
UB953_MODE_NONSYNC_INT,
/* FPD-Link III DVP mode */
UB953_MODE_DVP,
};
struct ub953_hw_data {
const char *model;
bool is_ub971;
};
struct ub953_clkout_data {
u32 hs_div;
u32 m;
u32 n;
unsigned long rate;
};
struct ub953_data {
const struct ub953_hw_data *hw_data;
struct i2c_client *client;
struct regmap *regmap;
struct clk *clkin;
u32 num_data_lanes;
bool non_continous_clk;
struct gpio_chip gpio_chip;
struct v4l2_subdev sd;
struct media_pad pads[2];
struct v4l2_async_notifier notifier;
struct v4l2_subdev *source_sd;
u16 source_sd_pad;
u64 enabled_source_streams;
/* lock for register access */
struct mutex reg_lock;
u8 current_indirect_target;
struct clk_hw clkout_clk_hw;
enum ub953_mode