summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThierry Reding <treding@nvidia.com>2013-12-13 15:38:29 +0100
committerThierry Reding <treding@nvidia.com>2014-01-10 10:15:22 +0100
commit4e04e43faef1e601a4e5386ea096ae2b71267bce (patch)
tree472624ad0e5d97e84c8ca995a3090d6c5e0de79e
parent74b643ea922336e252092304db890c4cad1331bb (diff)
drm/tegra: Implement brightness property
When attached to a panel that supports the brightness operations, create a connector property that allows the brightness to be manipulated using the KMS API. Signed-off-by: Thierry Reding <treding@nvidia.com>
-rw-r--r--drivers/gpu/drm/tegra/drm.h2
-rw-r--r--drivers/gpu/drm/tegra/output.c59
2 files changed, 59 insertions, 2 deletions
diff --git a/drivers/gpu/drm/tegra/drm.h b/drivers/gpu/drm/tegra/drm.h
index 126332c3ecbb..1f23207a0cd2 100644
--- a/drivers/gpu/drm/tegra/drm.h
+++ b/drivers/gpu/drm/tegra/drm.h
@@ -204,6 +204,8 @@ struct tegra_output {
struct drm_encoder encoder;
struct drm_connector connector;
+
+ struct drm_property *brightness;
};
static inline struct tegra_output *encoder_to_output(struct drm_encoder *e)
diff --git a/drivers/gpu/drm/tegra/output.c b/drivers/gpu/drm/tegra/output.c
index 7973461af71a..4af68c142fda 100644
--- a/drivers/gpu/drm/tegra/output.c
+++ b/drivers/gpu/drm/tegra/output.c
@@ -67,6 +67,39 @@ static const struct drm_connector_helper_funcs connector_helper_funcs = {
.best_encoder = tegra_connector_best_encoder,
};
+static void tegra_output_add_panel_properties(struct tegra_output *output)
+{
+ struct drm_device *drm = output->connector.dev;
+ uint64_t min, max, value;
+ int err;
+
+ if (output->brightness)
+ return;
+
+ err = drm_panel_get_brightness_range(output->panel, &min, &max);
+ if (err < 0)
+ return;
+
+ err = drm_panel_get_brightness(output->panel, &value);
+ if (err < 0)
+ return;
+
+ output->brightness = drm_property_create_range(drm, 0, "brightness",
+ min, max);
+ drm_object_attach_property(&output->connector.base, output->brightness,
+ value);
+}
+
+static void tegra_output_remove_panel_properties(struct tegra_output *output)
+{
+ struct drm_device *drm = output->connector.dev;
+
+ if (output->brightness) {
+ drm_property_destroy(drm, output->brightness);
+ output->brightness = NULL;
+ }
+}
+
static enum drm_connector_status
tegra_connector_detect(struct drm_connector *connector, bool force)
{
@@ -82,10 +115,13 @@ tegra_connector_detect(struct drm_connector *connector, bool force)
else
status = connector_status_connected;
} else {
- if (!output->panel)
+ if (!output->panel) {
+ tegra_output_remove_panel_properties(output);
status = connector_status_disconnected;
- else
+ } else {
+ tegra_output_add_panel_properties(output);
status = connector_status_connected;
+ }
if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS)
status = connector_status_connected;
@@ -94,6 +130,24 @@ tegra_connector_detect(struct drm_connector *connector, bool force)
return status;
}
+static int tegra_connector_set_property(struct drm_connector *connector,
+ struct drm_property *property,
+ uint64_t value)
+{
+ struct tegra_output *output = connector_to_output(connector);
+ int err;
+
+ if (output->panel) {
+ if (property == output->brightness) {
+ err = drm_panel_set_brightness(output->panel, value);
+ if (err < 0)
+ return err;
+ }
+ }
+
+ return 0;
+}
+
static void drm_connector_clear(struct drm_connector *connector)
{
memset(connector, 0, sizeof(*connector));
@@ -110,6 +164,7 @@ static const struct drm_connector_funcs connector_funcs = {
.dpms = drm_helper_connector_dpms,
.detect = tegra_connector_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
+ .set_property = tegra_connector_set_property,
.destroy = tegra_connector_destroy,
};