Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Ajay Kumar and committed by
Thierry Reding
6a1688ae 3d3f8b1f

+93 -69
+8 -6
drivers/gpu/drm/bridge/Kconfig
··· 1 - config DRM_PTN3460 2 - tristate "PTN3460 DP/LVDS bridge" 3 - depends on DRM 4 - select DRM_KMS_HELPER 5 - ---help--- 6 - 7 1 config DRM_DW_HDMI 8 2 tristate 9 3 depends on DRM 10 4 select DRM_KMS_HELPER 5 + 6 + config DRM_PTN3460 7 + tristate "PTN3460 DP/LVDS bridge" 8 + depends on DRM 9 + depends on OF 10 + select DRM_KMS_HELPER 11 + ---help--- 12 + ptn3460 eDP-LVDS bridge chip driver.
+85 -41
drivers/gpu/drm/bridge/ptn3460.c
··· 36 36 struct ptn3460_bridge { 37 37 struct drm_connector connector; 38 38 struct i2c_client *client; 39 - struct drm_encoder *encoder; 40 39 struct drm_bridge bridge; 41 40 struct edid *edid; 42 41 int gpio_pd_n; ··· 175 176 { 176 177 } 177 178 178 - static struct drm_bridge_funcs ptn3460_bridge_funcs = { 179 - .pre_enable = ptn3460_pre_enable, 180 - .enable = ptn3460_enable, 181 - .disable = ptn3460_disable, 182 - .post_disable = ptn3460_post_disable, 183 - }; 184 - 185 179 static int ptn3460_get_modes(struct drm_connector *connector) 186 180 { 187 181 struct ptn3460_bridge *ptn_bridge; ··· 219 227 { 220 228 struct ptn3460_bridge *ptn_bridge = connector_to_ptn3460(connector); 221 229 222 - return ptn_bridge->encoder; 230 + return ptn_bridge->bridge.encoder; 223 231 } 224 232 225 233 static struct drm_connector_helper_funcs ptn3460_connector_helper_funcs = { ··· 245 253 .destroy = ptn3460_connector_destroy, 246 254 }; 247 255 248 - int ptn3460_init(struct drm_device *dev, struct drm_encoder *encoder, 249 - struct i2c_client *client, struct device_node *node) 256 + int ptn3460_bridge_attach(struct drm_bridge *bridge) 250 257 { 258 + struct ptn3460_bridge *ptn_bridge = bridge_to_ptn3460(bridge); 251 259 int ret; 252 - struct ptn3460_bridge *ptn_bridge; 253 260 254 - ptn_bridge = devm_kzalloc(dev->dev, sizeof(*ptn_bridge), GFP_KERNEL); 261 + if (!bridge->encoder) { 262 + DRM_ERROR("Parent encoder object not found"); 263 + return -ENODEV; 264 + } 265 + 266 + ret = drm_connector_init(bridge->dev, &ptn_bridge->connector, 267 + &ptn3460_connector_funcs, DRM_MODE_CONNECTOR_LVDS); 268 + if (ret) { 269 + DRM_ERROR("Failed to initialize connector with drm\n"); 270 + return ret; 271 + } 272 + drm_connector_helper_add(&ptn_bridge->connector, 273 + &ptn3460_connector_helper_funcs); 274 + drm_connector_register(&ptn_bridge->connector); 275 + drm_mode_connector_attach_encoder(&ptn_bridge->connector, 276 + bridge->encoder); 277 + 278 + return ret; 279 + } 280 + 281 + static struct drm_bridge_funcs ptn3460_bridge_funcs = { 282 + .pre_enable = ptn3460_pre_enable, 283 + .enable = ptn3460_enable, 284 + .disable = ptn3460_disable, 285 + .post_disable = ptn3460_post_disable, 286 + .attach = ptn3460_bridge_attach, 287 + }; 288 + 289 + static int ptn3460_probe(struct i2c_client *client, 290 + const struct i2c_device_id *id) 291 + { 292 + struct device *dev = &client->dev; 293 + struct ptn3460_bridge *ptn_bridge; 294 + int ret; 295 + 296 + ptn_bridge = devm_kzalloc(dev, sizeof(*ptn_bridge), GFP_KERNEL); 255 297 if (!ptn_bridge) { 256 298 return -ENOMEM; 257 299 } 258 300 259 301 ptn_bridge->client = client; 260 - ptn_bridge->encoder = encoder; 261 - ptn_bridge->gpio_pd_n = of_get_named_gpio(node, "powerdown-gpio", 0); 302 + ptn_bridge->gpio_pd_n = of_get_named_gpio(dev->of_node, 303 + "powerdown-gpio", 0); 262 304 if (gpio_is_valid(ptn_bridge->gpio_pd_n)) { 263 305 ret = gpio_request_one(ptn_bridge->gpio_pd_n, 264 306 GPIOF_OUT_INIT_HIGH, "PTN3460_PD_N"); 265 307 if (ret) { 266 - dev_err(&client->dev, 267 - "Request powerdown-gpio failed (%d)\n", ret); 308 + dev_err(dev, "Request powerdown-gpio failed (%d)\n", 309 + ret); 268 310 return ret; 269 311 } 270 312 } 271 313 272 - ptn_bridge->gpio_rst_n = of_get_named_gpio(node, "reset-gpio", 0); 314 + ptn_bridge->gpio_rst_n = of_get_named_gpio(dev->of_node, 315 + "reset-gpio", 0); 273 316 if (gpio_is_valid(ptn_bridge->gpio_rst_n)) { 274 317 /* 275 318 * Request the reset pin low to avoid the bridge being ··· 313 286 ret = gpio_request_one(ptn_bridge->gpio_rst_n, 314 287 GPIOF_OUT_INIT_LOW, "PTN3460_RST_N"); 315 288 if (ret) { 316 - dev_err(&client->dev, 317 - "Request reset-gpio failed (%d)\n", ret); 289 + dev_err(dev, "Request reset-gpio failed (%d)\n", ret); 318 290 gpio_free(ptn_bridge->gpio_pd_n); 319 291 return ret; 320 292 } 321 293 } 322 294 323 - ret = of_property_read_u32(node, "edid-emulation", 295 + ret = of_property_read_u32(dev->of_node, "edid-emulation", 324 296 &ptn_bridge->edid_emulation); 325 297 if (ret) { 326 - dev_err(&client->dev, "Can't read EDID emulation value\n"); 298 + dev_err(dev, "Can't read EDID emulation value\n"); 327 299 goto err; 328 300 } 329 301 330 302 ptn_bridge->bridge.funcs = &ptn3460_bridge_funcs; 331 - ret = drm_bridge_attach(dev, &ptn_bridge->bridge); 303 + ret = drm_bridge_add(&ptn_bridge->bridge); 332 304 if (ret) { 333 - DRM_ERROR("Failed to initialize bridge with drm\n"); 305 + DRM_ERROR("Failed to add bridge\n"); 334 306 goto err; 335 307 } 336 308 337 - encoder->bridge = &ptn_bridge->bridge; 338 - 339 - ret = drm_connector_init(dev, &ptn_bridge->connector, 340 - &ptn3460_connector_funcs, DRM_MODE_CONNECTOR_LVDS); 341 - if (ret) { 342 - DRM_ERROR("Failed to initialize connector with drm\n"); 343 - goto err; 344 - } 345 - drm_connector_helper_add(&ptn_bridge->connector, 346 - &ptn3460_connector_helper_funcs); 347 - drm_connector_register(&ptn_bridge->connector); 348 - drm_mode_connector_attach_encoder(&ptn_bridge->connector, encoder); 309 + i2c_set_clientdata(client, ptn_bridge); 349 310 350 311 return 0; 351 312 ··· 344 329 gpio_free(ptn_bridge->gpio_rst_n); 345 330 return ret; 346 331 } 347 - EXPORT_SYMBOL(ptn3460_init); 348 332 349 - void ptn3460_destroy(struct drm_bridge *bridge) 333 + static int ptn3460_remove(struct i2c_client *client) 350 334 { 351 - struct ptn3460_bridge *ptn_bridge = bridge->driver_private; 335 + struct ptn3460_bridge *ptn_bridge = i2c_get_clientdata(client); 336 + 337 + drm_bridge_remove(&ptn_bridge->bridge); 352 338 353 339 if (gpio_is_valid(ptn_bridge->gpio_pd_n)) 354 340 gpio_free(ptn_bridge->gpio_pd_n); 355 341 if (gpio_is_valid(ptn_bridge->gpio_rst_n)) 356 342 gpio_free(ptn_bridge->gpio_rst_n); 357 - /* Nothing else to free, we've got devm allocated memory */ 343 + 344 + return 0; 358 345 } 359 - EXPORT_SYMBOL(ptn3460_destroy); 346 + 347 + static const struct i2c_device_id ptn3460_i2c_table[] = { 348 + {"nxp,ptn3460", 0}, 349 + {}, 350 + }; 351 + MODULE_DEVICE_TABLE(i2c, ptn3460_i2c_table); 352 + 353 + static const struct of_device_id ptn3460_match[] = { 354 + { .compatible = "nxp,ptn3460" }, 355 + {}, 356 + }; 357 + MODULE_DEVICE_TABLE(of, ptn3460_match); 358 + 359 + static struct i2c_driver ptn3460_driver = { 360 + .id_table = ptn3460_i2c_table, 361 + .probe = ptn3460_probe, 362 + .remove = ptn3460_remove, 363 + .driver = { 364 + .name = "nxp,ptn3460", 365 + .owner = THIS_MODULE, 366 + .of_match_table = ptn3460_match, 367 + }, 368 + }; 369 + module_i2c_driver(ptn3460_driver); 370 + 371 + MODULE_AUTHOR("Sean Paul <seanpaul@chromium.org>"); 372 + MODULE_DESCRIPTION("NXP ptn3460 eDP-LVDS converter driver"); 373 + MODULE_LICENSE("GPL v2");
-22
drivers/gpu/drm/exynos/exynos_dp_core.c
··· 993 993 .best_encoder = exynos_dp_best_encoder, 994 994 }; 995 995 996 - static 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 996 /* returns the number of bridges attached */ 1011 997 static int exynos_drm_attach_lcd_bridge(struct drm_device *dev, 1012 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 1000 return 0; 1023 1001 } 1024 1002