Path: blob/master/drivers/gpu/drm/bridge/lontium-lt9211.c
26494 views
// SPDX-License-Identifier: GPL-2.01/*2* Lontium LT9211 bridge driver3*4* LT9211 is capable of converting:5* 2xDSI/2xLVDS/1xDPI -> 2xDSI/2xLVDS/1xDPI6* Currently supported is:7* 1xDSI -> 1xLVDS8*9* Copyright (C) 2022 Marek Vasut <[email protected]>10*/1112#include <linux/bits.h>13#include <linux/clk.h>14#include <linux/gpio/consumer.h>15#include <linux/i2c.h>16#include <linux/media-bus-format.h>17#include <linux/module.h>18#include <linux/of_graph.h>19#include <linux/regmap.h>20#include <linux/regulator/consumer.h>2122#include <drm/drm_atomic_helper.h>23#include <drm/drm_bridge.h>24#include <drm/drm_mipi_dsi.h>25#include <drm/drm_of.h>26#include <drm/drm_panel.h>27#include <drm/drm_print.h>28#include <drm/drm_probe_helper.h>2930#define REG_PAGE_CONTROL 0xff31#define REG_CHIPID0 0x810032#define REG_CHIPID0_VALUE 0x1833#define REG_CHIPID1 0x810134#define REG_CHIPID1_VALUE 0x0135#define REG_CHIPID2 0x810236#define REG_CHIPID2_VALUE 0xe33738#define REG_DSI_LANE 0xd00039/* DSI lane count - 0 means 4 lanes ; 1, 2, 3 means 1, 2, 3 lanes. */40#define REG_DSI_LANE_COUNT(n) ((n) & 3)4142struct lt9211 {43struct drm_bridge bridge;44struct device *dev;45struct regmap *regmap;46struct mipi_dsi_device *dsi;47struct drm_bridge *panel_bridge;48struct gpio_desc *reset_gpio;49struct regulator *vccio;50bool lvds_dual_link;51bool lvds_dual_link_even_odd_swap;52};5354static const struct regmap_range lt9211_rw_ranges[] = {55regmap_reg_range(0xff, 0xff),56regmap_reg_range(0x8100, 0x816b),57regmap_reg_range(0x8200, 0x82aa),58regmap_reg_range(0x8500, 0x85ff),59regmap_reg_range(0x8600, 0x86a0),60regmap_reg_range(0x8700, 0x8746),61regmap_reg_range(0xd000, 0xd0a7),62regmap_reg_range(0xd400, 0xd42c),63regmap_reg_range(0xd800, 0xd838),64regmap_reg_range(0xd9c0, 0xd9d5),65};6667static const struct regmap_access_table lt9211_rw_table = {68.yes_ranges = lt9211_rw_ranges,69.n_yes_ranges = ARRAY_SIZE(lt9211_rw_ranges),70};7172static const struct regmap_range_cfg lt9211_range = {73.name = "lt9211",74.range_min = 0x0000,75.range_max = 0xda00,76.selector_reg = REG_PAGE_CONTROL,77.selector_mask = 0xff,78.selector_shift = 0,79.window_start = 0,80.window_len = 0x100,81};8283static const struct regmap_config lt9211_regmap_config = {84.reg_bits = 8,85.val_bits = 8,86.rd_table = <9211_rw_table,87.wr_table = <9211_rw_table,88.volatile_table = <9211_rw_table,89.ranges = <9211_range,90.num_ranges = 1,91.cache_type = REGCACHE_MAPLE,92.max_register = 0xda00,93};9495static struct lt9211 *bridge_to_lt9211(struct drm_bridge *bridge)96{97return container_of(bridge, struct lt9211, bridge);98}99100static int lt9211_attach(struct drm_bridge *bridge,101struct drm_encoder *encoder,102enum drm_bridge_attach_flags flags)103{104struct lt9211 *ctx = bridge_to_lt9211(bridge);105106return drm_bridge_attach(encoder, ctx->panel_bridge,107&ctx->bridge, flags);108}109110static int lt9211_read_chipid(struct lt9211 *ctx)111{112u8 chipid[3];113int ret;114115/* Read Chip ID registers and verify the chip can communicate. */116ret = regmap_bulk_read(ctx->regmap, REG_CHIPID0, chipid, 3);117if (ret < 0) {118dev_err(ctx->dev, "Failed to read Chip ID: %d\n", ret);119return ret;120}121122/* Test for known Chip ID. */123if (chipid[0] != REG_CHIPID0_VALUE || chipid[1] != REG_CHIPID1_VALUE ||124chipid[2] != REG_CHIPID2_VALUE) {125dev_err(ctx->dev, "Unknown Chip ID: 0x%02x 0x%02x 0x%02x\n",126chipid[0], chipid[1], chipid[2]);127return -EINVAL;128}129130return 0;131}132133static int lt9211_system_init(struct lt9211 *ctx)134{135const 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};147148return regmap_multi_reg_write(ctx->regmap, lt9211_system_init_seq,149ARRAY_SIZE(lt9211_system_init_seq));150}151152static int lt9211_configure_rx(struct lt9211 *ctx)153{154const 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};165166const struct reg_sequence lt9211_rx_cal_reset_seq[] = {167{ 0x8120, 0x7f },168{ 0x8120, 0xff },169};170171const 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};179180const struct reg_sequence lt9211_rx_div_reset_seq[] = {181{ 0x810a, 0xc0 },182{ 0x8120, 0xbf },183};184185const struct reg_sequence lt9211_rx_div_clear_seq[] = {186{ 0x810a, 0xc1 },187{ 0x8120, 0xff },188};189190int ret;191192ret = regmap_multi_reg_write(ctx->regmap, lt9211_rx_phy_seq,193ARRAY_SIZE(lt9211_rx_phy_seq));194if (ret)195return ret;196197ret = regmap_multi_reg_write(ctx->regmap, lt9211_rx_cal_reset_seq,198ARRAY_SIZE(lt9211_rx_cal_reset_seq));199if (ret)200return ret;201202ret = regmap_multi_reg_write(ctx->regmap, lt9211_rx_dig_seq,203ARRAY_SIZE(lt9211_rx_dig_seq));204if (ret)205return ret;206207ret = regmap_multi_reg_write(ctx->regmap, lt9211_rx_div_reset_seq,208ARRAY_SIZE(lt9211_rx_div_reset_seq));209if (ret)210return ret;211212usleep_range(10000, 15000);213214return regmap_multi_reg_write(ctx->regmap, lt9211_rx_div_clear_seq,215ARRAY_SIZE(lt9211_rx_div_clear_seq));216}217218static int lt9211_autodetect_rx(struct lt9211 *ctx,219const struct drm_display_mode *mode)220{221u16 width, height;222u32 byteclk;223u8 buf[5];224u8 format;225u8 bc[3];226int ret;227228/* Measure ByteClock frequency. */229ret = regmap_write(ctx->regmap, 0x8600, 0x01);230if (ret)231return ret;232233/* Give the chip time to lock onto RX stream. */234msleep(100);235236/* Read the ByteClock frequency from the chip. */237ret = regmap_bulk_read(ctx->regmap, 0x8608, bc, sizeof(bc));238if (ret)239return ret;240241/* RX ByteClock in kHz */242byteclk = ((bc[0] & 0xf) << 16) | (bc[1] << 8) | bc[2];243244/* Width/Height/Format Auto-detection */245ret = regmap_bulk_read(ctx->regmap, 0xd082, buf, sizeof(buf));246if (ret)247return ret;248249width = (buf[0] << 8) | buf[1];250height = (buf[3] << 8) | buf[4];251format = buf[2] & 0xf;252253if (format == 0x3) { /* YUV422 16bit */254width /= 2;255} else if (format == 0xa) { /* RGB888 24bit */256width /= 3;257} else {258dev_err(ctx->dev, "Unsupported DSI pixel format 0x%01x\n",259format);260return -EINVAL;261}262263if (width != mode->hdisplay) {264dev_err(ctx->dev,265"RX: Detected DSI width (%d) does not match mode hdisplay (%d)\n",266width, mode->hdisplay);267return -EINVAL;268}269270if (height != mode->vdisplay) {271dev_err(ctx->dev,272"RX: Detected DSI height (%d) does not match mode vdisplay (%d)\n",273height, mode->vdisplay);274return -EINVAL;275}276277dev_dbg(ctx->dev, "RX: %dx%d format=0x%01x byteclock=%d kHz\n",278width, height, format, byteclk);279280return 0;281}282283static int lt9211_configure_timing(struct lt9211 *ctx,284const struct drm_display_mode *mode)285{286const 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};302303return regmap_multi_reg_write(ctx->regmap, lt9211_timing,304ARRAY_SIZE(lt9211_timing));305}306307static int lt9211_configure_plls(struct lt9211 *ctx,308const struct drm_display_mode *mode)309{310const 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};326327unsigned int pval;328int ret;329330/* DeSSC PLL reference clock is 25 MHz XTal. */331ret = regmap_write(ctx->regmap, 0x822d, 0x48);332if (ret)333return ret;334335if (mode->clock < 44000) {336ret = regmap_write(ctx->regmap, 0x8235, 0x83);337} else if (mode->clock < 88000) {338ret = regmap_write(ctx->regmap, 0x8235, 0x82);339} else if (mode->clock < 176000) {340ret = regmap_write(ctx->regmap, 0x8235, 0x81);341} else {342dev_err(ctx->dev,343"Unsupported mode clock (%d kHz) above 176 MHz.\n",344mode->clock);345return -EINVAL;346}347348if (ret)349return ret;350351/* Wait for the DeSSC PLL to stabilize. */352msleep(100);353354ret = regmap_multi_reg_write(ctx->regmap, lt9211_pcr_seq,355ARRAY_SIZE(lt9211_pcr_seq));356if (ret)357return ret;358359/* PCR stability test takes seconds. */360ret = regmap_read_poll_timeout(ctx->regmap, 0xd087, pval, pval & 0x8,36120000, 10000000);362if (ret)363dev_err(ctx->dev, "PCR unstable, ret=%i\n", ret);364365return ret;366}367368static int lt9211_configure_tx(struct lt9211 *ctx, bool jeida,369bool bpp24, bool de)370{371const 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};394395const 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};409410const 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};421422unsigned int pval;423int ret;424425ret = regmap_multi_reg_write(ctx->regmap, system_lt9211_tx_phy_seq,426ARRAY_SIZE(system_lt9211_tx_phy_seq));427if (ret)428return ret;429430ret = regmap_multi_reg_write(ctx->regmap, system_lt9211_tx_dig_seq,431ARRAY_SIZE(system_lt9211_tx_dig_seq));432if (ret)433return ret;434435ret = regmap_multi_reg_write(ctx->regmap, system_lt9211_tx_pll_seq,436ARRAY_SIZE(system_lt9211_tx_pll_seq));437if (ret)438return ret;439440ret = regmap_read_poll_timeout(ctx->regmap, 0x871f, pval, pval & 0x80,44110000, 1000000);442if (ret) {443dev_err(ctx->dev, "TX PLL unstable, ret=%i\n", ret);444return ret;445}446447ret = regmap_read_poll_timeout(ctx->regmap, 0x8720, pval, pval & 0x80,44810000, 1000000);449if (ret) {450dev_err(ctx->dev, "TX PLL unstable, ret=%i\n", ret);451return ret;452}453454return 0;455}456457static void lt9211_atomic_enable(struct drm_bridge *bridge,458struct drm_atomic_state *state)459{460struct lt9211 *ctx = bridge_to_lt9211(bridge);461const struct drm_bridge_state *bridge_state;462const struct drm_crtc_state *crtc_state;463const struct drm_display_mode *mode;464struct drm_connector *connector;465struct drm_crtc *crtc;466bool lvds_format_24bpp;467bool lvds_format_jeida;468u32 bus_flags;469int ret;470471ret = regulator_enable(ctx->vccio);472if (ret) {473dev_err(ctx->dev, "Failed to enable vccio: %d\n", ret);474return;475}476477/* Deassert reset */478gpiod_set_value(ctx->reset_gpio, 1);479usleep_range(20000, 21000); /* Very long post-reset delay. */480481/* Get the LVDS format from the bridge state. */482bridge_state = drm_atomic_get_new_bridge_state(state, bridge);483bus_flags = bridge_state->output_bus_cfg.flags;484485switch (bridge_state->output_bus_cfg.format) {486case MEDIA_BUS_FMT_RGB666_1X7X3_SPWG:487lvds_format_24bpp = false;488lvds_format_jeida = true;489break;490case MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA:491lvds_format_24bpp = true;492lvds_format_jeida = true;493break;494case MEDIA_BUS_FMT_RGB888_1X7X4_SPWG:495lvds_format_24bpp = true;496lvds_format_jeida = false;497break;498default:499/*500* Some bridges still don't set the correct501* LVDS bus pixel format, use SPWG24 default502* format until those are fixed.503*/504lvds_format_24bpp = true;505lvds_format_jeida = false;506dev_warn(ctx->dev,507"Unsupported LVDS bus format 0x%04x, please check output bridge driver. Falling back to SPWG24.\n",508bridge_state->output_bus_cfg.format);509break;510}511512/*513* Retrieve the CRTC adjusted mode. This requires a little dance to go514* from the bridge to the encoder, to the connector and to the CRTC.515*/516connector = drm_atomic_get_new_connector_for_encoder(state,517bridge->encoder);518crtc = drm_atomic_get_new_connector_state(state, connector)->crtc;519crtc_state = drm_atomic_get_new_crtc_state(state, crtc);520mode = &crtc_state->adjusted_mode;521522ret = lt9211_read_chipid(ctx);523if (ret)524return;525526ret = lt9211_system_init(ctx);527if (ret)528return;529530ret = lt9211_configure_rx(ctx);531if (ret)532return;533534ret = lt9211_autodetect_rx(ctx, mode);535if (ret)536return;537538ret = lt9211_configure_timing(ctx, mode);539if (ret)540return;541542ret = lt9211_configure_plls(ctx, mode);543if (ret)544return;545546ret = lt9211_configure_tx(ctx, lvds_format_jeida, lvds_format_24bpp,547bus_flags & DRM_BUS_FLAG_DE_HIGH);548if (ret)549return;550551dev_dbg(ctx->dev, "LT9211 enabled.\n");552}553554static void lt9211_atomic_disable(struct drm_bridge *bridge,555struct drm_atomic_state *state)556{557struct lt9211 *ctx = bridge_to_lt9211(bridge);558int ret;559560/*561* Put the chip in reset, pull nRST line low,562* and assure lengthy 10ms reset low timing.563*/564gpiod_set_value(ctx->reset_gpio, 0);565usleep_range(10000, 11000); /* Very long reset duration. */566567ret = regulator_disable(ctx->vccio);568if (ret)569dev_err(ctx->dev, "Failed to disable vccio: %d\n", ret);570571regcache_mark_dirty(ctx->regmap);572}573574static enum drm_mode_status575lt9211_mode_valid(struct drm_bridge *bridge,576const struct drm_display_info *info,577const struct drm_display_mode *mode)578{579/* LVDS output clock range 25..176 MHz */580if (mode->clock < 25000)581return MODE_CLOCK_LOW;582if (mode->clock > 176000)583return MODE_CLOCK_HIGH;584585return MODE_OK;586}587588#define MAX_INPUT_SEL_FORMATS 1589590static u32 *591lt9211_atomic_get_input_bus_fmts(struct drm_bridge *bridge,592struct drm_bridge_state *bridge_state,593struct drm_crtc_state *crtc_state,594struct drm_connector_state *conn_state,595u32 output_fmt,596unsigned int *num_input_fmts)597{598u32 *input_fmts;599600*num_input_fmts = 0;601602input_fmts = kcalloc(MAX_INPUT_SEL_FORMATS, sizeof(*input_fmts),603GFP_KERNEL);604if (!input_fmts)605return NULL;606607/* This is the DSI-end bus format */608input_fmts[0] = MEDIA_BUS_FMT_RGB888_1X24;609*num_input_fmts = 1;610611return input_fmts;612}613614static const struct drm_bridge_funcs lt9211_funcs = {615.attach = lt9211_attach,616.mode_valid = lt9211_mode_valid,617.atomic_enable = lt9211_atomic_enable,618.atomic_disable = lt9211_atomic_disable,619.atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,620.atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,621.atomic_get_input_bus_fmts = lt9211_atomic_get_input_bus_fmts,622.atomic_reset = drm_atomic_helper_bridge_reset,623};624625static int lt9211_parse_dt(struct lt9211 *ctx)626{627struct device_node *port2, *port3;628struct drm_bridge *panel_bridge;629struct device *dev = ctx->dev;630struct drm_panel *panel;631int dual_link;632int ret;633634ctx->vccio = devm_regulator_get(dev, "vccio");635if (IS_ERR(ctx->vccio))636return dev_err_probe(dev, PTR_ERR(ctx->vccio),637"Failed to get supply 'vccio'\n");638639ctx->lvds_dual_link = false;640ctx->lvds_dual_link_even_odd_swap = false;641642port2 = of_graph_get_port_by_id(dev->of_node, 2);643port3 = of_graph_get_port_by_id(dev->of_node, 3);644dual_link = drm_of_lvds_get_dual_link_pixel_order(port2, port3);645of_node_put(port2);646of_node_put(port3);647648if (dual_link == DRM_LVDS_DUAL_LINK_ODD_EVEN_PIXELS) {649ctx->lvds_dual_link = true;650/* Odd pixels to LVDS Channel A, even pixels to B */651ctx->lvds_dual_link_even_odd_swap = false;652} else if (dual_link == DRM_LVDS_DUAL_LINK_EVEN_ODD_PIXELS) {653ctx->lvds_dual_link = true;654/* Even pixels to LVDS Channel A, odd pixels to B */655ctx->lvds_dual_link_even_odd_swap = true;656}657658ret = drm_of_find_panel_or_bridge(dev->of_node, 2, 0, &panel, &panel_bridge);659if (ret < 0)660return ret;661if (panel) {662panel_bridge = devm_drm_panel_bridge_add(dev, panel);663if (IS_ERR(panel_bridge))664return PTR_ERR(panel_bridge);665}666667ctx->panel_bridge = panel_bridge;668669return 0;670}671672static int lt9211_host_attach(struct lt9211 *ctx)673{674const struct mipi_dsi_device_info info = {675.type = "lt9211",676.channel = 0,677.node = NULL,678};679struct device *dev = ctx->dev;680struct device_node *host_node;681struct device_node *endpoint;682struct mipi_dsi_device *dsi;683struct mipi_dsi_host *host;684int dsi_lanes;685int ret;686687endpoint = of_graph_get_endpoint_by_regs(dev->of_node, 0, -1);688dsi_lanes = drm_of_get_data_lanes_count(endpoint, 1, 4);689host_node = of_graph_get_remote_port_parent(endpoint);690host = of_find_mipi_dsi_host_by_node(host_node);691of_node_put(host_node);692of_node_put(endpoint);693694if (!host)695return -EPROBE_DEFER;696697if (dsi_lanes < 0)698return dsi_lanes;699700dsi = devm_mipi_dsi_device_register_full(dev, host, &info);701if (IS_ERR(dsi))702return dev_err_probe(dev, PTR_ERR(dsi),703"failed to create dsi device\n");704705ctx->dsi = dsi;706707dsi->lanes = dsi_lanes;708dsi->format = MIPI_DSI_FMT_RGB888;709dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE |710MIPI_DSI_MODE_VIDEO_HSE | MIPI_DSI_MODE_VIDEO_NO_HSA |711MIPI_DSI_MODE_VIDEO_NO_HFP | MIPI_DSI_MODE_VIDEO_NO_HBP |712MIPI_DSI_MODE_NO_EOT_PACKET;713714ret = devm_mipi_dsi_attach(dev, dsi);715if (ret < 0) {716dev_err(dev, "failed to attach dsi to host: %d\n", ret);717return ret;718}719720return 0;721}722723static int lt9211_probe(struct i2c_client *client)724{725struct device *dev = &client->dev;726struct lt9211 *ctx;727int ret;728729ctx = devm_drm_bridge_alloc(dev, struct lt9211, bridge, <9211_funcs);730if (IS_ERR(ctx))731return PTR_ERR(ctx);732733ctx->dev = dev;734735/*736* Put the chip in reset, pull nRST line low,737* and assure lengthy 10ms reset low timing.738*/739ctx->reset_gpio = devm_gpiod_get_optional(ctx->dev, "reset",740GPIOD_OUT_LOW);741if (IS_ERR(ctx->reset_gpio))742return PTR_ERR(ctx->reset_gpio);743744usleep_range(10000, 11000); /* Very long reset duration. */745746ret = lt9211_parse_dt(ctx);747if (ret)748return ret;749750ctx->regmap = devm_regmap_init_i2c(client, <9211_regmap_config);751if (IS_ERR(ctx->regmap))752return PTR_ERR(ctx->regmap);753754dev_set_drvdata(dev, ctx);755i2c_set_clientdata(client, ctx);756757ctx->bridge.of_node = dev->of_node;758drm_bridge_add(&ctx->bridge);759760ret = lt9211_host_attach(ctx);761if (ret)762drm_bridge_remove(&ctx->bridge);763764return ret;765}766767static void lt9211_remove(struct i2c_client *client)768{769struct lt9211 *ctx = i2c_get_clientdata(client);770771drm_bridge_remove(&ctx->bridge);772}773774static const struct i2c_device_id lt9211_id[] = {775{ "lontium,lt9211" },776{},777};778MODULE_DEVICE_TABLE(i2c, lt9211_id);779780static const struct of_device_id lt9211_match_table[] = {781{ .compatible = "lontium,lt9211" },782{},783};784MODULE_DEVICE_TABLE(of, lt9211_match_table);785786static struct i2c_driver lt9211_driver = {787.probe = lt9211_probe,788.remove = lt9211_remove,789.id_table = lt9211_id,790.driver = {791.name = "lt9211",792.of_match_table = lt9211_match_table,793},794};795module_i2c_driver(lt9211_driver);796797MODULE_AUTHOR("Marek Vasut <[email protected]>");798MODULE_DESCRIPTION("Lontium LT9211 DSI/LVDS/DPI bridge driver");799MODULE_LICENSE("GPL");800801802