Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions drivers/gpu/drm/bridge/panel.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include <drm/drm_panel.h>
#include <drm/drm_print.h>
#include <drm/drm_probe_helper.h>
#include <linux/backlight.h>

struct panel_bridge {
struct drm_bridge bridge;
Expand Down Expand Up @@ -86,6 +87,9 @@ static int panel_bridge_attach(struct drm_bridge *bridge,
drm_connector_attach_encoder(&panel_bridge->connector,
bridge->encoder);

backlight_set_display_name(panel_bridge->panel->backlight,
panel_bridge->connector.name);

if (bridge->dev->registered) {
if (connector->funcs->reset)
connector->funcs->reset(connector);
Expand Down
53 changes: 52 additions & 1 deletion drivers/regulator/rpi-panel-v2-regulator.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,39 @@ static const struct backlight_ops rpi_panel_v2_bl = {
.update_status = rpi_panel_v2_update_status,
};

static int rpi_panel_v2_i2c_read(struct i2c_client *client, u8 reg, unsigned int *buf)
{
struct i2c_msg msgs[1];
u8 addr_buf[1] = { reg };
u8 data_buf[1] = { 0, };
int ret;

/* Write register address */
msgs[0].addr = client->addr;
msgs[0].flags = 0;
msgs[0].len = ARRAY_SIZE(addr_buf);
msgs[0].buf = addr_buf;

ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
if (ret != ARRAY_SIZE(msgs))
return -EIO;

usleep_range(5000, 10000);

/* Read data from register */
msgs[0].addr = client->addr;
msgs[0].flags = I2C_M_RD;
msgs[0].len = 1;
msgs[0].buf = data_buf;

ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
if (ret != ARRAY_SIZE(msgs))
return -EIO;

*buf = data_buf[0];
return 0;
}

/*
* I2C driver interface functions
*/
Expand All @@ -104,6 +137,7 @@ static int rpi_panel_v2_i2c_probe(struct i2c_client *i2c)
return -ENOMEM;

mutex_init(&state->lock);
i2c_set_clientdata(i2c, state);

regmap = devm_regmap_init_i2c(i2c, &rpi_panel_regmap_config);
if (IS_ERR(regmap)) {
Expand All @@ -113,7 +147,7 @@ static int rpi_panel_v2_i2c_probe(struct i2c_client *i2c)
goto error;
}

ret = regmap_read(regmap, REG_ID, &data);
ret = rpi_panel_v2_i2c_read(i2c, REG_ID, &data);
if (ret < 0) {
dev_err(&i2c->dev, "Failed to read REG_ID reg: %d\n", ret);
goto error;
Expand Down Expand Up @@ -168,6 +202,21 @@ static int rpi_panel_v2_i2c_probe(struct i2c_client *i2c)
return ret;
}

static void rpi_panel_v2_i2c_remove(struct i2c_client *client)
{
struct rpi_panel_v2_lcd *state = i2c_get_clientdata(client);

mutex_destroy(&state->lock);
}

static void rpi_panel_v2_i2c_shutdown(struct i2c_client *client)
{
struct rpi_panel_v2_lcd *state = i2c_get_clientdata(client);

regmap_write(state->regmap, REG_PWM, 0);
regmap_write(state->regmap, REG_POWERON, 0);
}

static const struct of_device_id rpi_panel_v2_dt_ids[] = {
{ .compatible = "raspberrypi,v2-touchscreen-panel-regulator" },
{},
Expand All @@ -180,6 +229,8 @@ static struct i2c_driver rpi_panel_v2_regulator_driver = {
.of_match_table = of_match_ptr(rpi_panel_v2_dt_ids),
},
.probe = rpi_panel_v2_i2c_probe,
.remove = rpi_panel_v2_i2c_remove,
.shutdown = rpi_panel_v2_i2c_shutdown,
};

module_i2c_driver(rpi_panel_v2_regulator_driver);
Expand Down
21 changes: 21 additions & 0 deletions drivers/video/backlight/backlight.c
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,15 @@ static ssize_t max_brightness_show(struct device *dev,
}
static DEVICE_ATTR_RO(max_brightness);

static ssize_t display_name_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct backlight_device *bd = to_backlight_device(dev);

return sprintf(buf, "%s\n", bd->props.display_name);
}
static DEVICE_ATTR_RO(display_name);

static ssize_t actual_brightness_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
Expand Down Expand Up @@ -365,6 +374,7 @@ static struct attribute *bl_device_attrs[] = {
&dev_attr_max_brightness.attr,
&dev_attr_scale.attr,
&dev_attr_type.attr,
&dev_attr_display_name.attr,
NULL,
};
ATTRIBUTE_GROUPS(bl_device);
Expand Down Expand Up @@ -662,6 +672,17 @@ static int of_parent_match(struct device *dev, const void *data)
return dev->parent && dev->parent->of_node == data;
}

int backlight_set_display_name(struct backlight_device *bd, const char *name)
{
if (!bd)
return -EINVAL;

strscpy_pad(bd->props.display_name, name, sizeof(bd->props.display_name));

return 0;
}
EXPORT_SYMBOL(backlight_set_display_name);

/**
* of_find_backlight_by_node() - find backlight device by device-tree node
* @node: device-tree node of the backlight device
Expand Down
15 changes: 15 additions & 0 deletions include/linux/backlight.h
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,13 @@ struct backlight_properties {
* @scale: The type of the brightness scale.
*/
enum backlight_scale scale;

#define BL_DISPLAY_NAME_LEN 32
/**
* @display_name: Optional name that can be registered to associate a
* backlight device with a display device.
*/
char display_name[BL_DISPLAY_NAME_LEN];
};

/**
Expand Down Expand Up @@ -478,12 +485,20 @@ of_find_backlight_by_node(struct device_node *node)

#if IS_ENABLED(CONFIG_BACKLIGHT_CLASS_DEVICE)
struct backlight_device *devm_of_find_backlight(struct device *dev);
int backlight_set_display_name(struct backlight_device *bd, const char *name);
#else
static inline struct backlight_device *
devm_of_find_backlight(struct device *dev)
{
return NULL;
}

static inline int backlight_set_display_name(struct backlight_device *bd,
const char *name)
{
return 0;
}

#endif

#endif