• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2012 Texas Instruments
3  * Author: Rob Clark <robdclark@gmail.com>
4  *
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.
8  *
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
12  * more details.
13  *
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/>.
16  */
17 
18 #include <linux/i2c.h>
19 #include <linux/of_i2c.h>
20 #include <linux/gpio.h>
21 #include <linux/of_gpio.h>
22 #include <linux/pinctrl/pinmux.h>
23 #include <linux/pinctrl/consumer.h>
24 
25 #include "tilcdc_drv.h"
26 
27 struct tfp410_module {
28 	struct tilcdc_module base;
29 	struct i2c_adapter *i2c;
30 	int gpio;
31 };
32 #define to_tfp410_module(x) container_of(x, struct tfp410_module, base)
33 
34 
35 static const struct tilcdc_panel_info dvi_info = {
36 		.ac_bias                = 255,
37 		.ac_bias_intrpt         = 0,
38 		.dma_burst_sz           = 16,
39 		.bpp                    = 16,
40 		.fdd                    = 0x80,
41 		.tft_alt_mode           = 0,
42 		.sync_edge              = 0,
43 		.sync_ctrl              = 1,
44 		.raster_order           = 0,
45 };
46 
47 /*
48  * Encoder:
49  */
50 
51 struct tfp410_encoder {
52 	struct drm_encoder base;
53 	struct tfp410_module *mod;
54 	int dpms;
55 };
56 #define to_tfp410_encoder(x) container_of(x, struct tfp410_encoder, base)
57 
58 
tfp410_encoder_destroy(struct drm_encoder * encoder)59 static void tfp410_encoder_destroy(struct drm_encoder *encoder)
60 {
61 	struct tfp410_encoder *tfp410_encoder = to_tfp410_encoder(encoder);
62 	drm_encoder_cleanup(encoder);
63 	kfree(tfp410_encoder);
64 }
65 
tfp410_encoder_dpms(struct drm_encoder * encoder,int mode)66 static void tfp410_encoder_dpms(struct drm_encoder *encoder, int mode)
67 {
68 	struct tfp410_encoder *tfp410_encoder = to_tfp410_encoder(encoder);
69 
70 	if (tfp410_encoder->dpms == mode)
71 		return;
72 
73 	if (mode == DRM_MODE_DPMS_ON) {
74 		DBG("Power on");
75 		gpio_direction_output(tfp410_encoder->mod->gpio, 1);
76 	} else {
77 		DBG("Power off");
78 		gpio_direction_output(tfp410_encoder->mod->gpio, 0);
79 	}
80 
81 	tfp410_encoder->dpms = mode;
82 }
83 
tfp410_encoder_mode_fixup(struct drm_encoder * encoder,const struct drm_display_mode * mode,struct drm_display_mode * adjusted_mode)84 static bool tfp410_encoder_mode_fixup(struct drm_encoder *encoder,
85 		const struct drm_display_mode *mode,
86 		struct drm_display_mode *adjusted_mode)
87 {
88 	/* nothing needed */
89 	return true;
90 }
91 
tfp410_encoder_prepare(struct drm_encoder * encoder)92 static void tfp410_encoder_prepare(struct drm_encoder *encoder)
93 {
94 	tfp410_encoder_dpms(encoder, DRM_MODE_DPMS_OFF);
95 	tilcdc_crtc_set_panel_info(encoder->crtc, &dvi_info);
96 }
97 
tfp410_encoder_commit(struct drm_encoder * encoder)98 static void tfp410_encoder_commit(struct drm_encoder *encoder)
99 {
100 	tfp410_encoder_dpms(encoder, DRM_MODE_DPMS_ON);
101 }
102 
tfp410_encoder_mode_set(struct drm_encoder * encoder,struct drm_display_mode * mode,struct drm_display_mode * adjusted_mode)103 static void tfp410_encoder_mode_set(struct drm_encoder *encoder,
104 		struct drm_display_mode *mode,
105 		struct drm_display_mode *adjusted_mode)
106 {
107 	/* nothing needed */
108 }
109 
110 static const struct drm_encoder_funcs tfp410_encoder_funcs = {
111 		.destroy        = tfp410_encoder_destroy,
112 };
113 
114 static const struct drm_encoder_helper_funcs tfp410_encoder_helper_funcs = {
115 		.dpms           = tfp410_encoder_dpms,
116 		.mode_fixup     = tfp410_encoder_mode_fixup,
117 		.prepare        = tfp410_encoder_prepare,
118 		.commit         = tfp410_encoder_commit,
119 		.mode_set       = tfp410_encoder_mode_set,
120 };
121 
tfp410_encoder_create(struct drm_device * dev,struct tfp410_module * mod)122 static struct drm_encoder *tfp410_encoder_create(struct drm_device *dev,
123 		struct tfp410_module *mod)
124 {
125 	struct tfp410_encoder *tfp410_encoder;
126 	struct drm_encoder *encoder;
127 	int ret;
128 
129 	tfp410_encoder = kzalloc(sizeof(*tfp410_encoder), GFP_KERNEL);
130 	if (!tfp410_encoder) {
131 		dev_err(dev->dev, "allocation failed\n");
132 		return NULL;
133 	}
134 
135 	tfp410_encoder->dpms = DRM_MODE_DPMS_OFF;
136 	tfp410_encoder->mod = mod;
137 
138 	encoder = &tfp410_encoder->base;
139 	encoder->possible_crtcs = 1;
140 
141 	ret = drm_encoder_init(dev, encoder, &tfp410_encoder_funcs,
142 			DRM_MODE_ENCODER_TMDS);
143 	if (ret < 0)
144 		goto fail;
145 
146 	drm_encoder_helper_add(encoder, &tfp410_encoder_helper_funcs);
147 
148 	return encoder;
149 
150 fail:
151 	tfp410_encoder_destroy(encoder);
152 	return NULL;
153 }
154 
155 /*
156  * Connector:
157  */
158 
159 struct tfp410_connector {
160 	struct drm_connector base;
161 
162 	struct drm_encoder *encoder;  /* our connected encoder */
163 	struct tfp410_module *mod;
164 };
165 #define to_tfp410_connector(x) container_of(x, struct tfp410_connector, base)
166 
167 
tfp410_connector_destroy(struct drm_connector * connector)168 static void tfp410_connector_destroy(struct drm_connector *connector)
169 {
170 	struct tfp410_connector *tfp410_connector = to_tfp410_connector(connector);
171 	drm_connector_cleanup(connector);
172 	kfree(tfp410_connector);
173 }
174 
tfp410_connector_detect(struct drm_connector * connector,bool force)175 static enum drm_connector_status tfp410_connector_detect(
176 		struct drm_connector *connector,
177 		bool force)
178 {
179 	struct tfp410_connector *tfp410_connector = to_tfp410_connector(connector);
180 
181 	if (drm_probe_ddc(tfp410_connector->mod->i2c))
182 		return connector_status_connected;
183 
184 	return connector_status_unknown;
185 }
186 
tfp410_connector_get_modes(struct drm_connector * connector)187 static int tfp410_connector_get_modes(struct drm_connector *connector)
188 {
189 	struct tfp410_connector *tfp410_connector = to_tfp410_connector(connector);
190 	struct edid *edid;
191 	int ret = 0;
192 
193 	edid = drm_get_edid(connector, tfp410_connector->mod->i2c);
194 
195 	drm_mode_connector_update_edid_property(connector, edid);
196 
197 	if (edid) {
198 		ret = drm_add_edid_modes(connector, edid);
199 		kfree(edid);
200 	}
201 
202 	return ret;
203 }
204 
tfp410_connector_mode_valid(struct drm_connector * connector,struct drm_display_mode * mode)205 static int tfp410_connector_mode_valid(struct drm_connector *connector,
206 		  struct drm_display_mode *mode)
207 {
208 	struct tilcdc_drm_private *priv = connector->dev->dev_private;
209 	/* our only constraints are what the crtc can generate: */
210 	return tilcdc_crtc_mode_valid(priv->crtc, mode);
211 }
212 
tfp410_connector_best_encoder(struct drm_connector * connector)213 static struct drm_encoder *tfp410_connector_best_encoder(
214 		struct drm_connector *connector)
215 {
216 	struct tfp410_connector *tfp410_connector = to_tfp410_connector(connector);
217 	return tfp410_connector->encoder;
218 }
219 
220 static const struct drm_connector_funcs tfp410_connector_funcs = {
221 	.destroy            = tfp410_connector_destroy,
222 	.dpms               = drm_helper_connector_dpms,
223 	.detect             = tfp410_connector_detect,
224 	.fill_modes         = drm_helper_probe_single_connector_modes,
225 };
226 
227 static const struct drm_connector_helper_funcs tfp410_connector_helper_funcs = {
228 	.get_modes          = tfp410_connector_get_modes,
229 	.mode_valid         = tfp410_connector_mode_valid,
230 	.best_encoder       = tfp410_connector_best_encoder,
231 };
232 
tfp410_connector_create(struct drm_device * dev,struct tfp410_module * mod,struct drm_encoder * encoder)233 static struct drm_connector *tfp410_connector_create(struct drm_device *dev,
234 		struct tfp410_module *mod, struct drm_encoder *encoder)
235 {
236 	struct tfp410_connector *tfp410_connector;
237 	struct drm_connector *connector;
238 	int ret;
239 
240 	tfp410_connector = kzalloc(sizeof(*tfp410_connector), GFP_KERNEL);
241 	if (!tfp410_connector) {
242 		dev_err(dev->dev, "allocation failed\n");
243 		return NULL;
244 	}
245 
246 	tfp410_connector->encoder = encoder;
247 	tfp410_connector->mod = mod;
248 
249 	connector = &tfp410_connector->base;
250 
251 	drm_connector_init(dev, connector, &tfp410_connector_funcs,
252 			DRM_MODE_CONNECTOR_DVID);
253 	drm_connector_helper_add(connector, &tfp410_connector_helper_funcs);
254 
255 	connector->polled = DRM_CONNECTOR_POLL_CONNECT |
256 			DRM_CONNECTOR_POLL_DISCONNECT;
257 
258 	connector->interlace_allowed = 0;
259 	connector->doublescan_allowed = 0;
260 
261 	ret = drm_mode_connector_attach_encoder(connector, encoder);
262 	if (ret)
263 		goto fail;
264 
265 	drm_sysfs_connector_add(connector);
266 
267 	return connector;
268 
269 fail:
270 	tfp410_connector_destroy(connector);
271 	return NULL;
272 }
273 
274 /*
275  * Module:
276  */
277 
tfp410_modeset_init(struct tilcdc_module * mod,struct drm_device * dev)278 static int tfp410_modeset_init(struct tilcdc_module *mod, struct drm_device *dev)
279 {
280 	struct tfp410_module *tfp410_mod = to_tfp410_module(mod);
281 	struct tilcdc_drm_private *priv = dev->dev_private;
282 	struct drm_encoder *encoder;
283 	struct drm_connector *connector;
284 
285 	encoder = tfp410_encoder_create(dev, tfp410_mod);
286 	if (!encoder)
287 		return -ENOMEM;
288 
289 	connector = tfp410_connector_create(dev, tfp410_mod, encoder);
290 	if (!connector)
291 		return -ENOMEM;
292 
293 	priv->encoders[priv->num_encoders++] = encoder;
294 	priv->connectors[priv->num_connectors++] = connector;
295 
296 	return 0;
297 }
298 
tfp410_destroy(struct tilcdc_module * mod)299 static void tfp410_destroy(struct tilcdc_module *mod)
300 {
301 	struct tfp410_module *tfp410_mod = to_tfp410_module(mod);
302 
303 	if (tfp410_mod->i2c)
304 		i2c_put_adapter(tfp410_mod->i2c);
305 
306 	if (!IS_ERR_VALUE(tfp410_mod->gpio))
307 		gpio_free(tfp410_mod->gpio);
308 
309 	tilcdc_module_cleanup(mod);
310 	kfree(tfp410_mod);
311 }
312 
313 static const struct tilcdc_module_ops tfp410_module_ops = {
314 		.modeset_init = tfp410_modeset_init,
315 		.destroy = tfp410_destroy,
316 };
317 
318 /*
319  * Device:
320  */
321 
322 static struct of_device_id tfp410_of_match[];
323 
tfp410_probe(struct platform_device * pdev)324 static int tfp410_probe(struct platform_device *pdev)
325 {
326 	struct device_node *node = pdev->dev.of_node;
327 	struct device_node *i2c_node;
328 	struct tfp410_module *tfp410_mod;
329 	struct tilcdc_module *mod;
330 	struct pinctrl *pinctrl;
331 	uint32_t i2c_phandle;
332 	int ret = -EINVAL;
333 
334 	/* bail out early if no DT data: */
335 	if (!node) {
336 		dev_err(&pdev->dev, "device-tree data is missing\n");
337 		return -ENXIO;
338 	}
339 
340 	tfp410_mod = kzalloc(sizeof(*tfp410_mod), GFP_KERNEL);
341 	if (!tfp410_mod)
342 		return -ENOMEM;
343 
344 	mod = &tfp410_mod->base;
345 
346 	tilcdc_module_init(mod, "tfp410", &tfp410_module_ops);
347 
348 	pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
349 	if (IS_ERR(pinctrl))
350 		dev_warn(&pdev->dev, "pins are not configured\n");
351 
352 	if (of_property_read_u32(node, "i2c", &i2c_phandle)) {
353 		dev_err(&pdev->dev, "could not get i2c bus phandle\n");
354 		goto fail;
355 	}
356 
357 	i2c_node = of_find_node_by_phandle(i2c_phandle);
358 	if (!i2c_node) {
359 		dev_err(&pdev->dev, "could not get i2c bus node\n");
360 		goto fail;
361 	}
362 
363 	tfp410_mod->i2c = of_find_i2c_adapter_by_node(i2c_node);
364 	if (!tfp410_mod->i2c) {
365 		dev_err(&pdev->dev, "could not get i2c\n");
366 		goto fail;
367 	}
368 
369 	of_node_put(i2c_node);
370 
371 	tfp410_mod->gpio = of_get_named_gpio_flags(node, "powerdn-gpio",
372 			0, NULL);
373 	if (IS_ERR_VALUE(tfp410_mod->gpio)) {
374 		dev_warn(&pdev->dev, "No power down GPIO\n");
375 	} else {
376 		ret = gpio_request(tfp410_mod->gpio, "DVI_PDn");
377 		if (ret) {
378 			dev_err(&pdev->dev, "could not get DVI_PDn gpio\n");
379 			goto fail;
380 		}
381 	}
382 
383 	return 0;
384 
385 fail:
386 	tfp410_destroy(mod);
387 	return ret;
388 }
389 
tfp410_remove(struct platform_device * pdev)390 static int tfp410_remove(struct platform_device *pdev)
391 {
392 	return 0;
393 }
394 
395 static struct of_device_id tfp410_of_match[] = {
396 		{ .compatible = "ti,tilcdc,tfp410", },
397 		{ },
398 };
399 
400 struct platform_driver tfp410_driver = {
401 	.probe = tfp410_probe,
402 	.remove = tfp410_remove,
403 	.driver = {
404 		.owner = THIS_MODULE,
405 		.name = "tfp410",
406 		.of_match_table = tfp410_of_match,
407 	},
408 };
409 
tilcdc_tfp410_init(void)410 int __init tilcdc_tfp410_init(void)
411 {
412 	return platform_driver_register(&tfp410_driver);
413 }
414 
tilcdc_tfp410_fini(void)415 void __exit tilcdc_tfp410_fini(void)
416 {
417 	platform_driver_unregister(&tfp410_driver);
418 }
419