diff options
| -rw-r--r-- | drivers/gpu/drm/i2c/tda998x_drv.c | 212 |
1 files changed, 198 insertions, 14 deletions
diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c index 64e120c5299a..3b07ff7e6348 100644 --- a/drivers/gpu/drm/i2c/tda998x_drv.c +++ b/drivers/gpu/drm/i2c/tda998x_drv.c | |||
| @@ -15,8 +15,7 @@ | |||
| 15 | * this program. If not, see <http://www.gnu.org/licenses/>. | 15 | * this program. If not, see <http://www.gnu.org/licenses/>. |
| 16 | */ | 16 | */ |
| 17 | 17 | ||
| 18 | 18 | #include <linux/component.h> | |
| 19 | |||
| 20 | #include <linux/hdmi.h> | 19 | #include <linux/hdmi.h> |
| 21 | #include <linux/module.h> | 20 | #include <linux/module.h> |
| 22 | #include <linux/irq.h> | 21 | #include <linux/irq.h> |
| @@ -1252,18 +1251,6 @@ static struct drm_encoder_slave_funcs tda998x_encoder_slave_funcs = { | |||
| 1252 | 1251 | ||
| 1253 | /* I2C driver functions */ | 1252 | /* I2C driver functions */ |
| 1254 | 1253 | ||
| 1255 | static int | ||
| 1256 | tda998x_probe(struct i2c_client *client, const struct i2c_device_id *id) | ||
| 1257 | { | ||
| 1258 | return 0; | ||
| 1259 | } | ||
| 1260 | |||
| 1261 | static int | ||
| 1262 | tda998x_remove(struct i2c_client *client) | ||
| 1263 | { | ||
| 1264 | return 0; | ||
| 1265 | } | ||
| 1266 | |||
| 1267 | static int tda998x_create(struct i2c_client *client, struct tda998x_priv *priv) | 1254 | static int tda998x_create(struct i2c_client *client, struct tda998x_priv *priv) |
| 1268 | { | 1255 | { |
| 1269 | struct device_node *np = client->dev.of_node; | 1256 | struct device_node *np = client->dev.of_node; |
| @@ -1412,6 +1399,203 @@ static int tda998x_encoder_init(struct i2c_client *client, | |||
| 1412 | return 0; | 1399 | return 0; |
| 1413 | } | 1400 | } |
| 1414 | 1401 | ||
| 1402 | struct tda998x_priv2 { | ||
| 1403 | struct tda998x_priv base; | ||
| 1404 | struct drm_encoder encoder; | ||
| 1405 | struct drm_connector connector; | ||
| 1406 | }; | ||
| 1407 | |||
| 1408 | #define conn_to_tda998x_priv2(x) \ | ||
| 1409 | container_of(x, struct tda998x_priv2, connector); | ||
| 1410 | |||
| 1411 | #define enc_to_tda998x_priv2(x) \ | ||
| 1412 | container_of(x, struct tda998x_priv2, encoder); | ||
| 1413 | |||
| 1414 | static void tda998x_encoder2_dpms(struct drm_encoder *encoder, int mode) | ||
| 1415 | { | ||
| 1416 | struct tda998x_priv2 *priv = enc_to_tda998x_priv2(encoder); | ||
| 1417 | |||
| 1418 | tda998x_encoder_dpms(&priv->base, mode); | ||
| 1419 | } | ||
| 1420 | |||
| 1421 | static void tda998x_encoder_prepare(struct drm_encoder *encoder) | ||
| 1422 | { | ||
| 1423 | tda998x_encoder2_dpms(encoder, DRM_MODE_DPMS_OFF); | ||
| 1424 | } | ||
| 1425 | |||
| 1426 | static void tda998x_encoder_commit(struct drm_encoder *encoder) | ||
| 1427 | { | ||
| 1428 | tda998x_encoder2_dpms(encoder, DRM_MODE_DPMS_ON); | ||
| 1429 | } | ||
| 1430 | |||
| 1431 | static void tda998x_encoder2_mode_set(struct drm_encoder *encoder, | ||
| 1432 | struct drm_display_mode *mode, | ||
| 1433 | struct drm_display_mode *adjusted_mode) | ||
| 1434 | { | ||
| 1435 | struct tda998x_priv2 *priv = enc_to_tda998x_priv2(encoder); | ||
| 1436 | |||
| 1437 | tda998x_encoder_mode_set(&priv->base, mode, adjusted_mode); | ||
| 1438 | } | ||
| 1439 | |||
| 1440 | static const struct drm_encoder_helper_funcs tda998x_encoder_helper_funcs = { | ||
| 1441 | .dpms = tda998x_encoder2_dpms, | ||
| 1442 | .save = tda998x_encoder_save, | ||
| 1443 | .restore = tda998x_encoder_restore, | ||
| 1444 | .mode_fixup = tda998x_encoder_mode_fixup, | ||
| 1445 | .prepare = tda998x_encoder_prepare, | ||
| 1446 | .commit = tda998x_encoder_commit, | ||
| 1447 | .mode_set = tda998x_encoder2_mode_set, | ||
| 1448 | }; | ||
| 1449 | |||
| 1450 | static void tda998x_encoder_destroy(struct drm_encoder *encoder) | ||
| 1451 | { | ||
| 1452 | struct tda998x_priv2 *priv = enc_to_tda998x_priv2(encoder); | ||
| 1453 | |||
| 1454 | tda998x_destroy(&priv->base); | ||
| 1455 | drm_encoder_cleanup(encoder); | ||
| 1456 | } | ||
| 1457 | |||
| 1458 | static const struct drm_encoder_funcs tda998x_encoder_funcs = { | ||
| 1459 | .destroy = tda998x_encoder_destroy, | ||
| 1460 | }; | ||
| 1461 | |||
| 1462 | static int tda998x_connector_get_modes(struct drm_connector *connector) | ||
| 1463 | { | ||
| 1464 | struct tda998x_priv2 *priv = conn_to_tda998x_priv2(connector); | ||
| 1465 | |||
| 1466 | return tda998x_encoder_get_modes(&priv->base, connector); | ||
| 1467 | } | ||
| 1468 | |||
| 1469 | static int tda998x_connector_mode_valid(struct drm_connector *connector, | ||
| 1470 | struct drm_display_mode *mode) | ||
| 1471 | { | ||
| 1472 | struct tda998x_priv2 *priv = conn_to_tda998x_priv2(connector); | ||
| 1473 | |||
| 1474 | return tda998x_encoder_mode_valid(&priv->base, mode); | ||
| 1475 | } | ||
| 1476 | |||
| 1477 | static struct drm_encoder * | ||
| 1478 | tda998x_connector_best_encoder(struct drm_connector *connector) | ||
| 1479 | { | ||
| 1480 | struct tda998x_priv2 *priv = conn_to_tda998x_priv2(connector); | ||
| 1481 | |||
| 1482 | return &priv->encoder; | ||
| 1483 | } | ||
| 1484 | |||
| 1485 | static | ||
| 1486 | const struct drm_connector_helper_funcs tda998x_connector_helper_funcs = { | ||
| 1487 | .get_modes = tda998x_connector_get_modes, | ||
| 1488 | .mode_valid = tda998x_connector_mode_valid, | ||
| 1489 | .best_encoder = tda998x_connector_best_encoder, | ||
| 1490 | }; | ||
| 1491 | |||
| 1492 | static enum drm_connector_status | ||
| 1493 | tda998x_connector_detect(struct drm_connector *connector, bool force) | ||
| 1494 | { | ||
| 1495 | struct tda998x_priv2 *priv = conn_to_tda998x_priv2(connector); | ||
| 1496 | |||
| 1497 | return tda998x_encoder_detect(&priv->base); | ||
| 1498 | } | ||
| 1499 | |||
| 1500 | static void tda998x_connector_destroy(struct drm_connector *connector) | ||
| 1501 | { | ||
| 1502 | drm_sysfs_connector_remove(connector); | ||
| 1503 | drm_connector_cleanup(connector); | ||
| 1504 | } | ||
| 1505 | |||
| 1506 | static const struct drm_connector_funcs tda998x_connector_funcs = { | ||
| 1507 | .dpms = drm_helper_connector_dpms, | ||
| 1508 | .fill_modes = drm_helper_probe_single_connector_modes, | ||
| 1509 | .detect = tda998x_connector_detect, | ||
| 1510 | .destroy = tda998x_connector_destroy, | ||
| 1511 | }; | ||
| 1512 | |||
| 1513 | static int tda998x_bind(struct device *dev, struct device *master, void *data) | ||
| 1514 | { | ||
| 1515 | struct tda998x_encoder_params *params = dev->platform_data; | ||
| 1516 | struct i2c_client *client = to_i2c_client(dev); | ||
| 1517 | struct drm_device *drm = data; | ||
| 1518 | struct tda998x_priv2 *priv; | ||
| 1519 | int ret; | ||
| 1520 | |||
| 1521 | priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); | ||
| 1522 | if (!priv) | ||
| 1523 | return -ENOMEM; | ||
| 1524 | |||
| 1525 | dev_set_drvdata(dev, priv); | ||
| 1526 | |||
| 1527 | priv->base.encoder = &priv->encoder; | ||
| 1528 | priv->connector.interlace_allowed = 1; | ||
| 1529 | priv->encoder.possible_crtcs = 1 << 0; | ||
| 1530 | |||
| 1531 | ret = tda998x_create(client, &priv->base); | ||
| 1532 | if (ret) | ||
| 1533 | return ret; | ||
| 1534 | |||
| 1535 | if (!dev->of_node && params) | ||
| 1536 | tda998x_encoder_set_config(&priv->base, params); | ||
| 1537 | |||
| 1538 | tda998x_encoder_set_polling(&priv->base, &priv->connector); | ||
| 1539 | |||
| 1540 | drm_encoder_helper_add(&priv->encoder, &tda998x_encoder_helper_funcs); | ||
| 1541 | ret = drm_encoder_init(drm, &priv->encoder, &tda998x_encoder_funcs, | ||
| 1542 | DRM_MODE_ENCODER_TMDS); | ||
| 1543 | if (ret) | ||
| 1544 | goto err_encoder; | ||
| 1545 | |||
| 1546 | drm_connector_helper_add(&priv->connector, | ||
| 1547 | &tda998x_connector_helper_funcs); | ||
| 1548 | ret = drm_connector_init(drm, &priv->connector, | ||
| 1549 | &tda998x_connector_funcs, | ||
| 1550 | DRM_MODE_CONNECTOR_HDMIA); | ||
| 1551 | if (ret) | ||
| 1552 | goto err_connector; | ||
| 1553 | |||
| 1554 | ret = drm_sysfs_connector_add(&priv->connector); | ||
| 1555 | if (ret) | ||
| 1556 | goto err_sysfs; | ||
| 1557 | |||
| 1558 | priv->connector.encoder = &priv->encoder; | ||
| 1559 | drm_mode_connector_attach_encoder(&priv->connector, &priv->encoder); | ||
| 1560 | |||
| 1561 | return 0; | ||
| 1562 | |||
| 1563 | err_sysfs: | ||
| 1564 | drm_connector_cleanup(&priv->connector); | ||
| 1565 | err_connector: | ||
| 1566 | drm_encoder_cleanup(&priv->encoder); | ||
| 1567 | err_encoder: | ||
| 1568 | tda998x_destroy(&priv->base); | ||
| 1569 | return ret; | ||
| 1570 | } | ||
| 1571 | |||
| 1572 | static void tda998x_unbind(struct device *dev, struct device *master, | ||
| 1573 | void *data) | ||
| 1574 | { | ||
| 1575 | struct tda998x_priv2 *priv = dev_get_drvdata(dev); | ||
| 1576 | |||
| 1577 | drm_connector_cleanup(&priv->connector); | ||
| 1578 | drm_encoder_cleanup(&priv->encoder); | ||
| 1579 | tda998x_destroy(&priv->base); | ||
| 1580 | } | ||
| 1581 | |||
| 1582 | static const struct component_ops tda998x_ops = { | ||
| 1583 | .bind = tda998x_bind, | ||
| 1584 | .unbind = tda998x_unbind, | ||
| 1585 | }; | ||
| 1586 | |||
| 1587 | static int | ||
| 1588 | tda998x_probe(struct i2c_client *client, const struct i2c_device_id *id) | ||
| 1589 | { | ||
| 1590 | return component_add(&client->dev, &tda998x_ops); | ||
| 1591 | } | ||
| 1592 | |||
| 1593 | static int tda998x_remove(struct i2c_client *client) | ||
| 1594 | { | ||
| 1595 | component_del(&client->dev, &tda998x_ops); | ||
| 1596 | return 0; | ||
| 1597 | } | ||
| 1598 | |||
| 1415 | #ifdef CONFIG_OF | 1599 | #ifdef CONFIG_OF |
| 1416 | static const struct of_device_id tda998x_dt_ids[] = { | 1600 | static const struct of_device_id tda998x_dt_ids[] = { |
| 1417 | { .compatible = "nxp,tda998x", }, | 1601 | { .compatible = "nxp,tda998x", }, |
