File Index
Files and directories
Sign in
FILE

max96714.c

File preview with syntax highlighting.

linux-6.19.14/drivers/media/i2c/max96714.c C
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Maxim GMSL2 Deserializer Driver
   4 *
   5 * Copyright (C) 2024 Collabora Ltd.
   6 */
   7
   8#include <linux/bitfield.h>
   9#include <linux/bitops.h>
  10#include <linux/gpio/consumer.h>
  11#include <linux/i2c.h>
  12#include <linux/i2c-mux.h>
  13#include <linux/module.h>
  14#include <linux/property.h>
  15#include <linux/regmap.h>
  16#include <linux/regulator/consumer.h>
  17
  18#include <media/v4l2-cci.h>
  19#include <media/v4l2-ctrls.h>
  20#include <media/v4l2-fwnode.h>
  21#include <media/v4l2-subdev.h>
  22
  23#define MAX96714_DEVICE_ID  0xc9
  24#define MAX96714F_DEVICE_ID 0xca
  25#define MAX96714_NPORTS     2
  26#define MAX96714_PAD_SINK   0
  27#define MAX96714_PAD_SOURCE 1
  28#define MAX96714_CSI_NLANES 4
  29
  30/* DEV */
  31#define MAX96714_REG13                 CCI_REG8(0x0d)
  32#define MAX96714_DEV_REV               CCI_REG8(0x0e)
  33#define MAX96714_DEV_REV_MASK          GENMASK(3, 0)
  34#define MAX96714_LINK_LOCK             CCI_REG8(0x13)
  35#define MAX96714_LINK_LOCK_BIT         BIT(3)
  36#define MAX96714_IO_CHK0               CCI_REG8(0x38)
  37#define MAX96714_PATTERN_CLK_FREQ      GENMASK(1, 0)
  38/* VID_RX */
  39#define MAX96714_VIDEO_RX8             CCI_REG8(0x11a)
  40#define MAX96714_VID_LOCK              BIT(6)
  41
  42/* VRX_PATGEN_0 */
  43#define MAX96714_PATGEN_0              CCI_REG8(0x240)
  44#define MAX96714_PATGEN_1              CCI_REG8(0x241)
  45#define MAX96714_PATGEN_MODE           GENMASK(5, 4)
  46#define MAX96714_PATGEN_VS_DLY         CCI_REG24(0x242)
  47#define MAX96714_PATGEN_VS_HIGH        CCI_REG24(0x245)
  48#define MAX96714_PATGEN_VS_LOW         CCI_REG24(0x248)
  49#define MAX96714_PATGEN_V2H            CCI_REG24(0x24b)
  50#define MAX96714_PATGEN_HS_HIGH        CCI_REG16(0x24e)
  51#define MAX96714_PATGEN_HS_LOW         CCI_REG16(0x250)
  52#define MAX96714_PATGEN_HS_CNT         CCI_REG16(0x252)
  53#define MAX96714_PATGEN_V2D            CCI_REG24(0x254)
  54#define MAX96714_PATGEN_DE_HIGH        CCI_REG16(0x257)
  55#define MAX96714_PATGEN_DE_LOW         CCI_REG16(0x259)
  56#define MAX96714_PATGEN_DE_CNT         CCI_REG16(0x25b)
  57#define MAX96714_PATGEN_GRAD_INC       CCI_REG8(0x25d)
  58#define MAX96714_PATGEN_CHKB_COLOR_A   CCI_REG24(0x25e)
  59#define MAX96714_PATGEN_CHKB_COLOR_B   CCI_REG24(0x261)
  60#define MAX96714_PATGEN_CHKB_RPT_CNT_A CCI_REG8(0x264)
  61#define MAX96714_PATGEN_CHKB_RPT_CNT_B CCI_REG8(0x265)
  62#define MAX96714_PATGEN_CHKB_ALT       CCI_REG8(0x266)
  63/* BACKTOP */
  64#define MAX96714_BACKTOP25             CCI_REG8(0x320)
  65#define CSI_DPLL_FREQ_MASK             GENMASK(4, 0)
  66
  67/* MIPI_PHY */
  68#define MAX96714_MIPI_PHY0             CCI_REG8(0x330)
  69#define MAX96714_FORCE_CSI_OUT         BIT(7)
  70#define MAX96714_MIPI_STDBY_N          CCI_REG8(0x332)
  71#define MAX96714_MIPI_STDBY_MASK       GENMASK(5, 4)
  72#define MAX96714_MIPI_LANE_MAP         CCI_REG8(0x333)
  73#define MAX96714_MIPI_POLARITY         CCI_REG8(0x335)
  74#define MAX96714_MIPI_POLARITY_MASK    GENMASK(5, 0)
  75
  76/* MIPI_TX */
  77#define MAX96714_MIPI_LANE_CNT         CCI_REG8(0x44a)
  78#define MAX96714_CSI2_LANE_CNT_MASK    GENMASK(7, 6)
  79#define MAX96714_MIPI_TX52             CCI_REG8(0x474)
  80#define MAX96714_TUN_EN                BIT(0)
  81
  82#define MHZ(v) ((u32)((v)  * 1000000U))
  83
  84enum max96714_vpg_mode {
  85	MAX96714_VPG_DISABLED = 0,
  86	MAX96714_VPG_CHECKERBOARD = 1,
  87	MAX96714_VPG_GRADIENT = 2,
  88};
  89
  90struct max96714_rxport {
  91	struct {
  92		struct v4l2_subdev   *sd;
  93		u16                  pad;
  94		struct fwnode_handle *ep_fwnode;
  95	} source;
  96	struct regulator	     *poc;
  97};
  98
  99struct max96714_txport {
 100	struct v4l2_fwnode_endpoint vep;
 101};
 102
 103struct max96714_priv {
 104	struct i2c_client                 *client;
 105	struct regmap                     *regmap;
 106	struct gpio_desc                  *pd_gpio;
 107	struct max96714_rxport            rxport;
 108	struct i2c_mux_core               *mux;
 109	u64                               enabled_source_streams;
 110	struct v4l2_subdev		  sd;
 111	struct media_pad		  pads[MAX96714_NPORTS];
 112	struct v4l2_mbus_config_mipi_csi2 mipi_csi2;
 113	struct v4l2_ctrl_handler          ctrl_handler;
 114	struct v4l2_async_notifier        notifier;
 115	s64                               tx_link_freq;
 116	enum max96714_vpg_mode            pattern;
 117};
 118
 119static inline struct max96714_priv *sd_to_max96714(struct v4l2_subdev *sd)
 120{
 121	return container_of(sd, struct max96714_priv, sd);
 122}
 123
 124static int max96714_enable_tx_port(struct max96714_priv *priv)
 125{
 126	return cci_update_bits(priv->regmap, MAX96714_MIPI_STDBY_N,
 127			       MAX96714_MIPI_STDBY_MASK,
 128			       MAX96714_MIPI_STDBY_MASK, NULL);
 129}
 130
 131static int max96714_disable_tx_port(struct max96714_priv *priv)
 132{
 133	return cci_update_bits(priv->regmap, MAX96714_MIPI_STDBY_N,
 134			       MAX96714_MIPI_STDBY_MASK, 0, NULL);
 135}
 136
 137static bool max96714_tx_port_enabled(struct max96714_priv *priv)
 138{
 139	u64 val;
 140
 141	cci_read(priv->regmap, MAX96714_MIPI_STDBY_N, &val, NULL);
 142
 143	return val & MAX96714_MIPI_STDBY_MASK;
 144}
 145
 146static int max96714_apply_patgen_timing(struct max96714_priv *priv,
 147					struct v4l2_subdev_state *state)
 148{
 149	struct v4l2_mbus_framefmt *fmt =
 150		v4l2_subdev_state_get_format(state, MAX96714_PAD_SOURCE);
 151	const u32 h_active = fmt->width;
 152	const u32 h_fp = 88;
 153	const u32 h_sw = 44;
 154	const u32 h_bp = 148;
 155	u32 h_tot;
 156	const u32 v_active = fmt->height;
 157	const u32 v_fp = 4;
 158	const u32 v_sw = 5;
 159	const u32 v_bp = 36;
 160	u32 v_tot;
 161	int ret = 0;
 162
 163	h_tot = h_active + h_fp + h_sw + h_bp;
 164	v_tot = v_active + v_fp + v_sw + v_bp;
 165
 166	/* 75 Mhz pixel clock */
 167	cci_update_bits(priv->regmap, MAX96714_IO_CHK0,
 168			MAX96714_PATTERN_CLK_FREQ, 1, &ret);
 169
 170	dev_info(&priv->client->dev, "height: %d width: %d\n", fmt->height,
 171		 fmt->width);
 172
 173	cci_write(priv->regmap, MAX96714_PATGEN_VS_DLY, 0, &ret);
 174	cci_write(priv->regmap, MAX96714_PATGEN_VS_HIGH, v_sw * h_tot, &ret);
 175	cci_write(priv->regmap, MAX96714_PATGEN_VS_LOW,
 176		  (v_active + v_fp + v_bp) * h_tot, &ret);
 177	cci_write(priv->regmap, MAX96714_PATGEN_HS_HIGH, h_sw, &ret);
 178	cci_write(priv->regmap, MAX96714_PATGEN_HS_LOW, h_active + h_fp + h_bp,
 179		  &ret);
 180	cci_write(priv->regmap, MAX96714_PATGEN_V2D,
 181		  h_tot * (v_sw + v_bp) + (h_sw + h_bp), &ret);
 182	cci_write(priv->regmap, MAX96714_PATGEN_HS_CNT, v_tot, &ret);
 183	cci_write(priv->regmap, MAX96714_PATGEN_DE_HIGH, h_active, &ret);
 184	cci_write(priv->regmap, MAX96714_PATGEN_DE_LOW, h_fp + h_sw + h_bp,
 185		  &ret);
 186	cci_write(priv->regmap, MAX96714_PATGEN_DE_CNT, v_active, &ret);
 187	/* B G R */
 188	cci_write(priv->regmap, MAX96714_PATGEN_CHKB_COLOR_A, 0xfecc00, &ret);
 189	/* B G R */
 190	cci_write(priv->regmap, MAX96714_PATGEN_CHKB_COLOR_B, 0x006aa7, &ret);
 191	cci_write(priv->regmap, MAX96714_PATGEN_CHKB_RPT_CNT_A, 0x3c, &ret);
 192	cci_write(priv->regmap, MAX96714_PATGEN_CHKB_RPT_CNT_B, 0x3c, &ret);
 193	cci_write(priv->regmap, MAX96714_PATGEN_CHKB_ALT, 0x3c, &ret);
 194	cci_write(priv->regmap, MAX96714_PATGEN_GRAD_INC, 0x10, &ret);
 195
 196	return ret;
 197}
 198
 199static int max96714_apply_patgen(struct max96714_priv *priv,
 200				 struct v4l2_subdev_state *state)
 201{
 202	unsigned int val;
 203	int ret = 0;
 204
 205	if (priv->pattern)
 206		ret = max96714_apply_patgen_timing(priv, state);
 207
 208	cci_write(priv->regmap, MAX96714_PATGEN_0, priv->pattern ? 0xfb : 0,
 209		  &ret);
 210
 211	val = FIELD_PREP(MAX96714_PATGEN_MODE, priv->pattern);
 212	cci_update_bits(priv->regmap, MAX96714_PATGEN_1, MAX96714_PATGEN_MODE,
 213			val, &ret);
 214	return ret;
 215}
 216
 217static int max96714_s_ctrl(struct v4l2_ctrl *ctrl)
 218{
 219	struct max96714_priv *priv =
 220		container_of(ctrl->handler, struct max96714_priv, ctrl_handler);
 221	int ret;
 222
 223	switch (ctrl->id) {
 224	case V4L2_CID_TEST_PATTERN:
 225		if (priv->enabled_source_streams)
 226			return -EBUSY;
 227		priv->pattern = ctrl->val;
 228		break;
 229	default:
 230		return -EINVAL;
 231	}
 232
 233	ret = cci_update_bits(priv->regmap, MAX96714_MIPI_PHY0,
 234			      MAX96714_FORCE_CSI_OUT,
 235			      priv->pattern ? MAX96714_FORCE_CSI_OUT : 0, NULL);
 236
 237	/* Pattern generator doesn't work with tunnel mode */
 238	return cci_update_bits(priv->regmap, MAX96714_MIPI_TX52,
 239			       MAX96714_TUN_EN,
 240			       priv->pattern ? 0 : MAX96714_TUN_EN, &ret);
 241}
 242
 243static const char * const max96714_test_pattern[] = {
 244	"Disabled",
 245	"Checkerboard",
 246	"Gradient"
 247};
 248
 249static const struct v4l2_ctrl_ops max96714_ctrl_ops = {
 250	.s_ctrl = max96714_s_ctrl,
 251};
 252
 253static int max96714_enable_streams(struct v4l2_subdev *sd,
 254				   struct v4l2_subdev_state *state,
 255				   u32 source_pad, u64 streams_mask)
 256{
 257	struct max96714_priv *priv = sd_to_max96714(sd);
 258	u64 sink_streams;
 259	int ret;
 260
 261	if (!priv->enabled_source_streams)
 262		max96714_enable_tx_port(priv);
 263
 264	ret = max96714_apply_patgen(priv, state);
 265	if (ret)
 266		goto err;
 267
 268	if (!priv->pattern) {
 269		if (!priv->rxport.source.sd) {
 270			ret = -ENODEV;
 271			goto err;
 272		}
 273
 274		sink_streams =
 275			v4l2_subdev_state_xlate_streams(state,
 276							MAX96714_PAD_SOURCE,
 277							MAX96714_PAD_SINK,
 278							&streams_mask);
 279
 280		ret = v4l2_subdev_enable_streams(priv->rxport.source.sd,
 281						 priv->rxport.source.pad,
 282						 sink_streams);
 283		if (ret)
 284			goto err;
 285	}
 286
 287	priv->enabled_source_streams |= streams_mask;
 288
 289	return 0;
 290
 291err:
 292	if (!priv->enabled_source_streams)
 293		max96714_disable_tx_port(priv);
 294
 295	return ret;
 296}
 297
 298static int max96714_disable_streams(struct v4l2_subdev *sd,
 299				    struct v4l2_subdev_state *state,
 300				    u32 source_pad, u64 streams_mask)
 301{
 302	struct max96714_priv *priv = sd_to_max96714(sd);
 303	u64 sink_streams;
 304
 305	if (!priv->pattern) {
 306		int ret;
 307
 308		sink_streams =
 309			v4l2_subdev_state_xlate_streams(state,
 310							MAX96714_PAD_SOURCE,
 311							MAX96714_PAD_SINK,
 312							&streams_mask);
 313
 314		ret = v4l2_subdev_disable_streams(priv->rxport.source.sd,
 315						  priv->rxport.source.pad,
 316						  sink_streams);
 317		if (ret)
 318			return ret;
 319	}
 320
 321	priv->enabled_source_streams &= ~streams_mask;
 322
 323	if (!priv->enabled_source_streams)
 324		max96714_disable_tx_port(priv);
 325
 326	return 0;
 327}
 328
 329static int max96714_set_fmt(struct v4l2_subdev *sd,
 330			    struct v4l2_subdev_state *state,
 331			    struct v4l2_subdev_format *format)
 332{
 333	struct max96714_priv *priv = sd_to_max96714(sd);
 334	struct v4l2_mbus_framefmt *fmt;
 335
 336	if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE &&
 337	    priv->enabled_source_streams)
 338		return -EBUSY;
 339
 340	/* No transcoding, source and sink formats must match. */
 341	if (format->pad == MAX96714_PAD_SOURCE)
 342		return v4l2_subdev_get_fmt(sd, state, format);
 343
 344	fmt = v4l2_subdev_state_get_format(state, format->pad, format->stream);
 345	if (!fmt)
 346		return -EINVAL;
 347
 348	*fmt = format->format;
 349
 350	fmt = v4l2_subdev_state_get_opposite_stream_format(state, format->pad,
 351							   format->stream);
 352	if (!fmt)
 353		return -EINVAL;
 354
 355	*fmt = format->format;
 356
 357	return 0;
 358}
 359
 360static int _max96714_set_routing(struct v4l2_subdev *sd,
 361				 struct v4l2_subdev_state *state,
 362				 enum v4l2_subdev_format_whence which,
 363				 struct v4l2_subdev_krouting *routing)
 364{
 365	static const struct v4l2_mbus_framefmt format = {
 366		.width = 1280,
 367		.height = 1080,
 368		.code = MEDIA_BUS_FMT_Y8_1X8,
 369		.field = V4L2_FIELD_NONE,
 370	};
 371	int ret;
 372
 373	ret = v4l2_subdev_routing_validate(sd, routing,
 374					   V4L2_SUBDEV_ROUTING_ONLY_1_TO_1);
 375	if (ret)
 376		return ret;
 377
 378	return v4l2_subdev_set_routing_with_fmt(sd, state, routing, &format);
 379}
 380
 381static int max96714_set_routing(struct v4l2_subdev *sd,
 382				struct v4l2_subdev_state *state,
 383				enum v4l2_subdev_format_whence which,
 384				struct v4l2_subdev_krouting *routing)
 385{
 386	struct max96714_priv *priv = sd_to_max96714(sd);
 387
 388	if (which == V4L2_SUBDEV_FORMAT_ACTIVE && priv->enabled_source_streams)
 389		return -EBUSY;
 390
 391	return _max96714_set_routing(sd, state, which, routing);
 392}
 393
 394static int max96714_init_state(struct v4l2_subdev *sd,
 395			       struct v4l2_subdev_state *state)
 396{
 397	struct v4l2_subdev_route routes[] = {
 398		{
 399			.sink_pad = MAX96714_PAD_SINK,
 400			.sink_stream = 0,
 401			.source_pad = MAX96714_PAD_SOURCE,
 402			.source_stream = 0,
 403			.flags = V4L2_SUBDEV_ROUTE_FL_ACTIVE,
 404		}
 405	};
 406	struct v4l2_subdev_krouting routing = {
 407		.num_routes = ARRAY_SIZE(routes),
 408		.routes = routes,
 409	};
 410
 411	return _max96714_set_routing(sd, state, V4L2_SUBDEV_FORMAT_ACTIVE,
 412				     &routing);
 413}
 414
 415static const struct v4l2_subdev_pad_ops max96714_pad_ops = {
 416	.enable_streams = max96714_enable_streams,
 417	.disable_streams = max96714_disable_streams,
 418
 419	.set_routing = max96714_set_routing,
 420	.get_fmt = v4l2_subdev_get_fmt,
 421	.set_fmt = max96714_set_fmt,
 422};
 423
 424static bool max96714_link_locked(struct max96714_priv *priv)
 425{
 426	u64 val = 0;
 427
 428	cci_read(priv->regmap, MAX96714_LINK_LOCK, &val, NULL);
 429
 430	return val & MAX96714_LINK_LOCK_BIT;
 431}
 432
 433static void max96714_link_status(struct max96714_priv *priv)
 434{
 435	struct device *dev = &priv->client->dev;
 436
 437	dev_info(dev, "Link locked:%d\n", max96714_link_locked(priv));
 438}
 439
 440static bool max96714_pipe_locked(struct max96714_priv *priv)
 441{
 442	u64 val;
 443
 444	cci_read(priv->regmap, MAX96714_VIDEO_RX8, &val, NULL);
 445
 446	return val & MAX96714_VID_LOCK;
 447}
 448
 449static void max96714_pipe_status(struct max96714_priv *priv)
 450{
 451	struct device *dev = &priv->client->dev;
 452
 453	dev_info(dev, "Pipe vidlock:%d\n", max96714_pipe_locked(priv));
 454}
 455
 456static void max96714_csi_status(struct max96714_priv *priv)
 457{
 458	struct device *dev = &priv->client->dev;
 459	u64 freq = 0;
 460
 461	cci_read(priv->regmap, MAX96714_BACKTOP25, &freq, NULL);
 462	freq = FIELD_GET(CSI_DPLL_FREQ_MASK, freq);
 463
 464	dev_info(dev, "CSI controller DPLL freq:%u00MHz CSIPHY enabled:%d\n",
 465		 (u8)freq, max96714_tx_port_enabled(priv));
 466}
 467
 468static int max96714_log_status(struct v4l2_subdev *sd)
 469{
 470	struct max96714_priv *priv = sd_to_max96714(sd);
 471	struct device *dev = &priv->client->dev;
 472
 473	dev_info(dev, "Deserializer: max96714\n");
 474
 475	max96714_link_status(priv);
 476	max96714_pipe_status(priv);
 477	max96714_csi_status(priv);
 478
 479	return 0;
 480}
 481
 482static const struct v4l2_subdev_core_ops max96714_subdev_core_ops = {
 483	.log_status = max96714_log_status,
 484};
 485
 486static const struct v4l2_subdev_video_ops max96714_video_ops = {
 487	.s_stream	= v4l2_subdev_s_stream_helper,
 488};
 489
 490static const struct v4l2_subdev_internal_ops max96714_internal_ops = {
 491	.init_state = max96714_init_state,
 492};
 493
 494static const struct v4l2_subdev_ops max96714_subdev_ops = {
 495	.video = &max96714_video_ops,
 496	.core = &max96714_subdev_core_ops,
 497	.pad = &max96714_pad_ops,
 498};
 499
 500static const struct media_entity_operations max96714_entity_ops = {
 501	.link_validate = v4l2_subdev_link_validate,
 502};
 503
 504static int max96714_notify_bound(struct v4l2_async_notifier *notifier,
 505				 struct v4l2_subdev *subdev,
 506				 struct v4l2_async_connection *asd)
 507{
 508	struct max96714_priv *priv = sd_to_max96714(notifier->sd);
 509	struct device *dev = &priv->client->dev;
 510	int ret;
 511
 512	ret = media_entity_get_fwnode_pad(&subdev->entity,
 513					  priv->rxport.source.ep_fwnode,
 514					  MEDIA_PAD_FL_SOURCE);
 515	if (ret < 0) {
 516		dev_err(dev, "Failed to find pad for %s\n", subdev->name);
 517		return ret;
 518	}
 519
 520	priv->rxport.source.sd = subdev;
 521	priv->rxport.source.pad = ret;
 522
 523	ret = media_create_pad_link(&priv->rxport.source.sd->entity,
 524				    priv->rxport.source.pad, &priv->sd.entity,
 525				    MAX96714_PAD_SINK,
 526				    MEDIA_LNK_FL_ENABLED |
 527				    MEDIA_LNK_FL_IMMUTABLE);
 528	if (ret) {
 529		dev_err(dev, "Unable to link %s:%u -> %s:%u\n",
 530			priv->rxport.source.sd->name, priv->rxport.source.pad,
 531			priv->sd.name, MAX96714_PAD_SINK);
 532		return ret;
 533	}
 534
 535	return 0;
 536}
 537
 538static const struct v4l2_async_notifier_operations max96714_notify_ops = {
 539	.bound = max96714_notify_bound,
 540};
 541
 542static int max96714_v4l2_notifier_register(struct max96714_priv *priv)
 543{
 544	struct device *dev = &priv->client->dev;
 545	struct max96714_rxport *rxport = &priv->rxport;
 546	struct v4l2_async_connection *asd;
 547	int ret;
 548
 549	if (!rxport->source.ep_fwnode)
 550		return 0;
 551
 552	v4l2_async_subdev_nf_init(&priv->notifier, &priv->sd);
 553
 554	asd = v4l2_async_nf_add_fwnode(&priv->notifier,
 555				       rxport->source.ep_fwnode,
 556				       struct v4l2_async_connection);
 557	if (IS_ERR(asd)) {
 558		dev_err(dev, "Failed to add subdev: %pe", asd);
 559		v4l2_async_nf_cleanup(&priv->notifier);
 560		return PTR_ERR(asd);
 561	}
 562
 563	priv->notifier.ops = &max96714_notify_ops;
 564
 565	ret = v4l2_async_nf_register(&priv->notifier);
 566	if (ret) {
 567		dev_err(dev, "Failed to register subdev_notifier");
 568		v4l2_async_nf_cleanup(&priv->notifier);
 569		return ret;
 570	}
 571
 572	return 0;
 573}
 574
 575static int max96714_create_subdev(struct max96714_priv *priv)
 576{
 577	struct device *dev = &priv->client->dev;
 578	int ret;
 579
 580	v4l2_i2c_subdev_init(&priv->sd, priv->client, &max96714_subdev_ops);
 581	priv->sd.internal_ops = &max96714_internal_ops;
 582
 583	v4l2_ctrl_handler_init(&priv->ctrl_handler, 1);
 584	priv->sd.ctrl_handler = &priv->ctrl_handler;
 585
 586	v4l2_ctrl_new_int_menu(&priv->ctrl_handler, NULL, V4L2_CID_LINK_FREQ,
 587			       0, 0, &priv->tx_link_freq);
 588	v4l2_ctrl_new_std_menu_items(&priv->ctrl_handler,
 589				     &max96714_ctrl_ops,
 590				     V4L2_CID_TEST_PATTERN,
 591				     ARRAY_SIZE(max96714_test_pattern) - 1,
 592				     0, 0, max96714_test_pattern);
 593	if (priv->ctrl_handler.error) {
 594		ret = priv->ctrl_handler.error;
 595		goto err_free_ctrl;
 596	}
 597
 598	priv->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_STREAMS;
 599	priv->sd.entity.function = MEDIA_ENT_F_VID_IF_BRIDGE;
 600	priv->sd.entity.ops = &max96714_entity_ops;
 601
 602	priv->pads[MAX96714_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
 603	priv->pads[MAX96714_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
 604
 605	ret = media_entity_pads_init(&priv->sd.entity,
 606				     MAX96714_NPORTS,
 607				     priv->pads);
 608	if (ret)
 609		goto err_free_ctrl;
 610
 611	priv->sd.state_lock = priv->sd.ctrl_handler->lock;
 612
 613	ret = v4l2_subdev_init_finalize(&priv->sd);
 614	if (ret)
 615		goto err_entity_cleanup;
 616
 617	ret = max96714_v4l2_notifier_register(priv);
 618	if (ret) {
 619		dev_err(dev, "v4l2 subdev notifier register failed: %d\n", ret);
 620		goto err_subdev_cleanup;
 621	}
 622
 623	ret = v4l2_async_register_subdev(&priv->sd);
 624	if (ret) {
 625		dev_err(dev, "v4l2_async_register_subdev error: %d\n", ret);
 626		goto err_unreg_notif;
 627	}
 628
 629	return 0;
 630
 631err_unreg_notif:
 632	v4l2_async_nf_unregister(&priv->notifier);
 633	v4l2_async_nf_cleanup(&priv->notifier);
 634err_subdev_cleanup:
 635	v4l2_subdev_cleanup(&priv->sd);
 636err_entity_cleanup:
 637	media_entity_cleanup(&priv->sd.entity);
 638err_free_ctrl:
 639	v4l2_ctrl_handler_free(&priv->ctrl_handler);
 640
 641	return ret;
 642};
 643
 644static void max96714_destroy_subdev(struct max96714_priv *priv)
 645{
 646	v4l2_async_nf_unregister(&priv->notifier);
 647	v4l2_async_nf_cleanup(&priv->notifier);
 648	v4l2_async_unregister_subdev(&priv->sd);
 649
 650	v4l2_subdev_cleanup(&priv->sd);
 651
 652	media_entity_cleanup(&priv->sd.entity);
 653	v4l2_ctrl_handler_free(&priv->ctrl_handler);
 654}
 655
 656static int max96714_i2c_mux_select(struct i2c_mux_core *mux, u32 chan)
 657{
 658	return 0;
 659}
 660
 661static int max96714_i2c_mux_init(struct max96714_priv *priv)
 662{
 663	priv->mux = i2c_mux_alloc(priv->client->adapter, &priv->client->dev,
 664				  1, 0, I2C_MUX_LOCKED | I2C_MUX_GATE,
 665				  max96714_i2c_mux_select, NULL);
 666	if (!priv->mux)
 667		return -ENOMEM;
 668
 669	return i2c_mux_add_adapter(priv->mux, 0, 0);
 670}
 671
 672static int max96714_init_tx_port(struct max96714_priv *priv)
 673{
 674	struct v4l2_mbus_config_mipi_csi2 *mipi;
 675	unsigned long lanes_used = 0;
 676	unsigned int val, lane;
 677	int ret;
 678
 679	ret = max96714_disable_tx_port(priv);
 680
 681	mipi = &priv->mipi_csi2;
 682	val = div_u64(priv->tx_link_freq * 2, MHZ(100));
 683
 684	cci_update_bits(priv->regmap, MAX96714_BACKTOP25,
 685			CSI_DPLL_FREQ_MASK, val, &ret);
 686
 687	val = FIELD_PREP(MAX96714_CSI2_LANE_CNT_MASK, mipi->num_data_lanes - 1);
 688	cci_update_bits(priv->regmap, MAX96714_MIPI_LANE_CNT,
 689			MAX96714_CSI2_LANE_CNT_MASK, val, &ret);
 690
 691	/* lanes polarity */
 692	val = 0;
 693	for (lane = 0; lane < mipi->num_data_lanes + 1; lane++) {
 694		if (!mipi->lane_polarities[lane])
 695			continue;
 696		if (lane == 0)
 697			/* clock lane */
 698			val |= BIT(5);
 699		else if (lane < 3)
 700			/* Lane D0 and D1 */
 701			val |= BIT(lane - 1);
 702		else
 703			/* D2 and D3 */
 704			val |= BIT(lane);
 705	}
 706
 707	cci_update_bits(priv->regmap, MAX96714_MIPI_POLARITY,
 708			MAX96714_MIPI_POLARITY_MASK, val, &ret);
 709
 710	/* lanes mapping */
 711	val = 0;
 712	for (lane = 0; lane < mipi->num_data_lanes; lane++) {
 713		val |= (mipi->data_lanes[lane] - 1) << (lane * 2);
 714		lanes_used |= BIT(mipi->data_lanes[lane] - 1);
 715	}
 716
 717	/*
 718	 * Unused lanes need to be mapped as well to not have
 719	 * the same lanes mapped twice.
 720	 */
 721	for (; lane < MAX96714_CSI_NLANES; lane++) {
 722		unsigned int idx = find_first_zero_bit(&lanes_used,
 723						       MAX96714_CSI_NLANES);
 724
 725		val |= idx << (lane * 2);
 726		lanes_used |= BIT(idx);
 727	}
 728
 729	return cci_write(priv->regmap, MAX96714_MIPI_LANE_MAP, val, &ret);
 730}
 731
 732static int max96714_rxport_enable_poc(struct max96714_priv *priv)
 733{
 734	struct max96714_rxport *rxport = &priv->rxport;
 735
 736	if (!rxport->poc)
 737		return 0;
 738
 739	return regulator_enable(rxport->poc);
 740}
 741
 742static int max96714_rxport_disable_poc(struct max96714_priv *priv)
 743{
 744	struct max96714_rxport *rxport = &priv->rxport;
 745
 746	if (!rxport->poc)
 747		return 0;
 748
 749	return regulator_disable(rxport->poc);
 750}
 751
 752static int max96714_parse_dt_txport(struct max96714_priv *priv)
 753{
 754	struct device *dev = &priv->client->dev;
 755	struct v4l2_fwnode_endpoint vep = { .bus_type = V4L2_MBUS_CSI2_DPHY };
 756	struct fwnode_handle *ep_fwnode;
 757	u32 num_data_lanes;
 758	int ret;
 759
 760	ep_fwnode = fwnode_graph_get_endpoint_by_id(dev_fwnode(dev),
 761						    MAX96714_PAD_SOURCE, 0, 0);
 762	if (!ep_fwnode)
 763		return -EINVAL;
 764
 765	ret = v4l2_fwnode_endpoint_alloc_parse(ep_fwnode, &vep);
 766	fwnode_handle_put(ep_fwnode);
 767	if (ret) {
 768		dev_err(dev, "tx: failed to parse endpoint data\n");
 769		return -EINVAL;
 770	}
 771
 772	if (vep.nr_of_link_frequencies != 1) {
 773		ret = -EINVAL;
 774		goto err_free_vep;
 775	}
 776
 777	priv->tx_link_freq = vep.link_frequencies[0];
 778	/* Min 50MHz, Max 1250MHz, 50MHz step */
 779	if (priv->tx_link_freq < MHZ(50) || priv->tx_link_freq > MHZ(1250) ||
 780	    (u32)priv->tx_link_freq % MHZ(50)) {
 781		dev_err(dev, "tx: invalid link frequency\n");
 782		ret = -EINVAL;
 783		goto err_free_vep;
 784	}
 785
 786	num_data_lanes = vep.bus.mipi_csi2.num_data_lanes;
 787	if (num_data_lanes < 1 || num_data_lanes > MAX96714_CSI_NLANES) {
 788		dev_err(dev,
 789			"tx: invalid number of data lanes must be 1 to 4\n");
 790		ret = -EINVAL;
 791		goto err_free_vep;
 792	}
 793
 794	priv->mipi_csi2 = vep.bus.mipi_csi2;
 795
 796err_free_vep:
 797	v4l2_fwnode_endpoint_free(&vep);
 798
 799	return ret;
 800}
 801
 802static int max96714_parse_dt_rxport(struct max96714_priv *priv)
 803{
 804	static const char *poc_name = "port0-poc";
 805	struct max96714_rxport *rxport = &priv->rxport;
 806	struct device *dev = &priv->client->dev;
 807	struct fwnode_handle *ep_fwnode;
 808	int ret;
 809
 810	ep_fwnode = fwnode_graph_get_endpoint_by_id(dev_fwnode(dev),
 811						    MAX96714_PAD_SINK, 0, 0);
 812	if (!ep_fwnode)
 813		return -ENOENT;
 814
 815	rxport->source.ep_fwnode = fwnode_graph_get_remote_endpoint(ep_fwnode);
 816	fwnode_handle_put(ep_fwnode);
 817
 818	if (!rxport->source.ep_fwnode) {
 819		dev_err(dev, "rx: no remote endpoint\n");
 820		return -EINVAL;
 821	}
 822
 823	rxport->poc = devm_regulator_get_optional(dev, poc_name);
 824	if (IS_ERR(rxport->poc)) {
 825		ret = PTR_ERR(rxport->poc);
 826		if (ret == -ENODEV) {
 827			rxport->poc = NULL;
 828		} else {
 829			dev_err(dev, "rx: failed to get POC supply: %d\n", ret);
 830			goto err_put_source_ep_fwnode;
 831		}
 832	}
 833
 834	return 0;
 835
 836err_put_source_ep_fwnode:
 837	fwnode_handle_put(rxport->source.ep_fwnode);
 838	return ret;
 839}
 840
 841static int max96714_parse_dt(struct max96714_priv *priv)
 842{
 843	int ret;
 844
 845	ret = max96714_parse_dt_txport(priv);
 846	if (ret)
 847		return ret;
 848
 849	ret = max96714_parse_dt_rxport(priv);
 850	/*
 851	 * The deserializer can create a test pattern even if the
 852	 * rx port is not connected to a serializer.
 853	 */
 854	if (ret && ret == -ENOENT)
 855		ret = 0;
 856
 857	return ret;
 858}
 859
 860static int max96714_enable_core_hw(struct max96714_priv *priv)
 861{
 862	struct device *dev = &priv->client->dev;
 863	u64 val;
 864	int ret;
 865
 866	if (priv->pd_gpio) {
 867		/* wait min 2 ms for reset to complete */
 868		gpiod_set_value_cansleep(priv->pd_gpio, 1);
 869		fsleep(2000);
 870		gpiod_set_value_cansleep(priv->pd_gpio, 0);
 871		/* wait min 2 ms for power up to finish */
 872		fsleep(2000);
 873	}
 874
 875	ret = cci_read(priv->regmap, MAX96714_REG13, &val, NULL);
 876	if (ret) {
 877		dev_err_probe(dev, ret, "Cannot read first register, abort\n");
 878		goto err_pd_gpio;
 879	}
 880
 881	if (val != MAX96714_DEVICE_ID && val != MAX96714F_DEVICE_ID) {
 882		dev_err(dev, "Unsupported device id expected %x got %x\n",
 883			MAX96714F_DEVICE_ID, (u8)val);
 884		ret = -EOPNOTSUPP;
 885		goto err_pd_gpio;
 886	}
 887
 888	ret = cci_read(priv->regmap, MAX96714_DEV_REV, &val, NULL);
 889	if (ret)
 890		goto err_pd_gpio;
 891
 892	dev_dbg(dev, "Found %x (rev %lx)\n", MAX96714F_DEVICE_ID,
 893		(u8)val & MAX96714_DEV_REV_MASK);
 894
 895	ret = cci_read(priv->regmap, MAX96714_MIPI_TX52, &val, NULL);
 896	if (ret)
 897		goto err_pd_gpio;
 898
 899	if (!(val & MAX96714_TUN_EN)) {
 900		dev_err(dev, "Only supporting tunnel mode");
 901		ret = -EOPNOTSUPP;
 902		goto err_pd_gpio;
 903	}
 904
 905	return 0;
 906
 907err_pd_gpio:
 908	gpiod_set_value_cansleep(priv->pd_gpio, 1);
 909	return ret;
 910}
 911
 912static void max96714_disable_core_hw(struct max96714_priv *priv)
 913{
 914	gpiod_set_value_cansleep(priv->pd_gpio, 1);
 915}
 916
 917static int max96714_get_hw_resources(struct max96714_priv *priv)
 918{
 919	struct device *dev = &priv->client->dev;
 920
 921	priv->regmap = devm_cci_regmap_init_i2c(priv->client, 16);
 922	if (IS_ERR(priv->regmap))
 923		return PTR_ERR(priv->regmap);
 924
 925	priv->pd_gpio =
 926		devm_gpiod_get_optional(dev, "powerdown", GPIOD_OUT_HIGH);
 927	if (IS_ERR(priv->pd_gpio))
 928		return dev_err_probe(dev, PTR_ERR(priv->pd_gpio),
 929				     "Cannot get powerdown GPIO\n");
 930	return 0;
 931}
 932
 933static int max96714_probe(struct i2c_client *client)
 934{
 935	struct device *dev = &client->dev;
 936	struct max96714_priv *priv;
 937	int ret;
 938
 939	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
 940	if (!priv)
 941		return -ENOMEM;
 942
 943	priv->client = client;
 944
 945	ret = max96714_get_hw_resources(priv);
 946	if (ret)
 947		return ret;
 948
 949	ret = max96714_enable_core_hw(priv);
 950	if (ret)
 951		return ret;
 952
 953	ret = max96714_parse_dt(priv);
 954	if (ret)
 955		goto err_disable_core_hw;
 956
 957	max96714_init_tx_port(priv);
 958
 959	ret = max96714_rxport_enable_poc(priv);
 960	if (ret)
 961		goto err_free_ports;
 962
 963	ret = max96714_i2c_mux_init(priv);
 964	if (ret)
 965		goto err_disable_poc;
 966
 967	ret = max96714_create_subdev(priv);
 968	if (ret)
 969		goto err_del_mux;
 970
 971	return 0;
 972
 973err_del_mux:
 974	i2c_mux_del_adapters(priv->mux);
 975err_disable_poc:
 976	max96714_rxport_disable_poc(priv);
 977err_free_ports:
 978	fwnode_handle_put(priv->rxport.source.ep_fwnode);
 979err_disable_core_hw:
 980	max96714_disable_core_hw(priv);
 981
 982	return ret;
 983}
 984
 985static void max96714_remove(struct i2c_client *client)
 986{
 987	struct v4l2_subdev *sd = i2c_get_clientdata(client);
 988	struct max96714_priv *priv = sd_to_max96714(sd);
 989
 990	max96714_destroy_subdev(priv);
 991	i2c_mux_del_adapters(priv->mux);
 992	max96714_rxport_disable_poc(priv);
 993	fwnode_handle_put(priv->rxport.source.ep_fwnode);
 994	max96714_disable_core_hw(priv);
 995	gpiod_set_value_cansleep(priv->pd_gpio, 1);
 996}
 997
 998static const struct of_device_id max96714_of_ids[] = {
 999	{ .compatible = "maxim,max96714f" },
1000	{ }
1001};
1002MODULE_DEVICE_TABLE(of, max96714_of_ids);
1003
1004static struct i2c_driver max96714_i2c_driver = {
1005	.driver	= {
1006		.name		= "max96714",
1007		.of_match_table	= max96714_of_ids,
1008	},
1009	.probe		= max96714_probe,
1010	.remove		= max96714_remove,
1011};
1012
1013module_i2c_driver(max96714_i2c_driver);
1014
1015MODULE_LICENSE("GPL");
1016MODULE_DESCRIPTION("Maxim Integrated GMSL2 Deserializers Driver");
1017MODULE_AUTHOR("Julien Massot <julien.massot@collabora.com>");
~/ Read-only file preview.