The current code expect the configuration of the backlight to stay constant after initialization. This patch allows to move it around. Signed-off-by: Pantelis Antoniou <panto@xxxxxxxxxxxxxxxxxxxxxxx> --- drivers/video/backlight/tps65217_bl.c | 103 ++++++++++++++++++++++++++++++---- 1 file changed, 92 insertions(+), 11 deletions(-) diff --git a/drivers/video/backlight/tps65217_bl.c b/drivers/video/backlight/tps65217_bl.c index 7088163..69c1dfe 100644 --- a/drivers/video/backlight/tps65217_bl.c +++ b/drivers/video/backlight/tps65217_bl.c @@ -24,8 +24,11 @@ #include <linux/module.h> #include <linux/platform_device.h> #include <linux/slab.h> +#include <linux/i2c.h> +#include <linux/of_i2c.h> struct tps65217_bl { + struct i2c_client *i2c_client; struct tps65217 *tps; struct device *dev; struct backlight_device *bl; @@ -98,8 +101,6 @@ static int tps65217_bl_update_status(struct backlight_device *bl) return rc; } - dev_dbg(tps65217_bl->dev, "brightness set to %d\n", brightness); - if (!tps65217_bl->is_enabled) rc = tps65217_bl_enable(tps65217_bl); } else { @@ -187,14 +188,69 @@ static int tps65217_bl_hw_init(struct tps65217_bl *tps65217_bl, #ifdef CONFIG_OF static struct tps65217_bl_pdata * -tps65217_bl_parse_dt(struct platform_device *pdev) +tps65217_bl_parse_dt(struct platform_device *pdev, struct tps65217 **tpsp, + int *brightnessp) { - struct tps65217 *tps = dev_get_drvdata(pdev->dev.parent); - struct device_node *node = of_node_get(tps->dev->of_node); + struct i2c_client *i2c_client; + struct tps65217 *tps; + struct device_node *node, *rnode, *pnode; struct tps65217_bl_pdata *pdata, *err; + u32 tps_handle; u32 val; - node = of_find_node_by_name(node, "backlight"); + tps = NULL; + node = NULL; + *brightnessp = 0; + + /* our node (compatible) */ + pnode = pdev->dev.of_node; + if (pnode != NULL && + of_property_read_u32(pnode, "tps", &tps_handle) == 0) { + /* we are not instantiated from the mfd */ + node = of_find_node_by_phandle(tps_handle); + if (node == NULL) { + dev_err(&pdev->dev, "failed to find the tps node\n"); + err = ERR_PTR(-EINVAL); + goto err; + } + i2c_client = of_find_i2c_device_by_node(node); + if (i2c_client == NULL) { + dev_err(&pdev->dev, "failed to find the i2c device " + "of tps node\n"); + err = ERR_PTR(-EINVAL); + goto err; + } + /* yeah this is gross; the whole concept is */ + tps = i2c_get_clientdata(i2c_client); + if (tps == NULL) { + dev_err(&pdev->dev, "failed to get tps structure\n"); + err = ERR_PTR(-EINVAL); + goto err; + } + + /* read default brightness */ + val = 0; + of_property_read_u32(pnode, "brightness", &val); + if (val >= 100) + val = 100; + + *brightnessp = val; + + /* no need for this anymore */ + of_node_put(node); + + dev_info(&pdev->dev, "got tps=%p from handle 0x%x\n", tps, tps_handle); + } + + if (tps == NULL) + tps = dev_get_drvdata(pdev->dev.parent); + + rnode = of_node_get(tps->dev->of_node); + + node = of_find_node_by_name(rnode, "backlight"); + of_node_put(rnode); + rnode = NULL; + if (!node) return ERR_PTR(-ENODEV); @@ -247,6 +303,7 @@ tps65217_bl_parse_dt(struct platform_device *pdev) of_node_put(node); + *tpsp = tps; return pdata; err: @@ -254,9 +311,16 @@ err: return err; } + +static struct of_device_id tps65217_backlight_of_match[] = { + { .compatible = "tps65217-backlight" }, + { } +}; +MODULE_DEVICE_TABLE(of, tps65217_backlight_of_match); #else static struct tps65217_bl_pdata * -tps65217_bl_parse_dt(struct platform_device *pdev) +tps65217_bl_parse_dt(struct platform_device *pdev, struct tps65217 **tpsp, + int *brightnessp) { return NULL; } @@ -265,13 +329,16 @@ tps65217_bl_parse_dt(struct platform_device *pdev) static int tps65217_bl_probe(struct platform_device *pdev) { int rc; - struct tps65217 *tps = dev_get_drvdata(pdev->dev.parent); + struct tps65217 *tps; struct tps65217_bl *tps65217_bl; struct tps65217_bl_pdata *pdata; struct backlight_properties bl_props; + int brightness = 0; - if (tps->dev->of_node) { - pdata = tps65217_bl_parse_dt(pdev); + tps = NULL; + + if (pdev->dev.of_node) { + pdata = tps65217_bl_parse_dt(pdev, &tps, &brightness); if (IS_ERR(pdata)) return PTR_ERR(pdata); } else { @@ -281,6 +348,14 @@ static int tps65217_bl_probe(struct platform_device *pdev) } pdata = pdev->dev.platform_data; + + /* get the parent device */ + tps = dev_get_drvdata(pdev->dev.parent); + } + + if (tps == NULL) { + dev_err(&pdev->dev, "failed to find tps\n"); + return -EINVAL; } tps65217_bl = devm_kzalloc(&pdev->dev, sizeof(*tps65217_bl), @@ -311,9 +386,14 @@ static int tps65217_bl_probe(struct platform_device *pdev) return PTR_ERR(tps65217_bl->bl); } - tps65217_bl->bl->props.brightness = 0; + tps65217_bl->bl->props.brightness = brightness; platform_set_drvdata(pdev, tps65217_bl); + /* update with initial settings */ + tps65217_bl_update_status(tps65217_bl->bl); + + dev_info(&pdev->dev, "OK.\n"); + return 0; } @@ -332,6 +412,7 @@ static struct platform_driver tps65217_bl_driver = { .driver = { .owner = THIS_MODULE, .name = "tps65217-bl", + .of_match_table = of_match_ptr(tps65217_backlight_of_match), }, }; -- 1.7.12 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html