static int dw_mipi_dsi_host_attach(struct mipi_dsi_host *host, struct mipi_dsi_device *device) { struct dw_mipi_dsi *dsi = host_to_dsi(host); if (device->lanes > dsi->pdata->max_data_lanes) { dev_err(dsi->dev, "the number of data lanes(%u) is too many\n", device->lanes); return -EINVAL; } if (!(device->mode_flags & MIPI_DSI_MODE_VIDEO_BURST) || !(device->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE)) { dev_err(dsi->dev, "device mode is unsupported\n"); return -EINVAL; } dsi->lanes = device->lanes; dsi->channel = device->channel; dsi->format = device->format; dsi->panel = of_drm_find_panel(device->dev.of_node); if (dsi->panel) return drm_panel_attach(dsi->panel, &dsi->connector); return -EINVAL; }
static ssize_t dw_mipi_dsi_host_transfer(struct mipi_dsi_host *host, const struct mipi_dsi_msg *msg) { struct dw_mipi_dsi *dsi = host_to_dsi(host); int ret; dw_mipi_message_config(dsi, msg); switch (msg->type) { case MIPI_DSI_DCS_SHORT_WRITE: case MIPI_DSI_DCS_SHORT_WRITE_PARAM: case MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE: ret = dw_mipi_dsi_dcs_short_write(dsi, msg); break; case MIPI_DSI_DCS_LONG_WRITE: ret = dw_mipi_dsi_dcs_long_write(dsi, msg); break; default: DRM_DEV_ERROR(dsi->dev, "unsupported message type 0x%02x\n", msg->type); ret = -EINVAL; } return ret; }
static int dw_mipi_dsi_host_detach(struct mipi_dsi_host *host, struct mipi_dsi_device *device) { struct dw_mipi_dsi *dsi = host_to_dsi(host); drm_panel_detach(dsi->panel); return 0; }
static int dw_mipi_dsi_host_detach(struct mipi_dsi_host *host, struct mipi_dsi_device *device) { struct dw_mipi_dsi *dsi = host_to_dsi(host); const struct dw_mipi_dsi_plat_data *pdata = dsi->plat_data; int ret; if (pdata->host_ops && pdata->host_ops->detach) { ret = pdata->host_ops->detach(pdata->priv_data, device); if (ret < 0) return ret; } drm_of_panel_bridge_remove(host->dev->of_node, 1, 0); drm_bridge_remove(&dsi->bridge); return 0; }
static int dw_mipi_dsi_host_attach(struct mipi_dsi_host *host, struct mipi_dsi_device *device) { struct dw_mipi_dsi *dsi = host_to_dsi(host); const struct dw_mipi_dsi_plat_data *pdata = dsi->plat_data; struct drm_bridge *bridge; struct drm_panel *panel; int ret; if (device->lanes > dsi->plat_data->max_data_lanes) { dev_err(dsi->dev, "the number of data lanes(%u) is too many\n", device->lanes); return -EINVAL; } dsi->lanes = device->lanes; dsi->channel = device->channel; dsi->format = device->format; dsi->mode_flags = device->mode_flags; ret = drm_of_find_panel_or_bridge(host->dev->of_node, 1, 0, &panel, &bridge); if (ret) return ret; if (panel) { bridge = drm_panel_bridge_add(panel, DRM_MODE_CONNECTOR_DSI); if (IS_ERR(bridge)) return PTR_ERR(bridge); } dsi->panel_bridge = bridge; drm_bridge_add(&dsi->bridge); if (pdata->host_ops && pdata->host_ops->attach) { ret = pdata->host_ops->attach(pdata->priv_data, device); if (ret < 0) return ret; } return 0; }
static int dw_mipi_dsi_host_attach(struct mipi_dsi_host *host, struct mipi_dsi_device *device) { struct dw_mipi_dsi *dsi = host_to_dsi(host); if (device->lanes > dsi->pdata->max_data_lanes) { DRM_DEV_ERROR(dsi->dev, "the number of data lanes(%u) is too many\n", device->lanes); return -EINVAL; } dsi->lanes = device->lanes; dsi->channel = device->channel; dsi->format = device->format; dsi->mode_flags = device->mode_flags; dsi->panel = of_drm_find_panel(device->dev.of_node); if (dsi->panel) return drm_panel_attach(dsi->panel, &dsi->connector); return -EINVAL; }
static ssize_t dw_mipi_dsi_host_transfer(struct mipi_dsi_host *host, const struct mipi_dsi_msg *msg) { struct dw_mipi_dsi *dsi = host_to_dsi(host); struct mipi_dsi_packet packet; int ret, nb_bytes; ret = mipi_dsi_create_packet(&packet, msg); if (ret) { dev_err(dsi->dev, "failed to create packet: %d\n", ret); return ret; } dw_mipi_message_config(dsi, msg); if (dsi->slave) dw_mipi_message_config(dsi->slave, msg); ret = dw_mipi_dsi_write(dsi, &packet); if (ret) return ret; if (dsi->slave) { ret = dw_mipi_dsi_write(dsi->slave, &packet); if (ret) return ret; } if (msg->rx_buf && msg->rx_len) { ret = dw_mipi_dsi_read(dsi, msg); if (ret) return ret; nb_bytes = msg->rx_len; } else { nb_bytes = packet.size; } return nb_bytes; }