2 * Copyright (C) 2012 Avionic Design GmbH
3 * Copyright (C) 2012 NVIDIA CORPORATION. All rights reserved.
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
10 #include <drm/drm_atomic_helper.h>
11 #include <drm/drm_panel.h>
14 int tegra_output_connector_get_modes(struct drm_connector
*connector
)
16 struct tegra_output
*output
= connector_to_output(connector
);
17 struct edid
*edid
= NULL
;
21 * If the panel provides one or more modes, use them exclusively and
22 * ignore any other means of obtaining a mode.
25 err
= output
->panel
->funcs
->get_modes(output
->panel
);
31 edid
= kmemdup(output
->edid
, sizeof(*edid
), GFP_KERNEL
);
33 edid
= drm_get_edid(connector
, output
->ddc
);
35 drm_mode_connector_update_edid_property(connector
, edid
);
38 err
= drm_add_edid_modes(connector
, edid
);
39 drm_edid_to_eld(connector
, edid
);
46 enum drm_connector_status
47 tegra_output_connector_detect(struct drm_connector
*connector
, bool force
)
49 struct tegra_output
*output
= connector_to_output(connector
);
50 enum drm_connector_status status
= connector_status_unknown
;
52 if (gpio_is_valid(output
->hpd_gpio
)) {
53 if (output
->hpd_gpio_flags
& OF_GPIO_ACTIVE_LOW
) {
54 if (gpio_get_value(output
->hpd_gpio
) != 0)
55 status
= connector_status_disconnected
;
57 status
= connector_status_connected
;
59 if (gpio_get_value(output
->hpd_gpio
) == 0)
60 status
= connector_status_disconnected
;
62 status
= connector_status_connected
;
66 status
= connector_status_disconnected
;
68 status
= connector_status_connected
;
74 void tegra_output_connector_destroy(struct drm_connector
*connector
)
76 drm_connector_unregister(connector
);
77 drm_connector_cleanup(connector
);
80 void tegra_output_encoder_destroy(struct drm_encoder
*encoder
)
82 drm_encoder_cleanup(encoder
);
85 static irqreturn_t
hpd_irq(int irq
, void *data
)
87 struct tegra_output
*output
= data
;
89 if (output
->connector
.dev
)
90 drm_helper_hpd_irq_event(output
->connector
.dev
);
95 int tegra_output_probe(struct tegra_output
*output
)
97 struct device_node
*ddc
, *panel
;
100 if (!output
->of_node
)
101 output
->of_node
= output
->dev
->of_node
;
103 panel
= of_parse_phandle(output
->of_node
, "nvidia,panel", 0);
105 output
->panel
= of_drm_find_panel(panel
);
107 return -EPROBE_DEFER
;
112 output
->edid
= of_get_property(output
->of_node
, "nvidia,edid", &size
);
114 ddc
= of_parse_phandle(output
->of_node
, "nvidia,ddc-i2c-bus", 0);
116 output
->ddc
= of_find_i2c_adapter_by_node(ddc
);
126 output
->hpd_gpio
= of_get_named_gpio_flags(output
->of_node
,
127 "nvidia,hpd-gpio", 0,
128 &output
->hpd_gpio_flags
);
129 if (gpio_is_valid(output
->hpd_gpio
)) {
132 err
= gpio_request_one(output
->hpd_gpio
, GPIOF_DIR_IN
,
133 "HDMI hotplug detect");
135 dev_err(output
->dev
, "gpio_request_one(): %d\n", err
);
139 err
= gpio_to_irq(output
->hpd_gpio
);
141 dev_err(output
->dev
, "gpio_to_irq(): %d\n", err
);
142 gpio_free(output
->hpd_gpio
);
146 output
->hpd_irq
= err
;
148 flags
= IRQF_TRIGGER_RISING
| IRQF_TRIGGER_FALLING
|
151 err
= request_threaded_irq(output
->hpd_irq
, NULL
, hpd_irq
,
152 flags
, "hpd", output
);
154 dev_err(output
->dev
, "failed to request IRQ#%u: %d\n",
155 output
->hpd_irq
, err
);
156 gpio_free(output
->hpd_gpio
);
160 output
->connector
.polled
= DRM_CONNECTOR_POLL_HPD
;
163 * Disable the interrupt until the connector has been
164 * initialized to avoid a race in the hotplug interrupt
167 disable_irq(output
->hpd_irq
);
173 void tegra_output_remove(struct tegra_output
*output
)
175 if (gpio_is_valid(output
->hpd_gpio
)) {
176 free_irq(output
->hpd_irq
, output
);
177 gpio_free(output
->hpd_gpio
);
181 put_device(&output
->ddc
->dev
);
184 int tegra_output_init(struct drm_device
*drm
, struct tegra_output
*output
)
189 err
= drm_panel_attach(output
->panel
, &output
->connector
);
195 * The connector is now registered and ready to receive hotplug events
196 * so the hotplug interrupt can be enabled.
198 if (gpio_is_valid(output
->hpd_gpio
))
199 enable_irq(output
->hpd_irq
);
204 void tegra_output_exit(struct tegra_output
*output
)
207 * The connector is going away, so the interrupt must be disabled to
208 * prevent the hotplug interrupt handler from potentially crashing.
210 if (gpio_is_valid(output
->hpd_gpio
))
211 disable_irq(output
->hpd_irq
);
214 drm_panel_detach(output
->panel
);