2 * Copyright (C) 2012 Texas Instruments
3 * Author: Rob Clark <robdclark@gmail.com>
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 as published by
7 * the Free Software Foundation.
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * You should have received a copy of the GNU General Public License along with
15 * this program. If not, see <http://www.gnu.org/licenses/>.
18 #include <linux/i2c.h>
19 #include <linux/gpio.h>
20 #include <linux/of_gpio.h>
21 #include <linux/pinctrl/pinmux.h>
22 #include <linux/pinctrl/consumer.h>
23 #include <drm/drm_atomic_helper.h>
24 #include <drm/drm_probe_helper.h>
26 #include "tilcdc_drv.h"
27 #include "tilcdc_tfp410.h"
29 struct tfp410_module
{
30 struct tilcdc_module base
;
31 struct i2c_adapter
*i2c
;
34 #define to_tfp410_module(x) container_of(x, struct tfp410_module, base)
37 static const struct tilcdc_panel_info dvi_info
= {
53 struct tfp410_encoder
{
54 struct drm_encoder base
;
55 struct tfp410_module
*mod
;
58 #define to_tfp410_encoder(x) container_of(x, struct tfp410_encoder, base)
60 static void tfp410_encoder_dpms(struct drm_encoder
*encoder
, int mode
)
62 struct tfp410_encoder
*tfp410_encoder
= to_tfp410_encoder(encoder
);
64 if (tfp410_encoder
->dpms
== mode
)
67 if (mode
== DRM_MODE_DPMS_ON
) {
69 gpio_direction_output(tfp410_encoder
->mod
->gpio
, 1);
72 gpio_direction_output(tfp410_encoder
->mod
->gpio
, 0);
75 tfp410_encoder
->dpms
= mode
;
78 static void tfp410_encoder_prepare(struct drm_encoder
*encoder
)
80 tfp410_encoder_dpms(encoder
, DRM_MODE_DPMS_OFF
);
83 static void tfp410_encoder_commit(struct drm_encoder
*encoder
)
85 tfp410_encoder_dpms(encoder
, DRM_MODE_DPMS_ON
);
88 static void tfp410_encoder_mode_set(struct drm_encoder
*encoder
,
89 struct drm_display_mode
*mode
,
90 struct drm_display_mode
*adjusted_mode
)
95 static const struct drm_encoder_funcs tfp410_encoder_funcs
= {
96 .destroy
= drm_encoder_cleanup
,
99 static const struct drm_encoder_helper_funcs tfp410_encoder_helper_funcs
= {
100 .dpms
= tfp410_encoder_dpms
,
101 .prepare
= tfp410_encoder_prepare
,
102 .commit
= tfp410_encoder_commit
,
103 .mode_set
= tfp410_encoder_mode_set
,
106 static struct drm_encoder
*tfp410_encoder_create(struct drm_device
*dev
,
107 struct tfp410_module
*mod
)
109 struct tfp410_encoder
*tfp410_encoder
;
110 struct drm_encoder
*encoder
;
113 tfp410_encoder
= devm_kzalloc(dev
->dev
, sizeof(*tfp410_encoder
),
118 tfp410_encoder
->dpms
= DRM_MODE_DPMS_OFF
;
119 tfp410_encoder
->mod
= mod
;
121 encoder
= &tfp410_encoder
->base
;
122 encoder
->possible_crtcs
= 1;
124 ret
= drm_encoder_init(dev
, encoder
, &tfp410_encoder_funcs
,
125 DRM_MODE_ENCODER_TMDS
, NULL
);
129 drm_encoder_helper_add(encoder
, &tfp410_encoder_helper_funcs
);
134 drm_encoder_cleanup(encoder
);
142 struct tfp410_connector
{
143 struct drm_connector base
;
145 struct drm_encoder
*encoder
; /* our connected encoder */
146 struct tfp410_module
*mod
;
148 #define to_tfp410_connector(x) container_of(x, struct tfp410_connector, base)
151 static void tfp410_connector_destroy(struct drm_connector
*connector
)
153 drm_connector_unregister(connector
);
154 drm_connector_cleanup(connector
);
157 static enum drm_connector_status
tfp410_connector_detect(
158 struct drm_connector
*connector
,
161 struct tfp410_connector
*tfp410_connector
= to_tfp410_connector(connector
);
163 if (drm_probe_ddc(tfp410_connector
->mod
->i2c
))
164 return connector_status_connected
;
166 return connector_status_unknown
;
169 static int tfp410_connector_get_modes(struct drm_connector
*connector
)
171 struct tfp410_connector
*tfp410_connector
= to_tfp410_connector(connector
);
175 edid
= drm_get_edid(connector
, tfp410_connector
->mod
->i2c
);
177 drm_connector_update_edid_property(connector
, edid
);
180 ret
= drm_add_edid_modes(connector
, edid
);
187 static int tfp410_connector_mode_valid(struct drm_connector
*connector
,
188 struct drm_display_mode
*mode
)
190 struct tilcdc_drm_private
*priv
= connector
->dev
->dev_private
;
191 /* our only constraints are what the crtc can generate: */
192 return tilcdc_crtc_mode_valid(priv
->crtc
, mode
);
195 static struct drm_encoder
*tfp410_connector_best_encoder(
196 struct drm_connector
*connector
)
198 struct tfp410_connector
*tfp410_connector
= to_tfp410_connector(connector
);
199 return tfp410_connector
->encoder
;
202 static const struct drm_connector_funcs tfp410_connector_funcs
= {
203 .destroy
= tfp410_connector_destroy
,
204 .detect
= tfp410_connector_detect
,
205 .fill_modes
= drm_helper_probe_single_connector_modes
,
206 .reset
= drm_atomic_helper_connector_reset
,
207 .atomic_duplicate_state
= drm_atomic_helper_connector_duplicate_state
,
208 .atomic_destroy_state
= drm_atomic_helper_connector_destroy_state
,
211 static const struct drm_connector_helper_funcs tfp410_connector_helper_funcs
= {
212 .get_modes
= tfp410_connector_get_modes
,
213 .mode_valid
= tfp410_connector_mode_valid
,
214 .best_encoder
= tfp410_connector_best_encoder
,
217 static struct drm_connector
*tfp410_connector_create(struct drm_device
*dev
,
218 struct tfp410_module
*mod
, struct drm_encoder
*encoder
)
220 struct tfp410_connector
*tfp410_connector
;
221 struct drm_connector
*connector
;
224 tfp410_connector
= devm_kzalloc(dev
->dev
, sizeof(*tfp410_connector
),
226 if (!tfp410_connector
)
229 tfp410_connector
->encoder
= encoder
;
230 tfp410_connector
->mod
= mod
;
232 connector
= &tfp410_connector
->base
;
234 drm_connector_init(dev
, connector
, &tfp410_connector_funcs
,
235 DRM_MODE_CONNECTOR_DVID
);
236 drm_connector_helper_add(connector
, &tfp410_connector_helper_funcs
);
238 connector
->polled
= DRM_CONNECTOR_POLL_CONNECT
|
239 DRM_CONNECTOR_POLL_DISCONNECT
;
241 connector
->interlace_allowed
= 0;
242 connector
->doublescan_allowed
= 0;
244 ret
= drm_connector_attach_encoder(connector
, encoder
);
251 tfp410_connector_destroy(connector
);
259 static int tfp410_modeset_init(struct tilcdc_module
*mod
, struct drm_device
*dev
)
261 struct tfp410_module
*tfp410_mod
= to_tfp410_module(mod
);
262 struct tilcdc_drm_private
*priv
= dev
->dev_private
;
263 struct drm_encoder
*encoder
;
264 struct drm_connector
*connector
;
266 encoder
= tfp410_encoder_create(dev
, tfp410_mod
);
270 connector
= tfp410_connector_create(dev
, tfp410_mod
, encoder
);
274 priv
->encoders
[priv
->num_encoders
++] = encoder
;
275 priv
->connectors
[priv
->num_connectors
++] = connector
;
277 tilcdc_crtc_set_panel_info(priv
->crtc
, &dvi_info
);
281 static const struct tilcdc_module_ops tfp410_module_ops
= {
282 .modeset_init
= tfp410_modeset_init
,
289 static int tfp410_probe(struct platform_device
*pdev
)
291 struct device_node
*node
= pdev
->dev
.of_node
;
292 struct device_node
*i2c_node
;
293 struct tfp410_module
*tfp410_mod
;
294 struct tilcdc_module
*mod
;
295 struct pinctrl
*pinctrl
;
296 uint32_t i2c_phandle
;
299 /* bail out early if no DT data: */
301 dev_err(&pdev
->dev
, "device-tree data is missing\n");
305 tfp410_mod
= devm_kzalloc(&pdev
->dev
, sizeof(*tfp410_mod
), GFP_KERNEL
);
309 mod
= &tfp410_mod
->base
;
310 pdev
->dev
.platform_data
= mod
;
312 tilcdc_module_init(mod
, "tfp410", &tfp410_module_ops
);
314 pinctrl
= devm_pinctrl_get_select_default(&pdev
->dev
);
316 dev_warn(&pdev
->dev
, "pins are not configured\n");
318 if (of_property_read_u32(node
, "i2c", &i2c_phandle
)) {
319 dev_err(&pdev
->dev
, "could not get i2c bus phandle\n");
323 i2c_node
= of_find_node_by_phandle(i2c_phandle
);
325 dev_err(&pdev
->dev
, "could not get i2c bus node\n");
329 tfp410_mod
->i2c
= of_find_i2c_adapter_by_node(i2c_node
);
330 if (!tfp410_mod
->i2c
) {
331 dev_err(&pdev
->dev
, "could not get i2c\n");
332 of_node_put(i2c_node
);
336 of_node_put(i2c_node
);
338 tfp410_mod
->gpio
= of_get_named_gpio_flags(node
, "powerdn-gpio",
340 if (tfp410_mod
->gpio
< 0) {
341 dev_warn(&pdev
->dev
, "No power down GPIO\n");
343 ret
= gpio_request(tfp410_mod
->gpio
, "DVI_PDn");
345 dev_err(&pdev
->dev
, "could not get DVI_PDn gpio\n");
353 i2c_put_adapter(tfp410_mod
->i2c
);
356 tilcdc_module_cleanup(mod
);
360 static int tfp410_remove(struct platform_device
*pdev
)
362 struct tilcdc_module
*mod
= dev_get_platdata(&pdev
->dev
);
363 struct tfp410_module
*tfp410_mod
= to_tfp410_module(mod
);
365 i2c_put_adapter(tfp410_mod
->i2c
);
366 gpio_free(tfp410_mod
->gpio
);
368 tilcdc_module_cleanup(mod
);
373 static const struct of_device_id tfp410_of_match
[] = {
374 { .compatible
= "ti,tilcdc,tfp410", },
378 struct platform_driver tfp410_driver
= {
379 .probe
= tfp410_probe
,
380 .remove
= tfp410_remove
,
382 .owner
= THIS_MODULE
,
384 .of_match_table
= tfp410_of_match
,
388 int __init
tilcdc_tfp410_init(void)
390 return platform_driver_register(&tfp410_driver
);
393 void __exit
tilcdc_tfp410_fini(void)
395 platform_driver_unregister(&tfp410_driver
);