diff options
author | Jyri Sarha <jsarha@ti.com> | 2015-02-24 08:24:31 -0500 |
---|---|---|
committer | Jyri Sarha <jsarha@ti.com> | 2015-05-27 06:13:32 -0400 |
commit | 6730201f4fdcfbb1e6ec5ec374e6ef95e5bf9662 (patch) | |
tree | 7b02fcc30818221d82d18d7077410a157d791e0b /drivers/gpu/drm/tilcdc/tilcdc_slave.c | |
parent | de9cb5f20a50f2811caf909ee254699fd2228910 (diff) |
drm/tilcdc: Remove tilcdc slave support for tda998x driver
Remove tilcdc slave support for tda998x driver. The tilcdc slave
support would conflicts with componentized use of tda998x.
Signed-off-by: Jyri Sarha <jsarha@ti.com>
Acked-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Diffstat (limited to 'drivers/gpu/drm/tilcdc/tilcdc_slave.c')
-rw-r--r-- | drivers/gpu/drm/tilcdc/tilcdc_slave.c | 411 |
1 files changed, 0 insertions, 411 deletions
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_slave.c b/drivers/gpu/drm/tilcdc/tilcdc_slave.c deleted file mode 100644 index 3775fd49dac4..000000000000 --- a/drivers/gpu/drm/tilcdc/tilcdc_slave.c +++ /dev/null | |||
@@ -1,411 +0,0 @@ | |||
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/pinctrl/pinmux.h> | ||
20 | #include <linux/pinctrl/consumer.h> | ||
21 | #include <drm/drm_encoder_slave.h> | ||
22 | |||
23 | #include "tilcdc_drv.h" | ||
24 | |||
25 | struct slave_module { | ||
26 | struct tilcdc_module base; | ||
27 | struct i2c_adapter *i2c; | ||
28 | }; | ||
29 | #define to_slave_module(x) container_of(x, struct slave_module, base) | ||
30 | |||
31 | static const struct tilcdc_panel_info slave_info = { | ||
32 | .bpp = 16, | ||
33 | .ac_bias = 255, | ||
34 | .ac_bias_intrpt = 0, | ||
35 | .dma_burst_sz = 16, | ||
36 | .fdd = 0x80, | ||
37 | .tft_alt_mode = 0, | ||
38 | .sync_edge = 0, | ||
39 | .sync_ctrl = 1, | ||
40 | .raster_order = 0, | ||
41 | }; | ||
42 | |||
43 | |||
44 | /* | ||
45 | * Encoder: | ||
46 | */ | ||
47 | |||
48 | struct slave_encoder { | ||
49 | struct drm_encoder_slave base; | ||
50 | struct slave_module *mod; | ||
51 | }; | ||
52 | #define to_slave_encoder(x) container_of(to_encoder_slave(x), struct slave_encoder, base) | ||
53 | |||
54 | static inline struct drm_encoder_slave_funcs * | ||
55 | get_slave_funcs(struct drm_encoder *enc) | ||
56 | { | ||
57 | return to_encoder_slave(enc)->slave_funcs; | ||
58 | } | ||
59 | |||
60 | static void slave_encoder_destroy(struct drm_encoder *encoder) | ||
61 | { | ||
62 | struct slave_encoder *slave_encoder = to_slave_encoder(encoder); | ||
63 | if (get_slave_funcs(encoder)) | ||
64 | get_slave_funcs(encoder)->destroy(encoder); | ||
65 | drm_encoder_cleanup(encoder); | ||
66 | kfree(slave_encoder); | ||
67 | } | ||
68 | |||
69 | static void slave_encoder_prepare(struct drm_encoder *encoder) | ||
70 | { | ||
71 | drm_i2c_encoder_prepare(encoder); | ||
72 | tilcdc_crtc_set_panel_info(encoder->crtc, &slave_info); | ||
73 | } | ||
74 | |||
75 | static bool slave_encoder_fixup(struct drm_encoder *encoder, | ||
76 | const struct drm_display_mode *mode, | ||
77 | struct drm_display_mode *adjusted_mode) | ||
78 | { | ||
79 | /* | ||
80 | * tilcdc does not generate VESA-complient sync but aligns | ||
81 | * VS on the second edge of HS instead of first edge. | ||
82 | * We use adjusted_mode, to fixup sync by aligning both rising | ||
83 | * edges and add HSKEW offset to let the slave encoder fix it up. | ||
84 | */ | ||
85 | adjusted_mode->hskew = mode->hsync_end - mode->hsync_start; | ||
86 | adjusted_mode->flags |= DRM_MODE_FLAG_HSKEW; | ||
87 | |||
88 | if (mode->flags & DRM_MODE_FLAG_NHSYNC) { | ||
89 | adjusted_mode->flags |= DRM_MODE_FLAG_PHSYNC; | ||
90 | adjusted_mode->flags &= ~DRM_MODE_FLAG_NHSYNC; | ||
91 | } else { | ||
92 | adjusted_mode->flags |= DRM_MODE_FLAG_NHSYNC; | ||
93 | adjusted_mode->flags &= ~DRM_MODE_FLAG_PHSYNC; | ||
94 | } | ||
95 | |||
96 | return drm_i2c_encoder_mode_fixup(encoder, mode, adjusted_mode); | ||
97 | } | ||
98 | |||
99 | |||
100 | static const struct drm_encoder_funcs slave_encoder_funcs = { | ||
101 | .destroy = slave_encoder_destroy, | ||
102 | }; | ||
103 | |||
104 | static const struct drm_encoder_helper_funcs slave_encoder_helper_funcs = { | ||
105 | .dpms = drm_i2c_encoder_dpms, | ||
106 | .mode_fixup = slave_encoder_fixup, | ||
107 | .prepare = slave_encoder_prepare, | ||
108 | .commit = drm_i2c_encoder_commit, | ||
109 | .mode_set = drm_i2c_encoder_mode_set, | ||
110 | .save = drm_i2c_encoder_save, | ||
111 | .restore = drm_i2c_encoder_restore, | ||
112 | }; | ||
113 | |||
114 | static const struct i2c_board_info info = { | ||
115 | I2C_BOARD_INFO("tda998x", 0x70) | ||
116 | }; | ||
117 | |||
118 | static struct drm_encoder *slave_encoder_create(struct drm_device *dev, | ||
119 | struct slave_module *mod) | ||
120 | { | ||
121 | struct slave_encoder *slave_encoder; | ||
122 | struct drm_encoder *encoder; | ||
123 | int ret; | ||
124 | |||
125 | slave_encoder = kzalloc(sizeof(*slave_encoder), GFP_KERNEL); | ||
126 | if (!slave_encoder) { | ||
127 | dev_err(dev->dev, "allocation failed\n"); | ||
128 | return NULL; | ||
129 | } | ||
130 | |||
131 | slave_encoder->mod = mod; | ||
132 | |||
133 | encoder = &slave_encoder->base.base; | ||
134 | encoder->possible_crtcs = 1; | ||
135 | |||
136 | ret = drm_encoder_init(dev, encoder, &slave_encoder_funcs, | ||
137 | DRM_MODE_ENCODER_TMDS); | ||
138 | if (ret) | ||
139 | goto fail; | ||
140 | |||
141 | drm_encoder_helper_add(encoder, &slave_encoder_helper_funcs); | ||
142 | |||
143 | ret = drm_i2c_encoder_init(dev, to_encoder_slave(encoder), mod->i2c, &info); | ||
144 | if (ret) | ||
145 | goto fail; | ||
146 | |||
147 | return encoder; | ||
148 | |||
149 | fail: | ||
150 | slave_encoder_destroy(encoder); | ||
151 | return NULL; | ||
152 | } | ||
153 | |||
154 | /* | ||
155 | * Connector: | ||
156 | */ | ||
157 | |||
158 | struct slave_connector { | ||
159 | struct drm_connector base; | ||
160 | |||
161 | struct drm_encoder *encoder; /* our connected encoder */ | ||
162 | struct slave_module *mod; | ||
163 | }; | ||
164 | #define to_slave_connector(x) container_of(x, struct slave_connector, base) | ||
165 | |||
166 | static void slave_connector_destroy(struct drm_connector *connector) | ||
167 | { | ||
168 | struct slave_connector *slave_connector = to_slave_connector(connector); | ||
169 | drm_connector_unregister(connector); | ||
170 | drm_connector_cleanup(connector); | ||
171 | kfree(slave_connector); | ||
172 | } | ||
173 | |||
174 | static enum drm_connector_status slave_connector_detect( | ||
175 | struct drm_connector *connector, | ||
176 | bool force) | ||
177 | { | ||
178 | struct drm_encoder *encoder = to_slave_connector(connector)->encoder; | ||
179 | return get_slave_funcs(encoder)->detect(encoder, connector); | ||
180 | } | ||
181 | |||
182 | static int slave_connector_get_modes(struct drm_connector *connector) | ||
183 | { | ||
184 | struct drm_encoder *encoder = to_slave_connector(connector)->encoder; | ||
185 | return get_slave_funcs(encoder)->get_modes(encoder, connector); | ||
186 | } | ||
187 | |||
188 | static int slave_connector_mode_valid(struct drm_connector *connector, | ||
189 | struct drm_display_mode *mode) | ||
190 | { | ||
191 | struct drm_encoder *encoder = to_slave_connector(connector)->encoder; | ||
192 | struct tilcdc_drm_private *priv = connector->dev->dev_private; | ||
193 | int ret; | ||
194 | |||
195 | ret = tilcdc_crtc_mode_valid(priv->crtc, mode); | ||
196 | if (ret != MODE_OK) | ||
197 | return ret; | ||
198 | |||
199 | return get_slave_funcs(encoder)->mode_valid(encoder, mode); | ||
200 | } | ||
201 | |||
202 | static struct drm_encoder *slave_connector_best_encoder( | ||
203 | struct drm_connector *connector) | ||
204 | { | ||
205 | struct slave_connector *slave_connector = to_slave_connector(connector); | ||
206 | return slave_connector->encoder; | ||
207 | } | ||
208 | |||
209 | static int slave_connector_set_property(struct drm_connector *connector, | ||
210 | struct drm_property *property, uint64_t value) | ||
211 | { | ||
212 | struct drm_encoder *encoder = to_slave_connector(connector)->encoder; | ||
213 | return get_slave_funcs(encoder)->set_property(encoder, | ||
214 | connector, property, value); | ||
215 | } | ||
216 | |||
217 | static const struct drm_connector_funcs slave_connector_funcs = { | ||
218 | .destroy = slave_connector_destroy, | ||
219 | .dpms = drm_helper_connector_dpms, | ||
220 | .detect = slave_connector_detect, | ||
221 | .fill_modes = drm_helper_probe_single_connector_modes, | ||
222 | .set_property = slave_connector_set_property, | ||
223 | }; | ||
224 | |||
225 | static const struct drm_connector_helper_funcs slave_connector_helper_funcs = { | ||
226 | .get_modes = slave_connector_get_modes, | ||
227 | .mode_valid = slave_connector_mode_valid, | ||
228 | .best_encoder = slave_connector_best_encoder, | ||
229 | }; | ||
230 | |||
231 | static struct drm_connector *slave_connector_create(struct drm_device *dev, | ||
232 | struct slave_module *mod, struct drm_encoder *encoder) | ||
233 | { | ||
234 | struct slave_connector *slave_connector; | ||
235 | struct drm_connector *connector; | ||
236 | int ret; | ||
237 | |||
238 | slave_connector = kzalloc(sizeof(*slave_connector), GFP_KERNEL); | ||
239 | if (!slave_connector) { | ||
240 | dev_err(dev->dev, "allocation failed\n"); | ||
241 | return NULL; | ||
242 | } | ||
243 | |||
244 | slave_connector->encoder = encoder; | ||
245 | slave_connector->mod = mod; | ||
246 | |||
247 | connector = &slave_connector->base; | ||
248 | |||
249 | drm_connector_init(dev, connector, &slave_connector_funcs, | ||
250 | DRM_MODE_CONNECTOR_HDMIA); | ||
251 | drm_connector_helper_add(connector, &slave_connector_helper_funcs); | ||
252 | |||
253 | connector->polled = DRM_CONNECTOR_POLL_CONNECT | | ||
254 | DRM_CONNECTOR_POLL_DISCONNECT; | ||
255 | |||
256 | connector->interlace_allowed = 0; | ||
257 | connector->doublescan_allowed = 0; | ||
258 | |||
259 | get_slave_funcs(encoder)->create_resources(encoder, connector); | ||
260 | |||
261 | ret = drm_mode_connector_attach_encoder(connector, encoder); | ||
262 | if (ret) | ||
263 | goto fail; | ||
264 | |||
265 | drm_connector_register(connector); | ||
266 | |||
267 | return connector; | ||
268 | |||
269 | fail: | ||
270 | slave_connector_destroy(connector); | ||
271 | return NULL; | ||
272 | } | ||
273 | |||
274 | /* | ||
275 | * Module: | ||
276 | */ | ||
277 | |||
278 | static int slave_modeset_init(struct tilcdc_module *mod, struct drm_device *dev) | ||
279 | { | ||
280 | struct slave_module *slave_mod = to_slave_module(mod); | ||
281 | struct tilcdc_drm_private *priv = dev->dev_private; | ||
282 | struct drm_encoder *encoder; | ||
283 | struct drm_connector *connector; | ||
284 | |||
285 | encoder = slave_encoder_create(dev, slave_mod); | ||
286 | if (!encoder) | ||
287 | return -ENOMEM; | ||
288 | |||
289 | connector = slave_connector_create(dev, slave_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 | |||
299 | static const struct tilcdc_module_ops slave_module_ops = { | ||
300 | .modeset_init = slave_modeset_init, | ||
301 | }; | ||
302 | |||
303 | /* | ||
304 | * Device: | ||
305 | */ | ||
306 | |||
307 | static struct of_device_id slave_of_match[]; | ||
308 | |||
309 | static int slave_probe(struct platform_device *pdev) | ||
310 | { | ||
311 | struct device_node *node = pdev->dev.of_node; | ||
312 | struct device_node *i2c_node; | ||
313 | struct slave_module *slave_mod; | ||
314 | struct tilcdc_module *mod; | ||
315 | struct pinctrl *pinctrl; | ||
316 | uint32_t i2c_phandle; | ||
317 | struct i2c_adapter *slavei2c; | ||
318 | int ret = -EINVAL; | ||
319 | |||
320 | /* bail out early if no DT data: */ | ||
321 | if (!node) { | ||
322 | dev_err(&pdev->dev, "device-tree data is missing\n"); | ||
323 | return -ENXIO; | ||
324 | } | ||
325 | |||
326 | /* Bail out early if i2c not specified */ | ||
327 | if (of_property_read_u32(node, "i2c", &i2c_phandle)) { | ||
328 | dev_err(&pdev->dev, "could not get i2c bus phandle\n"); | ||
329 | return ret; | ||
330 | } | ||
331 | |||
332 | i2c_node = of_find_node_by_phandle(i2c_phandle); | ||
333 | if (!i2c_node) { | ||
334 | dev_err(&pdev->dev, "could not get i2c bus node\n"); | ||
335 | return ret; | ||
336 | } | ||
337 | |||
338 | /* but defer the probe if it can't be initialized it might come later */ | ||
339 | slavei2c = of_find_i2c_adapter_by_node(i2c_node); | ||
340 | of_node_put(i2c_node); | ||
341 | |||
342 | if (!slavei2c) { | ||
343 | ret = -EPROBE_DEFER; | ||
344 | tilcdc_slave_probedefer(true); | ||
345 | dev_err(&pdev->dev, "could not get i2c\n"); | ||
346 | return ret; | ||
347 | } | ||
348 | |||
349 | slave_mod = kzalloc(sizeof(*slave_mod), GFP_KERNEL); | ||
350 | if (!slave_mod) { | ||
351 | ret = -ENOMEM; | ||
352 | goto fail_adapter; | ||
353 | } | ||
354 | |||
355 | mod = &slave_mod->base; | ||
356 | pdev->dev.platform_data = mod; | ||
357 | |||
358 | mod->preferred_bpp = slave_info.bpp; | ||
359 | |||
360 | slave_mod->i2c = slavei2c; | ||
361 | |||
362 | tilcdc_module_init(mod, "slave", &slave_module_ops); | ||
363 | |||
364 | pinctrl = devm_pinctrl_get_select_default(&pdev->dev); | ||
365 | if (IS_ERR(pinctrl)) | ||
366 | dev_warn(&pdev->dev, "pins are not configured\n"); | ||
367 | |||
368 | tilcdc_slave_probedefer(false); | ||
369 | |||
370 | return 0; | ||
371 | |||
372 | fail_adapter: | ||
373 | i2c_put_adapter(slavei2c); | ||
374 | return ret; | ||
375 | } | ||
376 | |||
377 | static int slave_remove(struct platform_device *pdev) | ||
378 | { | ||
379 | struct tilcdc_module *mod = dev_get_platdata(&pdev->dev); | ||
380 | struct slave_module *slave_mod = to_slave_module(mod); | ||
381 | |||
382 | tilcdc_module_cleanup(mod); | ||
383 | kfree(slave_mod); | ||
384 | |||
385 | return 0; | ||
386 | } | ||
387 | |||
388 | static struct of_device_id slave_of_match[] = { | ||
389 | { .compatible = "ti,tilcdc,slave", }, | ||
390 | { }, | ||
391 | }; | ||
392 | |||
393 | struct platform_driver slave_driver = { | ||
394 | .probe = slave_probe, | ||
395 | .remove = slave_remove, | ||
396 | .driver = { | ||
397 | .owner = THIS_MODULE, | ||
398 | .name = "slave", | ||
399 | .of_match_table = slave_of_match, | ||
400 | }, | ||
401 | }; | ||
402 | |||
403 | int __init tilcdc_slave_init(void) | ||
404 | { | ||
405 | return platform_driver_register(&slave_driver); | ||
406 | } | ||
407 | |||
408 | void __exit tilcdc_slave_fini(void) | ||
409 | { | ||
410 | platform_driver_unregister(&slave_driver); | ||
411 | } | ||