diff --git a/drivers/video/sh_mipi_dsi.c b/drivers/video/sh_mipi_dsi.c
index 05151b8..8c56fb7 100644
--- a/drivers/video/sh_mipi_dsi.c
+++ b/drivers/video/sh_mipi_dsi.c
@@ -49,6 +49,65 @@
/* E.g., sh7372 has 2 MIPI-DSIs - one for each LCDC */
#define MAX_SH_MIPI_DSI 2
+/*
+ * sh_mipi_dsi driver/device register
+ *
+ * FIXME
+ *
+ * sh_mipi_dsi has original driver/device register method here,
+ * since we don't have common MIPI interface at this point.
+ * These should be replaced in the future.
+ */
+static LIST_HEAD(sh_mipi_dsi_driver_list);
+
+static int sh_mipi_dsi_register_device(struct sh_mipi_dsi_device *shdev,
+ const char *driver_name)
+{
+ static int dev_num;
+ struct sh_mipi_dsi_driver *shdrv;
+
+ /* no driver is not error at this point */
+ if (!driver_name)
+ return 0;
+
+ list_for_each_entry(shdrv, &sh_mipi_dsi_driver_list, node) {
+ if (0 = strcmp(driver_name, shdrv->name))
+ goto driver_find;
+ }
+ /* no driver is not error at this point */
+ return 0;
+
+driver_find:
+ dev_set_name(&shdev->dev, "display%d", dev_num++);
+ shdev->driver = shdrv;
+
+ return device_register(&shdev->dev);
+}
+
+static void sh_mipi_dsi_unregister_device(struct sh_mipi_dsi_device *shdev)
+{
+ shdev->driver = NULL;
+ device_unregister(&shdev->dev);
+}
+
+int sh_mipi_dsi_register_driver(struct sh_mipi_dsi_driver *shdriver)
+{
+ INIT_LIST_HEAD(&shdriver->node);
+ list_add_tail(&shdriver->node, &sh_mipi_dsi_driver_list);
+
+ return 0;
+}
+EXPORT_SYMBOL(sh_mipi_dsi_register_driver);
+
+void sh_mipi_dsi_unregister_driver(struct sh_mipi_dsi_driver *shdriver)
+{
+ list_del_init(&shdriver->node);
+}
+EXPORT_SYMBOL(sh_mipi_dsi_unregister_driver);
+
+/*
+ * sh_mipi_dsi
+ */
struct sh_mipi {
void __iomem *base;
void __iomem *linkbase;@@ -58,8 +117,12 @@ struct sh_mipi {
void *next_board_data;
void (*next_display_on)(void *board_data, struct fb_info *info);
void (*next_display_off)(void *board_data);
+
+ struct sh_mipi_dsi_device device;
};
+#define to_shmipi(x) container_of((x), struct sh_mipi, device)
+
static struct sh_mipi *mipi_dsi[MAX_SH_MIPI_DSI];
/* Protect the above array */@@ -109,6 +172,27 @@ static int sh_mipi_dcs_param(int handle, u8 cmd, u8 param)
param);
}
+int sh_mipi_dsi_dcs(struct sh_mipi_dsi_device *shdev, u8 cmd)
+{
+ struct sh_mipi *mipi = to_shmipi(shdev);
+ if (!mipi)
+ return -ENODEV;
+
+ return sh_mipi_send_short(mipi, MIPI_DSI_DCS_SHORT_WRITE, cmd, 0);
+}
+EXPORT_SYMBOL(sh_mipi_dsi_dcs);
+
+int sh_mipi_dsi_dcs_param(struct sh_mipi_dsi_device *shdev, u8 cmd, u8 param)
+{
+ struct sh_mipi *mipi = to_shmipi(shdev);
+ if (!mipi)
+ return -ENODEV;
+
+ return sh_mipi_send_short(mipi, MIPI_DSI_DCS_SHORT_WRITE_PARAM, cmd,
+ param);
+}
+EXPORT_SYMBOL(sh_mipi_dsi_dcs_param);
+
static void sh_mipi_dsi_enable(struct sh_mipi *mipi, bool enable)
{
/*@@ -130,6 +214,8 @@ static int __init sh_mipi_setup(struct sh_mipi *mipi,
{
void __iomem *base = mipi->base;
struct sh_mobile_lcdc_chan_cfg *ch = pdata->lcd_chan;
+ struct sh_mipi_dsi_device *shdev = &mipi->device;
+ struct sh_mipi_dsi_driver *shdrv = shdev->driver;
u32 pctype, datatype, pixfmt, linelength, vmctr2;
u32 tmp, top, bottom, delay, div;
bool yuv;@@ -386,6 +472,9 @@ static int __init sh_mipi_setup(struct sh_mipi *mipi,
pixfmt << 4);
sh_mipi_dcs(ch->chan, MIPI_DCS_SET_DISPLAY_ON);
+ if (shdrv && shdrv->setup)
+ shdrv->setup(shdev);
+
/* Enable timeout counters */
iowrite32(0x00000f00, base + DSICTRL);
@@ -534,8 +623,14 @@ static int __init sh_mipi_probe(struct platform_device *pdev)
pdata->lcd_chan->board_cfg.display_off = mipi_display_off;
pdata->lcd_chan->board_cfg.owner = THIS_MODULE;
+ ret = sh_mipi_dsi_register_device(&mipi->device, pdata->driver_name);
+ if (ret < 0)
+ goto eregister;
+
return 0;
+eregister:
+ clk_disable(mipi->dsit_clk);
eclkton:
esettrate:
clk_put(mipi->dsit_clk);
@@ -597,6 +692,8 @@ static int __exit sh_mipi_remove(struct platform_device *pdev)
if (res)
release_mem_region(res->start, resource_size(res));
platform_set_drvdata(pdev, NULL);
+
+ sh_mipi_dsi_unregister_device(&mipi->device);
kfree(mipi);
return 0;
diff --git a/include/video/sh_mipi_dsi.h b/include/video/sh_mipi_dsi.h
index 434d56b..066184f 100644
--- a/include/video/sh_mipi_dsi.h
+++ b/include/video/sh_mipi_dsi.h
@@ -10,6 +10,9 @@
#ifndef VIDEO_SH_MIPI_DSI_H
#define VIDEO_SH_MIPI_DSI_H
+#include <linux/platform_device.h>
+#include <linux/device.h>
+
enum sh_mipi_dsi_data_fmt {
MIPI_RGB888,
MIPI_RGB565,@@ -55,6 +58,36 @@ struct sh_mipi_dsi_info {
int (*set_dot_clock)(struct platform_device *pdev,
void __iomem *base,
int enable);
+ const char *driver_name;
+};
+
+/*
+ * FIXME
+ *
+ * sh_mipi has original MIPI DSI interface here
+ * since we don't have common interface at this point.
+ * These should be removed in the future.
+ */
+#define to_shmipidsi_driver(x)\
+ container_of((x), struct sh_mipi_dsi_driver, driver)
+#define to_shmipidsi_device(x)\
+ container_of((x), struct sh_mipi_dsi_device, dev)
+
+struct sh_mipi_dsi_driver;
+struct sh_mipi_dsi_device {
+ struct device dev;
+ struct sh_mipi_dsi_driver *driver;
};
+struct sh_mipi_dsi_driver {
+ int (*setup)(struct sh_mipi_dsi_device *);
+ const char *name;
+ struct list_head node;
+};
+
+int sh_mipi_dsi_register_driver(struct sh_mipi_dsi_driver *shdriver);
+void sh_mipi_dsi_unregister_driver(struct sh_mipi_dsi_driver *shdriver);
+int sh_mipi_dsi_dcs(struct sh_mipi_dsi_device *shdev, u8 cmd);
+int sh_mipi_dsi_dcs_param(struct sh_mipi_dsi_device *shdev, u8 cmd, u8 param);
+
#endif--
1.7.5.4