]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
drm/mipi_dsi: Create dummy DSI devices
authorArchit Taneja <architt@codeaurora.org>
Mon, 7 Sep 2015 05:08:51 +0000 (10:38 +0530)
committerSrinivas Kandagatla <srinivas.kandagatla@linaro.org>
Mon, 11 Jan 2016 09:54:42 +0000 (09:54 +0000)
We can have devices where the data bus is MIPI DSI, but the control bus
is something else (i2c, spi etc). A typical example is i2c controlled
encoder bridge chips.

Such devices too require passing DSI specific parameters (number of data
lanes, DSI mode flags, color format etc) to their DSI host. For a device
that isn't 'mipi_dsi_device', there is no way of passing such parameters.

Provide the option of creating a dummy DSI device. The main purpose of
this would be to attach to a DSI host by calling mipi_dsi_attach, and
pass DSI params.

Create mipi_dsi_new_dummy for creating a dummy dsi device. The driver
calling this needs to be aware of the mipi_dsi_host it wants to attach
to, and also the DSI virtual channel the DSI device intends to use.

Signed-off-by: Archit Taneja <architt@codeaurora.org>
drivers/gpu/drm/drm_mipi_dsi.c
include/drm/drm_mipi_dsi.h

index 3a507fe534fdd891ca6eefcfb80f936c5666d201..2d642752e1a5de34edf821b3187613623a7f80d3 100644 (file)
  * subset of the MIPI DCS command set.
  */
 
+static const struct device_type mipi_dsi_device_type;
+
 static int mipi_dsi_device_match(struct device *dev, struct device_driver *drv)
 {
-       return of_driver_match_device(dev, drv);
+       struct mipi_dsi_device *dsi;
+
+       dsi = dev->type == &mipi_dsi_device_type ?
+               to_mipi_dsi_device(dev) : NULL;
+
+       if (!dsi)
+               return 0;
+
+       if (of_driver_match_device(dev, drv))
+               return 1;
+
+       if (!strcmp(drv->name, "mipi_dsi_dummy") &&
+                       !strcmp(dsi->name, "dummy"))
+               return 1;
+
+       return 0;
 }
 
 static const struct dev_pm_ops mipi_dsi_device_pm_ops = {
@@ -121,7 +138,7 @@ static int __dsi_check_chan_busy(struct device *dev, void *data)
 
 static int mipi_dsi_check_chan_busy(struct mipi_dsi_host *host, u32 reg)
 {
-       return device_for_each_child(&host->dev, &reg, __dsi_check_chan_busy);
+       return device_for_each_child(host->dev, &reg, __dsi_check_chan_busy);
 }
 
 static struct mipi_dsi_device *
@@ -190,6 +207,25 @@ of_mipi_dsi_device_add(struct mipi_dsi_host *host, struct device_node *node)
        return mipi_dsi_device_new(host, &info);
 }
 
+static struct mipi_dsi_driver dummy_dsi_driver = {
+       .driver.name = "mipi_dsi_dummy",
+};
+
+struct mipi_dsi_device *mipi_dsi_new_dummy(struct mipi_dsi_host *host, u32 reg)
+{
+       struct mipi_dsi_device_info info = { "dummy", reg, NULL, };
+
+       return mipi_dsi_device_new(host, &info);
+}
+EXPORT_SYMBOL(mipi_dsi_new_dummy);
+
+void mipi_dsi_unregister_device(struct mipi_dsi_device *dsi)
+{
+       if (dsi)
+               device_unregister(&dsi->dev);
+}
+EXPORT_SYMBOL(mipi_dsi_unregister_device);
+
 int mipi_dsi_host_register(struct mipi_dsi_host *host)
 {
        struct device_node *node;
@@ -943,7 +979,13 @@ EXPORT_SYMBOL(mipi_dsi_driver_unregister);
 
 static int __init mipi_dsi_bus_init(void)
 {
-       return bus_register(&mipi_dsi_bus_type);
+       int ret;
+
+       ret = bus_register(&mipi_dsi_bus_type);
+       if (ret < 0)
+               return ret;
+
+       return mipi_dsi_driver_register(&dummy_dsi_driver);
 }
 postcore_initcall(mipi_dsi_bus_init);
 
index 5a35c6fd9b09d28ed7c0ae18d93963144eb9dbf5..f95c8ef3003e7a92d3835692dbc0a5c3ba81c98b 100644 (file)
@@ -168,6 +168,8 @@ static inline struct mipi_dsi_device *to_mipi_dsi_device(struct device *dev)
        return container_of(dev, struct mipi_dsi_device, dev);
 }
 
+struct mipi_dsi_device *mipi_dsi_new_dummy(struct mipi_dsi_host *host, u32 reg);
+void mipi_dsi_unregister_device(struct mipi_dsi_device *dsi);
 struct mipi_dsi_device *of_find_mipi_dsi_device_by_node(struct device_node *np);
 int mipi_dsi_attach(struct mipi_dsi_device *dsi);
 int mipi_dsi_detach(struct mipi_dsi_device *dsi);