2121
2222struct int3406_thermal_data {
2323 int upper_limit ;
24- int upper_limit_index ;
2524 int lower_limit ;
26- int lower_limit_index ;
2725 acpi_handle handle ;
2826 struct acpi_video_device_brightness * br ;
2927 struct backlight_device * raw_bd ;
3028 struct thermal_cooling_device * cooling_dev ;
3129};
3230
33- static int int3406_thermal_to_raw (int level , struct int3406_thermal_data * d )
34- {
35- int max_level = d -> br -> levels [d -> br -> count - 1 ];
36- int raw_max = d -> raw_bd -> props .max_brightness ;
37-
38- return level * raw_max / max_level ;
39- }
40-
41- static int int3406_thermal_to_acpi (int level , struct int3406_thermal_data * d )
42- {
43- int raw_max = d -> raw_bd -> props .max_brightness ;
44- int max_level = d -> br -> levels [d -> br -> count - 1 ];
45-
46- return level * max_level / raw_max ;
47- }
31+ /*
32+ * According to the ACPI spec,
33+ * "Each brightness level is represented by a number between 0 and 100,
34+ * and can be thought of as a percentage. For example, 50 can be 50%
35+ * power consumption or 50% brightness, as defined by the OEM."
36+ *
37+ * As int3406 device uses this value to communicate with the native
38+ * graphics driver, we make the assumption that it represents
39+ * the percentage of brightness only
40+ */
41+ #define ACPI_TO_RAW (v , d ) (d->raw_bd->props.max_brightness * v / 100)
42+ #define RAW_TO_ACPI (v , d ) (v * 100 / d->raw_bd->props.max_brightness)
4843
4944static int
5045int3406_thermal_get_max_state (struct thermal_cooling_device * cooling_dev ,
5146 unsigned long * state )
5247{
5348 struct int3406_thermal_data * d = cooling_dev -> devdata ;
54- int index = d -> lower_limit_index ? d -> lower_limit_index : 2 ;
5549
56- * state = d -> br -> count - 1 - index ;
50+ * state = d -> upper_limit - d -> lower_limit ;
5751 return 0 ;
5852}
5953
@@ -62,19 +56,15 @@ int3406_thermal_set_cur_state(struct thermal_cooling_device *cooling_dev,
6256 unsigned long state )
6357{
6458 struct int3406_thermal_data * d = cooling_dev -> devdata ;
65- int level , raw_level ;
59+ int acpi_level , raw_level ;
6660
67- if (state > d -> br -> count - 3 )
61+ if (state > d -> upper_limit - d -> lower_limit )
6862 return - EINVAL ;
6963
70- state = d -> br -> count - 1 - state ;
71- level = d -> br -> levels [state ];
64+ acpi_level = d -> br -> levels [d -> upper_limit - state ];
7265
73- if ((d -> upper_limit && level > d -> upper_limit ) ||
74- (d -> lower_limit && level < d -> lower_limit ))
75- return - EINVAL ;
66+ raw_level = ACPI_TO_RAW (acpi_level , d );
7667
77- raw_level = int3406_thermal_to_raw (level , d );
7868 return backlight_device_set_brightness (d -> raw_bd , raw_level );
7969}
8070
@@ -83,27 +73,22 @@ int3406_thermal_get_cur_state(struct thermal_cooling_device *cooling_dev,
8373 unsigned long * state )
8474{
8575 struct int3406_thermal_data * d = cooling_dev -> devdata ;
86- int raw_level , level , i ;
87- int * levels = d -> br -> levels ;
76+ int acpi_level ;
77+ int index ;
8878
89- raw_level = d -> raw_bd -> props .brightness ;
90- level = int3406_thermal_to_acpi (raw_level , d );
79+ acpi_level = RAW_TO_ACPI (d -> raw_bd -> props .brightness , d );
9180
9281 /*
93- * There is no 1:1 mapping between the firmware interface level with the
94- * raw interface level, we will have to find one that is close enough.
82+ * There is no 1:1 mapping between the firmware interface level
83+ * with the raw interface level, we will have to find one that is
84+ * right above it.
9585 */
96- for (i = 2 ; i < d -> br -> count ; i ++ ) {
97- if (level < levels [i ]) {
98- if (i == 2 )
99- break ;
100- if ((level - levels [i - 1 ]) < (levels [i ] - level ))
101- i -- ;
86+ for (index = d -> lower_limit ; index < d -> upper_limit ; index ++ ) {
87+ if (acpi_level <= d -> br -> levels [index ])
10288 break ;
103- }
10489 }
10590
106- * state = d -> br -> count - 1 - i ;
91+ * state = d -> upper_limit - index ;
10792 return 0 ;
10893}
10994
@@ -117,7 +102,7 @@ static int int3406_thermal_get_index(int *array, int nr, int value)
117102{
118103 int i ;
119104
120- for (i = 0 ; i < nr ; i ++ ) {
105+ for (i = 2 ; i < nr ; i ++ ) {
121106 if (array [i ] == value )
122107 break ;
123108 }
@@ -128,27 +113,20 @@ static void int3406_thermal_get_limit(struct int3406_thermal_data *d)
128113{
129114 acpi_status status ;
130115 unsigned long long lower_limit , upper_limit ;
131- int index ;
132116
133117 status = acpi_evaluate_integer (d -> handle , "DDDL" , NULL , & lower_limit );
134- if (ACPI_SUCCESS (status )) {
135- index = int3406_thermal_get_index (d -> br -> levels , d -> br -> count ,
136- lower_limit );
137- if (index > 0 ) {
138- d -> lower_limit = (int )lower_limit ;
139- d -> lower_limit_index = index ;
140- }
141- }
118+ if (ACPI_SUCCESS (status ))
119+ d -> lower_limit = int3406_thermal_get_index (d -> br -> levels ,
120+ d -> br -> count , lower_limit );
142121
143122 status = acpi_evaluate_integer (d -> handle , "DDPC" , NULL , & upper_limit );
144- if (ACPI_SUCCESS (status )) {
145- index = int3406_thermal_get_index (d -> br -> levels , d -> br -> count ,
146- upper_limit );
147- if (index > 0 ) {
148- d -> upper_limit = (int )upper_limit ;
149- d -> upper_limit_index = index ;
150- }
151- }
123+ if (ACPI_SUCCESS (status ))
124+ d -> upper_limit = int3406_thermal_get_index (d -> br -> levels ,
125+ d -> br -> count , upper_limit );
126+
127+ /* lower_limit and upper_limit should be always set */
128+ d -> lower_limit = d -> lower_limit > 0 ? d -> lower_limit : 2 ;
129+ d -> upper_limit = d -> upper_limit > 0 ? d -> upper_limit : d -> br -> count - 1 ;
152130}
153131
154132static void int3406_notify (acpi_handle handle , u32 event , void * data )
0 commit comments