Lines Matching +full:aux +full:- +full:bus
1 // SPDX-License-Identifier: GPL-2.0-only
99 struct drm_dp_aux aux; member
152 static inline struct ps8640 *aux_to_ps8640(struct drm_dp_aux *aux) in aux_to_ps8640() argument
154 return container_of(aux, struct ps8640, aux); in aux_to_ps8640()
159 struct regmap *map = ps_bridge->regmap[PAGE2_TOP_CNTL]; in _ps8640_wait_hpd_asserted()
180 if (!ret && ps_bridge->need_post_hpd_delay) { in _ps8640_wait_hpd_asserted()
181 ps_bridge->need_post_hpd_delay = false; in _ps8640_wait_hpd_asserted()
188 static int ps8640_wait_hpd_asserted(struct drm_dp_aux *aux, unsigned long wait_us) in ps8640_wait_hpd_asserted() argument
190 struct ps8640 *ps_bridge = aux_to_ps8640(aux); in ps8640_wait_hpd_asserted()
191 struct device *dev = &ps_bridge->page[PAGE0_DP_CNTL]->dev; in ps8640_wait_hpd_asserted()
207 static ssize_t ps8640_aux_transfer_msg(struct drm_dp_aux *aux, in ps8640_aux_transfer_msg() argument
210 struct ps8640 *ps_bridge = aux_to_ps8640(aux); in ps8640_aux_transfer_msg()
211 struct regmap *map = ps_bridge->regmap[PAGE0_DP_CNTL]; in ps8640_aux_transfer_msg()
212 struct device *dev = &ps_bridge->page[PAGE0_DP_CNTL]->dev; in ps8640_aux_transfer_msg()
213 size_t len = msg->size; in ps8640_aux_transfer_msg()
217 u8 request = msg->request & in ps8640_aux_transfer_msg()
219 u8 *buf = msg->buffer; in ps8640_aux_transfer_msg()
220 u8 addr_len[PAGE0_SWAUX_LENGTH + 1 - PAGE0_SWAUX_ADDR_7_0]; in ps8640_aux_transfer_msg()
225 return -EINVAL; in ps8640_aux_transfer_msg()
227 if (msg->address & ~SWAUX_ADDR_MASK) in ps8640_aux_transfer_msg()
228 return -EINVAL; in ps8640_aux_transfer_msg()
239 return -EINVAL; in ps8640_aux_transfer_msg()
250 msg->reply = 0; in ps8640_aux_transfer_msg()
253 addr_len[PAGE0_SWAUX_ADDR_7_0 - base] = msg->address; in ps8640_aux_transfer_msg()
254 addr_len[PAGE0_SWAUX_ADDR_15_8 - base] = msg->address >> 8; in ps8640_aux_transfer_msg()
255 addr_len[PAGE0_SWAUX_ADDR_23_16 - base] = (msg->address >> 16) | in ps8640_aux_transfer_msg()
256 (msg->request << 4); in ps8640_aux_transfer_msg()
257 addr_len[PAGE0_SWAUX_LENGTH - base] = (len == 0) ? SWAUX_NO_PAYLOAD : in ps8640_aux_transfer_msg()
258 ((len - 1) & SWAUX_LENGTH_MASK); in ps8640_aux_transfer_msg()
299 msg->reply |= DP_AUX_NATIVE_REPLY_NACK; in ps8640_aux_transfer_msg()
301 msg->reply |= DP_AUX_I2C_REPLY_NACK; in ps8640_aux_transfer_msg()
310 msg->reply |= DP_AUX_NATIVE_REPLY_DEFER; in ps8640_aux_transfer_msg()
312 msg->reply |= DP_AUX_I2C_REPLY_DEFER; in ps8640_aux_transfer_msg()
316 return -EOPNOTSUPP; in ps8640_aux_transfer_msg()
318 return -ETIMEDOUT; in ps8640_aux_transfer_msg()
333 if (i < msg->size) in ps8640_aux_transfer_msg()
338 return min(len, msg->size); in ps8640_aux_transfer_msg()
341 static ssize_t ps8640_aux_transfer(struct drm_dp_aux *aux, in ps8640_aux_transfer() argument
344 struct ps8640 *ps_bridge = aux_to_ps8640(aux); in ps8640_aux_transfer()
345 struct device *dev = &ps_bridge->page[PAGE0_DP_CNTL]->dev; in ps8640_aux_transfer()
348 mutex_lock(&ps_bridge->aux_lock); in ps8640_aux_transfer()
355 ret = ps8640_aux_transfer_msg(aux, msg); in ps8640_aux_transfer()
360 mutex_unlock(&ps_bridge->aux_lock); in ps8640_aux_transfer()
368 struct regmap *map = ps_bridge->regmap[PAGE3_DSI_CNTL1]; in ps8640_bridge_vdo_control()
369 struct device *dev = &ps_bridge->page[PAGE3_DSI_CNTL1]->dev; in ps8640_bridge_vdo_control()
386 ret = regulator_bulk_enable(ARRAY_SIZE(ps_bridge->supplies), in ps8640_resume()
387 ps_bridge->supplies); in ps8640_resume()
393 gpiod_set_value(ps_bridge->gpio_powerdown, 0); in ps8640_resume()
394 gpiod_set_value(ps_bridge->gpio_reset, 1); in ps8640_resume()
396 gpiod_set_value(ps_bridge->gpio_reset, 0); in ps8640_resume()
399 gpiod_set_value(ps_bridge->gpio_reset, 1); in ps8640_resume()
401 gpiod_set_value(ps_bridge->gpio_reset, 0); in ps8640_resume()
404 ps_bridge->need_post_hpd_delay = true; in ps8640_resume()
423 gpiod_set_value(ps_bridge->gpio_reset, 1); in ps8640_suspend()
424 gpiod_set_value(ps_bridge->gpio_powerdown, 1); in ps8640_suspend()
425 ret = regulator_bulk_disable(ARRAY_SIZE(ps_bridge->supplies), in ps8640_suspend()
426 ps_bridge->supplies); in ps8640_suspend()
443 struct regmap *map = ps_bridge->regmap[PAGE2_TOP_CNTL]; in ps8640_atomic_pre_enable()
444 struct device *dev = &ps_bridge->page[PAGE0_DP_CNTL]->dev; in ps8640_atomic_pre_enable()
471 ps_bridge->pre_enabled = true; in ps8640_atomic_pre_enable()
479 ps_bridge->pre_enabled = false; in ps8640_atomic_post_disable()
489 mutex_lock(&ps_bridge->aux_lock); in ps8640_atomic_post_disable()
491 pm_runtime_put_sync_suspend(&ps_bridge->page[PAGE0_DP_CNTL]->dev); in ps8640_atomic_post_disable()
493 mutex_unlock(&ps_bridge->aux_lock); in ps8640_atomic_post_disable()
500 struct device *dev = &ps_bridge->page[0]->dev; in ps8640_bridge_attach()
504 return -EINVAL; in ps8640_bridge_attach()
506 ps_bridge->aux.drm_dev = bridge->dev; in ps8640_bridge_attach()
507 ret = drm_dp_aux_register(&ps_bridge->aux); in ps8640_bridge_attach()
509 dev_err(dev, "failed to register DP AUX channel: %d\n", ret); in ps8640_bridge_attach()
513 ps_bridge->link = device_link_add(bridge->dev->dev, dev, DL_FLAG_STATELESS); in ps8640_bridge_attach()
514 if (!ps_bridge->link) { in ps8640_bridge_attach()
516 ret = -EINVAL; in ps8640_bridge_attach()
520 /* Attach the panel-bridge to the dsi bridge */ in ps8640_bridge_attach()
521 ret = drm_bridge_attach(bridge->encoder, ps_bridge->panel_bridge, in ps8640_bridge_attach()
522 &ps_bridge->bridge, flags); in ps8640_bridge_attach()
529 device_link_del(ps_bridge->link); in ps8640_bridge_attach()
531 drm_dp_aux_unregister(&ps_bridge->aux); in ps8640_bridge_attach()
540 drm_dp_aux_unregister(&ps_bridge->aux); in ps8640_bridge_detach()
541 if (ps_bridge->link) in ps8640_bridge_detach()
542 device_link_del(ps_bridge->link); in ps8640_bridge_detach()
572 in_ep = of_graph_get_endpoint_by_regs(dev->of_node, 0, -1); in ps8640_bridge_get_dsi_resources()
574 return -ENODEV; in ps8640_bridge_get_dsi_resources()
579 return -ENODEV; in ps8640_bridge_get_dsi_resources()
584 return -EPROBE_DEFER; in ps8640_bridge_get_dsi_resources()
592 ps_bridge->dsi = dsi; in ps8640_bridge_get_dsi_resources()
594 dsi->host = host; in ps8640_bridge_get_dsi_resources()
595 dsi->mode_flags = MIPI_DSI_MODE_VIDEO | in ps8640_bridge_get_dsi_resources()
597 dsi->format = MIPI_DSI_FMT_RGB888; in ps8640_bridge_get_dsi_resources()
598 dsi->lanes = NUM_MIPI_LANES; in ps8640_bridge_get_dsi_resources()
603 static int ps8640_bridge_link_panel(struct drm_dp_aux *aux) in ps8640_bridge_link_panel() argument
605 struct ps8640 *ps_bridge = aux_to_ps8640(aux); in ps8640_bridge_link_panel()
606 struct device *dev = aux->dev; in ps8640_bridge_link_panel()
607 struct device_node *np = dev->of_node; in ps8640_bridge_link_panel()
611 * NOTE about returning -EPROBE_DEFER from this function: if we in ps8640_bridge_link_panel()
612 * return an error (most relevant to -EPROBE_DEFER) it will only in ps8640_bridge_link_panel()
614 * panel isn't under the "aux-bus" node). That should be fine because in ps8640_bridge_link_panel()
615 * if the panel is under "aux-bus" it's guaranteed to have probed by in ps8640_bridge_link_panel()
620 ps_bridge->panel_bridge = devm_drm_of_get_bridge(dev, np, 1, 0); in ps8640_bridge_link_panel()
621 if (IS_ERR(ps_bridge->panel_bridge)) in ps8640_bridge_link_panel()
622 return PTR_ERR(ps_bridge->panel_bridge); in ps8640_bridge_link_panel()
624 ret = devm_drm_bridge_add(dev, &ps_bridge->bridge); in ps8640_bridge_link_panel()
628 return devm_mipi_dsi_attach(dev, ps_bridge->dsi); in ps8640_bridge_link_panel()
633 struct device *dev = &client->dev; in ps8640_probe()
640 return -ENOMEM; in ps8640_probe()
642 mutex_init(&ps_bridge->aux_lock); in ps8640_probe()
644 ps_bridge->supplies[0].supply = "vdd12"; in ps8640_probe()
645 ps_bridge->supplies[1].supply = "vdd33"; in ps8640_probe()
646 ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(ps_bridge->supplies), in ps8640_probe()
647 ps_bridge->supplies); in ps8640_probe()
651 ps_bridge->gpio_powerdown = devm_gpiod_get(&client->dev, "powerdown", in ps8640_probe()
653 if (IS_ERR(ps_bridge->gpio_powerdown)) in ps8640_probe()
654 return PTR_ERR(ps_bridge->gpio_powerdown); in ps8640_probe()
659 ps_bridge->gpio_reset = devm_gpiod_get(&client->dev, "reset", in ps8640_probe()
661 if (IS_ERR(ps_bridge->gpio_reset)) in ps8640_probe()
662 return PTR_ERR(ps_bridge->gpio_reset); in ps8640_probe()
664 ps_bridge->bridge.funcs = &ps8640_bridge_funcs; in ps8640_probe()
665 ps_bridge->bridge.of_node = dev->of_node; in ps8640_probe()
666 ps_bridge->bridge.type = DRM_MODE_CONNECTOR_eDP; in ps8640_probe()
669 * Get MIPI DSI resources early. These can return -EPROBE_DEFER so in ps8640_probe()
672 ret = ps8640_bridge_get_dsi_resources(&client->dev, ps_bridge); in ps8640_probe()
676 ps_bridge->page[PAGE0_DP_CNTL] = client; in ps8640_probe()
678 ps_bridge->regmap[PAGE0_DP_CNTL] = devm_regmap_init_i2c(client, ps8640_regmap_config); in ps8640_probe()
679 if (IS_ERR(ps_bridge->regmap[PAGE0_DP_CNTL])) in ps8640_probe()
680 return PTR_ERR(ps_bridge->regmap[PAGE0_DP_CNTL]); in ps8640_probe()
682 for (i = 1; i < ARRAY_SIZE(ps_bridge->page); i++) { in ps8640_probe()
683 ps_bridge->page[i] = devm_i2c_new_dummy_device(&client->dev, in ps8640_probe()
684 client->adapter, in ps8640_probe()
685 client->addr + i); in ps8640_probe()
686 if (IS_ERR(ps_bridge->page[i])) in ps8640_probe()
687 return PTR_ERR(ps_bridge->page[i]); in ps8640_probe()
689 ps_bridge->regmap[i] = devm_regmap_init_i2c(ps_bridge->page[i], in ps8640_probe()
691 if (IS_ERR(ps_bridge->regmap[i])) in ps8640_probe()
692 return PTR_ERR(ps_bridge->regmap[i]); in ps8640_probe()
697 ps_bridge->aux.name = "parade-ps8640-aux"; in ps8640_probe()
698 ps_bridge->aux.dev = dev; in ps8640_probe()
699 ps_bridge->aux.transfer = ps8640_aux_transfer; in ps8640_probe()
700 ps_bridge->aux.wait_hpd_asserted = ps8640_wait_hpd_asserted; in ps8640_probe()
701 drm_dp_aux_init(&ps_bridge->aux); in ps8640_probe()
719 ret = devm_of_dp_aux_populate_bus(&ps_bridge->aux, ps8640_bridge_link_panel); in ps8640_probe()
722 * If devm_of_dp_aux_populate_bus() returns -ENODEV then it's up to in ps8640_probe()
724 * the function is allowed to -EPROBE_DEFER. in ps8640_probe()
726 if (ret == -ENODEV) in ps8640_probe()
727 return ps8640_bridge_link_panel(&ps_bridge->aux); in ps8640_probe()
751 MODULE_DESCRIPTION("PARADE ps8640 DSI-eDP converter driver");