brintos

brintos / linux-shallow public Read only

0
0
Text · 19.8 KiB · c888179 Raw
802 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Lontium LT9211 bridge driver4 *5 * LT9211 is capable of converting:6 *   2xDSI/2xLVDS/1xDPI -> 2xDSI/2xLVDS/1xDPI7 * Currently supported is:8 *   1xDSI -> 1xLVDS9 *10 * Copyright (C) 2022 Marek Vasut <marex@denx.de>11 */12 13#include <linux/bits.h>14#include <linux/clk.h>15#include <linux/gpio/consumer.h>16#include <linux/i2c.h>17#include <linux/media-bus-format.h>18#include <linux/module.h>19#include <linux/of_graph.h>20#include <linux/regmap.h>21#include <linux/regulator/consumer.h>22 23#include <drm/drm_atomic_helper.h>24#include <drm/drm_bridge.h>25#include <drm/drm_mipi_dsi.h>26#include <drm/drm_of.h>27#include <drm/drm_panel.h>28#include <drm/drm_print.h>29#include <drm/drm_probe_helper.h>30 31#define REG_PAGE_CONTROL			0xff32#define REG_CHIPID0				0x810033#define REG_CHIPID0_VALUE			0x1834#define REG_CHIPID1				0x810135#define REG_CHIPID1_VALUE			0x0136#define REG_CHIPID2				0x810237#define REG_CHIPID2_VALUE			0xe338 39#define REG_DSI_LANE				0xd00040/* DSI lane count - 0 means 4 lanes ; 1, 2, 3 means 1, 2, 3 lanes. */41#define REG_DSI_LANE_COUNT(n)			((n) & 3)42 43struct lt9211 {44	struct drm_bridge		bridge;45	struct device			*dev;46	struct regmap			*regmap;47	struct mipi_dsi_device		*dsi;48	struct drm_bridge		*panel_bridge;49	struct gpio_desc		*reset_gpio;50	struct regulator		*vccio;51	bool				lvds_dual_link;52	bool				lvds_dual_link_even_odd_swap;53};54 55static const struct regmap_range lt9211_rw_ranges[] = {56	regmap_reg_range(0xff, 0xff),57	regmap_reg_range(0x8100, 0x816b),58	regmap_reg_range(0x8200, 0x82aa),59	regmap_reg_range(0x8500, 0x85ff),60	regmap_reg_range(0x8600, 0x86a0),61	regmap_reg_range(0x8700, 0x8746),62	regmap_reg_range(0xd000, 0xd0a7),63	regmap_reg_range(0xd400, 0xd42c),64	regmap_reg_range(0xd800, 0xd838),65	regmap_reg_range(0xd9c0, 0xd9d5),66};67 68static const struct regmap_access_table lt9211_rw_table = {69	.yes_ranges = lt9211_rw_ranges,70	.n_yes_ranges = ARRAY_SIZE(lt9211_rw_ranges),71};72 73static const struct regmap_range_cfg lt9211_range = {74	.name = "lt9211",75	.range_min = 0x0000,76	.range_max = 0xda00,77	.selector_reg = REG_PAGE_CONTROL,78	.selector_mask = 0xff,79	.selector_shift = 0,80	.window_start = 0,81	.window_len = 0x100,82};83 84static const struct regmap_config lt9211_regmap_config = {85	.reg_bits = 8,86	.val_bits = 8,87	.rd_table = &lt9211_rw_table,88	.wr_table = &lt9211_rw_table,89	.volatile_table	= &lt9211_rw_table,90	.ranges = &lt9211_range,91	.num_ranges = 1,92	.cache_type = REGCACHE_MAPLE,93	.max_register = 0xda00,94};95 96static struct lt9211 *bridge_to_lt9211(struct drm_bridge *bridge)97{98	return container_of(bridge, struct lt9211, bridge);99}100 101static int lt9211_attach(struct drm_bridge *bridge,102			 enum drm_bridge_attach_flags flags)103{104	struct lt9211 *ctx = bridge_to_lt9211(bridge);105 106	return drm_bridge_attach(bridge->encoder, ctx->panel_bridge,107				 &ctx->bridge, flags);108}109 110static int lt9211_read_chipid(struct lt9211 *ctx)111{112	u8 chipid[3];113	int ret;114 115	/* Read Chip ID registers and verify the chip can communicate. */116	ret = regmap_bulk_read(ctx->regmap, REG_CHIPID0, chipid, 3);117	if (ret < 0) {118		dev_err(ctx->dev, "Failed to read Chip ID: %d\n", ret);119		return ret;120	}121 122	/* Test for known Chip ID. */123	if (chipid[0] != REG_CHIPID0_VALUE || chipid[1] != REG_CHIPID1_VALUE ||124	    chipid[2] != REG_CHIPID2_VALUE) {125		dev_err(ctx->dev, "Unknown Chip ID: 0x%02x 0x%02x 0x%02x\n",126			chipid[0], chipid[1], chipid[2]);127		return -EINVAL;128	}129 130	return 0;131}132 133static int lt9211_system_init(struct lt9211 *ctx)134{135	const struct reg_sequence lt9211_system_init_seq[] = {136		{ 0x8201, 0x18 },137		{ 0x8606, 0x61 },138		{ 0x8607, 0xa8 },139		{ 0x8714, 0x08 },140		{ 0x8715, 0x00 },141		{ 0x8718, 0x0f },142		{ 0x8722, 0x08 },143		{ 0x8723, 0x00 },144		{ 0x8726, 0x0f },145		{ 0x810b, 0xfe },146	};147 148	return regmap_multi_reg_write(ctx->regmap, lt9211_system_init_seq,149				      ARRAY_SIZE(lt9211_system_init_seq));150}151 152static int lt9211_configure_rx(struct lt9211 *ctx)153{154	const struct reg_sequence lt9211_rx_phy_seq[] = {155		{ 0x8202, 0x44 },156		{ 0x8204, 0xa0 },157		{ 0x8205, 0x22 },158		{ 0x8207, 0x9f },159		{ 0x8208, 0xfc },160		/* ORR with 0xf8 here to enable DSI DN/DP swap. */161		{ 0x8209, 0x01 },162		{ 0x8217, 0x0c },163		{ 0x8633, 0x1b },164	};165 166	const struct reg_sequence lt9211_rx_cal_reset_seq[] = {167		{ 0x8120, 0x7f },168		{ 0x8120, 0xff },169	};170 171	const struct reg_sequence lt9211_rx_dig_seq[] = {172		{ 0x8630, 0x85 },173		/* 0x8588: BIT 6 set = MIPI-RX, BIT 4 unset = LVDS-TX */174		{ 0x8588, 0x40 },175		{ 0x85ff, 0xd0 },176		{ REG_DSI_LANE, REG_DSI_LANE_COUNT(ctx->dsi->lanes) },177		{ 0xd002, 0x05 },178	};179 180	const struct reg_sequence lt9211_rx_div_reset_seq[] = {181		{ 0x810a, 0xc0 },182		{ 0x8120, 0xbf },183	};184 185	const struct reg_sequence lt9211_rx_div_clear_seq[] = {186		{ 0x810a, 0xc1 },187		{ 0x8120, 0xff },188	};189 190	int ret;191 192	ret = regmap_multi_reg_write(ctx->regmap, lt9211_rx_phy_seq,193				     ARRAY_SIZE(lt9211_rx_phy_seq));194	if (ret)195		return ret;196 197	ret = regmap_multi_reg_write(ctx->regmap, lt9211_rx_cal_reset_seq,198				     ARRAY_SIZE(lt9211_rx_cal_reset_seq));199	if (ret)200		return ret;201 202	ret = regmap_multi_reg_write(ctx->regmap, lt9211_rx_dig_seq,203				     ARRAY_SIZE(lt9211_rx_dig_seq));204	if (ret)205		return ret;206 207	ret = regmap_multi_reg_write(ctx->regmap, lt9211_rx_div_reset_seq,208				     ARRAY_SIZE(lt9211_rx_div_reset_seq));209	if (ret)210		return ret;211 212	usleep_range(10000, 15000);213 214	return regmap_multi_reg_write(ctx->regmap, lt9211_rx_div_clear_seq,215				      ARRAY_SIZE(lt9211_rx_div_clear_seq));216}217 218static int lt9211_autodetect_rx(struct lt9211 *ctx,219				const struct drm_display_mode *mode)220{221	u16 width, height;222	u32 byteclk;223	u8 buf[5];224	u8 format;225	u8 bc[3];226	int ret;227 228	/* Measure ByteClock frequency. */229	ret = regmap_write(ctx->regmap, 0x8600, 0x01);230	if (ret)231		return ret;232 233	/* Give the chip time to lock onto RX stream. */234	msleep(100);235 236	/* Read the ByteClock frequency from the chip. */237	ret = regmap_bulk_read(ctx->regmap, 0x8608, bc, sizeof(bc));238	if (ret)239		return ret;240 241	/* RX ByteClock in kHz */242	byteclk = ((bc[0] & 0xf) << 16) | (bc[1] << 8) | bc[2];243 244	/* Width/Height/Format Auto-detection */245	ret = regmap_bulk_read(ctx->regmap, 0xd082, buf, sizeof(buf));246	if (ret)247		return ret;248 249	width = (buf[0] << 8) | buf[1];250	height = (buf[3] << 8) | buf[4];251	format = buf[2] & 0xf;252 253	if (format == 0x3) {		/* YUV422 16bit */254		width /= 2;255	} else if (format == 0xa) {	/* RGB888 24bit */256		width /= 3;257	} else {258		dev_err(ctx->dev, "Unsupported DSI pixel format 0x%01x\n",259			format);260		return -EINVAL;261	}262 263	if (width != mode->hdisplay) {264		dev_err(ctx->dev,265			"RX: Detected DSI width (%d) does not match mode hdisplay (%d)\n",266			width, mode->hdisplay);267		return -EINVAL;268	}269 270	if (height != mode->vdisplay) {271		dev_err(ctx->dev,272			"RX: Detected DSI height (%d) does not match mode vdisplay (%d)\n",273			height, mode->vdisplay);274		return -EINVAL;275	}276 277	dev_dbg(ctx->dev, "RX: %dx%d format=0x%01x byteclock=%d kHz\n",278		width, height, format, byteclk);279 280	return 0;281}282 283static int lt9211_configure_timing(struct lt9211 *ctx,284				   const struct drm_display_mode *mode)285{286	const struct reg_sequence lt9211_timing[] = {287		{ 0xd00d, (mode->vtotal >> 8) & 0xff },288		{ 0xd00e, mode->vtotal & 0xff },289		{ 0xd00f, (mode->vdisplay >> 8) & 0xff },290		{ 0xd010, mode->vdisplay & 0xff },291		{ 0xd011, (mode->htotal >> 8) & 0xff },292		{ 0xd012, mode->htotal & 0xff },293		{ 0xd013, (mode->hdisplay >> 8) & 0xff },294		{ 0xd014, mode->hdisplay & 0xff },295		{ 0xd015, (mode->vsync_end - mode->vsync_start) & 0xff },296		{ 0xd016, (mode->hsync_end - mode->hsync_start) & 0xff },297		{ 0xd017, ((mode->vsync_start - mode->vdisplay) >> 8) & 0xff },298		{ 0xd018, (mode->vsync_start - mode->vdisplay) & 0xff },299		{ 0xd019, ((mode->hsync_start - mode->hdisplay) >> 8) & 0xff },300		{ 0xd01a, (mode->hsync_start - mode->hdisplay) & 0xff },301	};302 303	return regmap_multi_reg_write(ctx->regmap, lt9211_timing,304				      ARRAY_SIZE(lt9211_timing));305}306 307static int lt9211_configure_plls(struct lt9211 *ctx,308				 const struct drm_display_mode *mode)309{310	const struct reg_sequence lt9211_pcr_seq[] = {311		{ 0xd026, 0x17 },312		{ 0xd027, 0xc3 },313		{ 0xd02d, 0x30 },314		{ 0xd031, 0x10 },315		{ 0xd023, 0x20 },316		{ 0xd038, 0x02 },317		{ 0xd039, 0x10 },318		{ 0xd03a, 0x20 },319		{ 0xd03b, 0x60 },320		{ 0xd03f, 0x04 },321		{ 0xd040, 0x08 },322		{ 0xd041, 0x10 },323		{ 0x810b, 0xee },324		{ 0x810b, 0xfe },325	};326 327	unsigned int pval;328	int ret;329 330	/* DeSSC PLL reference clock is 25 MHz XTal. */331	ret = regmap_write(ctx->regmap, 0x822d, 0x48);332	if (ret)333		return ret;334 335	if (mode->clock < 44000) {336		ret = regmap_write(ctx->regmap, 0x8235, 0x83);337	} else if (mode->clock < 88000) {338		ret = regmap_write(ctx->regmap, 0x8235, 0x82);339	} else if (mode->clock < 176000) {340		ret = regmap_write(ctx->regmap, 0x8235, 0x81);341	} else {342		dev_err(ctx->dev,343			"Unsupported mode clock (%d kHz) above 176 MHz.\n",344			mode->clock);345		return -EINVAL;346	}347 348	if (ret)349		return ret;350 351	/* Wait for the DeSSC PLL to stabilize. */352	msleep(100);353 354	ret = regmap_multi_reg_write(ctx->regmap, lt9211_pcr_seq,355				     ARRAY_SIZE(lt9211_pcr_seq));356	if (ret)357		return ret;358 359	/* PCR stability test takes seconds. */360	ret = regmap_read_poll_timeout(ctx->regmap, 0xd087, pval, pval & 0x8,361				       20000, 10000000);362	if (ret)363		dev_err(ctx->dev, "PCR unstable, ret=%i\n", ret);364 365	return ret;366}367 368static int lt9211_configure_tx(struct lt9211 *ctx, bool jeida,369			       bool bpp24, bool de)370{371	const struct reg_sequence system_lt9211_tx_phy_seq[] = {372		/* DPI output disable */373		{ 0x8262, 0x00 },374		/* BIT(7) is LVDS dual-port */375		{ 0x823b, 0x38 | (ctx->lvds_dual_link ? BIT(7) : 0) },376		{ 0x823e, 0x92 },377		{ 0x823f, 0x48 },378		{ 0x8240, 0x31 },379		{ 0x8243, 0x80 },380		{ 0x8244, 0x00 },381		{ 0x8245, 0x00 },382		{ 0x8249, 0x00 },383		{ 0x824a, 0x01 },384		{ 0x824e, 0x00 },385		{ 0x824f, 0x00 },386		{ 0x8250, 0x00 },387		{ 0x8253, 0x00 },388		{ 0x8254, 0x01 },389		/* LVDS channel order, Odd:Even 0x10..A:B, 0x40..B:A */390		{ 0x8646, ctx->lvds_dual_link_even_odd_swap ? 0x40 : 0x10 },391		{ 0x8120, 0x7b },392		{ 0x816b, 0xff },393	};394 395	const struct reg_sequence system_lt9211_tx_dig_seq[] = {396		{ 0x8559, 0x40 | (jeida ? BIT(7) : 0) |397			  (de ? BIT(5) : 0) | (bpp24 ? BIT(4) : 0) },398		{ 0x855a, 0xaa },399		{ 0x855b, 0xaa },400		{ 0x855c, ctx->lvds_dual_link ? BIT(0) : 0 },401		{ 0x85a1, 0x77 },402		{ 0x8640, 0x40 },403		{ 0x8641, 0x34 },404		{ 0x8642, 0x10 },405		{ 0x8643, 0x23 },406		{ 0x8644, 0x41 },407		{ 0x8645, 0x02 },408	};409 410	const struct reg_sequence system_lt9211_tx_pll_seq[] = {411		/* TX PLL power down */412		{ 0x8236, 0x01 },413		{ 0x8237, ctx->lvds_dual_link ? 0x2a : 0x29 },414		{ 0x8238, 0x06 },415		{ 0x8239, 0x30 },416		{ 0x823a, 0x8e },417		{ 0x8737, 0x14 },418		{ 0x8713, 0x00 },419		{ 0x8713, 0x80 },420	};421 422	unsigned int pval;423	int ret;424 425	ret = regmap_multi_reg_write(ctx->regmap, system_lt9211_tx_phy_seq,426				     ARRAY_SIZE(system_lt9211_tx_phy_seq));427	if (ret)428		return ret;429 430	ret = regmap_multi_reg_write(ctx->regmap, system_lt9211_tx_dig_seq,431				     ARRAY_SIZE(system_lt9211_tx_dig_seq));432	if (ret)433		return ret;434 435	ret = regmap_multi_reg_write(ctx->regmap, system_lt9211_tx_pll_seq,436				     ARRAY_SIZE(system_lt9211_tx_pll_seq));437	if (ret)438		return ret;439 440	ret = regmap_read_poll_timeout(ctx->regmap, 0x871f, pval, pval & 0x80,441				       10000, 1000000);442	if (ret) {443		dev_err(ctx->dev, "TX PLL unstable, ret=%i\n", ret);444		return ret;445	}446 447	ret = regmap_read_poll_timeout(ctx->regmap, 0x8720, pval, pval & 0x80,448				       10000, 1000000);449	if (ret) {450		dev_err(ctx->dev, "TX PLL unstable, ret=%i\n", ret);451		return ret;452	}453 454	return 0;455}456 457static void lt9211_atomic_enable(struct drm_bridge *bridge,458				 struct drm_bridge_state *old_bridge_state)459{460	struct lt9211 *ctx = bridge_to_lt9211(bridge);461	struct drm_atomic_state *state = old_bridge_state->base.state;462	const struct drm_bridge_state *bridge_state;463	const struct drm_crtc_state *crtc_state;464	const struct drm_display_mode *mode;465	struct drm_connector *connector;466	struct drm_crtc *crtc;467	bool lvds_format_24bpp;468	bool lvds_format_jeida;469	u32 bus_flags;470	int ret;471 472	ret = regulator_enable(ctx->vccio);473	if (ret) {474		dev_err(ctx->dev, "Failed to enable vccio: %d\n", ret);475		return;476	}477 478	/* Deassert reset */479	gpiod_set_value(ctx->reset_gpio, 1);480	usleep_range(20000, 21000);	/* Very long post-reset delay. */481 482	/* Get the LVDS format from the bridge state. */483	bridge_state = drm_atomic_get_new_bridge_state(state, bridge);484	bus_flags = bridge_state->output_bus_cfg.flags;485 486	switch (bridge_state->output_bus_cfg.format) {487	case MEDIA_BUS_FMT_RGB666_1X7X3_SPWG:488		lvds_format_24bpp = false;489		lvds_format_jeida = true;490		break;491	case MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA:492		lvds_format_24bpp = true;493		lvds_format_jeida = true;494		break;495	case MEDIA_BUS_FMT_RGB888_1X7X4_SPWG:496		lvds_format_24bpp = true;497		lvds_format_jeida = false;498		break;499	default:500		/*501		 * Some bridges still don't set the correct502		 * LVDS bus pixel format, use SPWG24 default503		 * format until those are fixed.504		 */505		lvds_format_24bpp = true;506		lvds_format_jeida = false;507		dev_warn(ctx->dev,508			 "Unsupported LVDS bus format 0x%04x, please check output bridge driver. Falling back to SPWG24.\n",509			 bridge_state->output_bus_cfg.format);510		break;511	}512 513	/*514	 * Retrieve the CRTC adjusted mode. This requires a little dance to go515	 * from the bridge to the encoder, to the connector and to the CRTC.516	 */517	connector = drm_atomic_get_new_connector_for_encoder(state,518							     bridge->encoder);519	crtc = drm_atomic_get_new_connector_state(state, connector)->crtc;520	crtc_state = drm_atomic_get_new_crtc_state(state, crtc);521	mode = &crtc_state->adjusted_mode;522 523	ret = lt9211_read_chipid(ctx);524	if (ret)525		return;526 527	ret = lt9211_system_init(ctx);528	if (ret)529		return;530 531	ret = lt9211_configure_rx(ctx);532	if (ret)533		return;534 535	ret = lt9211_autodetect_rx(ctx, mode);536	if (ret)537		return;538 539	ret = lt9211_configure_timing(ctx, mode);540	if (ret)541		return;542 543	ret = lt9211_configure_plls(ctx, mode);544	if (ret)545		return;546 547	ret = lt9211_configure_tx(ctx, lvds_format_jeida, lvds_format_24bpp,548				  bus_flags & DRM_BUS_FLAG_DE_HIGH);549	if (ret)550		return;551 552	dev_dbg(ctx->dev, "LT9211 enabled.\n");553}554 555static void lt9211_atomic_disable(struct drm_bridge *bridge,556				  struct drm_bridge_state *old_bridge_state)557{558	struct lt9211 *ctx = bridge_to_lt9211(bridge);559	int ret;560 561	/*562	 * Put the chip in reset, pull nRST line low,563	 * and assure lengthy 10ms reset low timing.564	 */565	gpiod_set_value(ctx->reset_gpio, 0);566	usleep_range(10000, 11000);	/* Very long reset duration. */567 568	ret = regulator_disable(ctx->vccio);569	if (ret)570		dev_err(ctx->dev, "Failed to disable vccio: %d\n", ret);571 572	regcache_mark_dirty(ctx->regmap);573}574 575static enum drm_mode_status576lt9211_mode_valid(struct drm_bridge *bridge,577		  const struct drm_display_info *info,578		  const struct drm_display_mode *mode)579{580	/* LVDS output clock range 25..176 MHz */581	if (mode->clock < 25000)582		return MODE_CLOCK_LOW;583	if (mode->clock > 176000)584		return MODE_CLOCK_HIGH;585 586	return MODE_OK;587}588 589#define MAX_INPUT_SEL_FORMATS	1590 591static u32 *592lt9211_atomic_get_input_bus_fmts(struct drm_bridge *bridge,593				 struct drm_bridge_state *bridge_state,594				 struct drm_crtc_state *crtc_state,595				 struct drm_connector_state *conn_state,596				 u32 output_fmt,597				 unsigned int *num_input_fmts)598{599	u32 *input_fmts;600 601	*num_input_fmts = 0;602 603	input_fmts = kcalloc(MAX_INPUT_SEL_FORMATS, sizeof(*input_fmts),604			     GFP_KERNEL);605	if (!input_fmts)606		return NULL;607 608	/* This is the DSI-end bus format */609	input_fmts[0] = MEDIA_BUS_FMT_RGB888_1X24;610	*num_input_fmts = 1;611 612	return input_fmts;613}614 615static const struct drm_bridge_funcs lt9211_funcs = {616	.attach			= lt9211_attach,617	.mode_valid		= lt9211_mode_valid,618	.atomic_enable		= lt9211_atomic_enable,619	.atomic_disable		= lt9211_atomic_disable,620	.atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,621	.atomic_destroy_state	= drm_atomic_helper_bridge_destroy_state,622	.atomic_get_input_bus_fmts = lt9211_atomic_get_input_bus_fmts,623	.atomic_reset		= drm_atomic_helper_bridge_reset,624};625 626static int lt9211_parse_dt(struct lt9211 *ctx)627{628	struct device_node *port2, *port3;629	struct drm_bridge *panel_bridge;630	struct device *dev = ctx->dev;631	struct drm_panel *panel;632	int dual_link;633	int ret;634 635	ctx->vccio = devm_regulator_get(dev, "vccio");636	if (IS_ERR(ctx->vccio))637		return dev_err_probe(dev, PTR_ERR(ctx->vccio),638				     "Failed to get supply 'vccio'\n");639 640	ctx->lvds_dual_link = false;641	ctx->lvds_dual_link_even_odd_swap = false;642 643	port2 = of_graph_get_port_by_id(dev->of_node, 2);644	port3 = of_graph_get_port_by_id(dev->of_node, 3);645	dual_link = drm_of_lvds_get_dual_link_pixel_order(port2, port3);646	of_node_put(port2);647	of_node_put(port3);648 649	if (dual_link == DRM_LVDS_DUAL_LINK_ODD_EVEN_PIXELS) {650		ctx->lvds_dual_link = true;651		/* Odd pixels to LVDS Channel A, even pixels to B */652		ctx->lvds_dual_link_even_odd_swap = false;653	} else if (dual_link == DRM_LVDS_DUAL_LINK_EVEN_ODD_PIXELS) {654		ctx->lvds_dual_link = true;655		/* Even pixels to LVDS Channel A, odd pixels to B */656		ctx->lvds_dual_link_even_odd_swap = true;657	}658 659	ret = drm_of_find_panel_or_bridge(dev->of_node, 2, 0, &panel, &panel_bridge);660	if (ret < 0)661		return ret;662	if (panel) {663		panel_bridge = devm_drm_panel_bridge_add(dev, panel);664		if (IS_ERR(panel_bridge))665			return PTR_ERR(panel_bridge);666	}667 668	ctx->panel_bridge = panel_bridge;669 670	return 0;671}672 673static int lt9211_host_attach(struct lt9211 *ctx)674{675	const struct mipi_dsi_device_info info = {676		.type = "lt9211",677		.channel = 0,678		.node = NULL,679	};680	struct device *dev = ctx->dev;681	struct device_node *host_node;682	struct device_node *endpoint;683	struct mipi_dsi_device *dsi;684	struct mipi_dsi_host *host;685	int dsi_lanes;686	int ret;687 688	endpoint = of_graph_get_endpoint_by_regs(dev->of_node, 0, -1);689	dsi_lanes = drm_of_get_data_lanes_count(endpoint, 1, 4);690	host_node = of_graph_get_remote_port_parent(endpoint);691	host = of_find_mipi_dsi_host_by_node(host_node);692	of_node_put(host_node);693	of_node_put(endpoint);694 695	if (!host)696		return -EPROBE_DEFER;697 698	if (dsi_lanes < 0)699		return dsi_lanes;700 701	dsi = devm_mipi_dsi_device_register_full(dev, host, &info);702	if (IS_ERR(dsi))703		return dev_err_probe(dev, PTR_ERR(dsi),704				     "failed to create dsi device\n");705 706	ctx->dsi = dsi;707 708	dsi->lanes = dsi_lanes;709	dsi->format = MIPI_DSI_FMT_RGB888;710	dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE |711			  MIPI_DSI_MODE_VIDEO_HSE | MIPI_DSI_MODE_VIDEO_NO_HSA |712			  MIPI_DSI_MODE_VIDEO_NO_HFP | MIPI_DSI_MODE_VIDEO_NO_HBP |713			  MIPI_DSI_MODE_NO_EOT_PACKET;714 715	ret = devm_mipi_dsi_attach(dev, dsi);716	if (ret < 0) {717		dev_err(dev, "failed to attach dsi to host: %d\n", ret);718		return ret;719	}720 721	return 0;722}723 724static int lt9211_probe(struct i2c_client *client)725{726	struct device *dev = &client->dev;727	struct lt9211 *ctx;728	int ret;729 730	ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);731	if (!ctx)732		return -ENOMEM;733 734	ctx->dev = dev;735 736	/*737	 * Put the chip in reset, pull nRST line low,738	 * and assure lengthy 10ms reset low timing.739	 */740	ctx->reset_gpio = devm_gpiod_get_optional(ctx->dev, "reset",741						  GPIOD_OUT_LOW);742	if (IS_ERR(ctx->reset_gpio))743		return PTR_ERR(ctx->reset_gpio);744 745	usleep_range(10000, 11000);	/* Very long reset duration. */746 747	ret = lt9211_parse_dt(ctx);748	if (ret)749		return ret;750 751	ctx->regmap = devm_regmap_init_i2c(client, &lt9211_regmap_config);752	if (IS_ERR(ctx->regmap))753		return PTR_ERR(ctx->regmap);754 755	dev_set_drvdata(dev, ctx);756	i2c_set_clientdata(client, ctx);757 758	ctx->bridge.funcs = &lt9211_funcs;759	ctx->bridge.of_node = dev->of_node;760	drm_bridge_add(&ctx->bridge);761 762	ret = lt9211_host_attach(ctx);763	if (ret)764		drm_bridge_remove(&ctx->bridge);765 766	return ret;767}768 769static void lt9211_remove(struct i2c_client *client)770{771	struct lt9211 *ctx = i2c_get_clientdata(client);772 773	drm_bridge_remove(&ctx->bridge);774}775 776static struct i2c_device_id lt9211_id[] = {777	{ "lontium,lt9211" },778	{},779};780MODULE_DEVICE_TABLE(i2c, lt9211_id);781 782static const struct of_device_id lt9211_match_table[] = {783	{ .compatible = "lontium,lt9211" },784	{},785};786MODULE_DEVICE_TABLE(of, lt9211_match_table);787 788static struct i2c_driver lt9211_driver = {789	.probe = lt9211_probe,790	.remove = lt9211_remove,791	.id_table = lt9211_id,792	.driver = {793		.name = "lt9211",794		.of_match_table = lt9211_match_table,795	},796};797module_i2c_driver(lt9211_driver);798 799MODULE_AUTHOR("Marek Vasut <marex@denx.de>");800MODULE_DESCRIPTION("Lontium LT9211 DSI/LVDS/DPI bridge driver");801MODULE_LICENSE("GPL");802