1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * GMA500 Backlight Interface |
4 | * |
5 | * Copyright (c) 2009-2011, Intel Corporation. |
6 | * |
7 | * Authors: Eric Knopp |
8 | */ |
9 | |
10 | #include <linux/backlight.h> |
11 | |
12 | #include <acpi/video.h> |
13 | |
14 | #include "psb_drv.h" |
15 | #include "psb_intel_reg.h" |
16 | #include "psb_intel_drv.h" |
17 | #include "intel_bios.h" |
18 | #include "power.h" |
19 | |
20 | void gma_backlight_enable(struct drm_device *dev) |
21 | { |
22 | struct drm_psb_private *dev_priv = to_drm_psb_private(dev); |
23 | |
24 | dev_priv->backlight_enabled = true; |
25 | dev_priv->ops->backlight_set(dev, dev_priv->backlight_level); |
26 | } |
27 | |
28 | void gma_backlight_disable(struct drm_device *dev) |
29 | { |
30 | struct drm_psb_private *dev_priv = to_drm_psb_private(dev); |
31 | |
32 | dev_priv->backlight_enabled = false; |
33 | dev_priv->ops->backlight_set(dev, 0); |
34 | } |
35 | |
36 | void gma_backlight_set(struct drm_device *dev, int v) |
37 | { |
38 | struct drm_psb_private *dev_priv = to_drm_psb_private(dev); |
39 | |
40 | dev_priv->backlight_level = v; |
41 | if (dev_priv->backlight_enabled) |
42 | dev_priv->ops->backlight_set(dev, v); |
43 | } |
44 | |
45 | static int gma_backlight_get_brightness(struct backlight_device *bd) |
46 | { |
47 | struct drm_device *dev = bl_get_data(bl_dev: bd); |
48 | struct drm_psb_private *dev_priv = to_drm_psb_private(dev); |
49 | |
50 | if (dev_priv->ops->backlight_get) |
51 | return dev_priv->ops->backlight_get(dev); |
52 | |
53 | return dev_priv->backlight_level; |
54 | } |
55 | |
56 | static int gma_backlight_update_status(struct backlight_device *bd) |
57 | { |
58 | struct drm_device *dev = bl_get_data(bl_dev: bd); |
59 | int level = backlight_get_brightness(bd); |
60 | |
61 | /* Percentage 1-100% being valid */ |
62 | if (level < 1) |
63 | level = 1; |
64 | |
65 | gma_backlight_set(dev, v: level); |
66 | return 0; |
67 | } |
68 | |
69 | static const struct backlight_ops gma_backlight_ops __maybe_unused = { |
70 | .get_brightness = gma_backlight_get_brightness, |
71 | .update_status = gma_backlight_update_status, |
72 | }; |
73 | |
74 | int gma_backlight_init(struct drm_device *dev) |
75 | { |
76 | struct drm_psb_private *dev_priv = to_drm_psb_private(dev); |
77 | struct backlight_properties props __maybe_unused = {}; |
78 | int ret; |
79 | |
80 | dev_priv->backlight_enabled = true; |
81 | dev_priv->backlight_level = 100; |
82 | |
83 | ret = dev_priv->ops->backlight_init(dev); |
84 | if (ret) |
85 | return ret; |
86 | |
87 | if (!acpi_video_backlight_use_native()) { |
88 | drm_info(dev, "Skipping %s backlight registration\n" , |
89 | dev_priv->ops->backlight_name); |
90 | return 0; |
91 | } |
92 | |
93 | #ifdef CONFIG_BACKLIGHT_CLASS_DEVICE |
94 | props.brightness = dev_priv->backlight_level; |
95 | props.max_brightness = PSB_MAX_BRIGHTNESS; |
96 | props.type = BACKLIGHT_RAW; |
97 | |
98 | dev_priv->backlight_device = |
99 | backlight_device_register(name: dev_priv->ops->backlight_name, |
100 | dev: dev->dev, devdata: dev, |
101 | ops: &gma_backlight_ops, props: &props); |
102 | if (IS_ERR(ptr: dev_priv->backlight_device)) |
103 | return PTR_ERR(ptr: dev_priv->backlight_device); |
104 | #endif |
105 | |
106 | return 0; |
107 | } |
108 | |
109 | void gma_backlight_exit(struct drm_device *dev) |
110 | { |
111 | #ifdef CONFIG_BACKLIGHT_CLASS_DEVICE |
112 | struct drm_psb_private *dev_priv = to_drm_psb_private(dev); |
113 | |
114 | if (dev_priv->backlight_device) |
115 | backlight_device_unregister(bd: dev_priv->backlight_device); |
116 | #endif |
117 | } |
118 | |