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/of_gpio.h>
14 static int tegra_connector_get_modes(struct drm_connector
*connector
)
16 struct tegra_output
*output
= connector_to_output(connector
);
17 struct edid
*edid
= NULL
;
21 edid
= kmemdup(output
->edid
, sizeof(*edid
), GFP_KERNEL
);
23 edid
= drm_get_edid(connector
, output
->ddc
);
25 drm_mode_connector_update_edid_property(connector
, edid
);
28 err
= drm_add_edid_modes(connector
, edid
);
35 static int tegra_connector_mode_valid(struct drm_connector
*connector
,
36 struct drm_display_mode
*mode
)
38 struct tegra_output
*output
= connector_to_output(connector
);
39 enum drm_mode_status status
= MODE_OK
;
42 err
= tegra_output_check_mode(output
, mode
, &status
);
49 static struct drm_encoder
*
50 tegra_connector_best_encoder(struct drm_connector
*connector
)
52 struct tegra_output
*output
= connector_to_output(connector
);
54 return &output
->encoder
;
57 static const struct drm_connector_helper_funcs connector_helper_funcs
= {
58 .get_modes
= tegra_connector_get_modes
,
59 .mode_valid
= tegra_connector_mode_valid
,
60 .best_encoder
= tegra_connector_best_encoder
,
63 static enum drm_connector_status
64 tegra_connector_detect(struct drm_connector
*connector
, bool force
)
66 struct tegra_output
*output
= connector_to_output(connector
);
67 enum drm_connector_status status
= connector_status_unknown
;
69 if (gpio_is_valid(output
->hpd_gpio
)) {
70 if (gpio_get_value(output
->hpd_gpio
) == 0)
71 status
= connector_status_disconnected
;
73 status
= connector_status_connected
;
75 if (connector
->connector_type
== DRM_MODE_CONNECTOR_LVDS
)
76 status
= connector_status_connected
;
82 static void drm_connector_clear(struct drm_connector
*connector
)
84 memset(connector
, 0, sizeof(*connector
));
87 static void tegra_connector_destroy(struct drm_connector
*connector
)
89 drm_sysfs_connector_remove(connector
);
90 drm_connector_cleanup(connector
);
91 drm_connector_clear(connector
);
94 static const struct drm_connector_funcs connector_funcs
= {
95 .dpms
= drm_helper_connector_dpms
,
96 .detect
= tegra_connector_detect
,
97 .fill_modes
= drm_helper_probe_single_connector_modes
,
98 .destroy
= tegra_connector_destroy
,
101 static void drm_encoder_clear(struct drm_encoder
*encoder
)
103 memset(encoder
, 0, sizeof(*encoder
));
106 static void tegra_encoder_destroy(struct drm_encoder
*encoder
)
108 drm_encoder_cleanup(encoder
);
109 drm_encoder_clear(encoder
);
112 static const struct drm_encoder_funcs encoder_funcs
= {
113 .destroy
= tegra_encoder_destroy
,
116 static void tegra_encoder_dpms(struct drm_encoder
*encoder
, int mode
)
120 static bool tegra_encoder_mode_fixup(struct drm_encoder
*encoder
,
121 const struct drm_display_mode
*mode
,
122 struct drm_display_mode
*adjusted
)
127 static void tegra_encoder_prepare(struct drm_encoder
*encoder
)
131 static void tegra_encoder_commit(struct drm_encoder
*encoder
)
135 static void tegra_encoder_mode_set(struct drm_encoder
*encoder
,
136 struct drm_display_mode
*mode
,
137 struct drm_display_mode
*adjusted
)
139 struct tegra_output
*output
= encoder_to_output(encoder
);
142 err
= tegra_output_enable(output
);
144 dev_err(encoder
->dev
->dev
, "tegra_output_enable(): %d\n", err
);
147 static const struct drm_encoder_helper_funcs encoder_helper_funcs
= {
148 .dpms
= tegra_encoder_dpms
,
149 .mode_fixup
= tegra_encoder_mode_fixup
,
150 .prepare
= tegra_encoder_prepare
,
151 .commit
= tegra_encoder_commit
,
152 .mode_set
= tegra_encoder_mode_set
,
155 static irqreturn_t
hpd_irq(int irq
, void *data
)
157 struct tegra_output
*output
= data
;
159 drm_helper_hpd_irq_event(output
->connector
.dev
);
164 int tegra_output_probe(struct tegra_output
*output
)
166 enum of_gpio_flags flags
;
167 struct device_node
*ddc
;
171 if (!output
->of_node
)
172 output
->of_node
= output
->dev
->of_node
;
174 output
->edid
= of_get_property(output
->of_node
, "nvidia,edid", &size
);
176 ddc
= of_parse_phandle(output
->of_node
, "nvidia,ddc-i2c-bus", 0);
178 output
->ddc
= of_find_i2c_adapter_by_node(ddc
);
188 if (!output
->edid
&& !output
->ddc
)
191 output
->hpd_gpio
= of_get_named_gpio_flags(output
->of_node
,
192 "nvidia,hpd-gpio", 0,
194 if (gpio_is_valid(output
->hpd_gpio
)) {
197 err
= gpio_request_one(output
->hpd_gpio
, GPIOF_DIR_IN
,
198 "HDMI hotplug detect");
200 dev_err(output
->dev
, "gpio_request_one(): %d\n", err
);
204 err
= gpio_to_irq(output
->hpd_gpio
);
206 dev_err(output
->dev
, "gpio_to_irq(): %d\n", err
);
207 gpio_free(output
->hpd_gpio
);
211 output
->hpd_irq
= err
;
213 flags
= IRQF_TRIGGER_RISING
| IRQF_TRIGGER_FALLING
|
216 err
= request_threaded_irq(output
->hpd_irq
, NULL
, hpd_irq
,
217 flags
, "hpd", output
);
219 dev_err(output
->dev
, "failed to request IRQ#%u: %d\n",
220 output
->hpd_irq
, err
);
221 gpio_free(output
->hpd_gpio
);
225 output
->connector
.polled
= DRM_CONNECTOR_POLL_HPD
;
231 int tegra_output_remove(struct tegra_output
*output
)
233 if (gpio_is_valid(output
->hpd_gpio
)) {
234 free_irq(output
->hpd_irq
, output
);
235 gpio_free(output
->hpd_gpio
);
239 put_device(&output
->ddc
->dev
);
244 int tegra_output_init(struct drm_device
*drm
, struct tegra_output
*output
)
246 int connector
, encoder
;
248 switch (output
->type
) {
249 case TEGRA_OUTPUT_RGB
:
250 connector
= DRM_MODE_CONNECTOR_LVDS
;
251 encoder
= DRM_MODE_ENCODER_LVDS
;
254 case TEGRA_OUTPUT_HDMI
:
255 connector
= DRM_MODE_CONNECTOR_HDMIA
;
256 encoder
= DRM_MODE_ENCODER_TMDS
;
260 connector
= DRM_MODE_CONNECTOR_Unknown
;
261 encoder
= DRM_MODE_ENCODER_NONE
;
265 drm_connector_init(drm
, &output
->connector
, &connector_funcs
,
267 drm_connector_helper_add(&output
->connector
, &connector_helper_funcs
);
269 drm_encoder_init(drm
, &output
->encoder
, &encoder_funcs
, encoder
);
270 drm_encoder_helper_add(&output
->encoder
, &encoder_helper_funcs
);
272 drm_mode_connector_attach_encoder(&output
->connector
, &output
->encoder
);
273 drm_sysfs_connector_add(&output
->connector
);
275 output
->encoder
.possible_crtcs
= 0x3;
280 int tegra_output_exit(struct tegra_output
*output
)