Commit aaa6fd2a authored by Matthew Garrett's avatar Matthew Garrett Committed by Keith Packard

Not all systems expose a firmware or platform mechanism for changing the...

Not all systems expose a firmware or platform mechanism for changing the backlight intensity on i915, so add native driver support.
Signed-off-by: default avatarMatthew Garrett <mjg@redhat.com>
Cc: Richard Purdie <rpurdie@rpsys.net>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Cc: David Airlie <airlied@linux.ie>
Cc: Alex Deucher <alexdeucher@gmail.com>
Cc: Ben Skeggs <bskeggs@redhat.com>
Cc: Zhang Rui <rui.zhang@intel.com>
Cc: Len Brown <lenb@kernel.org>
Cc: Jesse Barnes <jbarnes@virtuousgeek.org>
Tested-by: default avatarSedat Dilek <sedat.dilek@googlemail.com>
Tested-by: default avatarMichel Alexandre Salim <salimma@fedoraproject.org>
Tested-by: default avatarKamal Mostafa <kamal@canonical.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarKeith Packard <keithp@keithp.com>
parent 13d83a67
...@@ -36,6 +36,7 @@ ...@@ -36,6 +36,7 @@
#include <linux/io-mapping.h> #include <linux/io-mapping.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <drm/intel-gtt.h> #include <drm/intel-gtt.h>
#include <linux/backlight.h>
/* General customization: /* General customization:
*/ */
...@@ -690,6 +691,7 @@ typedef struct drm_i915_private { ...@@ -690,6 +691,7 @@ typedef struct drm_i915_private {
int child_dev_num; int child_dev_num;
struct child_device_config *child_dev; struct child_device_config *child_dev;
struct drm_connector *int_lvds_connector; struct drm_connector *int_lvds_connector;
struct drm_connector *int_edp_connector;
bool mchbar_need_disable; bool mchbar_need_disable;
...@@ -723,6 +725,8 @@ typedef struct drm_i915_private { ...@@ -723,6 +725,8 @@ typedef struct drm_i915_private {
/* list of fbdev register on this device */ /* list of fbdev register on this device */
struct intel_fbdev *fbdev; struct intel_fbdev *fbdev;
struct backlight_device *backlight;
struct drm_property *broadcast_rgb_property; struct drm_property *broadcast_rgb_property;
struct drm_property *force_audio_property; struct drm_property *force_audio_property;
......
...@@ -1841,6 +1841,11 @@ intel_dp_set_property(struct drm_connector *connector, ...@@ -1841,6 +1841,11 @@ intel_dp_set_property(struct drm_connector *connector,
static void static void
intel_dp_destroy (struct drm_connector *connector) intel_dp_destroy (struct drm_connector *connector)
{ {
struct drm_device *dev = connector->dev;
if (intel_dpd_is_edp(dev))
intel_panel_destroy_backlight(dev);
drm_sysfs_connector_remove(connector); drm_sysfs_connector_remove(connector);
drm_connector_cleanup(connector); drm_connector_cleanup(connector);
kfree(connector); kfree(connector);
...@@ -2072,6 +2077,8 @@ intel_dp_init(struct drm_device *dev, int output_reg) ...@@ -2072,6 +2077,8 @@ intel_dp_init(struct drm_device *dev, int output_reg)
DRM_MODE_TYPE_PREFERRED; DRM_MODE_TYPE_PREFERRED;
} }
} }
dev_priv->int_edp_connector = connector;
intel_panel_setup_backlight(dev);
} }
intel_dp_add_properties(intel_dp, connector); intel_dp_add_properties(intel_dp, connector);
......
...@@ -297,9 +297,10 @@ extern void intel_pch_panel_fitting(struct drm_device *dev, ...@@ -297,9 +297,10 @@ extern void intel_pch_panel_fitting(struct drm_device *dev,
extern u32 intel_panel_get_max_backlight(struct drm_device *dev); extern u32 intel_panel_get_max_backlight(struct drm_device *dev);
extern u32 intel_panel_get_backlight(struct drm_device *dev); extern u32 intel_panel_get_backlight(struct drm_device *dev);
extern void intel_panel_set_backlight(struct drm_device *dev, u32 level); extern void intel_panel_set_backlight(struct drm_device *dev, u32 level);
extern void intel_panel_setup_backlight(struct drm_device *dev); extern int intel_panel_setup_backlight(struct drm_device *dev);
extern void intel_panel_enable_backlight(struct drm_device *dev); extern void intel_panel_enable_backlight(struct drm_device *dev);
extern void intel_panel_disable_backlight(struct drm_device *dev); extern void intel_panel_disable_backlight(struct drm_device *dev);
extern void intel_panel_destroy_backlight(struct drm_device *dev);
extern enum drm_connector_status intel_panel_detect(struct drm_device *dev); extern enum drm_connector_status intel_panel_detect(struct drm_device *dev);
extern void intel_crtc_load_lut(struct drm_crtc *crtc); extern void intel_crtc_load_lut(struct drm_crtc *crtc);
......
...@@ -552,6 +552,8 @@ static void intel_lvds_destroy(struct drm_connector *connector) ...@@ -552,6 +552,8 @@ static void intel_lvds_destroy(struct drm_connector *connector)
struct drm_device *dev = connector->dev; struct drm_device *dev = connector->dev;
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
intel_panel_destroy_backlight(dev);
if (dev_priv->lid_notifier.notifier_call) if (dev_priv->lid_notifier.notifier_call)
acpi_lid_notifier_unregister(&dev_priv->lid_notifier); acpi_lid_notifier_unregister(&dev_priv->lid_notifier);
drm_sysfs_connector_remove(connector); drm_sysfs_connector_remove(connector);
...@@ -1032,6 +1034,9 @@ bool intel_lvds_init(struct drm_device *dev) ...@@ -1032,6 +1034,9 @@ bool intel_lvds_init(struct drm_device *dev)
/* keep the LVDS connector */ /* keep the LVDS connector */
dev_priv->int_lvds_connector = connector; dev_priv->int_lvds_connector = connector;
drm_sysfs_connector_add(connector); drm_sysfs_connector_add(connector);
intel_panel_setup_backlight(dev);
return true; return true;
failed: failed:
......
...@@ -227,7 +227,6 @@ void intel_opregion_asle_intr(struct drm_device *dev) ...@@ -227,7 +227,6 @@ void intel_opregion_asle_intr(struct drm_device *dev)
asle->aslc = asle_stat; asle->aslc = asle_stat;
} }
/* Only present on Ironlake+ */
void intel_opregion_gse_intr(struct drm_device *dev) void intel_opregion_gse_intr(struct drm_device *dev)
{ {
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
......
...@@ -277,7 +277,7 @@ void intel_panel_enable_backlight(struct drm_device *dev) ...@@ -277,7 +277,7 @@ void intel_panel_enable_backlight(struct drm_device *dev)
dev_priv->backlight_enabled = true; dev_priv->backlight_enabled = true;
} }
void intel_panel_setup_backlight(struct drm_device *dev) static void intel_panel_init_backlight(struct drm_device *dev)
{ {
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
...@@ -309,3 +309,73 @@ intel_panel_detect(struct drm_device *dev) ...@@ -309,3 +309,73 @@ intel_panel_detect(struct drm_device *dev)
return connector_status_unknown; return connector_status_unknown;
} }
#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
static int intel_panel_update_status(struct backlight_device *bd)
{
struct drm_device *dev = bl_get_data(bd);
intel_panel_set_backlight(dev, bd->props.brightness);
return 0;
}
static int intel_panel_get_brightness(struct backlight_device *bd)
{
struct drm_device *dev = bl_get_data(bd);
return intel_panel_get_backlight(dev);
}
static const struct backlight_ops intel_panel_bl_ops = {
.update_status = intel_panel_update_status,
.get_brightness = intel_panel_get_brightness,
};
int intel_panel_setup_backlight(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
struct backlight_properties props;
struct drm_connector *connector;
intel_panel_init_backlight(dev);
if (dev_priv->int_lvds_connector)
connector = dev_priv->int_lvds_connector;
else if (dev_priv->int_edp_connector)
connector = dev_priv->int_edp_connector;
else
return -ENODEV;
props.type = BACKLIGHT_RAW;
props.max_brightness = intel_panel_get_max_backlight(dev);
dev_priv->backlight =
backlight_device_register("intel_backlight",
&connector->kdev, dev,
&intel_panel_bl_ops, &props);
if (IS_ERR(dev_priv->backlight)) {
DRM_ERROR("Failed to register backlight: %ld\n",
PTR_ERR(dev_priv->backlight));
dev_priv->backlight = NULL;
return -ENODEV;
}
dev_priv->backlight->props.brightness = intel_panel_get_backlight(dev);
return 0;
}
void intel_panel_destroy_backlight(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
if (dev_priv->backlight)
backlight_device_unregister(dev_priv->backlight);
}
#else
int intel_panel_setup_backlight(struct drm_device *dev)
{
intel_panel_init_backlight(dev);
return 0;
}
void intel_panel_destroy_backlight(struct drm_device *dev)
{
return;
}
#endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment