root/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. hdmic_connect
  2. hdmic_disconnect
  3. hdmic_detect
  4. hdmic_register_hpd_cb
  5. hdmic_unregister_hpd_cb
  6. hdmic_hpd_isr
  7. hdmic_probe
  8. hdmic_remove

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * HDMI Connector driver
   4  *
   5  * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/
   6  * Author: Tomi Valkeinen <tomi.valkeinen@ti.com>
   7  */
   8 
   9 #include <linux/gpio/consumer.h>
  10 #include <linux/module.h>
  11 #include <linux/mutex.h>
  12 #include <linux/platform_device.h>
  13 #include <linux/slab.h>
  14 
  15 #include "../dss/omapdss.h"
  16 
  17 struct panel_drv_data {
  18         struct omap_dss_device dssdev;
  19         void (*hpd_cb)(void *cb_data, enum drm_connector_status status);
  20         void *hpd_cb_data;
  21         struct mutex hpd_lock;
  22 
  23         struct device *dev;
  24 
  25         struct gpio_desc *hpd_gpio;
  26 };
  27 
  28 #define to_panel_data(x) container_of(x, struct panel_drv_data, dssdev)
  29 
  30 static int hdmic_connect(struct omap_dss_device *src,
  31                          struct omap_dss_device *dst)
  32 {
  33         return 0;
  34 }
  35 
  36 static void hdmic_disconnect(struct omap_dss_device *src,
  37                              struct omap_dss_device *dst)
  38 {
  39 }
  40 
  41 static bool hdmic_detect(struct omap_dss_device *dssdev)
  42 {
  43         struct panel_drv_data *ddata = to_panel_data(dssdev);
  44 
  45         return gpiod_get_value_cansleep(ddata->hpd_gpio);
  46 }
  47 
  48 static void hdmic_register_hpd_cb(struct omap_dss_device *dssdev,
  49                                   void (*cb)(void *cb_data,
  50                                             enum drm_connector_status status),
  51                                   void *cb_data)
  52 {
  53         struct panel_drv_data *ddata = to_panel_data(dssdev);
  54 
  55         mutex_lock(&ddata->hpd_lock);
  56         ddata->hpd_cb = cb;
  57         ddata->hpd_cb_data = cb_data;
  58         mutex_unlock(&ddata->hpd_lock);
  59 }
  60 
  61 static void hdmic_unregister_hpd_cb(struct omap_dss_device *dssdev)
  62 {
  63         struct panel_drv_data *ddata = to_panel_data(dssdev);
  64 
  65         mutex_lock(&ddata->hpd_lock);
  66         ddata->hpd_cb = NULL;
  67         ddata->hpd_cb_data = NULL;
  68         mutex_unlock(&ddata->hpd_lock);
  69 }
  70 
  71 static const struct omap_dss_device_ops hdmic_ops = {
  72         .connect                = hdmic_connect,
  73         .disconnect             = hdmic_disconnect,
  74 
  75         .detect                 = hdmic_detect,
  76         .register_hpd_cb        = hdmic_register_hpd_cb,
  77         .unregister_hpd_cb      = hdmic_unregister_hpd_cb,
  78 };
  79 
  80 static irqreturn_t hdmic_hpd_isr(int irq, void *data)
  81 {
  82         struct panel_drv_data *ddata = data;
  83 
  84         mutex_lock(&ddata->hpd_lock);
  85         if (ddata->hpd_cb) {
  86                 enum drm_connector_status status;
  87 
  88                 if (hdmic_detect(&ddata->dssdev))
  89                         status = connector_status_connected;
  90                 else
  91                         status = connector_status_disconnected;
  92 
  93                 ddata->hpd_cb(ddata->hpd_cb_data, status);
  94         }
  95         mutex_unlock(&ddata->hpd_lock);
  96 
  97         return IRQ_HANDLED;
  98 }
  99 
 100 static int hdmic_probe(struct platform_device *pdev)
 101 {
 102         struct panel_drv_data *ddata;
 103         struct omap_dss_device *dssdev;
 104         struct gpio_desc *gpio;
 105         int r;
 106 
 107         ddata = devm_kzalloc(&pdev->dev, sizeof(*ddata), GFP_KERNEL);
 108         if (!ddata)
 109                 return -ENOMEM;
 110 
 111         platform_set_drvdata(pdev, ddata);
 112         ddata->dev = &pdev->dev;
 113 
 114         mutex_init(&ddata->hpd_lock);
 115 
 116         /* HPD GPIO */
 117         gpio = devm_gpiod_get_optional(&pdev->dev, "hpd", GPIOD_IN);
 118         if (IS_ERR(gpio)) {
 119                 dev_err(&pdev->dev, "failed to parse HPD gpio\n");
 120                 return PTR_ERR(gpio);
 121         }
 122 
 123         ddata->hpd_gpio = gpio;
 124 
 125         if (ddata->hpd_gpio) {
 126                 r = devm_request_threaded_irq(&pdev->dev,
 127                                 gpiod_to_irq(ddata->hpd_gpio),
 128                                 NULL, hdmic_hpd_isr,
 129                                 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING |
 130                                 IRQF_ONESHOT,
 131                                 "hdmic hpd", ddata);
 132                 if (r)
 133                         return r;
 134         }
 135 
 136         dssdev = &ddata->dssdev;
 137         dssdev->ops = &hdmic_ops;
 138         dssdev->dev = &pdev->dev;
 139         dssdev->type = OMAP_DISPLAY_TYPE_HDMI;
 140         dssdev->display = true;
 141         dssdev->owner = THIS_MODULE;
 142         dssdev->of_ports = BIT(0);
 143         dssdev->ops_flags = ddata->hpd_gpio
 144                           ? OMAP_DSS_DEVICE_OP_DETECT | OMAP_DSS_DEVICE_OP_HPD
 145                           : 0;
 146 
 147         omapdss_display_init(dssdev);
 148         omapdss_device_register(dssdev);
 149 
 150         return 0;
 151 }
 152 
 153 static int __exit hdmic_remove(struct platform_device *pdev)
 154 {
 155         struct panel_drv_data *ddata = platform_get_drvdata(pdev);
 156 
 157         omapdss_device_unregister(&ddata->dssdev);
 158 
 159         return 0;
 160 }
 161 
 162 static const struct of_device_id hdmic_of_match[] = {
 163         { .compatible = "omapdss,hdmi-connector", },
 164         {},
 165 };
 166 
 167 MODULE_DEVICE_TABLE(of, hdmic_of_match);
 168 
 169 static struct platform_driver hdmi_connector_driver = {
 170         .probe  = hdmic_probe,
 171         .remove = __exit_p(hdmic_remove),
 172         .driver = {
 173                 .name   = "connector-hdmi",
 174                 .of_match_table = hdmic_of_match,
 175                 .suppress_bind_attrs = true,
 176         },
 177 };
 178 
 179 module_platform_driver(hdmi_connector_driver);
 180 
 181 MODULE_AUTHOR("Tomi Valkeinen <tomi.valkeinen@ti.com>");
 182 MODULE_DESCRIPTION("HDMI Connector driver");
 183 MODULE_LICENSE("GPL");

/* [<][>][^][v][top][bottom][index][help] */