hdmi->pwr_clks[i] = clk;
}
+ hdmi->hpd_gpiod = devm_gpiod_get_optional(&pdev->dev, "hpd", GPIOD_IN);
+ /* This will catch e.g. -EPROBE_DEFER */
+ if (IS_ERR(hdmi->hpd_gpiod)) {
+ ret = PTR_ERR(hdmi->hpd_gpiod);
+ DRM_DEV_ERROR(&pdev->dev, "failed to get hpd gpio: (%d)\n", ret);
+ goto fail;
+ }
+
+ if (!hdmi->hpd_gpiod)
+ DBG("failed to get HPD gpio");
+
+ if (hdmi->hpd_gpiod)
+ gpiod_set_consumer_name(hdmi->hpd_gpiod, "HDMI_HPD");
+
pm_runtime_enable(&pdev->dev);
hdmi->workq = alloc_ordered_workqueue("msm_hdmi", 0);
.hpd_freq = hpd_clk_freq_8x74,
};
-static const struct {
- const char *name;
- const bool output;
- const int value;
- const char *label;
-} msm_hdmi_gpio_pdata[] = {
- { "qcom,hdmi-tx-ddc-clk", true, 1, "HDMI_DDC_CLK" },
- { "qcom,hdmi-tx-ddc-data", true, 1, "HDMI_DDC_DATA" },
- { "qcom,hdmi-tx-hpd", false, 1, "HDMI_HPD" },
- { "qcom,hdmi-tx-mux-en", true, 1, "HDMI_MUX_EN" },
- { "qcom,hdmi-tx-mux-sel", true, 0, "HDMI_MUX_SEL" },
- { "qcom,hdmi-tx-mux-lpm", true, 1, "HDMI_MUX_LPM" },
-};
-
/*
* HDMI audio codec callbacks
*/
struct hdmi_platform_config *hdmi_cfg;
struct hdmi *hdmi;
struct device_node *of_node = dev->of_node;
- int i, err;
+ int err;
hdmi_cfg = (struct hdmi_platform_config *)
of_device_get_match_data(dev);
hdmi_cfg->mmio_name = "core_physical";
hdmi_cfg->qfprom_mmio_name = "qfprom_physical";
- for (i = 0; i < HDMI_MAX_NUM_GPIO; i++) {
- const char *name = msm_hdmi_gpio_pdata[i].name;
- struct gpio_desc *gpiod;
-
- /*
- * We are fetching the GPIO lines "as is" since the connector
- * code is enabling and disabling the lines. Until that point
- * the power-on default value will be kept.
- */
- gpiod = devm_gpiod_get_optional(dev, name, GPIOD_ASIS);
- /* This will catch e.g. -PROBE_DEFER */
- if (IS_ERR(gpiod))
- return PTR_ERR(gpiod);
- if (!gpiod) {
- /* Try a second time, stripping down the name */
- char name3[32];
-
- /*
- * Try again after stripping out the "qcom,hdmi-tx"
- * prefix. This is mainly to match "hpd-gpios" used
- * in the upstream bindings.
- */
- if (sscanf(name, "qcom,hdmi-tx-%s", name3))
- gpiod = devm_gpiod_get_optional(dev, name3, GPIOD_ASIS);
- if (IS_ERR(gpiod))
- return PTR_ERR(gpiod);
- if (!gpiod)
- DBG("failed to get gpio: %s", name);
- }
- hdmi_cfg->gpios[i].gpiod = gpiod;
- if (gpiod)
- gpiod_set_consumer_name(gpiod, msm_hdmi_gpio_pdata[i].label);
- hdmi_cfg->gpios[i].output = msm_hdmi_gpio_pdata[i].output;
- hdmi_cfg->gpios[i].value = msm_hdmi_gpio_pdata[i].value;
- }
-
dev->platform_data = hdmi_cfg;
hdmi = msm_hdmi_init(to_platform_device(dev));
}
}
-static int gpio_config(struct hdmi *hdmi, bool on)
-{
- const struct hdmi_platform_config *config = hdmi->config;
- int i;
-
- if (on) {
- for (i = 0; i < HDMI_MAX_NUM_GPIO; i++) {
- struct hdmi_gpio_data gpio = config->gpios[i];
-
- if (gpio.gpiod) {
- if (gpio.output) {
- gpiod_direction_output(gpio.gpiod,
- gpio.value);
- } else {
- gpiod_direction_input(gpio.gpiod);
- gpiod_set_value_cansleep(gpio.gpiod,
- gpio.value);
- }
- }
- }
-
- DBG("gpio on");
- } else {
- for (i = 0; i < HDMI_MAX_NUM_GPIO; i++) {
- struct hdmi_gpio_data gpio = config->gpios[i];
-
- if (!gpio.gpiod)
- continue;
-
- if (gpio.output) {
- int value = gpio.value ? 0 : 1;
-
- gpiod_set_value_cansleep(gpio.gpiod, value);
- }
- }
-
- DBG("gpio off");
- }
-
- return 0;
-}
-
static void enable_hpd_clocks(struct hdmi *hdmi, bool enable)
{
const struct hdmi_platform_config *config = hdmi->config;
goto fail;
}
- ret = gpio_config(hdmi, true);
- if (ret) {
- DRM_DEV_ERROR(dev, "failed to configure GPIOs: %d\n", ret);
- goto fail;
- }
+ if (hdmi->hpd_gpiod)
+ gpiod_set_value_cansleep(hdmi->hpd_gpiod, 1);
pm_runtime_get_sync(dev);
enable_hpd_clocks(hdmi, true);
enable_hpd_clocks(hdmi, false);
pm_runtime_put(dev);
- ret = gpio_config(hdmi, false);
- if (ret)
- dev_warn(dev, "failed to unconfigure GPIOs: %d\n", ret);
-
ret = pinctrl_pm_select_sleep_state(dev);
if (ret)
dev_warn(dev, "pinctrl state chg failed: %d\n", ret);
#define HPD_GPIO_INDEX 2
static enum drm_connector_status detect_gpio(struct hdmi *hdmi)
{
- const struct hdmi_platform_config *config = hdmi->config;
- struct hdmi_gpio_data hpd_gpio = config->gpios[HPD_GPIO_INDEX];
-
- return gpiod_get_value(hpd_gpio.gpiod) ?
+ return gpiod_get_value(hdmi->hpd_gpiod) ?
connector_status_connected :
connector_status_disconnected;
}
{
struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge);
struct hdmi *hdmi = hdmi_bridge->hdmi;
- const struct hdmi_platform_config *config = hdmi->config;
- struct hdmi_gpio_data hpd_gpio = config->gpios[HPD_GPIO_INDEX];
enum drm_connector_status stat_gpio, stat_reg;
int retry = 20;
* some platforms may not have hpd gpio. Rely only on the status
* provided by REG_HDMI_HPD_INT_STATUS in this case.
*/
- if (!hpd_gpio.gpiod)
+ if (!hdmi->hpd_gpiod)
return detect_reg(hdmi);
do {