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 <linux/module.h>
11 #include <linux/of_gpio.h>
12 #include <linux/of_i2c.h>
16 static int tegra_connector_get_modes(struct drm_connector
*connector
)
18 struct tegra_output
*output
= connector_to_output(connector
);
19 struct edid
*edid
= NULL
;
23 edid
= kmemdup(output
->edid
, sizeof(*edid
), GFP_KERNEL
);
25 edid
= drm_get_edid(connector
, output
->ddc
);
27 drm_mode_connector_update_edid_property(connector
, edid
);
30 err
= drm_add_edid_modes(connector
, edid
);
37 static int tegra_connector_mode_valid(struct drm_connector
*connector
,
38 struct drm_display_mode
*mode
)
40 struct tegra_output
*output
= connector_to_output(connector
);
41 enum drm_mode_status status
= MODE_OK
;
44 err
= tegra_output_check_mode(output
, mode
, &status
);
51 static struct drm_encoder
*
52 tegra_connector_best_encoder(struct drm_connector
*connector
)
54 struct tegra_output
*output
= connector_to_output(connector
);
56 return &output
->encoder
;
59 static const struct drm_connector_helper_funcs connector_helper_funcs
= {
60 .get_modes
= tegra_connector_get_modes
,
61 .mode_valid
= tegra_connector_mode_valid
,
62 .best_encoder
= tegra_connector_best_encoder
,
65 static enum drm_connector_status
66 tegra_connector_detect(struct drm_connector
*connector
, bool force
)
68 struct tegra_output
*output
= connector_to_output(connector
);
69 enum drm_connector_status status
= connector_status_unknown
;
71 if (gpio_is_valid(output
->hpd_gpio
)) {
72 if (gpio_get_value(output
->hpd_gpio
) == 0)
73 status
= connector_status_disconnected
;
75 status
= connector_status_connected
;
77 if (connector
->connector_type
== DRM_MODE_CONNECTOR_LVDS
)
78 status
= connector_status_connected
;
84 static void tegra_connector_destroy(struct drm_connector
*connector
)
86 drm_sysfs_connector_remove(connector
);
87 drm_connector_cleanup(connector
);
90 static const struct drm_connector_funcs connector_funcs
= {
91 .dpms
= drm_helper_connector_dpms
,
92 .detect
= tegra_connector_detect
,
93 .fill_modes
= drm_helper_probe_single_connector_modes
,
94 .destroy
= tegra_connector_destroy
,
97 static void tegra_encoder_destroy(struct drm_encoder
*encoder
)
99 drm_encoder_cleanup(encoder
);
102 static const struct drm_encoder_funcs encoder_funcs
= {
103 .destroy
= tegra_encoder_destroy
,
106 static void tegra_encoder_dpms(struct drm_encoder
*encoder
, int mode
)
110 static bool tegra_encoder_mode_fixup(struct drm_encoder
*encoder
,
111 const struct drm_display_mode
*mode
,
112 struct drm_display_mode
*adjusted
)
117 static void tegra_encoder_prepare(struct drm_encoder
*encoder
)
121 static void tegra_encoder_commit(struct drm_encoder
*encoder
)
125 static void tegra_encoder_mode_set(struct drm_encoder
*encoder
,
126 struct drm_display_mode
*mode
,
127 struct drm_display_mode
*adjusted
)
129 struct tegra_output
*output
= encoder_to_output(encoder
);
132 err
= tegra_output_enable(output
);
134 dev_err(encoder
->dev
->dev
, "tegra_output_enable(): %d\n", err
);
137 static const struct drm_encoder_helper_funcs encoder_helper_funcs
= {
138 .dpms
= tegra_encoder_dpms
,
139 .mode_fixup
= tegra_encoder_mode_fixup
,
140 .prepare
= tegra_encoder_prepare
,
141 .commit
= tegra_encoder_commit
,
142 .mode_set
= tegra_encoder_mode_set
,
145 static irqreturn_t
hpd_irq(int irq
, void *data
)
147 struct tegra_output
*output
= data
;
149 drm_helper_hpd_irq_event(output
->connector
.dev
);
154 int tegra_output_parse_dt(struct tegra_output
*output
)
156 enum of_gpio_flags flags
;
157 struct device_node
*ddc
;
161 if (!output
->of_node
)
162 output
->of_node
= output
->dev
->of_node
;
164 output
->edid
= of_get_property(output
->of_node
, "nvidia,edid", &size
);
166 ddc
= of_parse_phandle(output
->of_node
, "nvidia,ddc-i2c-bus", 0);
168 output
->ddc
= of_find_i2c_adapter_by_node(ddc
);
178 if (!output
->edid
&& !output
->ddc
)
181 output
->hpd_gpio
= of_get_named_gpio_flags(output
->of_node
,
182 "nvidia,hpd-gpio", 0,
188 int tegra_output_init(struct drm_device
*drm
, struct tegra_output
*output
)
190 int connector
, encoder
, err
;
192 if (gpio_is_valid(output
->hpd_gpio
)) {
195 err
= gpio_request_one(output
->hpd_gpio
, GPIOF_DIR_IN
,
196 "HDMI hotplug detect");
198 dev_err(output
->dev
, "gpio_request_one(): %d\n", err
);
202 err
= gpio_to_irq(output
->hpd_gpio
);
204 dev_err(output
->dev
, "gpio_to_irq(): %d\n", err
);
208 output
->hpd_irq
= err
;
210 flags
= IRQF_TRIGGER_RISING
| IRQF_TRIGGER_FALLING
|
213 err
= request_threaded_irq(output
->hpd_irq
, NULL
, hpd_irq
,
214 flags
, "hpd", output
);
216 dev_err(output
->dev
, "failed to request IRQ#%u: %d\n",
217 output
->hpd_irq
, err
);
221 output
->connector
.polled
= DRM_CONNECTOR_POLL_HPD
;
224 switch (output
->type
) {
225 case TEGRA_OUTPUT_RGB
:
226 connector
= DRM_MODE_CONNECTOR_LVDS
;
227 encoder
= DRM_MODE_ENCODER_LVDS
;
230 case TEGRA_OUTPUT_HDMI
:
231 connector
= DRM_MODE_CONNECTOR_HDMIA
;
232 encoder
= DRM_MODE_ENCODER_TMDS
;
236 connector
= DRM_MODE_CONNECTOR_Unknown
;
237 encoder
= DRM_MODE_ENCODER_NONE
;
241 drm_connector_init(drm
, &output
->connector
, &connector_funcs
,
243 drm_connector_helper_add(&output
->connector
, &connector_helper_funcs
);
245 drm_encoder_init(drm
, &output
->encoder
, &encoder_funcs
, encoder
);
246 drm_encoder_helper_add(&output
->encoder
, &encoder_helper_funcs
);
248 drm_mode_connector_attach_encoder(&output
->connector
, &output
->encoder
);
249 drm_sysfs_connector_add(&output
->connector
);
251 output
->encoder
.possible_crtcs
= 0x3;
256 gpio_free(output
->hpd_gpio
);
261 int tegra_output_exit(struct tegra_output
*output
)
263 if (gpio_is_valid(output
->hpd_gpio
)) {
264 free_irq(output
->hpd_irq
, output
);
265 gpio_free(output
->hpd_gpio
);
269 put_device(&output
->ddc
->dev
);