@@ -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),
},
};
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@antoniou-consulting.com> --- drivers/video/backlight/tps65217_bl.c | 103 ++++++++++++++++++++++++++++++---- 1 file changed, 92 insertions(+), 11 deletions(-)