aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorAjay Kumar <ajaykumar.rs@samsung.com>2015-01-20 11:38:45 -0500
committerThierry Reding <treding@nvidia.com>2015-01-28 02:47:28 -0500
commit6a1688ae8794ac62667ac231d20ac697bf7967fc (patch)
tree3853c4215787dd0a4154265957c0179770cc6d15 /drivers
parent3d3f8b1f8b62c3a010976269df454baa9246fc65 (diff)
drm/bridge: ptn3460: Convert to I2C driver model
Use drm_bridge helpers to modify the driver to support I2C driver model. Signed-off-by: Ajay Kumar <ajaykumar.rs@samsung.com> Acked-by: Inki Dae <inki.dae@samsung.com> Tested-by: Rahul Sharma <rahul.sharma@samsung.com> Tested-by: Javier Martinez Canillas <javier.martinez@collabora.co.uk> Tested-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk> Tested-by: Sjoerd Simons <sjoerd.simons@collabora.co.uk> [treding@nvidia.com: remove recursive dependency on I2C] Signed-off-by: Thierry Reding <treding@nvidia.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/bridge/Kconfig12
-rw-r--r--drivers/gpu/drm/bridge/ptn3460.c124
-rw-r--r--drivers/gpu/drm/exynos/exynos_dp_core.c22
3 files changed, 91 insertions, 67 deletions
diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
index b70f3c8d4e8a..ffa3e061a618 100644
--- a/drivers/gpu/drm/bridge/Kconfig
+++ b/drivers/gpu/drm/bridge/Kconfig
@@ -1,10 +1,12 @@
1config DRM_PTN3460 1config DRM_DW_HDMI
2 tristate "PTN3460 DP/LVDS bridge" 2 tristate
3 depends on DRM 3 depends on DRM
4 select DRM_KMS_HELPER 4 select DRM_KMS_HELPER
5 ---help---
6 5
7config DRM_DW_HDMI 6config DRM_PTN3460
8 tristate 7 tristate "PTN3460 DP/LVDS bridge"
9 depends on DRM 8 depends on DRM
9 depends on OF
10 select DRM_KMS_HELPER 10 select DRM_KMS_HELPER
11 ---help---
12 ptn3460 eDP-LVDS bridge chip driver.
diff --git a/drivers/gpu/drm/bridge/ptn3460.c b/drivers/gpu/drm/bridge/ptn3460.c
index 4a818c1b62e0..7adeb607f6fb 100644
--- a/drivers/gpu/drm/bridge/ptn3460.c
+++ b/drivers/gpu/drm/bridge/ptn3460.c
@@ -36,7 +36,6 @@
36struct ptn3460_bridge { 36struct ptn3460_bridge {
37 struct drm_connector connector; 37 struct drm_connector connector;
38 struct i2c_client *client; 38 struct i2c_client *client;
39 struct drm_encoder *encoder;
40 struct drm_bridge bridge; 39 struct drm_bridge bridge;
41 struct edid *edid; 40 struct edid *edid;
42 int gpio_pd_n; 41 int gpio_pd_n;
@@ -176,13 +175,6 @@ static void ptn3460_post_disable(struct drm_bridge *bridge)
176{ 175{
177} 176}
178 177
179static struct drm_bridge_funcs ptn3460_bridge_funcs = {
180 .pre_enable = ptn3460_pre_enable,
181 .enable = ptn3460_enable,
182 .disable = ptn3460_disable,
183 .post_disable = ptn3460_post_disable,
184};
185
186static int ptn3460_get_modes(struct drm_connector *connector) 178static int ptn3460_get_modes(struct drm_connector *connector)
187{ 179{
188 struct ptn3460_bridge *ptn_bridge; 180 struct ptn3460_bridge *ptn_bridge;
@@ -227,7 +219,7 @@ static struct drm_encoder *ptn3460_best_encoder(struct drm_connector *connector)
227{ 219{
228 struct ptn3460_bridge *ptn_bridge = connector_to_ptn3460(connector); 220 struct ptn3460_bridge *ptn_bridge = connector_to_ptn3460(connector);
229 221
230 return ptn_bridge->encoder; 222 return ptn_bridge->bridge.encoder;
231} 223}
232 224
233static struct drm_connector_helper_funcs ptn3460_connector_helper_funcs = { 225static struct drm_connector_helper_funcs ptn3460_connector_helper_funcs = {
@@ -253,31 +245,66 @@ static struct drm_connector_funcs ptn3460_connector_funcs = {
253 .destroy = ptn3460_connector_destroy, 245 .destroy = ptn3460_connector_destroy,
254}; 246};
255 247
256int ptn3460_init(struct drm_device *dev, struct drm_encoder *encoder, 248int ptn3460_bridge_attach(struct drm_bridge *bridge)
257 struct i2c_client *client, struct device_node *node)
258{ 249{
250 struct ptn3460_bridge *ptn_bridge = bridge_to_ptn3460(bridge);
259 int ret; 251 int ret;
252
253 if (!bridge->encoder) {
254 DRM_ERROR("Parent encoder object not found");
255 return -ENODEV;
256 }
257
258 ret = drm_connector_init(bridge->dev, &ptn_bridge->connector,
259 &ptn3460_connector_funcs, DRM_MODE_CONNECTOR_LVDS);
260 if (ret) {
261 DRM_ERROR("Failed to initialize connector with drm\n");
262 return ret;
263 }
264 drm_connector_helper_add(&ptn_bridge->connector,
265 &ptn3460_connector_helper_funcs);
266 drm_connector_register(&ptn_bridge->connector);
267 drm_mode_connector_attach_encoder(&ptn_bridge->connector,
268 bridge->encoder);
269
270 return ret;
271}
272
273static struct drm_bridge_funcs ptn3460_bridge_funcs = {
274 .pre_enable = ptn3460_pre_enable,
275 .enable = ptn3460_enable,
276 .disable = ptn3460_disable,
277 .post_disable = ptn3460_post_disable,
278 .attach = ptn3460_bridge_attach,
279};
280
281static int ptn3460_probe(struct i2c_client *client,
282 const struct i2c_device_id *id)
283{
284 struct device *dev = &client->dev;
260 struct ptn3460_bridge *ptn_bridge; 285 struct ptn3460_bridge *ptn_bridge;
286 int ret;
261 287
262 ptn_bridge = devm_kzalloc(dev->dev, sizeof(*ptn_bridge), GFP_KERNEL); 288 ptn_bridge = devm_kzalloc(dev, sizeof(*ptn_bridge), GFP_KERNEL);
263 if (!ptn_bridge) { 289 if (!ptn_bridge) {
264 return -ENOMEM; 290 return -ENOMEM;
265 } 291 }
266 292
267 ptn_bridge->client = client; 293 ptn_bridge->client = client;
268 ptn_bridge->encoder = encoder; 294 ptn_bridge->gpio_pd_n = of_get_named_gpio(dev->of_node,
269 ptn_bridge->gpio_pd_n = of_get_named_gpio(node, "powerdown-gpio", 0); 295 "powerdown-gpio", 0);
270 if (gpio_is_valid(ptn_bridge->gpio_pd_n)) { 296 if (gpio_is_valid(ptn_bridge->gpio_pd_n)) {
271 ret = gpio_request_one(ptn_bridge->gpio_pd_n, 297 ret = gpio_request_one(ptn_bridge->gpio_pd_n,
272 GPIOF_OUT_INIT_HIGH, "PTN3460_PD_N"); 298 GPIOF_OUT_INIT_HIGH, "PTN3460_PD_N");
273 if (ret) { 299 if (ret) {
274 dev_err(&client->dev, 300 dev_err(dev, "Request powerdown-gpio failed (%d)\n",
275 "Request powerdown-gpio failed (%d)\n", ret); 301 ret);
276 return ret; 302 return ret;
277 } 303 }
278 } 304 }
279 305
280 ptn_bridge->gpio_rst_n = of_get_named_gpio(node, "reset-gpio", 0); 306 ptn_bridge->gpio_rst_n = of_get_named_gpio(dev->of_node,
307 "reset-gpio", 0);
281 if (gpio_is_valid(ptn_bridge->gpio_rst_n)) { 308 if (gpio_is_valid(ptn_bridge->gpio_rst_n)) {
282 /* 309 /*
283 * Request the reset pin low to avoid the bridge being 310 * Request the reset pin low to avoid the bridge being
@@ -286,39 +313,27 @@ int ptn3460_init(struct drm_device *dev, struct drm_encoder *encoder,
286 ret = gpio_request_one(ptn_bridge->gpio_rst_n, 313 ret = gpio_request_one(ptn_bridge->gpio_rst_n,
287 GPIOF_OUT_INIT_LOW, "PTN3460_RST_N"); 314 GPIOF_OUT_INIT_LOW, "PTN3460_RST_N");
288 if (ret) { 315 if (ret) {
289 dev_err(&client->dev, 316 dev_err(dev, "Request reset-gpio failed (%d)\n", ret);
290 "Request reset-gpio failed (%d)\n", ret);
291 gpio_free(ptn_bridge->gpio_pd_n); 317 gpio_free(ptn_bridge->gpio_pd_n);
292 return ret; 318 return ret;
293 } 319 }
294 } 320 }
295 321
296 ret = of_property_read_u32(node, "edid-emulation", 322 ret = of_property_read_u32(dev->of_node, "edid-emulation",
297 &ptn_bridge->edid_emulation); 323 &ptn_bridge->edid_emulation);
298 if (ret) { 324 if (ret) {
299 dev_err(&client->dev, "Can't read EDID emulation value\n"); 325 dev_err(dev, "Can't read EDID emulation value\n");
300 goto err; 326 goto err;
301 } 327 }
302 328
303 ptn_bridge->bridge.funcs = &ptn3460_bridge_funcs; 329 ptn_bridge->bridge.funcs = &ptn3460_bridge_funcs;
304 ret = drm_bridge_attach(dev, &ptn_bridge->bridge); 330 ret = drm_bridge_add(&ptn_bridge->bridge);
305 if (ret) { 331 if (ret) {
306 DRM_ERROR("Failed to initialize bridge with drm\n"); 332 DRM_ERROR("Failed to add bridge\n");
307 goto err; 333 goto err;
308 } 334 }
309 335
310 encoder->bridge = &ptn_bridge->bridge; 336 i2c_set_clientdata(client, ptn_bridge);
311
312 ret = drm_connector_init(dev, &ptn_bridge->connector,
313 &ptn3460_connector_funcs, DRM_MODE_CONNECTOR_LVDS);
314 if (ret) {
315 DRM_ERROR("Failed to initialize connector with drm\n");
316 goto err;
317 }
318 drm_connector_helper_add(&ptn_bridge->connector,
319 &ptn3460_connector_helper_funcs);
320 drm_connector_register(&ptn_bridge->connector);
321 drm_mode_connector_attach_encoder(&ptn_bridge->connector, encoder);
322 337
323 return 0; 338 return 0;
324 339
@@ -329,16 +344,45 @@ err:
329 gpio_free(ptn_bridge->gpio_rst_n); 344 gpio_free(ptn_bridge->gpio_rst_n);
330 return ret; 345 return ret;
331} 346}
332EXPORT_SYMBOL(ptn3460_init);
333 347
334void ptn3460_destroy(struct drm_bridge *bridge) 348static int ptn3460_remove(struct i2c_client *client)
335{ 349{
336 struct ptn3460_bridge *ptn_bridge = bridge->driver_private; 350 struct ptn3460_bridge *ptn_bridge = i2c_get_clientdata(client);
351
352 drm_bridge_remove(&ptn_bridge->bridge);
337 353
338 if (gpio_is_valid(ptn_bridge->gpio_pd_n)) 354 if (gpio_is_valid(ptn_bridge->gpio_pd_n))
339 gpio_free(ptn_bridge->gpio_pd_n); 355 gpio_free(ptn_bridge->gpio_pd_n);
340 if (gpio_is_valid(ptn_bridge->gpio_rst_n)) 356 if (gpio_is_valid(ptn_bridge->gpio_rst_n))
341 gpio_free(ptn_bridge->gpio_rst_n); 357 gpio_free(ptn_bridge->gpio_rst_n);
342 /* Nothing else to free, we've got devm allocated memory */ 358
359 return 0;
343} 360}
344EXPORT_SYMBOL(ptn3460_destroy); 361
362static const struct i2c_device_id ptn3460_i2c_table[] = {
363 {"nxp,ptn3460", 0},
364 {},
365};
366MODULE_DEVICE_TABLE(i2c, ptn3460_i2c_table);
367
368static const struct of_device_id ptn3460_match[] = {
369 { .compatible = "nxp,ptn3460" },
370 {},
371};
372MODULE_DEVICE_TABLE(of, ptn3460_match);
373
374static struct i2c_driver ptn3460_driver = {
375 .id_table = ptn3460_i2c_table,
376 .probe = ptn3460_probe,
377 .remove = ptn3460_remove,
378 .driver = {
379 .name = "nxp,ptn3460",
380 .owner = THIS_MODULE,
381 .of_match_table = ptn3460_match,
382 },
383};
384module_i2c_driver(ptn3460_driver);
385
386MODULE_AUTHOR("Sean Paul <seanpaul@chromium.org>");
387MODULE_DESCRIPTION("NXP ptn3460 eDP-LVDS converter driver");
388MODULE_LICENSE("GPL v2");
diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.c b/drivers/gpu/drm/exynos/exynos_dp_core.c
index 34d46aa75416..27e3d272ca2d 100644
--- a/drivers/gpu/drm/exynos/exynos_dp_core.c
+++ b/drivers/gpu/drm/exynos/exynos_dp_core.c
@@ -993,32 +993,10 @@ static struct drm_connector_helper_funcs exynos_dp_connector_helper_funcs = {
993 .best_encoder = exynos_dp_best_encoder, 993 .best_encoder = exynos_dp_best_encoder,
994}; 994};
995 995
996static bool find_bridge(const char *compat, struct bridge_init *bridge)
997{
998 bridge->client = NULL;
999 bridge->node = of_find_compatible_node(NULL, NULL, compat);
1000 if (!bridge->node)
1001 return false;
1002
1003 bridge->client = of_find_i2c_device_by_node(bridge->node);
1004 if (!bridge->client)
1005 return false;
1006
1007 return true;
1008}
1009
1010/* returns the number of bridges attached */ 996/* returns the number of bridges attached */
1011static int exynos_drm_attach_lcd_bridge(struct drm_device *dev, 997static int exynos_drm_attach_lcd_bridge(struct drm_device *dev,
1012 struct drm_encoder *encoder) 998 struct drm_encoder *encoder)
1013{ 999{
1014 struct bridge_init bridge;
1015 int ret;
1016
1017 if (find_bridge("nxp,ptn3460", &bridge)) {
1018 ret = ptn3460_init(dev, encoder, bridge.client, bridge.node);
1019 if (!ret)
1020 return 1;
1021 }
1022 return 0; 1000 return 0;
1023} 1001}
1024 1002