* [PATCH 21/25] OMAPDSS: interface drivers register their panel devices
From: Tomi Valkeinen @ 2012-05-03 13:57 UTC (permalink / raw)
To: linux-omap, linux-fbdev; +Cc: archit, Tomi Valkeinen
In-Reply-To: <1336053481-25433-1-git-send-email-tomi.valkeinen@ti.com>
Currently the higher level omapdss platform driver gets the list of
displays in its platform data, and uses that list to create the
omap_dss_device for each display.
With DT, the logical way to do the above is to list the displays under
each individual output, i.e. we'd have "dpi" node, under which we would
have the display that uses DPI. In other words, each output driver
handles the displays that use that particular output.
To make the current code ready for DT, this patch modifies the output
drivers so that each of them creates the display devices which use that
output. However, instead of changing the platform data to suit this
method, each output driver is passed the full list of displays, and the
drivers pick the displays that are meant for them. This allows us to
keep the old platform data, and thus we avoid the need to change the
board files.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
arch/arm/mach-omap2/display.c | 9 ++++----
drivers/video/omap2/dss/core.c | 46 ++++++++++++++--------------------------
drivers/video/omap2/dss/dpi.c | 17 +++++++++++++++
drivers/video/omap2/dss/dsi.c | 18 ++++++++++++++++
drivers/video/omap2/dss/dss.h | 5 +++++
drivers/video/omap2/dss/hdmi.c | 17 ++++++++++++++-
drivers/video/omap2/dss/rfbi.c | 16 +++++++++++++-
drivers/video/omap2/dss/sdi.c | 17 +++++++++++++++
drivers/video/omap2/dss/venc.c | 18 +++++++++++++++-
9 files changed, 126 insertions(+), 37 deletions(-)
diff --git a/arch/arm/mach-omap2/display.c b/arch/arm/mach-omap2/display.c
index 2c05a60..2c51809 100644
--- a/arch/arm/mach-omap2/display.c
+++ b/arch/arm/mach-omap2/display.c
@@ -325,7 +325,7 @@ int __init omap_display_init(struct omap_dss_board_info *board_data)
pdev = create_dss_pdev(curr_dss_hwmod[i].dev_name,
curr_dss_hwmod[i].id,
curr_dss_hwmod[i].oh_name,
- NULL, 0,
+ board_data, sizeof(*board_data),
dss_pdev);
if (IS_ERR(pdev)) {
@@ -341,15 +341,16 @@ int __init omap_display_init(struct omap_dss_board_info *board_data)
/* Create devices for DPI and SDI */
- pdev = create_simple_dss_pdev("omapdss_dpi", -1, NULL, 0, dss_pdev);
+ pdev = create_simple_dss_pdev("omapdss_dpi", -1,
+ board_data, sizeof(*board_data), dss_pdev);
if (IS_ERR(pdev)) {
pr_err("Could not build platform_device for omapdss_dpi\n");
return PTR_ERR(pdev);
}
if (cpu_is_omap34xx()) {
- pdev = create_simple_dss_pdev("omapdss_sdi", -1, NULL, 0,
- dss_pdev);
+ pdev = create_simple_dss_pdev("omapdss_sdi", -1,
+ board_data, sizeof(*board_data), dss_pdev);
if (IS_ERR(pdev)) {
pr_err("Could not build platform_device for omapdss_sdi\n");
return PTR_ERR(pdev);
diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c
index c3566a0..9915e9d 100644
--- a/drivers/video/omap2/dss/core.c
+++ b/drivers/video/omap2/dss/core.c
@@ -56,9 +56,6 @@ bool dss_debug;
module_param_named(debug, dss_debug, bool, 0644);
#endif
-static int omap_dss_register_device(struct omap_dss_device *);
-static void omap_dss_unregister_device(struct omap_dss_device *);
-
/* REGULATORS */
struct regulator *dss_get_vdds_dsi(void)
@@ -209,7 +206,6 @@ static int __init omap_dss_probe(struct platform_device *pdev)
{
struct omap_dss_board_info *pdata = pdev->dev.platform_data;
int r;
- int i;
core.pdev = pdev;
@@ -229,25 +225,8 @@ static int __init omap_dss_probe(struct platform_device *pdev)
else if (pdata->default_device)
core.default_display_name = pdata->default_device->name;
- for (i = 0; i < pdata->num_devices; ++i) {
- struct omap_dss_device *dssdev = pdata->devices[i];
-
- r = omap_dss_register_device(dssdev);
- if (r) {
- DSSERR("device %d %s register failed %d\n", i,
- dssdev->name ?: "unnamed", r);
-
- while (--i >= 0)
- omap_dss_unregister_device(pdata->devices[i]);
-
- goto err_register;
- }
- }
-
return 0;
-err_register:
- dss_uninitialize_debugfs();
err_debugfs:
return r;
@@ -255,17 +234,11 @@ err_debugfs:
static int omap_dss_remove(struct platform_device *pdev)
{
- struct omap_dss_board_info *pdata = pdev->dev.platform_data;
- int i;
-
dss_uninitialize_debugfs();
dss_uninit_overlays(pdev);
dss_uninit_overlay_managers(pdev);
- for (i = 0; i < pdata->num_devices; ++i)
- omap_dss_unregister_device(pdata->devices[i]);
-
return 0;
}
@@ -467,7 +440,8 @@ static void omap_dss_dev_release(struct device *dev)
reset_device(dev, 0);
}
-static int omap_dss_register_device(struct omap_dss_device *dssdev)
+int omap_dss_register_device(struct omap_dss_device *dssdev,
+ struct device *parent)
{
static int dev_num;
@@ -475,17 +449,29 @@ static int omap_dss_register_device(struct omap_dss_device *dssdev)
reset_device(&dssdev->dev, 1);
dssdev->dev.bus = &dss_bus_type;
- dssdev->dev.parent = &dss_bus;
+ dssdev->dev.parent = parent;
dssdev->dev.release = omap_dss_dev_release;
dev_set_name(&dssdev->dev, "display%d", dev_num++);
return device_register(&dssdev->dev);
}
-static void omap_dss_unregister_device(struct omap_dss_device *dssdev)
+void omap_dss_unregister_device(struct omap_dss_device *dssdev)
{
device_unregister(&dssdev->dev);
}
+static int dss_unregister_dss_dev(struct device *dev, void *data)
+{
+ struct omap_dss_device *dssdev = to_dss_device(dev);
+ omap_dss_unregister_device(dssdev);
+ return 0;
+}
+
+void omap_dss_unregister_child_devices(struct device *parent)
+{
+ device_for_each_child(parent, NULL, dss_unregister_dss_dev);
+}
+
/* BUS */
static int __init omap_dss_bus_register(void)
{
diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c
index f92134c..631953b 100644
--- a/drivers/video/omap2/dss/dpi.c
+++ b/drivers/video/omap2/dss/dpi.c
@@ -366,11 +366,28 @@ int dpi_init_display(struct omap_dss_device *dssdev)
static int __init omap_dpi_probe(struct platform_device *pdev)
{
+ struct omap_dss_board_info *pdata = pdev->dev.platform_data;
+ int i, r;
+
+ for (i = 0; i < pdata->num_devices; ++i) {
+ struct omap_dss_device *dssdev = pdata->devices[i];
+
+ if (dssdev->type != OMAP_DISPLAY_TYPE_DPI)
+ continue;
+
+ r = omap_dss_register_device(dssdev, &pdev->dev);
+ if (r)
+ DSSERR("device %s register failed: %d\n",
+ dssdev->name, r);
+ }
+
return 0;
}
static int __exit omap_dpi_remove(struct platform_device *pdev)
{
+ omap_dss_unregister_child_devices(&pdev->dev);
+
return 0;
}
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index f37e7ee..0ff1e63 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -4616,6 +4616,7 @@ static int __init omap_dsihw_probe(struct platform_device *dsidev)
int r, i, dsi_module = dsi_get_dsidev_id(dsidev);
struct resource *dsi_mem;
struct dsi_data *dsi;
+ struct omap_dss_board_info *pdata = dsidev->dev.platform_data;
dsi = devm_kzalloc(&dsidev->dev, sizeof(*dsi), GFP_KERNEL);
if (!dsi)
@@ -4702,6 +4703,21 @@ static int __init omap_dsihw_probe(struct platform_device *dsidev)
else
dsi->num_lanes_supported = 3;
+ for (i = 0; i < pdata->num_devices; ++i) {
+ struct omap_dss_device *dssdev = pdata->devices[i];
+
+ if (dssdev->type != OMAP_DISPLAY_TYPE_DSI)
+ continue;
+
+ if (dssdev->phy.dsi.module != dsi_module)
+ continue;
+
+ r = omap_dss_register_device(dssdev, &dsidev->dev);
+ if (r)
+ DSSERR("device %s register failed: %d\n",
+ dssdev->name, r);
+ }
+
dsi_runtime_put(dsidev);
if (dsi_module = 0)
@@ -4729,6 +4745,8 @@ static int __exit omap_dsihw_remove(struct platform_device *dsidev)
WARN_ON(dsi->scp_clk_refcount > 0);
+ omap_dss_unregister_child_devices(&dsidev->dev);
+
pm_runtime_disable(&dsidev->dev);
dsi_put_clocks(dsidev);
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 3ac9d1d..828f669 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -165,6 +165,11 @@ void dss_dsi_disable_pads(int dsi_id, unsigned lane_mask);
int dss_set_min_bus_tput(struct device *dev, unsigned long tput);
int dss_debugfs_create_file(const char *name, void (*write)(struct seq_file *));
+int omap_dss_register_device(struct omap_dss_device *dssdev,
+ struct device *parent);
+void omap_dss_unregister_device(struct omap_dss_device *dssdev);
+void omap_dss_unregister_child_devices(struct device *parent);
+
/* apply */
void dss_apply_init(void);
int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr);
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index 02933bc..28ce057 100644
--- a/drivers/video/omap2/dss/hdmi.c
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -772,8 +772,9 @@ static void hdmi_put_clocks(void)
/* HDMI HW IP initialisation */
static int __init omapdss_hdmihw_probe(struct platform_device *pdev)
{
+ struct omap_dss_board_info *pdata = pdev->dev.platform_data;
struct resource *hdmi_mem;
- int r;
+ int r, i;
hdmi.pdev = pdev;
@@ -810,6 +811,18 @@ static int __init omapdss_hdmihw_probe(struct platform_device *pdev)
dss_debugfs_create_file("hdmi", hdmi_dump_regs);
+ for (i = 0; i < pdata->num_devices; ++i) {
+ struct omap_dss_device *dssdev = pdata->devices[i];
+
+ if (dssdev->type != OMAP_DISPLAY_TYPE_HDMI)
+ continue;
+
+ r = omap_dss_register_device(dssdev, &pdev->dev);
+ if (r)
+ DSSERR("device %s register failed: %d\n",
+ dssdev->name, r);
+ }
+
#if defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI) || \
defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI_MODULE)
@@ -826,6 +839,8 @@ static int __init omapdss_hdmihw_probe(struct platform_device *pdev)
static int __exit omapdss_hdmihw_remove(struct platform_device *pdev)
{
+ omap_dss_unregister_child_devices(&pdev->dev);
+
hdmi_panel_exit();
#if defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI) || \
diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/omap2/dss/rfbi.c
index 6d489c0..d0d24a0 100644
--- a/drivers/video/omap2/dss/rfbi.c
+++ b/drivers/video/omap2/dss/rfbi.c
@@ -930,10 +930,11 @@ int rfbi_init_display(struct omap_dss_device *dssdev)
/* RFBI HW IP initialisation */
static int __init omap_rfbihw_probe(struct platform_device *pdev)
{
+ struct omap_dss_board_info *pdata = pdev->dev.platform_data;
u32 rev;
struct resource *rfbi_mem;
struct clk *clk;
- int r;
+ int r, i;
rfbi.pdev = pdev;
@@ -978,6 +979,18 @@ static int __init omap_rfbihw_probe(struct platform_device *pdev)
dss_debugfs_create_file("rfbi", rfbi_dump_regs);
+ for (i = 0; i < pdata->num_devices; ++i) {
+ struct omap_dss_device *dssdev = pdata->devices[i];
+
+ if (dssdev->type != OMAP_DISPLAY_TYPE_DBI)
+ continue;
+
+ r = omap_dss_register_device(dssdev, &pdev->dev);
+ if (r)
+ DSSERR("device %s register failed: %d\n",
+ dssdev->name, r);
+ }
+
return 0;
err_runtime_get:
@@ -987,6 +1000,7 @@ err_runtime_get:
static int __exit omap_rfbihw_remove(struct platform_device *pdev)
{
+ omap_dss_unregister_child_devices(&pdev->dev);
pm_runtime_disable(&pdev->dev);
return 0;
}
diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/omap2/dss/sdi.c
index 7dfe4fe..bf48fb4 100644
--- a/drivers/video/omap2/dss/sdi.c
+++ b/drivers/video/omap2/dss/sdi.c
@@ -178,11 +178,28 @@ int sdi_init_display(struct omap_dss_device *dssdev)
static int __init omap_sdi_probe(struct platform_device *pdev)
{
+ struct omap_dss_board_info *pdata = pdev->dev.platform_data;
+ int i, r;
+
+ for (i = 0; i < pdata->num_devices; ++i) {
+ struct omap_dss_device *dssdev = pdata->devices[i];
+
+ if (dssdev->type != OMAP_DISPLAY_TYPE_SDI)
+ continue;
+
+ r = omap_dss_register_device(dssdev, &pdev->dev);
+ if (r)
+ DSSERR("device %s register failed: %d\n",
+ dssdev->name, r);
+ }
+
return 0;
}
static int __exit omap_sdi_remove(struct platform_device *pdev)
{
+ omap_dss_unregister_child_devices(&pdev->dev);
+
return 0;
}
diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c
index a19138b..646903a 100644
--- a/drivers/video/omap2/dss/venc.c
+++ b/drivers/video/omap2/dss/venc.c
@@ -780,9 +780,10 @@ static void venc_put_clocks(void)
/* VENC HW IP initialisation */
static int __init omap_venchw_probe(struct platform_device *pdev)
{
+ struct omap_dss_board_info *pdata = pdev->dev.platform_data;
u8 rev_id;
struct resource *venc_mem;
- int r;
+ int r, i;
venc.pdev = pdev;
@@ -824,6 +825,18 @@ static int __init omap_venchw_probe(struct platform_device *pdev)
dss_debugfs_create_file("venc", venc_dump_regs);
+ for (i = 0; i < pdata->num_devices; ++i) {
+ struct omap_dss_device *dssdev = pdata->devices[i];
+
+ if (dssdev->type != OMAP_DISPLAY_TYPE_VENC)
+ continue;
+
+ r = omap_dss_register_device(dssdev, &pdev->dev);
+ if (r)
+ DSSERR("device %s register failed: %d\n",
+ dssdev->name, r);
+ }
+
return 0;
err_reg_panel_driver:
@@ -835,10 +848,13 @@ err_runtime_get:
static int __exit omap_venchw_remove(struct platform_device *pdev)
{
+ omap_dss_unregister_child_devices(&pdev->dev);
+
if (venc.vdda_dac_reg != NULL) {
regulator_put(venc.vdda_dac_reg);
venc.vdda_dac_reg = NULL;
}
+
omap_dss_unregister_driver(&venc_driver);
pm_runtime_disable(&pdev->dev);
--
1.7.9.5
^ permalink raw reply related
* [PATCH 22/25] OMAPDSS: init omap_dss_devices internally
From: Tomi Valkeinen @ 2012-05-03 13:57 UTC (permalink / raw)
To: linux-omap, linux-fbdev; +Cc: archit, Tomi Valkeinen
In-Reply-To: <1336053481-25433-1-git-send-email-tomi.valkeinen@ti.com>
Now that each output driver creates their own display devices, the
output drivers can also initialize those devices.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/display.c | 40 -------------------------------------
drivers/video/omap2/dss/dpi.c | 8 +++++++-
drivers/video/omap2/dss/dsi.c | 8 +++++++-
drivers/video/omap2/dss/dss.h | 10 ----------
drivers/video/omap2/dss/hdmi.c | 8 +++++++-
drivers/video/omap2/dss/rfbi.c | 8 +++++++-
drivers/video/omap2/dss/sdi.c | 8 +++++++-
drivers/video/omap2/dss/venc.c | 8 +++++++-
8 files changed, 42 insertions(+), 56 deletions(-)
diff --git a/drivers/video/omap2/dss/display.c b/drivers/video/omap2/dss/display.c
index e688d10..faf7d91 100644
--- a/drivers/video/omap2/dss/display.c
+++ b/drivers/video/omap2/dss/display.c
@@ -359,46 +359,6 @@ void dss_init_device(struct platform_device *pdev,
int i;
int r;
- switch (dssdev->type) {
-#ifdef CONFIG_OMAP2_DSS_DPI
- case OMAP_DISPLAY_TYPE_DPI:
- r = dpi_init_display(dssdev);
- break;
-#endif
-#ifdef CONFIG_OMAP2_DSS_RFBI
- case OMAP_DISPLAY_TYPE_DBI:
- r = rfbi_init_display(dssdev);
- break;
-#endif
-#ifdef CONFIG_OMAP2_DSS_VENC
- case OMAP_DISPLAY_TYPE_VENC:
- r = venc_init_display(dssdev);
- break;
-#endif
-#ifdef CONFIG_OMAP2_DSS_SDI
- case OMAP_DISPLAY_TYPE_SDI:
- r = sdi_init_display(dssdev);
- break;
-#endif
-#ifdef CONFIG_OMAP2_DSS_DSI
- case OMAP_DISPLAY_TYPE_DSI:
- r = dsi_init_display(dssdev);
- break;
-#endif
- case OMAP_DISPLAY_TYPE_HDMI:
- r = hdmi_init_display(dssdev);
- break;
- default:
- DSSERR("Support for display '%s' not compiled in.\n",
- dssdev->name);
- return;
- }
-
- if (r) {
- DSSERR("failed to init display %s\n", dssdev->name);
- return;
- }
-
/* create device sysfs files */
i = 0;
while ((attr = display_sysfs_attrs[i++]) != NULL) {
diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c
index 631953b..4f8defe 100644
--- a/drivers/video/omap2/dss/dpi.c
+++ b/drivers/video/omap2/dss/dpi.c
@@ -338,7 +338,7 @@ int dpi_check_timings(struct omap_dss_device *dssdev,
}
EXPORT_SYMBOL(dpi_check_timings);
-int dpi_init_display(struct omap_dss_device *dssdev)
+static int __init dpi_init_display(struct omap_dss_device *dssdev)
{
DSSDBG("init_display\n");
@@ -375,6 +375,12 @@ static int __init omap_dpi_probe(struct platform_device *pdev)
if (dssdev->type != OMAP_DISPLAY_TYPE_DPI)
continue;
+ r = dpi_init_display(dssdev);
+ if (r) {
+ DSSERR("device %s init failed: %d\n", dssdev->name, r);
+ continue;
+ }
+
r = omap_dss_register_device(dssdev, &pdev->dev);
if (r)
DSSERR("device %s register failed: %d\n",
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index 0ff1e63..49b83a4 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -4456,7 +4456,7 @@ int omapdss_dsi_enable_te(struct omap_dss_device *dssdev, bool enable)
}
EXPORT_SYMBOL(omapdss_dsi_enable_te);
-int dsi_init_display(struct omap_dss_device *dssdev)
+static int __init dsi_init_display(struct omap_dss_device *dssdev)
{
struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
@@ -4712,6 +4712,12 @@ static int __init omap_dsihw_probe(struct platform_device *dsidev)
if (dssdev->phy.dsi.module != dsi_module)
continue;
+ r = dsi_init_display(dssdev);
+ if (r) {
+ DSSERR("device %s init failed: %d\n", dssdev->name, r);
+ continue;
+ }
+
r = omap_dss_register_device(dssdev, &dsidev->dev);
if (r)
DSSERR("device %s register failed: %d\n",
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 828f669..c0a1532 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -270,7 +270,6 @@ int dss_calc_clock_div(bool is_tft, unsigned long req_pck,
/* SDI */
int sdi_init_platform_driver(void) __init;
void sdi_uninit_platform_driver(void) __exit;
-int sdi_init_display(struct omap_dss_device *display);
/* DSI */
#ifdef CONFIG_OMAP2_DSS_DSI
@@ -286,7 +285,6 @@ void dsi_runtime_put(struct platform_device *dsidev);
void dsi_dump_clocks(struct seq_file *s);
-int dsi_init_display(struct omap_dss_device *display);
void dsi_irq_handler(void);
u8 dsi_get_pixel_size(enum omap_dss_dsi_pixel_format fmt);
@@ -361,7 +359,6 @@ static inline struct platform_device *dsi_get_dsidev_from_id(int module)
/* DPI */
int dpi_init_platform_driver(void) __init;
void dpi_uninit_platform_driver(void) __exit;
-int dpi_init_display(struct omap_dss_device *dssdev);
/* DISPC */
int dispc_init_platform_driver(void) __init;
@@ -432,7 +429,6 @@ void dispc_mgr_setup(enum omap_channel channel,
#ifdef CONFIG_OMAP2_DSS_VENC
int venc_init_platform_driver(void) __init;
void venc_uninit_platform_driver(void) __exit;
-int venc_init_display(struct omap_dss_device *display);
unsigned long venc_get_pixel_clock(void);
#else
static inline unsigned long venc_get_pixel_clock(void)
@@ -446,13 +442,8 @@ static inline unsigned long venc_get_pixel_clock(void)
#ifdef CONFIG_OMAP4_DSS_HDMI
int hdmi_init_platform_driver(void) __init;
void hdmi_uninit_platform_driver(void) __exit;
-int hdmi_init_display(struct omap_dss_device *dssdev);
unsigned long hdmi_get_pixel_clock(void);
#else
-static inline int hdmi_init_display(struct omap_dss_device *dssdev)
-{
- return 0;
-}
static inline unsigned long hdmi_get_pixel_clock(void)
{
WARN("%s: HDMI not compiled in, returning pclk as 0\n", __func__);
@@ -472,7 +463,6 @@ void hdmi_panel_exit(void);
/* RFBI */
int rfbi_init_platform_driver(void) __init;
void rfbi_uninit_platform_driver(void) __exit;
-int rfbi_init_display(struct omap_dss_device *display);
#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index 28ce057..8b3ac6e 100644
--- a/drivers/video/omap2/dss/hdmi.c
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -147,7 +147,7 @@ static void hdmi_runtime_put(void)
WARN_ON(r < 0);
}
-int hdmi_init_display(struct omap_dss_device *dssdev)
+static int __init hdmi_init_display(struct omap_dss_device *dssdev)
{
DSSDBG("init_display\n");
@@ -817,6 +817,12 @@ static int __init omapdss_hdmihw_probe(struct platform_device *pdev)
if (dssdev->type != OMAP_DISPLAY_TYPE_HDMI)
continue;
+ r = hdmi_init_display(dssdev);
+ if (r) {
+ DSSERR("device %s init failed: %d\n", dssdev->name, r);
+ continue;
+ }
+
r = omap_dss_register_device(dssdev, &pdev->dev);
if (r)
DSSERR("device %s register failed: %d\n",
diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/omap2/dss/rfbi.c
index d0d24a0..a5d38a3 100644
--- a/drivers/video/omap2/dss/rfbi.c
+++ b/drivers/video/omap2/dss/rfbi.c
@@ -920,7 +920,7 @@ void omapdss_rfbi_display_disable(struct omap_dss_device *dssdev)
}
EXPORT_SYMBOL(omapdss_rfbi_display_disable);
-int rfbi_init_display(struct omap_dss_device *dssdev)
+static int __init rfbi_init_display(struct omap_dss_device *dssdev)
{
rfbi.dssdev[dssdev->phy.rfbi.channel] = dssdev;
dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE;
@@ -985,6 +985,12 @@ static int __init omap_rfbihw_probe(struct platform_device *pdev)
if (dssdev->type != OMAP_DISPLAY_TYPE_DBI)
continue;
+ r = rfbi_init_display(dssdev);
+ if (r) {
+ DSSERR("device %s init failed: %d\n", dssdev->name, r);
+ continue;
+ }
+
r = omap_dss_register_device(dssdev, &pdev->dev);
if (r)
DSSERR("device %s register failed: %d\n",
diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/omap2/dss/sdi.c
index bf48fb4..5d0785b 100644
--- a/drivers/video/omap2/dss/sdi.c
+++ b/drivers/video/omap2/dss/sdi.c
@@ -156,7 +156,7 @@ void omapdss_sdi_display_disable(struct omap_dss_device *dssdev)
}
EXPORT_SYMBOL(omapdss_sdi_display_disable);
-int sdi_init_display(struct omap_dss_device *dssdev)
+static int __init sdi_init_display(struct omap_dss_device *dssdev)
{
DSSDBG("SDI init\n");
@@ -187,6 +187,12 @@ static int __init omap_sdi_probe(struct platform_device *pdev)
if (dssdev->type != OMAP_DISPLAY_TYPE_SDI)
continue;
+ r = sdi_init_display(dssdev);
+ if (r) {
+ DSSERR("device %s init failed: %d\n", dssdev->name, r);
+ continue;
+ }
+
r = omap_dss_register_device(dssdev, &pdev->dev);
if (r)
DSSERR("device %s register failed: %d\n",
diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c
index 646903a..4d3128a 100644
--- a/drivers/video/omap2/dss/venc.c
+++ b/drivers/video/omap2/dss/venc.c
@@ -673,7 +673,7 @@ static struct omap_dss_driver venc_driver = {
};
/* driver end */
-int venc_init_display(struct omap_dss_device *dssdev)
+static int __init venc_init_display(struct omap_dss_device *dssdev)
{
DSSDBG("init_display\n");
@@ -831,6 +831,12 @@ static int __init omap_venchw_probe(struct platform_device *pdev)
if (dssdev->type != OMAP_DISPLAY_TYPE_VENC)
continue;
+ r = venc_init_display(dssdev);
+ if (r) {
+ DSSERR("device %s init failed: %d\n", dssdev->name, r);
+ continue;
+ }
+
r = omap_dss_register_device(dssdev, &pdev->dev);
if (r)
DSSERR("device %s register failed: %d\n",
--
1.7.9.5
^ permalink raw reply related
* [PATCH 23/25] OMAPDSS: DSI: implement generic DSI pin config
From: Tomi Valkeinen @ 2012-05-03 13:57 UTC (permalink / raw)
To: linux-omap, linux-fbdev; +Cc: archit, Tomi Valkeinen
In-Reply-To: <1336053481-25433-1-git-send-email-tomi.valkeinen@ti.com>
In preparation for device tree, this patch changes how the DSI pins are
configured. The current configuration method is only doable with board
files and the configuration data is OMAP specific.
This patch moves the configuration data to the panel's platform data,
and the data can easily be given via DT in the future. The configuration
data format is also changed to a generic one which should be suitable
for all platforms.
The new format is an array of pin numbers, where the array items start
from clock + and -, then data1 + and -, and so on. For example:
{
0, // pin num for clock lane +
1, // pin num for clock lane -
2, // pin num for data1 lane +
3, // pin num for data1 lane -
...
}
The pin numbers are translated by the DSI driver and used to configure
the hardware appropriately.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
arch/arm/mach-omap2/board-4430sdp.c | 21 ++---
drivers/video/omap2/displays/panel-taal.c | 7 ++
drivers/video/omap2/dss/dsi.c | 133 +++++++++++++++--------------
include/video/omap-panel-nokia-dsi.h | 3 +
include/video/omapdss.h | 28 +++---
5 files changed, 103 insertions(+), 89 deletions(-)
diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c
index 6cbb16f..b4ad706 100644
--- a/arch/arm/mach-omap2/board-4430sdp.c
+++ b/arch/arm/mach-omap2/board-4430sdp.c
@@ -666,6 +666,10 @@ static struct nokia_dsi_panel_data dsi1_panel = {
.use_ext_te = false,
.ext_te_gpio = 101,
.esd_interval = 0,
+ .pin_config = {
+ .num_pins = 6,
+ .pins = { 0, 1, 2, 3, 4, 5 },
+ },
};
static struct omap_dss_device sdp4430_lcd_device = {
@@ -674,13 +678,6 @@ static struct omap_dss_device sdp4430_lcd_device = {
.type = OMAP_DISPLAY_TYPE_DSI,
.data = &dsi1_panel,
.phy.dsi = {
- .clk_lane = 1,
- .clk_pol = 0,
- .data1_lane = 2,
- .data1_pol = 0,
- .data2_lane = 3,
- .data2_pol = 0,
-
.module = 0,
},
@@ -715,6 +712,10 @@ static struct nokia_dsi_panel_data dsi2_panel = {
.use_ext_te = false,
.ext_te_gpio = 103,
.esd_interval = 0,
+ .pin_config = {
+ .num_pins = 6,
+ .pins = { 0, 1, 2, 3, 4, 5 },
+ },
};
static struct omap_dss_device sdp4430_lcd2_device = {
@@ -723,12 +724,6 @@ static struct omap_dss_device sdp4430_lcd2_device = {
.type = OMAP_DISPLAY_TYPE_DSI,
.data = &dsi2_panel,
.phy.dsi = {
- .clk_lane = 1,
- .clk_pol = 0,
- .data1_lane = 2,
- .data1_pol = 0,
- .data2_lane = 3,
- .data2_pol = 0,
.module = 1,
},
diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c
index be9992f..2ce9992 100644
--- a/drivers/video/omap2/displays/panel-taal.c
+++ b/drivers/video/omap2/displays/panel-taal.c
@@ -1051,9 +1051,16 @@ static void __exit taal_remove(struct omap_dss_device *dssdev)
static int taal_power_on(struct omap_dss_device *dssdev)
{
struct taal_data *td = dev_get_drvdata(&dssdev->dev);
+ struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
u8 id1, id2, id3;
int r;
+ r = omapdss_dsi_configure_pins(dssdev, &panel_data->pin_config);
+ if (r) {
+ dev_err(&dssdev->dev, "failed to configure DSI pins\n");
+ goto err0;
+ };
+
r = omapdss_dsi_display_enable(dssdev);
if (r) {
dev_err(&dssdev->dev, "failed to enable DSI\n");
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index 49b83a4..6cc92a8 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -2011,65 +2011,6 @@ static unsigned dsi_get_line_buf_size(struct platform_device *dsidev)
}
}
-static int dsi_parse_lane_config(struct omap_dss_device *dssdev)
-{
- struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
- struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
- u8 lanes[DSI_MAX_NR_LANES];
- u8 polarities[DSI_MAX_NR_LANES];
- int num_lanes, i;
-
- static const enum dsi_lane_function functions[] = {
- DSI_LANE_CLK,
- DSI_LANE_DATA1,
- DSI_LANE_DATA2,
- DSI_LANE_DATA3,
- DSI_LANE_DATA4,
- };
-
- lanes[0] = dssdev->phy.dsi.clk_lane;
- lanes[1] = dssdev->phy.dsi.data1_lane;
- lanes[2] = dssdev->phy.dsi.data2_lane;
- lanes[3] = dssdev->phy.dsi.data3_lane;
- lanes[4] = dssdev->phy.dsi.data4_lane;
- polarities[0] = dssdev->phy.dsi.clk_pol;
- polarities[1] = dssdev->phy.dsi.data1_pol;
- polarities[2] = dssdev->phy.dsi.data2_pol;
- polarities[3] = dssdev->phy.dsi.data3_pol;
- polarities[4] = dssdev->phy.dsi.data4_pol;
-
- num_lanes = 0;
-
- for (i = 0; i < dsi->num_lanes_supported; ++i)
- dsi->lanes[i].function = DSI_LANE_UNUSED;
-
- for (i = 0; i < dsi->num_lanes_supported; ++i) {
- int num;
-
- if (lanes[i] = DSI_LANE_UNUSED)
- break;
-
- num = lanes[i] - 1;
-
- if (num >= dsi->num_lanes_supported)
- return -EINVAL;
-
- if (dsi->lanes[num].function != DSI_LANE_UNUSED)
- return -EINVAL;
-
- dsi->lanes[num].function = functions[i];
- dsi->lanes[num].polarity = polarities[i];
- num_lanes++;
- }
-
- if (num_lanes < 2 || num_lanes > dsi->num_lanes_supported)
- return -EINVAL;
-
- dsi->num_lanes_used = num_lanes;
-
- return 0;
-}
-
static int dsi_set_lane_config(struct omap_dss_device *dssdev)
{
struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
@@ -3909,6 +3850,74 @@ static void dsi_proto_timings(struct omap_dss_device *dssdev)
}
}
+int omapdss_dsi_configure_pins(struct omap_dss_device *dssdev,
+ const struct omap_dsi_pin_config *pin_cfg)
+{
+ struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+ struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
+ int num_pins;
+ const int *pins;
+ struct dsi_lane_config lanes[DSI_MAX_NR_LANES];
+ int num_lanes;
+ int i;
+
+ static const enum dsi_lane_function functions[] = {
+ DSI_LANE_CLK,
+ DSI_LANE_DATA1,
+ DSI_LANE_DATA2,
+ DSI_LANE_DATA3,
+ DSI_LANE_DATA4,
+ };
+
+ num_pins = pin_cfg->num_pins;
+ pins = pin_cfg->pins;
+
+ if (num_pins < 4 || num_pins > dsi->num_lanes_supported * 2
+ || num_pins % 2 != 0)
+ return -EINVAL;
+
+ for (i = 0; i < DSI_MAX_NR_LANES; ++i)
+ lanes[i].function = DSI_LANE_UNUSED;
+
+ num_lanes = 0;
+
+ for (i = 0; i < num_pins; i += 2) {
+ u8 lane, pol;
+ int dx, dy;
+
+ dx = pins[i];
+ dy = pins[i + 1];
+
+ if (dx < 0 || dx >= dsi->num_lanes_supported * 2)
+ return -EINVAL;
+
+ if (dy < 0 || dy >= dsi->num_lanes_supported * 2)
+ return -EINVAL;
+
+ if (dx & 1) {
+ if (dy != dx - 1)
+ return -EINVAL;
+ pol = 1;
+ } else {
+ if (dy != dx + 1)
+ return -EINVAL;
+ pol = 0;
+ }
+
+ lane = dx / 2;
+
+ lanes[lane].function = functions[i / 2];
+ lanes[lane].polarity = pol;
+ num_lanes++;
+ }
+
+ memcpy(dsi->lanes, lanes, sizeof(dsi->lanes));
+ dsi->num_lanes_used = num_lanes;
+
+ return 0;
+}
+EXPORT_SYMBOL(omapdss_dsi_configure_pins);
+
int dsi_enable_video_output(struct omap_dss_device *dssdev, int channel)
{
struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
@@ -4271,12 +4280,6 @@ static int dsi_display_init_dsi(struct omap_dss_device *dssdev)
int dsi_module = dsi_get_dsidev_id(dsidev);
int r;
- r = dsi_parse_lane_config(dssdev);
- if (r) {
- DSSERR("illegal lane config");
- goto err0;
- }
-
r = dsi_pll_init(dsidev, true, true);
if (r)
goto err0;
diff --git a/include/video/omap-panel-nokia-dsi.h b/include/video/omap-panel-nokia-dsi.h
index 7dc71f9..04219a2 100644
--- a/include/video/omap-panel-nokia-dsi.h
+++ b/include/video/omap-panel-nokia-dsi.h
@@ -11,6 +11,7 @@ struct omap_dss_device;
* @esd_interval: interval of ESD checks, 0 = disabled (ms)
* @ulps_timeout: time to wait before entering ULPS, 0 = disabled (ms)
* @use_dsi_backlight: true if panel uses DSI command to control backlight
+ * @pin_config: DSI pin configuration
*/
struct nokia_dsi_panel_data {
const char *name;
@@ -24,6 +25,8 @@ struct nokia_dsi_panel_data {
unsigned ulps_timeout;
bool use_dsi_backlight;
+
+ struct omap_dsi_pin_config pin_config;
};
#endif /* __OMAP_NOKIA_DSI_PANEL_H */
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index 49e7073..1217df4 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -464,6 +464,21 @@ struct omap_overlay_manager {
int (*wait_for_vsync)(struct omap_overlay_manager *mgr);
};
+/* 22 pins means 1 clk lane and 10 data lanes */
+#define OMAP_DSS_MAX_DSI_PINS 22
+
+struct omap_dsi_pin_config {
+ int num_pins;
+ /*
+ * pin numbers in the following order:
+ * clk+, clk-
+ * data1+, data1-
+ * data2+, data2-
+ * ...
+ */
+ int pins[OMAP_DSS_MAX_DSI_PINS];
+};
+
struct omap_dss_device {
struct device dev;
@@ -486,17 +501,6 @@ struct omap_dss_device {
} sdi;
struct {
- u8 clk_lane;
- u8 clk_pol;
- u8 data1_lane;
- u8 data1_pol;
- u8 data2_lane;
- u8 data2_pol;
- u8 data3_lane;
- u8 data3_pol;
- u8 data4_lane;
- u8 data4_pol;
-
int module;
bool ext_te;
@@ -685,6 +689,8 @@ int omap_dsi_update(struct omap_dss_device *dssdev, int channel,
int omap_dsi_request_vc(struct omap_dss_device *dssdev, int *channel);
int omap_dsi_set_vc_id(struct omap_dss_device *dssdev, int channel, int vc_id);
void omap_dsi_release_vc(struct omap_dss_device *dssdev, int channel);
+int omapdss_dsi_configure_pins(struct omap_dss_device *dssdev,
+ const struct omap_dsi_pin_config *pin_cfg);
int omapdss_dsi_display_enable(struct omap_dss_device *dssdev);
void omapdss_dsi_display_disable(struct omap_dss_device *dssdev,
--
1.7.9.5
^ permalink raw reply related
* [PATCH 24/25] OMAPDSS: DSI: improve DSI module id handling
From: Tomi Valkeinen @ 2012-05-03 13:58 UTC (permalink / raw)
To: linux-omap, linux-fbdev; +Cc: archit, Tomi Valkeinen
In-Reply-To: <1336053481-25433-1-git-send-email-tomi.valkeinen@ti.com>
We currently use the id of the dsi platform device (dsidev->id) as the
DSI hardware module ID. This works because we assign the ID manually in
arch/arm/mach-omap2/display.c at boot time.
However, with device tree the platform device IDs are automatically
assigned to an arbitrary number, and we can't use it.
Instead of using dsidev->id during operation, this patch stores the
value of dsidev->id to a private field of the dsi driver at probe(). The
future device tree code can thus set the private field with some other
way.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/dsi.c | 46 +++++++++++++++++++----------------------
1 file changed, 21 insertions(+), 25 deletions(-)
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index 6cc92a8..ce964dd 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -256,6 +256,8 @@ struct dsi_data {
struct platform_device *pdev;
void __iomem *base;
+ int module_id;
+
int irq;
struct clk *dss_clk;
@@ -358,11 +360,6 @@ struct platform_device *dsi_get_dsidev_from_id(int module)
return dsi_pdev_map[module];
}
-static inline int dsi_get_dsidev_id(struct platform_device *dsidev)
-{
- return dsidev->id;
-}
-
static inline void dsi_write_reg(struct platform_device *dsidev,
const struct dsi_reg idx, u32 val)
{
@@ -1181,10 +1178,9 @@ static unsigned long dsi_get_txbyteclkhs(struct platform_device *dsidev)
static unsigned long dsi_fclk_rate(struct platform_device *dsidev)
{
unsigned long r;
- int dsi_module = dsi_get_dsidev_id(dsidev);
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
- if (dss_get_dsi_clk_source(dsi_module) = OMAP_DSS_CLK_SRC_FCK) {
+ if (dss_get_dsi_clk_source(dsi->module_id) = OMAP_DSS_CLK_SRC_FCK) {
/* DSI FCLK source is DSS_CLK_FCK */
r = clk_get_rate(dsi->dss_clk);
} else {
@@ -1683,7 +1679,7 @@ static void dsi_dump_dsidev_clocks(struct platform_device *dsidev,
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
struct dsi_clock_info *cinfo = &dsi->current_cinfo;
enum omap_dss_clk_source dispc_clk_src, dsi_clk_src;
- int dsi_module = dsi_get_dsidev_id(dsidev);
+ int dsi_module = dsi->module_id;
dispc_clk_src = dss_get_dispc_clk_source();
dsi_clk_src = dss_get_dsi_clk_source(dsi_module);
@@ -1755,7 +1751,6 @@ static void dsi_dump_dsidev_irqs(struct platform_device *dsidev,
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
unsigned long flags;
struct dsi_irq_stats stats;
- int dsi_module = dsi_get_dsidev_id(dsidev);
spin_lock_irqsave(&dsi->irq_stats_lock, flags);
@@ -1772,7 +1767,7 @@ static void dsi_dump_dsidev_irqs(struct platform_device *dsidev,
#define PIS(x) \
seq_printf(s, "%-20s %10d\n", #x, stats.dsi_irqs[ffs(DSI_IRQ_##x)-1]);
- seq_printf(s, "-- DSI%d interrupts --\n", dsi_module + 1);
+ seq_printf(s, "-- DSI%d interrupts --\n", dsi->module_id + 1);
PIS(VC0);
PIS(VC1);
PIS(VC2);
@@ -2272,7 +2267,7 @@ static int dsi_cio_init(struct omap_dss_device *dssdev)
DSSDBGF();
- r = dss_dsi_enable_pads(dsi_get_dsidev_id(dsidev), dsi_get_lane_mask(dssdev));
+ r = dss_dsi_enable_pads(dsi->module_id, dsi_get_lane_mask(dssdev));
if (r)
return r;
@@ -2382,20 +2377,21 @@ err_cio_pwr:
dsi_cio_disable_lane_override(dsidev);
err_scp_clk_dom:
dsi_disable_scp_clk(dsidev);
- dss_dsi_disable_pads(dsi_get_dsidev_id(dsidev), dsi_get_lane_mask(dssdev));
+ dss_dsi_disable_pads(dsi->module_id, dsi_get_lane_mask(dssdev));
return r;
}
static void dsi_cio_uninit(struct omap_dss_device *dssdev)
{
struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+ struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
/* DDR_CLK_ALWAYS_ON */
REG_FLD_MOD(dsidev, DSI_CLK_CTRL, 0, 13, 13);
dsi_cio_power(dsidev, DSI_COMPLEXIO_POWER_OFF);
dsi_disable_scp_clk(dsidev);
- dss_dsi_disable_pads(dsi_get_dsidev_id(dsidev), dsi_get_lane_mask(dssdev));
+ dss_dsi_disable_pads(dsi->module_id, dsi_get_lane_mask(dssdev));
}
static void dsi_config_tx_fifo(struct platform_device *dsidev,
@@ -4277,7 +4273,7 @@ static int dsi_configure_dispc_clocks(struct omap_dss_device *dssdev)
static int dsi_display_init_dsi(struct omap_dss_device *dssdev)
{
struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
- int dsi_module = dsi_get_dsidev_id(dsidev);
+ struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
int r;
r = dsi_pll_init(dsidev, true, true);
@@ -4289,7 +4285,7 @@ static int dsi_display_init_dsi(struct omap_dss_device *dssdev)
goto err1;
dss_select_dispc_clk_source(dssdev->clocks.dispc.dispc_fclk_src);
- dss_select_dsi_clk_source(dsi_module, dssdev->clocks.dsi.dsi_fclk_src);
+ dss_select_dsi_clk_source(dsi->module_id, dssdev->clocks.dsi.dsi_fclk_src);
dss_select_lcd_clk_source(dssdev->manager->id,
dssdev->clocks.dispc.channel.lcd_clk_src);
@@ -4328,7 +4324,7 @@ err3:
dsi_cio_uninit(dssdev);
err2:
dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK);
- dss_select_dsi_clk_source(dsi_module, OMAP_DSS_CLK_SRC_FCK);
+ dss_select_dsi_clk_source(dsi->module_id, OMAP_DSS_CLK_SRC_FCK);
dss_select_lcd_clk_source(dssdev->manager->id, OMAP_DSS_CLK_SRC_FCK);
err1:
@@ -4342,7 +4338,6 @@ static void dsi_display_uninit_dsi(struct omap_dss_device *dssdev,
{
struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
- int dsi_module = dsi_get_dsidev_id(dsidev);
if (enter_ulps && !dsi->ulps_enabled)
dsi_enter_ulps(dsidev);
@@ -4355,7 +4350,7 @@ static void dsi_display_uninit_dsi(struct omap_dss_device *dssdev,
dsi_vc_enable(dsidev, 3, 0);
dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK);
- dss_select_dsi_clk_source(dsi_module, OMAP_DSS_CLK_SRC_FCK);
+ dss_select_dsi_clk_source(dsi->module_id, OMAP_DSS_CLK_SRC_FCK);
dss_select_lcd_clk_source(dssdev->manager->id, OMAP_DSS_CLK_SRC_FCK);
dsi_cio_uninit(dssdev);
dsi_pll_uninit(dsidev, disconnect_lanes);
@@ -4616,7 +4611,7 @@ static void dsi_put_clocks(struct platform_device *dsidev)
static int __init omap_dsihw_probe(struct platform_device *dsidev)
{
u32 rev;
- int r, i, dsi_module = dsi_get_dsidev_id(dsidev);
+ int r, i;
struct resource *dsi_mem;
struct dsi_data *dsi;
struct omap_dss_board_info *pdata = dsidev->dev.platform_data;
@@ -4625,8 +4620,9 @@ static int __init omap_dsihw_probe(struct platform_device *dsidev)
if (!dsi)
return -ENOMEM;
+ dsi->module_id = dsidev->id;
dsi->pdev = dsidev;
- dsi_pdev_map[dsi_module] = dsidev;
+ dsi_pdev_map[dsi->module_id] = dsidev;
dev_set_drvdata(&dsidev->dev, dsi);
spin_lock_init(&dsi->irq_lock);
@@ -4712,7 +4708,7 @@ static int __init omap_dsihw_probe(struct platform_device *dsidev)
if (dssdev->type != OMAP_DISPLAY_TYPE_DSI)
continue;
- if (dssdev->phy.dsi.module != dsi_module)
+ if (dssdev->phy.dsi.module != dsi->module_id)
continue;
r = dsi_init_display(dssdev);
@@ -4729,15 +4725,15 @@ static int __init omap_dsihw_probe(struct platform_device *dsidev)
dsi_runtime_put(dsidev);
- if (dsi_module = 0)
+ if (dsi->module_id = 0)
dss_debugfs_create_file("dsi1_regs", dsi1_dump_regs);
- else if (dsi_module = 1)
+ else if (dsi->module_id = 1)
dss_debugfs_create_file("dsi2_regs", dsi2_dump_regs);
#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
- if (dsi_module = 0)
+ if (dsi->module_id = 0)
dss_debugfs_create_file("dsi1_irqs", dsi1_dump_irqs);
- else if (dsi_module = 1)
+ else if (dsi->module_id = 1)
dss_debugfs_create_file("dsi2_irqs", dsi2_dump_irqs);
#endif
return 0;
--
1.7.9.5
^ permalink raw reply related
* [PATCH 25/25] OMAPDSS: separate pdata based initialization
From: Tomi Valkeinen @ 2012-05-03 13:58 UTC (permalink / raw)
To: linux-omap, linux-fbdev; +Cc: archit, Tomi Valkeinen
In-Reply-To: <1336053481-25433-1-git-send-email-tomi.valkeinen@ti.com>
Move the platform-data based display device initialization into a
separate function, so that we may later add of-based initialization.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/dpi.c | 7 +++++-
drivers/video/omap2/dss/dsi.c | 50 +++++++++++++++++++++++-----------------
drivers/video/omap2/dss/hdmi.c | 46 +++++++++++++++++++++---------------
drivers/video/omap2/dss/rfbi.c | 45 +++++++++++++++++++++---------------
drivers/video/omap2/dss/sdi.c | 7 +++++-
drivers/video/omap2/dss/venc.c | 45 +++++++++++++++++++++---------------
6 files changed, 120 insertions(+), 80 deletions(-)
diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c
index 4f8defe..835e106 100644
--- a/drivers/video/omap2/dss/dpi.c
+++ b/drivers/video/omap2/dss/dpi.c
@@ -364,7 +364,7 @@ static int __init dpi_init_display(struct omap_dss_device *dssdev)
return 0;
}
-static int __init omap_dpi_probe(struct platform_device *pdev)
+static void __init dpi_probe_pdata(struct platform_device *pdev)
{
struct omap_dss_board_info *pdata = pdev->dev.platform_data;
int i, r;
@@ -386,6 +386,11 @@ static int __init omap_dpi_probe(struct platform_device *pdev)
DSSERR("device %s register failed: %d\n",
dssdev->name, r);
}
+}
+
+static int __init omap_dpi_probe(struct platform_device *pdev)
+{
+ dpi_probe_pdata(pdev);
return 0;
}
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index ce964dd..429d918 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -4607,6 +4607,34 @@ static void dsi_put_clocks(struct platform_device *dsidev)
clk_put(dsi->sys_clk);
}
+static void __init dsi_probe_pdata(struct platform_device *dsidev)
+{
+ struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
+ struct omap_dss_board_info *pdata = dsidev->dev.platform_data;
+ int i, r;
+
+ for (i = 0; i < pdata->num_devices; ++i) {
+ struct omap_dss_device *dssdev = pdata->devices[i];
+
+ if (dssdev->type != OMAP_DISPLAY_TYPE_DSI)
+ continue;
+
+ if (dssdev->phy.dsi.module != dsi->module_id)
+ continue;
+
+ r = dsi_init_display(dssdev);
+ if (r) {
+ DSSERR("device %s init failed: %d\n", dssdev->name, r);
+ continue;
+ }
+
+ r = omap_dss_register_device(dssdev, &dsidev->dev);
+ if (r)
+ DSSERR("device %s register failed: %d\n",
+ dssdev->name, r);
+ }
+}
+
/* DSI1 HW IP initialisation */
static int __init omap_dsihw_probe(struct platform_device *dsidev)
{
@@ -4614,7 +4642,6 @@ static int __init omap_dsihw_probe(struct platform_device *dsidev)
int r, i;
struct resource *dsi_mem;
struct dsi_data *dsi;
- struct omap_dss_board_info *pdata = dsidev->dev.platform_data;
dsi = devm_kzalloc(&dsidev->dev, sizeof(*dsi), GFP_KERNEL);
if (!dsi)
@@ -4702,26 +4729,7 @@ static int __init omap_dsihw_probe(struct platform_device *dsidev)
else
dsi->num_lanes_supported = 3;
- for (i = 0; i < pdata->num_devices; ++i) {
- struct omap_dss_device *dssdev = pdata->devices[i];
-
- if (dssdev->type != OMAP_DISPLAY_TYPE_DSI)
- continue;
-
- if (dssdev->phy.dsi.module != dsi->module_id)
- continue;
-
- r = dsi_init_display(dssdev);
- if (r) {
- DSSERR("device %s init failed: %d\n", dssdev->name, r);
- continue;
- }
-
- r = omap_dss_register_device(dssdev, &dsidev->dev);
- if (r)
- DSSERR("device %s register failed: %d\n",
- dssdev->name, r);
- }
+ dsi_probe_pdata(dsidev);
dsi_runtime_put(dsidev);
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index 8b3ac6e..1b06df2 100644
--- a/drivers/video/omap2/dss/hdmi.c
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -769,12 +769,36 @@ static void hdmi_put_clocks(void)
clk_put(hdmi.sys_clk);
}
+static void __init hdmi_probe_pdata(struct platform_device *pdev)
+{
+ struct omap_dss_board_info *pdata = pdev->dev.platform_data;
+ int r, i;
+
+ for (i = 0; i < pdata->num_devices; ++i) {
+ struct omap_dss_device *dssdev = pdata->devices[i];
+ struct omap_dss_hdmi_data *priv = dssdev->data;
+
+ if (dssdev->type != OMAP_DISPLAY_TYPE_HDMI)
+ continue;
+
+ r = hdmi_init_display(dssdev);
+ if (r) {
+ DSSERR("device %s init failed: %d\n", dssdev->name, r);
+ continue;
+ }
+
+ r = omap_dss_register_device(dssdev, &pdev->dev);
+ if (r)
+ DSSERR("device %s register failed: %d\n",
+ dssdev->name, r);
+ }
+}
+
/* HDMI HW IP initialisation */
static int __init omapdss_hdmihw_probe(struct platform_device *pdev)
{
- struct omap_dss_board_info *pdata = pdev->dev.platform_data;
struct resource *hdmi_mem;
- int r, i;
+ int r;
hdmi.pdev = pdev;
@@ -811,23 +835,7 @@ static int __init omapdss_hdmihw_probe(struct platform_device *pdev)
dss_debugfs_create_file("hdmi", hdmi_dump_regs);
- for (i = 0; i < pdata->num_devices; ++i) {
- struct omap_dss_device *dssdev = pdata->devices[i];
-
- if (dssdev->type != OMAP_DISPLAY_TYPE_HDMI)
- continue;
-
- r = hdmi_init_display(dssdev);
- if (r) {
- DSSERR("device %s init failed: %d\n", dssdev->name, r);
- continue;
- }
-
- r = omap_dss_register_device(dssdev, &pdev->dev);
- if (r)
- DSSERR("device %s register failed: %d\n",
- dssdev->name, r);
- }
+ hdmi_probe_pdata(pdev);
#if defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI) || \
defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI_MODULE)
diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/omap2/dss/rfbi.c
index a5d38a3..8ea266f 100644
--- a/drivers/video/omap2/dss/rfbi.c
+++ b/drivers/video/omap2/dss/rfbi.c
@@ -927,14 +927,37 @@ static int __init rfbi_init_display(struct omap_dss_device *dssdev)
return 0;
}
+static void __init rfbi_probe_pdata(struct platform_device *pdev)
+{
+ struct omap_dss_board_info *pdata = pdev->dev.platform_data;
+ int i, r;
+
+ for (i = 0; i < pdata->num_devices; ++i) {
+ struct omap_dss_device *dssdev = pdata->devices[i];
+
+ if (dssdev->type != OMAP_DISPLAY_TYPE_DBI)
+ continue;
+
+ r = rfbi_init_display(dssdev);
+ if (r) {
+ DSSERR("device %s init failed: %d\n", dssdev->name, r);
+ continue;
+ }
+
+ r = omap_dss_register_device(dssdev, &pdev->dev);
+ if (r)
+ DSSERR("device %s register failed: %d\n",
+ dssdev->name, r);
+ }
+}
+
/* RFBI HW IP initialisation */
static int __init omap_rfbihw_probe(struct platform_device *pdev)
{
- struct omap_dss_board_info *pdata = pdev->dev.platform_data;
u32 rev;
struct resource *rfbi_mem;
struct clk *clk;
- int r, i;
+ int r;
rfbi.pdev = pdev;
@@ -979,23 +1002,7 @@ static int __init omap_rfbihw_probe(struct platform_device *pdev)
dss_debugfs_create_file("rfbi", rfbi_dump_regs);
- for (i = 0; i < pdata->num_devices; ++i) {
- struct omap_dss_device *dssdev = pdata->devices[i];
-
- if (dssdev->type != OMAP_DISPLAY_TYPE_DBI)
- continue;
-
- r = rfbi_init_display(dssdev);
- if (r) {
- DSSERR("device %s init failed: %d\n", dssdev->name, r);
- continue;
- }
-
- r = omap_dss_register_device(dssdev, &pdev->dev);
- if (r)
- DSSERR("device %s register failed: %d\n",
- dssdev->name, r);
- }
+ rfbi_probe_pdata(pdev);
return 0;
diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/omap2/dss/sdi.c
index 5d0785b..c322335 100644
--- a/drivers/video/omap2/dss/sdi.c
+++ b/drivers/video/omap2/dss/sdi.c
@@ -176,7 +176,7 @@ static int __init sdi_init_display(struct omap_dss_device *dssdev)
return 0;
}
-static int __init omap_sdi_probe(struct platform_device *pdev)
+static void __init sdi_probe_pdata(struct platform_device *pdev)
{
struct omap_dss_board_info *pdata = pdev->dev.platform_data;
int i, r;
@@ -198,6 +198,11 @@ static int __init omap_sdi_probe(struct platform_device *pdev)
DSSERR("device %s register failed: %d\n",
dssdev->name, r);
}
+}
+
+static int __init omap_sdi_probe(struct platform_device *pdev)
+{
+ sdi_probe_pdata(pdev);
return 0;
}
diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c
index 4d3128a..2c0747b 100644
--- a/drivers/video/omap2/dss/venc.c
+++ b/drivers/video/omap2/dss/venc.c
@@ -777,13 +777,36 @@ static void venc_put_clocks(void)
clk_put(venc.tv_dac_clk);
}
+static void __init venc_probe_pdata(struct platform_device *pdev)
+{
+ struct omap_dss_board_info *pdata = pdev->dev.platform_data;
+ int r, i;
+
+ for (i = 0; i < pdata->num_devices; ++i) {
+ struct omap_dss_device *dssdev = pdata->devices[i];
+
+ if (dssdev->type != OMAP_DISPLAY_TYPE_VENC)
+ continue;
+
+ r = venc_init_display(dssdev);
+ if (r) {
+ DSSERR("device %s init failed: %d\n", dssdev->name, r);
+ continue;
+ }
+
+ r = omap_dss_register_device(dssdev, &pdev->dev);
+ if (r)
+ DSSERR("device %s register failed: %d\n",
+ dssdev->name, r);
+ }
+}
+
/* VENC HW IP initialisation */
static int __init omap_venchw_probe(struct platform_device *pdev)
{
- struct omap_dss_board_info *pdata = pdev->dev.platform_data;
u8 rev_id;
struct resource *venc_mem;
- int r, i;
+ int r;
venc.pdev = pdev;
@@ -825,23 +848,7 @@ static int __init omap_venchw_probe(struct platform_device *pdev)
dss_debugfs_create_file("venc", venc_dump_regs);
- for (i = 0; i < pdata->num_devices; ++i) {
- struct omap_dss_device *dssdev = pdata->devices[i];
-
- if (dssdev->type != OMAP_DISPLAY_TYPE_VENC)
- continue;
-
- r = venc_init_display(dssdev);
- if (r) {
- DSSERR("device %s init failed: %d\n", dssdev->name, r);
- continue;
- }
-
- r = omap_dss_register_device(dssdev, &pdev->dev);
- if (r)
- DSSERR("device %s register failed: %d\n",
- dssdev->name, r);
- }
+ venc_probe_pdata(pdev);
return 0;
--
1.7.9.5
^ permalink raw reply related
* Re: [PATCH v2 3/4] leds: add LM3533 LED driver
From: Mark Brown @ 2012-05-03 14:51 UTC (permalink / raw)
To: Johan Hovold
Cc: Rob Landley, Richard Purdie, Samuel Ortiz, Jonathan Cameron,
Greg Kroah-Hartman, Florian Tobias Schandinat, Arnd Bergmann,
Andrew Morton, linux-doc, linux-kernel, linux-iio, devel,
linux-fbdev
In-Reply-To: <20120503115059.GB15752@localhost>
[-- Attachment #1: Type: text/plain, Size: 1560 bytes --]
On Thu, May 03, 2012 at 01:50:59PM +0200, Johan Hovold wrote:
> On Thu, May 03, 2012 at 11:43:44AM +0100, Mark Brown wrote:
> > > + 5 - 4.194 s
> > > + 6 - 8.389 s
> > > + 7 - 16.78 s
> > Shouldn't these be controlled by led_blink_set() rather than a custom
> > ABI?
> led_blink_set controls the on/off times, but the LM3533 has the two
> additional rise and fall-time settings which determine the transition
> time between these states.
Hrm. In that case these rise times are very large - I'd expect them to
cause issues with led_set_blink() users? Though actually I suspect the
solution here is to pull these out into the framework later; we can
probably simulate reasonably in software with a lot of brightness
variable LEDs.
> > > +What: /sys/class/leds/<led>/max_current
> > Shouldn't this be set by platform data, the maximum current you can push
> > through the LEDs seems like a board dependant thing which won't change
> > dynamically at runtime. The brightness can already be varied.
> I fully agree and it is possible to set via the platform data for that
> reason. The end-customer, however, insisted that even this setting be
> available through sysfs to facilitate their integration and testing.
> I'd be willing drop this attribute if requested, as it would only be used
> during integration and could easily be added back by the end-customer if
> needed.
I'd strongly suggest removing this for mainline. If it's present it
should at least be limited to the maximum specified in platform data
(just for safety if nothing else).
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply
* Re: [PATCH v2 1/4] mfd: add LM3533 lighting-power core driver
From: Johan Hovold @ 2012-05-03 15:00 UTC (permalink / raw)
To: Mark Brown
Cc: Rob Landley, Richard Purdie, Samuel Ortiz, Jonathan Cameron,
Greg Kroah-Hartman, Florian Tobias Schandinat, Arnd Bergmann,
Andrew Morton, linux-doc, linux-kernel, linux-iio, devel,
linux-fbdev
In-Reply-To: <20120503113801.GE3955@opensource.wolfsonmicro.com>
On Thu, May 03, 2012 at 12:38:02PM +0100, Mark Brown wrote:
> On Thu, May 03, 2012 at 01:28:03PM +0200, Johan Hovold wrote:
> > On Thu, May 03, 2012 at 11:38:48AM +0100, Mark Brown wrote:
>
> > > I'd expect you can drop these log messages, if there's stuff like this
> > > missing we should add it to regmap. At the minute the regmap logging is
> > > via trace points rather than debug logs as you can leave them enabled
> > > all the time.
>
> > If such debugging is added to regmap we still need a way to enable them
> > per driver (or rather regmap) to not clutter the logs.
>
> This is one of the reasons why we currently use tracepoints (they just
> don't have this issue as they're trivial to filter), though
> adding some sort of infrastructure for it ought not to be too difficult
> even if it's just at the regmap level.
So a /sys/kernel/debug/regmap/<device>/io_printk attribute (with a
better name) to enable debug printks in io paths
(regmap*{read,write,update} outside of mutex) in regmap.c would be
acceptable?
> > These three dev_dbg statements are extremely useful during debugging /
> > development especially in combination with the other dynamic printks in
> > these drivers.
>
> > I'd actually prefer just keeping them for now.
>
> OTOH the whole point in having stuff like this is to factor out repeated
> code like this so if the infrastructure isn't working we should fix
> that.
Ok, I'll drop them if you will consider a regmap patch to enable debug
printks to trace reg/val/mask.
> > > Might also be worth moving some of the sysfs stuff to live with the
> > > relevant drivers.
>
> > Which attributes do you have in mind?
>
> Pretty much all of those on the MFD.
>
> > The boost_freq and boost_ovp affect both backlight devices (i.e. cannot
> > be set separately) and as such belong in the parent driver IMO.
>
> > Same with the output_hvled{1..2}, output_lvled{1..5} attributes. The
> > chip has four logical LEDs ("control banks") but five low-voltage output
> > sinks. The five output_lvled attributes determine the mapping and as
> > such belong in the parent driver. The two logical backlight devices can
> > likewise be used to control either or both high-voltage outputs and
> > belong in the parent driver for the same reasons.
>
> Actually, the other question I had but forgot to ask (or I think punted
> on for your response) was why these are in sysfs at all - things like
> which things are connected to the backlight are going to be a property
> of the board design so should be defined by the machine not tweaked from
> userspace.
I agree with you and the reason is the same as for the max_current
attribute (discussed in the other thread) -- it was an explicit request
from the end customer.
I could replace the boost attributes with a platform_data entry where it
really belongs.
Regarding the output configuration, the chip defaults are probably what
will be used in most cases (i.e. one-one map of logical backlights/leds
and hvled/lvled outputs except for the last led which controls two
outputs). The plan was to add this to the platform data later.
There is a use case (beyond testing/integration) for keeping the (lvled)
outputs configurable from userspace, in that it provides a way to
synchronise LED activity such as blinking. So I still want to keep those,
at least for the lvleds.
Thanks,
Johan
^ permalink raw reply
* Re: [PATCH v2 1/4] mfd: add LM3533 lighting-power core driver
From: Mark Brown @ 2012-05-03 15:24 UTC (permalink / raw)
To: Johan Hovold
Cc: Rob Landley, Richard Purdie, Samuel Ortiz, Jonathan Cameron,
Greg Kroah-Hartman, Florian Tobias Schandinat, Arnd Bergmann,
Andrew Morton, linux-doc, linux-kernel, linux-iio, devel,
linux-fbdev
In-Reply-To: <20120503150040.GC15752@localhost>
[-- Attachment #1: Type: text/plain, Size: 1645 bytes --]
On Thu, May 03, 2012 at 05:00:40PM +0200, Johan Hovold wrote:
> On Thu, May 03, 2012 at 12:38:02PM +0100, Mark Brown wrote:
> > This is one of the reasons why we currently use tracepoints (they just
> > don't have this issue as they're trivial to filter), though
> > adding some sort of infrastructure for it ought not to be too difficult
> > even if it's just at the regmap level.
> So a /sys/kernel/debug/regmap/<device>/io_printk attribute (with a
> better name) to enable debug printks in io paths
> (regmap*{read,write,update} outside of mutex) in regmap.c would be
> acceptable?
Yes, that'd be totally fine for me - it's debugfs so we can always drop
it later if someone comes up with a better idea or something.
> > Actually, the other question I had but forgot to ask (or I think punted
> > on for your response) was why these are in sysfs at all - things like
> > which things are connected to the backlight are going to be a property
> > of the board design so should be defined by the machine not tweaked from
> > userspace.
> I agree with you and the reason is the same as for the max_current
> attribute (discussed in the other thread) -- it was an explicit request
> from the end customer.
> I could replace the boost attributes with a platform_data entry where it
> really belongs.
I really think this is much better for mainline.
> There is a use case (beyond testing/integration) for keeping the (lvled)
> outputs configurable from userspace, in that it provides a way to
> synchronise LED activity such as blinking. So I still want to keep those,
> at least for the lvleds.
I'm not sure exactly which control that is?
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply
* Re: [PATCH v2 2/4] iio: add LM3533 ambient light sensor driver
From: Johan Hovold @ 2012-05-03 16:36 UTC (permalink / raw)
To: Jonathan Cameron
Cc: Rob Landley, Richard Purdie, Samuel Ortiz, Greg Kroah-Hartman,
Florian Tobias Schandinat, Arnd Bergmann, Andrew Morton,
Mark Brown, linux-doc, linux-kernel, linux-iio, devel,
linux-fbdev
In-Reply-To: <4FA26E9A.8080209@cam.ac.uk>
On Thu, May 03, 2012 at 12:40:10PM +0100, Jonathan Cameron wrote:
> On 5/3/2012 11:26 AM, Johan Hovold wrote:
> > Add sub-driver for the ambient light sensor interface on National
> > Semiconductor / TI LM3533 lighting power chips.
> >
> > The sensor interface can be used to control the LEDs and backlights of
> > the chip through defining five light zones and three sets of
> > corresponding brightness target levels.
> >
> > The driver provides raw and mean adc readings along with the current
> > light zone through sysfs. A threshold event can be generated on zone
> > changes.
> Code is fine. Pretty much all my comments are to do with the interface.
[...]
> > diff --git a/drivers/staging/iio/Documentation/sysfs-bus-iio-light-lm3533-als b/drivers/staging/iio/Documentation/sysfs-bus-iio-light-lm3533-als
> > new file mode 100644
> > index 0000000..9849d14
> > --- /dev/null
> > +++ b/drivers/staging/iio/Documentation/sysfs-bus-iio-light-lm3533-als
> > @@ -0,0 +1,62 @@
> > +What: /sys/bus/iio/devices/iio:deviceX/gain
> > +Date: April 2012
> > +KernelVersion: 3.5
> > +Contact: Johan Hovold<jhovold@gmail.com>
> > +Description:
> > + Set the ALS gain-resistor setting (0..127) for analog input
> > + mode, where
> > +
> > + 0000000 - ALS input is high impedance
> > + 0000001 - 200kOhm (10uA at 2V full-scale)
> > + 0000010 - 100kOhm (20uA at 2V full-scale)
> > + ...
> > + 1111110 - 1.587kOhm (1.26mA at 2V full-scale)
> > + 1111111 - 1.575kOhm (1.27mA at 2V full-scale)
> > +
> > + R_als = 2V / (10uA * gain) (gain> 0)
> Firstly, no magic numbers. These are definitely magic.
Not that magic as they're clearly documented (in code and public
datasheets), right? What would you prefer instead?
> Secondly see
> in_illuminance0_scale for a suitable existing attribute.
I didn't consider scale to be appropriate given the following
documentation (e.g, for in_voltageY_scale):
"If known for a device, scale to be applied to <type>Y[_name]_raw post
addition of <type>[Y][_name]_offset in order to obtain the measured
value in <type> units as specified in <type>[Y][_name]_raw
documentation."
That is, the gain setting has nothing to do with scaling the raw adc
reading to SI-units or such, it's simply a setup dependent gain setting
(which affects the raw readings as well). [And as such, should probably
go into to the platform data eventually as well.]
> > +
> > +What: /sys/bus/iio/devices/iio:deviceX/illuminance_zone
> > +Date: April 2012
> > +KernelVersion: 3.5
> > +Contact: Johan Hovold<jhovold@gmail.com>
> > +Description:
> > + Get the current light zone (0..4) as defined by the
> > + in_illuminance_thresh[n]_{falling,rising} thresholds.
> Hmm.. definitely have an in prefix, beyond that I'm not sure what the
> cleanest
Thanks for catching this, it's a typo in the sysfs document -- the in_
prefix is in the code.
> interface will be for this. Could extend the event codes to deal with the
> zone index. Slightly tricky as the channel could already be modified so
> chan2 isn't necesarily available.
>
> > +
> > +What: /sys/.../events/in_illuminance_thresh_either_en
> > +Date: April 2012
> > +KernelVersion: 3.5
> > +Contact: Johan Hovold<jhovold@gmail.com>
> > +Description:
> > + Event generated when channel passes one of the four threshold
> > + in either direction (rising|falling) and a zone change occurs.
> > + The corresponding light zone can be read from
> > + illuminance_zone.
> > +
> > +What: /sys/.../events/illuminance_thresh0_falling_value
> hmm.. every time you think you are making progress a new and exciting
> device comes
> along requiring the abi to be extended.
Exciting isn't it. :)
> in_illuminanceX_threshY_rising_value
> in_illuminanceX_threshY_falling_value
> should do with appropriate description.
Ok.
> > +What: /sys/.../events/illuminance_thresh0_raising_value
> > +What: /sys/.../events/illuminance_thresh1_falling_value
> > +What: /sys/.../events/illuminance_thresh1_raising_value
> > +What: /sys/.../events/illuminance_thresh2_falling_value
> > +What: /sys/.../events/illuminance_thresh2_raising_value
> > +What: /sys/.../events/illuminance_thresh3_falling_value
> > +What: /sys/.../events/illuminance_thresh3_raising_value
> > +Date: April 2012
> > +KernelVersion: 3.5
> > +Contact: Johan Hovold<jhovold@gmail.com>
> > +Description:
> > + Specifies the value of threshold that the device is comparing
> > + against for the events enabled by
> > + in_illuminance_thresh_either_en, and defines the
> > + the five light zones.
> > +
> > + These thresholds correspond to the eight zone-boundary
> > + registers (boundary[n]_{low,high}).
> > +
> This interface is going to take some thought. We have
> in_illuminance0_target at the
> moment, so I guess we can add a zoning concept to that...
But target isn't really related, as far as I understand. That's another
calibration setting right? While zone is derived from the average adc
readings. (More below.)
> > +What: /sys/bus/iio/devices/iio:deviceX/target[m]_[n]
> > +Date: April 2012
> > +KernelVersion: 3.5
> > +Contact: Johan Hovold<jhovold@gmail.com>
> > +Description:
> > + Set the target brightness for ALS-mapper m in light zone n
> > + (0..255), where m in 1..3 and n in 0..4.
> Don't suppose you could do a quick summary of what these zones are and
> why there
> are 3 ALS-mappers? I'm not getting terribly far on a quick look at the
> datasheet!
Of course. The average adc readings are mapped to five light zones using
eight zone boundary registers (4 boundaries with hysteresis) and a set
of rules.
To simplify somewhat (by ignoring some of the rules): If the average
adc input drops below boundary0_low, the zone register reads 0; if it
drops below boundary1_low, it reads 1, and so on. If the input it
increases over boundary3_high, the zone register return 4; if it
increases passed boundary2_high, it returns zone 3, etc.
That is, roughly something like (we get 8-bits of input from the ADC):
zone 0
boundary0_low 51
boundary0_high 53
zone 1
boundary1_low 102
boundary1_high 106
zone 2
boundary2_low 153
boundary2_high 161
zone 3
boundary3_low 204
boundary3_high 220
zone 4
[ Figure 6 on page 20 in the datasheets should make it clear. ]
The ALS interface and it's zone concept can then be used to control the
LEDs and backlights of the chip, by determining the target brightness for
each zone, e.g., set brightness to 52 when in zone 0.
To complicate things further (and it is complicated), there are three
such sets of target brightness values: ALSM1, ALSM2, ALSM3.
So for each LED or backlight you can set ALS-input control mode, by
saying that the device should get it's brightness levels from target set
1, 2, or 3.
[ And it gets even more complicated, as ALSM1 can only control
backlight0, where as ALSM2 and ALSM3 can control any of the remaining
devices, but that's irrelevant here. ]
Initially, I thought this interface to be too esoteric to be worth
generalising, but it sort of fits with event thresholds so I gave it a
try. The biggest conceptual problem, I think, is that the zone
boundaries can be used to control the other devices, even when the event
is not enabled (or even an irq line not configured). That is, I find it
a bit awkward that the event thresholds also defines the zones (a sort of
discrete scaling factor).
Perhaps simply keeping the attributes outside of events (e.g. named
boundary[n]_{low,high}) and having a custom event enabled (e.g.
in_illuminance_zone_change_en) is the best solution?
[...]
> > diff --git a/drivers/staging/iio/light/lm3533-als.c b/drivers/staging/iio/light/lm3533-als.c
> > new file mode 100644
> > index 0000000..e2c9be6
> > --- /dev/null
> > +++ b/drivers/staging/iio/light/lm3533-als.c
> > @@ -0,0 +1,617 @@
> > +/*
> > + * lm3533-als.c -- LM3533 Ambient Light Sensor driver
> > + *
> > + * Copyright (C) 2011-2012 Texas Instruments
> > + *
> > + * Author: Johan Hovold<jhovold@gmail.com>
> > + *
> > + * This program is free software; you can redistribute it and/or modify it
> > + * under the terms of the GNU General Public License as published by the
> > + * Free Software Foundation; either version 2 of the License, or (at your
> > + * option) any later version.
> > + */
> > +
> > +#include<linux/atomic.h>
> > +#include<linux/fs.h>
> > +#include<linux/interrupt.h>
> > +#include<linux/io.h>
> > +#include<linux/module.h>
> > +#include<linux/mfd/core.h>
> > +#include<linux/platform_device.h>
> > +#include<linux/slab.h>
> > +#include<linux/uaccess.h>
> > +
> > +#include<linux/mfd/lm3533.h>
> > +
> > +#include "../events.h"
> > +#include "../iio.h"
> This will need to go through the staging-next tree. In there these
> headers have moved.
I'm aware of the move. Should the different sub-drivers go in through
each tree respectively? Right now the four patches are all against rc5.
[...]
> > +static const struct iio_chan_spec lm3533_als_channels[] = {
> > + {
> > + .type = IIO_LIGHT,
> > + .info_mask = IIO_CHAN_INFO_AVERAGE_RAW_SEPARATE_BIT,
> > + .channel = 0,
> channel doesn't get used unless you also set indexed = 1.
So, you mean I could drop channel as well? Or should I add indexed, as I
use channel 0 when reporting the event?
[...]
> > +static int lm3533_als_set_int_mode(struct iio_dev *indio_dev, int enable)
> > +{
> > + struct lm3533_als *als = iio_priv(indio_dev);
> > + u8 mask = LM3533_ALS_INT_ENABLE_MASK;
> > + u8 val;
> > + int ret;
> > +
> > + if (enable)
> > + val = mask;
> > + else
> > + val = 0;
> > +
> > + ret = lm3533_update(als->lm3533, LM3533_REG_ALS_ZONE_INFO, val, mask);
> > + if (ret) {
> > + dev_err(&indio_dev->dev, "failed to set int mode %d\n",
> > + enable);
> extra brackets.
I prefer the brackets for multi-line (single) statements even though
they are not required. (Especially if the single statement spans
several lines -- but I try to be consistent.) If you have a strong
opinion about this, I'll drop them.
> > + }
> > +
> > + return ret;
> > +}
> > +
Thanks,
Johan
^ permalink raw reply
* Re: [PATCH v2 3/4] leds: add LM3533 LED driver
From: Johan Hovold @ 2012-05-03 16:46 UTC (permalink / raw)
To: Mark Brown
Cc: Rob Landley, Richard Purdie, Samuel Ortiz, Jonathan Cameron,
Greg Kroah-Hartman, Florian Tobias Schandinat, Arnd Bergmann,
Andrew Morton, linux-doc, linux-kernel, linux-iio, devel,
linux-fbdev
In-Reply-To: <20120503145108.GI3955@opensource.wolfsonmicro.com>
On Thu, May 03, 2012 at 03:51:08PM +0100, Mark Brown wrote:
> On Thu, May 03, 2012 at 01:50:59PM +0200, Johan Hovold wrote:
> > On Thu, May 03, 2012 at 11:43:44AM +0100, Mark Brown wrote:
>
> > > > + 5 - 4.194 s
> > > > + 6 - 8.389 s
> > > > + 7 - 16.78 s
>
> > > Shouldn't these be controlled by led_blink_set() rather than a custom
> > > ABI?
>
> > led_blink_set controls the on/off times, but the LM3533 has the two
> > additional rise and fall-time settings which determine the transition
> > time between these states.
>
> Hrm. In that case these rise times are very large - I'd expect them to
> cause issues with led_set_blink() users?
They are. The default settings (as fast a transition as possible) will
probably what most people use, and if they start fiddling with the
transition times they probably know what they're doing.
> Though actually I suspect the
> solution here is to pull these out into the framework later; we can
> probably simulate reasonably in software with a lot of brightness
> variable LEDs.
Ok.
> > > > +What: /sys/class/leds/<led>/max_current
>
> > > Shouldn't this be set by platform data, the maximum current you can push
> > > through the LEDs seems like a board dependant thing which won't change
> > > dynamically at runtime. The brightness can already be varied.
>
> > I fully agree and it is possible to set via the platform data for that
> > reason. The end-customer, however, insisted that even this setting be
> > available through sysfs to facilitate their integration and testing.
>
> > I'd be willing drop this attribute if requested, as it would only be used
> > during integration and could easily be added back by the end-customer if
> > needed.
>
> I'd strongly suggest removing this for mainline. If it's present it
> should at least be limited to the maximum specified in platform data
> (just for safety if nothing else).
Agreed.
Thanks,
Johan
^ permalink raw reply
* Re: [PATCH v2 1/4] mfd: add LM3533 lighting-power core driver
From: Johan Hovold @ 2012-05-03 16:54 UTC (permalink / raw)
To: Mark Brown
Cc: Rob Landley, Richard Purdie, Samuel Ortiz, Jonathan Cameron,
Greg Kroah-Hartman, Florian Tobias Schandinat, Arnd Bergmann,
Andrew Morton, linux-doc, linux-kernel, linux-iio, devel,
linux-fbdev
In-Reply-To: <20120503152407.GK3955@opensource.wolfsonmicro.com>
On Thu, May 03, 2012 at 04:24:07PM +0100, Mark Brown wrote:
> On Thu, May 03, 2012 at 05:00:40PM +0200, Johan Hovold wrote:
> > On Thu, May 03, 2012 at 12:38:02PM +0100, Mark Brown wrote:
>
> > > This is one of the reasons why we currently use tracepoints (they just
> > > don't have this issue as they're trivial to filter), though
> > > adding some sort of infrastructure for it ought not to be too difficult
> > > even if it's just at the regmap level.
>
> > So a /sys/kernel/debug/regmap/<device>/io_printk attribute (with a
> > better name) to enable debug printks in io paths
> > (regmap*{read,write,update} outside of mutex) in regmap.c would be
> > acceptable?
>
> Yes, that'd be totally fine for me - it's debugfs so we can always drop
> it later if someone comes up with a better idea or something.
Ok. I'll have a look at this next week (will be on the road for a few
days), and drop the dev_dbg from the lm3533 io-functions for now.
> > > Actually, the other question I had but forgot to ask (or I think punted
> > > on for your response) was why these are in sysfs at all - things like
> > > which things are connected to the backlight are going to be a property
> > > of the board design so should be defined by the machine not tweaked from
> > > userspace.
>
> > I agree with you and the reason is the same as for the max_current
> > attribute (discussed in the other thread) -- it was an explicit request
> > from the end customer.
>
> > I could replace the boost attributes with a platform_data entry where it
> > really belongs.
>
> I really think this is much better for mainline.
Agreed.
> > There is a use case (beyond testing/integration) for keeping the (lvled)
> > outputs configurable from userspace, in that it provides a way to
> > synchronise LED activity such as blinking. So I still want to keep those,
> > at least for the lvleds.
>
> I'm not sure exactly which control that is?
That would be the output_lvled[n] (n = 1..5) attributes. For example, to
have all five low-voltage sinks blink synchronously, you could assign 0
to all these five attributes, and set a timer trigger for the led device
which has id 0.
Thanks,
Johan
^ permalink raw reply
* Re: [PATCH v2 1/4] mfd: add LM3533 lighting-power core driver
From: Mark Brown @ 2012-05-03 16:57 UTC (permalink / raw)
To: Johan Hovold
Cc: Rob Landley, Richard Purdie, Samuel Ortiz, Jonathan Cameron,
Greg Kroah-Hartman, Florian Tobias Schandinat, Arnd Bergmann,
Andrew Morton, linux-doc, linux-kernel, linux-iio, devel,
linux-fbdev
In-Reply-To: <20120503165437.GF15752@localhost>
[-- Attachment #1: Type: text/plain, Size: 473 bytes --]
On Thu, May 03, 2012 at 06:54:37PM +0200, Johan Hovold wrote:
> On Thu, May 03, 2012 at 04:24:07PM +0100, Mark Brown wrote:
> > I'm not sure exactly which control that is?
> That would be the output_lvled[n] (n = 1..5) attributes. For example, to
> have all five low-voltage sinks blink synchronously, you could assign 0
> to all these five attributes, and set a timer trigger for the led device
> which has id 0.
Sorry, I meant "what exactly does this do in hardware".
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply
* Re: [PATCH v2 1/4] mfd: add LM3533 lighting-power core driver
From: Johan Hovold @ 2012-05-03 17:14 UTC (permalink / raw)
To: Mark Brown
Cc: Rob Landley, Richard Purdie, Samuel Ortiz, Jonathan Cameron,
Greg Kroah-Hartman, Florian Tobias Schandinat, Arnd Bergmann,
Andrew Morton, linux-doc, linux-kernel, linux-iio, devel,
linux-fbdev
In-Reply-To: <20120503165748.GS3955@opensource.wolfsonmicro.com>
On Thu, May 03, 2012 at 05:57:49PM +0100, Mark Brown wrote:
> On Thu, May 03, 2012 at 06:54:37PM +0200, Johan Hovold wrote:
> > On Thu, May 03, 2012 at 04:24:07PM +0100, Mark Brown wrote:
>
> > > I'm not sure exactly which control that is?
>
> > That would be the output_lvled[n] (n = 1..5) attributes. For example, to
> > have all five low-voltage sinks blink synchronously, you could assign 0
> > to all these five attributes, and set a timer trigger for the led device
> > which has id 0.
>
> Sorry, I meant "what exactly does this do in hardware".
From the datasheet (page 14):
"CONTROL BANK MAPPING
Control of the LM3533's current sinks is not done directly, but
through the programming of Control Banks. The current sinks are
then assigned to the programmed Control Bank. This allows for
a wide variety of current control possibilities where LEDs can
be grouped and controlled via specific Control Banks (see
Figure 3)."
It is the control banks that has a brightness settings or can be
programmed to blink, that is, they correspond to the logical LEDs and
backlights.
Assigning a current sink to a control bank corresponds, then, to
setting, for example, output_lvled3 to (led) 1.
[ Figure 3 on page 16 of the data sheet may be instructive. In the
figure, BANK A and B corresponds to the two backlight devices, and
BANK C through F corresponds to the four led devices. Note that there
are more outputs (current sinks) than control banks. ]
Thanks,
Johan
^ permalink raw reply
* Re: [PATCH v2 1/4] mfd: add LM3533 lighting-power core driver
From: Mark Brown @ 2012-05-03 17:23 UTC (permalink / raw)
To: Johan Hovold
Cc: Rob Landley, Richard Purdie, Samuel Ortiz, Jonathan Cameron,
Greg Kroah-Hartman, Florian Tobias Schandinat, Arnd Bergmann,
Andrew Morton, linux-doc, linux-kernel, linux-iio, devel,
linux-fbdev
In-Reply-To: <20120503171402.GG15752@localhost>
[-- Attachment #1: Type: text/plain, Size: 380 bytes --]
On Thu, May 03, 2012 at 07:14:02PM +0200, Johan Hovold wrote:
> Assigning a current sink to a control bank corresponds, then, to
> setting, for example, output_lvled3 to (led) 1.
This seems sensible enough, though it does feel like what we're offering
up to the LED subsystem is relly the LED control banks rather than the
LEDs themselves - or some mix of this and other stuff.
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply
* Re: [PATCH v2 1/4] mfd: add LM3533 lighting-power core driver
From: Johan Hovold @ 2012-05-03 17:31 UTC (permalink / raw)
To: Mark Brown
Cc: Rob Landley, Richard Purdie, Samuel Ortiz, Jonathan Cameron,
Greg Kroah-Hartman, Florian Tobias Schandinat, Arnd Bergmann,
Andrew Morton, linux-doc, linux-kernel, linux-iio, devel,
linux-fbdev
In-Reply-To: <20120503172309.GT3955@opensource.wolfsonmicro.com>
On Thu, May 03, 2012 at 06:23:10PM +0100, Mark Brown wrote:
> On Thu, May 03, 2012 at 07:14:02PM +0200, Johan Hovold wrote:
>
> > Assigning a current sink to a control bank corresponds, then, to
> > setting, for example, output_lvled3 to (led) 1.
>
> This seems sensible enough, though it does feel like what we're offering
> up to the LED subsystem is relly the LED control banks rather than the
> LEDs themselves - or some mix of this and other stuff.
Exactly. That's why I've tried to refer to the led devices as "logical
leds" as they may be connected to more than one output (the physical
leds).
Johan
^ permalink raw reply
* Re: [PATCH] i2c: Split I2C_M_NOSTART support out of I2C_FUNC_PROTOCOL_MANGLING
From: Jean Delvare @ 2012-05-03 18:36 UTC (permalink / raw)
To: Mark Brown
Cc: Florian Tobias Schandinat, Dmitry Torokhov, Wolfram Sang,
linux-i2c-u79uwXL29TY76Z2rM5mHXA,
linux-input-u79uwXL29TY76Z2rM5mHXA,
linux-fbdev-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1336042416-28330-1-git-send-email-broonie-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E@public.gmane.org>
Hi Mark,
On Thu, 3 May 2012 11:53:36 +0100, Mark Brown wrote:
> Since there are uses for I2C_M_NOSTART which are much more sensible and
> standard than most of the protocol mangling functionality (the main one
> being gather writes to devices where something like a register address
> needs to be inserted before a block of data) create a new I2C_FUNC_NOSTART
> for this feature and update all the users to use it.
This is all correct, but it should be documented in
Documentation/i2c/i2c-protocol. At the moment documentation still says
that I2C_M_NOSTART is a weird protocol quirk nobody should be using.
When you update the documentation, I think it is important to stress
that there are now two use cases of I2C_M_NOSTART. If direction
changes, it is a rarely needed protocol quirk. If direction doesn't
change, it is used for buffer gathering.
>
> In the case of regmap-i2c we remove the requirement for mangling as
> I2C_M_NOSTART is the only mangling feature which is being used.
>
> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
> ---
> Documentation/i2c/functionality | 1 +
> drivers/base/regmap/regmap-i2c.c | 2 +-
> drivers/i2c/algos/i2c-algo-bit.c | 2 +-
> drivers/i2c/algos/i2c-algo-pcf.c | 2 +-
> drivers/i2c/busses/i2c-nuc900.c | 3 ++-
> drivers/i2c/busses/i2c-s3c2410.c | 3 ++-
> drivers/input/joystick/as5011.c | 1 +
> drivers/video/matrox/matroxfb_maven.c | 1 +
> include/linux/i2c.h | 5 +++--
> 9 files changed, 13 insertions(+), 7 deletions(-)
Review:
>
> diff --git a/Documentation/i2c/functionality b/Documentation/i2c/functionality
> index 42c17c1..fb2e77e 100644
> --- a/Documentation/i2c/functionality
> +++ b/Documentation/i2c/functionality
> @@ -33,6 +33,7 @@ For the most up-to-date list of functionality constants, please check
You must also update the description of I2C_FUNC_PROTOCOL_MANGLING to
no longer mention I2C_M_NOSTART.
> I2C_FUNC_SMBUS_WRITE_BLOCK_DATA Handles the SMBus write_block_data command
> I2C_FUNC_SMBUS_READ_I2C_BLOCK Handles the SMBus read_i2c_block_data command
> I2C_FUNC_SMBUS_WRITE_I2C_BLOCK Handles the SMBus write_i2c_block_data command
> + I2C_FUNC_NOSTART Transfers can be sent without a start
Not true. Transfers always begin with a Start, even when I2C_M_NOSTART
is used, because it is never set for the first message.
I2C_FUNC_NOSTART means that messages other than the first may not get
their usual Repeated Start and address prefix. So a better working IMHO
would be:
+ I2C_FUNC_NOSTART Can skip repeated start sequence
>
> A few combinations of the above flags are also defined for your convenience:
>
> diff --git a/drivers/base/regmap/regmap-i2c.c b/drivers/base/regmap/regmap-i2c.c
> index 5f6b247..fa6bf52 100644
> --- a/drivers/base/regmap/regmap-i2c.c
> +++ b/drivers/base/regmap/regmap-i2c.c
> @@ -42,7 +42,7 @@ static int regmap_i2c_gather_write(void *context,
> /* If the I2C controller can't do a gather tell the core, it
> * will substitute in a linear write for us.
> */
> - if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_PROTOCOL_MANGLING))
> + if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_NOSTART))
> return -ENOTSUPP;
>
> xfer[0].addr = i2c->addr;
> diff --git a/drivers/i2c/algos/i2c-algo-bit.c b/drivers/i2c/algos/i2c-algo-bit.c
> index 7f0b832..fad22b0 100644
> --- a/drivers/i2c/algos/i2c-algo-bit.c
> +++ b/drivers/i2c/algos/i2c-algo-bit.c
> @@ -608,7 +608,7 @@ bailout:
>
> static u32 bit_func(struct i2c_adapter *adap)
> {
> - return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL |
> + return I2C_FUNC_I2C | I2C_FUNC_NOSTART | I2C_FUNC_SMBUS_EMUL |
> I2C_FUNC_SMBUS_READ_BLOCK_DATA |
> I2C_FUNC_SMBUS_BLOCK_PROC_CALL |
> I2C_FUNC_10BIT_ADDR | I2C_FUNC_PROTOCOL_MANGLING;
> diff --git a/drivers/i2c/algos/i2c-algo-pcf.c b/drivers/i2c/algos/i2c-algo-pcf.c
> index 5c23795..8b38986 100644
> --- a/drivers/i2c/algos/i2c-algo-pcf.c
> +++ b/drivers/i2c/algos/i2c-algo-pcf.c
> @@ -401,7 +401,7 @@ out:
>
> static u32 pcf_func(struct i2c_adapter *adap)
> {
> - return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL |
> + return I2C_FUNC_I2C | I2C_FUNC_NOSTART | I2C_FUNC_SMBUS_EMUL |
> I2C_FUNC_PROTOCOL_MANGLING;
> }
>
A quick grep suggests that i2c-algo-pcf doesn't support I2C_M_NOSTART,
only I2C_M_REV_DIR_ADDR. So you don't want to add I2C_FUNC_NOSTART to
the functionality mask.
> diff --git a/drivers/i2c/busses/i2c-nuc900.c b/drivers/i2c/busses/i2c-nuc900.c
> index 03b6157..a26dfb8 100644
> --- a/drivers/i2c/busses/i2c-nuc900.c
> +++ b/drivers/i2c/busses/i2c-nuc900.c
> @@ -502,7 +502,8 @@ static int nuc900_i2c_xfer(struct i2c_adapter *adap,
> /* declare our i2c functionality */
> static u32 nuc900_i2c_func(struct i2c_adapter *adap)
> {
> - return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_PROTOCOL_MANGLING;
> + return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_NOSTART |
> + I2C_FUNC_PROTOCOL_MANGLING;
> }
>
> /* i2c bus registration info */
> diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c
> index fa0b134..0195915 100644
> --- a/drivers/i2c/busses/i2c-s3c2410.c
> +++ b/drivers/i2c/busses/i2c-s3c2410.c
> @@ -626,7 +626,8 @@ static int s3c24xx_i2c_xfer(struct i2c_adapter *adap,
> /* declare our i2c functionality */
> static u32 s3c24xx_i2c_func(struct i2c_adapter *adap)
> {
> - return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_PROTOCOL_MANGLING;
> + return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_NOSTART |
> + I2C_FUNC_PROTOCOL_MANGLING;
> }
>
> /* i2c bus registration info */
> diff --git a/drivers/input/joystick/as5011.c b/drivers/input/joystick/as5011.c
> index 3063464..57d19d4 100644
> --- a/drivers/input/joystick/as5011.c
> +++ b/drivers/input/joystick/as5011.c
> @@ -231,6 +231,7 @@ static int __devinit as5011_probe(struct i2c_client *client,
> }
>
> if (!i2c_check_functionality(client->adapter,
> + I2C_FUNC_NOSTART |
> I2C_FUNC_PROTOCOL_MANGLING)) {
> dev_err(&client->dev,
> "need i2c bus that supports protocol mangling\n");
> diff --git a/drivers/video/matrox/matroxfb_maven.c b/drivers/video/matrox/matroxfb_maven.c
> index 31b8f67..217678e 100644
> --- a/drivers/video/matrox/matroxfb_maven.c
> +++ b/drivers/video/matrox/matroxfb_maven.c
> @@ -1243,6 +1243,7 @@ static int maven_probe(struct i2c_client *client,
>
> if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WRITE_WORD_DATA |
> I2C_FUNC_SMBUS_BYTE_DATA |
> + I2C_FUNC_NOSTART |
> I2C_FUNC_PROTOCOL_MANGLING))
> goto ERROR0;
> if (!(data = kzalloc(sizeof(*data), GFP_KERNEL))) {
> diff --git a/include/linux/i2c.h b/include/linux/i2c.h
> index b66cb60..da46925 100644
> --- a/include/linux/i2c.h
> +++ b/include/linux/i2c.h
> @@ -541,7 +541,7 @@ struct i2c_msg {
> __u16 flags;
> #define I2C_M_TEN 0x0010 /* this is a ten bit chip address */
> #define I2C_M_RD 0x0001 /* read data, from slave to master */
> -#define I2C_M_NOSTART 0x4000 /* if I2C_FUNC_PROTOCOL_MANGLING */
> +#define I2C_M_NOSTART 0x4000 /* if I2C_FUNC_NOSTART */
> #define I2C_M_REV_DIR_ADDR 0x2000 /* if I2C_FUNC_PROTOCOL_MANGLING */
> #define I2C_M_IGNORE_NAK 0x1000 /* if I2C_FUNC_PROTOCOL_MANGLING */
> #define I2C_M_NO_RD_ACK 0x0800 /* if I2C_FUNC_PROTOCOL_MANGLING */
> @@ -554,7 +554,7 @@ struct i2c_msg {
>
> #define I2C_FUNC_I2C 0x00000001
> #define I2C_FUNC_10BIT_ADDR 0x00000002
> -#define I2C_FUNC_PROTOCOL_MANGLING 0x00000004 /* I2C_M_NOSTART etc. */
> +#define I2C_FUNC_PROTOCOL_MANGLING 0x00000004 /* I2C_M_IGNORE_NAK etc. */
> #define I2C_FUNC_SMBUS_PEC 0x00000008
> #define I2C_FUNC_SMBUS_BLOCK_PROC_CALL 0x00008000 /* SMBus 2.0 */
> #define I2C_FUNC_SMBUS_QUICK 0x00010000
> @@ -569,6 +569,7 @@ struct i2c_msg {
> #define I2C_FUNC_SMBUS_WRITE_BLOCK_DATA 0x02000000
> #define I2C_FUNC_SMBUS_READ_I2C_BLOCK 0x04000000 /* I2C-like block xfer */
> #define I2C_FUNC_SMBUS_WRITE_I2C_BLOCK 0x08000000 /* w/ 1-byte reg. addr. */
> +#define I2C_FUNC_NOSTART 0x10000000 /* I2C_M_NOSTART */
Sorry for nitpicking but wouldn't I2C_FUNC_GATHER be a better name?
NOSTART is an implementation detail now, the high level feature is the
ability to gather multiple messages into one.
Also I think I would prefer if you used 0x00000010 for the new
functionality, so that it isn't too far away from
I2C_FUNC_PROTOCOL_MANGLING.
>
> #define I2C_FUNC_SMBUS_BYTE (I2C_FUNC_SMBUS_READ_BYTE | \
> I2C_FUNC_SMBUS_WRITE_BYTE)
Thanks,
--
Jean Delvare
^ permalink raw reply
* Re: [PATCH v2] video/sis: Use SiS_DRAMType from init.h and annotate it __devinitconst
From: Peter Hüwe @ 2012-05-03 21:40 UTC (permalink / raw)
To: Florian Tobias Schandinat; +Cc: Thomas Winischhofer, linux-fbdev, linux-kernel
In-Reply-To: <4FA1BF76.8080109@gmx.de>
Hi Florian,
> As far as I can see it should be possible to keep the array in
> sis_main.c and just delete it in the header files, shouldn't it? I'd
> prefer to do it this way.
Yes it is absolutely possible to leave it in sis_main.c and remove it from the
header files. I already thought about this when creating the patch, but
decided against it, as the 17*5 = 85 bytes are allocated on the stack, while
they nicely can be put in the .devinit.rodata section ;)
With the patch:
344072 sis_main.o
1200950 sisfb.o
1217491 sisfb.ko
vs without the patch and removing it only from the header:
344176 sis_main.o
1201056 sisfb.o
1217597 sisfb.ko -> ~100bytes more in the final module.
However I'm fine with this and will remove it from the header and squash this
together with the
"video/sis: Remove unused structs SiS_SDRDRAM_TYPE/SiS_DDRDRAM_TYPE"
I also sent to you.
Thanks,
Peterq
^ permalink raw reply
* [PATCH] video/sis: Remove unused structs SiS_SDRDRAM_TYPE/SiS_DDRDRAM_TYPE/SiS_DRAMType
From: Peter Huewe @ 2012-05-03 21:42 UTC (permalink / raw)
To: Florian Tobias Schandinat
Cc: Thomas Winischhofer, linux-fbdev, linux-kernel, Peter Huewe
This patch removes the unused structs SiS_SDRDRAM_TYPE and SiS_DDRDRAM_TYPE
from init.h
These are not used anywhere so we can delete them.
The SiS_DRAMType is identically defined in sis_main.c and only used
there so we can remove it here.
Signed-off-by: Peter Huewe <peterhuewe@gmx.de>
---
drivers/video/sis/init.h | 45 ---------------------------------------------
1 files changed, 0 insertions(+), 45 deletions(-)
diff --git a/drivers/video/sis/init.h b/drivers/video/sis/init.h
index aff7384..85d6738 100644
--- a/drivers/video/sis/init.h
+++ b/drivers/video/sis/init.h
@@ -105,51 +105,6 @@ static const unsigned short ModeIndex_1920x1440[] = {0x68, 0x69, 0x00, 0x6b};
static const unsigned short ModeIndex_300_2048x1536[]= {0x6c, 0x6d, 0x00, 0x00};
static const unsigned short ModeIndex_310_2048x1536[]= {0x6c, 0x6d, 0x00, 0x6e};
-static const unsigned short SiS_DRAMType[17][5]={
- {0x0C,0x0A,0x02,0x40,0x39},
- {0x0D,0x0A,0x01,0x40,0x48},
- {0x0C,0x09,0x02,0x20,0x35},
- {0x0D,0x09,0x01,0x20,0x44},
- {0x0C,0x08,0x02,0x10,0x31},
- {0x0D,0x08,0x01,0x10,0x40},
- {0x0C,0x0A,0x01,0x20,0x34},
- {0x0C,0x09,0x01,0x08,0x32},
- {0x0B,0x08,0x02,0x08,0x21},
- {0x0C,0x08,0x01,0x08,0x30},
- {0x0A,0x08,0x02,0x04,0x11},
- {0x0B,0x0A,0x01,0x10,0x28},
- {0x09,0x08,0x02,0x02,0x01},
- {0x0B,0x09,0x01,0x08,0x24},
- {0x0B,0x08,0x01,0x04,0x20},
- {0x0A,0x08,0x01,0x02,0x10},
- {0x09,0x08,0x01,0x01,0x00}
-};
-
-static const unsigned short SiS_SDRDRAM_TYPE[13][5] -{
- { 2,12, 9,64,0x35},
- { 1,13, 9,64,0x44},
- { 2,12, 8,32,0x31},
- { 2,11, 9,32,0x25},
- { 1,12, 9,32,0x34},
- { 1,13, 8,32,0x40},
- { 2,11, 8,16,0x21},
- { 1,12, 8,16,0x30},
- { 1,11, 9,16,0x24},
- { 1,11, 8, 8,0x20},
- { 2, 9, 8, 4,0x01},
- { 1,10, 8, 4,0x10},
- { 1, 9, 8, 2,0x00}
-};
-
-static const unsigned short SiS_DDRDRAM_TYPE[4][5] -{
- { 2,12, 9,64,0x35},
- { 2,12, 8,32,0x31},
- { 2,11, 8,16,0x21},
- { 2, 9, 8, 4,0x01}
-};
-
static const unsigned char SiS_MDA_DAC[] {
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
--
1.7.3.4
^ permalink raw reply related
* Re: [PATCH v2] video/sis: Use SiS_DRAMType from init.h and annotate it __devinitconst
From: Florian Tobias Schandinat @ 2012-05-03 21:48 UTC (permalink / raw)
To: Peter Hüwe; +Cc: Thomas Winischhofer, linux-fbdev, linux-kernel
In-Reply-To: <201205032340.34483.PeterHuewe@gmx.de>
Hi Peter,
On 05/03/2012 09:40 PM, Peter Hüwe wrote:
> Hi Florian,
>
>> As far as I can see it should be possible to keep the array in
>> sis_main.c and just delete it in the header files, shouldn't it? I'd
>> prefer to do it this way.
>
> Yes it is absolutely possible to leave it in sis_main.c and remove it from the
> header files. I already thought about this when creating the patch, but
> decided against it, as the 17*5 = 85 bytes are allocated on the stack, while
> they nicely can be put in the .devinit.rodata section ;)
You can still mark it as __devinitconst, I just wanted to have the array
inside a C file, not a header. If you agree with this, I'll change your
new patch that way.
>
> With the patch:
> 344072 sis_main.o
> 1200950 sisfb.o
> 1217491 sisfb.ko
>
> vs without the patch and removing it only from the header:
> 344176 sis_main.o
> 1201056 sisfb.o
> 1217597 sisfb.ko -> ~100bytes more in the final module.
>
> However I'm fine with this and will remove it from the header and squash this
> together with the
> "video/sis: Remove unused structs SiS_SDRDRAM_TYPE/SiS_DDRDRAM_TYPE"
> I also sent to you.
Thanks,
Florian Tobias Schandinat
^ permalink raw reply
* Re: [PATCH v2] video/sis: Use SiS_DRAMType from init.h and annotate it __devinitconst
From: Peter Hüwe @ 2012-05-03 21:58 UTC (permalink / raw)
To: Florian Tobias Schandinat; +Cc: Thomas Winischhofer, linux-fbdev, linux-kernel
In-Reply-To: <4FA2FD10.6090306@gmx.de>
Am Donnerstag 03 Mai 2012, 23:48:00 schrieb Florian Tobias Schandinat:
> You can still mark it as __devinitconst, I just wanted to have the array
> inside a C file, not a header. If you agree with this, I'll change your
> new patch that way.
I'm totally fine with this - Thanks,
Peter
^ permalink raw reply
* [PATCH] video/sis: Annotate SiS_DRAMType as __devinitconst
From: Peter Huewe @ 2012-05-03 22:14 UTC (permalink / raw)
To: Florian Tobias Schandinat
Cc: Thomas Winischhofer, linux-fbdev, linux-kernel, Peter Huewe
In-Reply-To: <4FA2FD10.6090306@gmx.de>
SiS_DRAMType is const and only used by sisfb_post_300_rwtest which is
marked __devinit we can annotate SiS_DRAMType with __devinitconst and
move it into the file scope in order to not have it created on the
stack.
This patch decreases the compiled module size by about 100bytes.
And since hardcoded values are bad we use ARRAY_SIZE for determining
the size of SiS_DRAMType ;)
Signed-off-by: Peter Huewe <peterhuewe@gmx.de>
---
drivers/video/sis/sis_main.c | 41 +++++++++++++++++++++--------------------
1 files changed, 21 insertions(+), 20 deletions(-)
diff --git a/drivers/video/sis/sis_main.c b/drivers/video/sis/sis_main.c
index 078ca21..a7a48db 100644
--- a/drivers/video/sis/sis_main.c
+++ b/drivers/video/sis/sis_main.c
@@ -4222,6 +4222,26 @@ sisfb_post_300_buswidth(struct sis_video_info *ivideo)
return 1; /* 32bit */
}
+static const unsigned short __devinitconst SiS_DRAMType[17][5] = {
+ {0x0C,0x0A,0x02,0x40,0x39},
+ {0x0D,0x0A,0x01,0x40,0x48},
+ {0x0C,0x09,0x02,0x20,0x35},
+ {0x0D,0x09,0x01,0x20,0x44},
+ {0x0C,0x08,0x02,0x10,0x31},
+ {0x0D,0x08,0x01,0x10,0x40},
+ {0x0C,0x0A,0x01,0x20,0x34},
+ {0x0C,0x09,0x01,0x08,0x32},
+ {0x0B,0x08,0x02,0x08,0x21},
+ {0x0C,0x08,0x01,0x08,0x30},
+ {0x0A,0x08,0x02,0x04,0x11},
+ {0x0B,0x0A,0x01,0x10,0x28},
+ {0x09,0x08,0x02,0x02,0x01},
+ {0x0B,0x09,0x01,0x08,0x24},
+ {0x0B,0x08,0x01,0x04,0x20},
+ {0x0A,0x08,0x01,0x02,0x10},
+ {0x09,0x08,0x01,0x01,0x00}
+};
+
static int __devinit
sisfb_post_300_rwtest(struct sis_video_info *ivideo, int iteration, int buswidth,
int PseudoRankCapacity, int PseudoAdrPinCount,
@@ -4231,27 +4251,8 @@ sisfb_post_300_rwtest(struct sis_video_info *ivideo, int iteration, int buswidth
unsigned short sr14;
unsigned int k, RankCapacity, PageCapacity, BankNumHigh, BankNumMid;
unsigned int PhysicalAdrOtherPage, PhysicalAdrHigh, PhysicalAdrHalfPage;
- static const unsigned short SiS_DRAMType[17][5] = {
- {0x0C,0x0A,0x02,0x40,0x39},
- {0x0D,0x0A,0x01,0x40,0x48},
- {0x0C,0x09,0x02,0x20,0x35},
- {0x0D,0x09,0x01,0x20,0x44},
- {0x0C,0x08,0x02,0x10,0x31},
- {0x0D,0x08,0x01,0x10,0x40},
- {0x0C,0x0A,0x01,0x20,0x34},
- {0x0C,0x09,0x01,0x08,0x32},
- {0x0B,0x08,0x02,0x08,0x21},
- {0x0C,0x08,0x01,0x08,0x30},
- {0x0A,0x08,0x02,0x04,0x11},
- {0x0B,0x0A,0x01,0x10,0x28},
- {0x09,0x08,0x02,0x02,0x01},
- {0x0B,0x09,0x01,0x08,0x24},
- {0x0B,0x08,0x01,0x04,0x20},
- {0x0A,0x08,0x01,0x02,0x10},
- {0x09,0x08,0x01,0x01,0x00}
- };
- for(k = 0; k <= 16; k++) {
+ for(k = 0; k < ARRAY_SIZE(SiS_DRAMType); k++) {
RankCapacity = buswidth * SiS_DRAMType[k][3];
--
1.7.3.4
^ permalink raw reply related
* [PATCH v2] video/via: Convert to kstrtou8_from_user
From: Peter Huewe @ 2012-05-04 0:23 UTC (permalink / raw)
To: Florian Tobias Schandinat
Cc: Alexey Dobriyan, linux-fbdev, linux-kernel, kernel-janitors,
Peter Huewe
In-Reply-To: <CACVxJT96rXRqMoeabdDyNEjXCubuAnQ_fonisbopQvYL=Qhp2w@mail.gmail.com>
This patch replaces the code for getting an number from a
userspace buffer by a simple call to kstrou8_from_user.
This makes it easier to read and less error prone.
v2:
removed initialization of reg_val and dropped check if count < 1
Signed-off-by: Peter Huewe <peterhuewe@gmx.de>
---
@Alexey: Thanks for the review/feedback!
drivers/video/via/viafbdev.c | 34 ++++++++++++----------------------
1 files changed, 12 insertions(+), 22 deletions(-)
diff --git a/drivers/video/via/viafbdev.c b/drivers/video/via/viafbdev.c
index a13c258..88bf5ba 100644
--- a/drivers/video/via/viafbdev.c
+++ b/drivers/video/via/viafbdev.c
@@ -1279,17 +1279,12 @@ static int viafb_dfph_proc_open(struct inode *inode, struct file *file)
static ssize_t viafb_dfph_proc_write(struct file *file,
const char __user *buffer, size_t count, loff_t *pos)
{
- char buf[20];
- u8 reg_val = 0;
- unsigned long length;
- if (count < 1)
- return -EINVAL;
- length = count > 20 ? 20 : count;
- if (copy_from_user(&buf[0], buffer, length))
- return -EFAULT;
- buf[length - 1] = '\0'; /*Ensure end string */
- if (kstrtou8(buf, 0, ®_val) < 0)
- return -EINVAL;
+ int err;
+ u8 reg_val;
+ err = kstrtou8_from_user(buffer, count, 0, ®_val);
+ if (err)
+ return err;
+
viafb_write_reg_mask(CR97, VIACR, reg_val, 0x0f);
return count;
}
@@ -1319,17 +1314,12 @@ static int viafb_dfpl_proc_open(struct inode *inode, struct file *file)
static ssize_t viafb_dfpl_proc_write(struct file *file,
const char __user *buffer, size_t count, loff_t *pos)
{
- char buf[20];
- u8 reg_val = 0;
- unsigned long length;
- if (count < 1)
- return -EINVAL;
- length = count > 20 ? 20 : count;
- if (copy_from_user(&buf[0], buffer, length))
- return -EFAULT;
- buf[length - 1] = '\0'; /*Ensure end string */
- if (kstrtou8(buf, 0, ®_val) < 0)
- return -EINVAL;
+ int err;
+ u8 reg_val;
+ err = kstrtou8_from_user(buffer, count, 0, ®_val);
+ if (err)
+ return err;
+
viafb_write_reg_mask(CR99, VIACR, reg_val, 0x0f);
return count;
}
--
1.7.3.4
^ permalink raw reply related
* [PATCH] video: exynos_dp: remove unnecessary header includes
From: Jingoo Han @ 2012-05-04 1:48 UTC (permalink / raw)
To: linux-fbdev
Remove unnecessary headers from the file.
Signed-off-by: Jingoo Han <jg1.han@samsung.com>
---
drivers/video/exynos/exynos_dp_reg.c | 2 --
1 files changed, 0 insertions(+), 2 deletions(-)
diff --git a/drivers/video/exynos/exynos_dp_reg.c b/drivers/video/exynos/exynos_dp_reg.c
index 3863726..99bafb8 100644
--- a/drivers/video/exynos/exynos_dp_reg.c
+++ b/drivers/video/exynos/exynos_dp_reg.c
@@ -16,8 +16,6 @@
#include <video/exynos_dp.h>
-#include <plat/cpu.h>
-
#include "exynos_dp_core.h"
#include "exynos_dp_reg.h"
--
1.7.1
^ permalink raw reply related
* [PATCH] video: exynos_dp: fix max loop count in EQ sequence of link training
From: Jingoo Han @ 2012-05-04 1:49 UTC (permalink / raw)
To: linux-fbdev
This patch fixes max loop count in EQ(Channel Equalization) sequence
of link training. According to DP(displayport) specification,
the max loop count in this sequence should be 5.
Signed-off-by: Jingoo Han <jg1.han@samsung.com>
---
include/video/exynos_dp.h | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/include/video/exynos_dp.h b/include/video/exynos_dp.h
index 8847a9d..bd8cabd 100644
--- a/include/video/exynos_dp.h
+++ b/include/video/exynos_dp.h
@@ -14,7 +14,7 @@
#define DP_TIMEOUT_LOOP_COUNT 100
#define MAX_CR_LOOP 5
-#define MAX_EQ_LOOP 4
+#define MAX_EQ_LOOP 5
enum link_rate_type {
LINK_RATE_1_62GBPS = 0x06,
--
1.7.1
^ permalink raw reply related
* [PATCH] video: EXYNOS: enable interrupt again after sw reset
From: Donghwa Lee @ 2012-05-04 4:59 UTC (permalink / raw)
To: linux-arm-kernel
When exynos_mipi_update_cfg() is called, mipi dsi registers were become
sw reset. So, It needs to enable interrupt again.
Signed-off-by: Donghwa Lee <dh09.lee@samsung.com>
Signed-off-by: Inki Dae <inki.dae@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
drivers/video/exynos/exynos_mipi_dsi.c | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/drivers/video/exynos/exynos_mipi_dsi.c b/drivers/video/exynos/exynos_mipi_dsi.c
index 557091d..49c7351 100644
--- a/drivers/video/exynos/exynos_mipi_dsi.c
+++ b/drivers/video/exynos/exynos_mipi_dsi.c
@@ -102,6 +102,8 @@ static void exynos_mipi_update_cfg(struct mipi_dsim_device *dsim)
/* set display timing. */
exynos_mipi_dsi_set_display_mode(dsim, dsim->dsim_config);
+ exynos_mipi_dsi_init_interrupt(dsim);
+
/*
* data from Display controller(FIMD) is transferred in video mode
* but in case of command mode, all settigs is updated to registers.
--
1.7.4.1
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox