71 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
73 #include <linux/module.h>
74 #include <linux/kernel.h>
80 #include <linux/rfkill.h>
90 #define DRIVER_NAME "compal-laptop"
91 #define DRIVER_VERSION "0.2.7"
93 #define BACKLIGHT_LEVEL_ADDR 0xB9
94 #define BACKLIGHT_LEVEL_MAX 7
95 #define BACKLIGHT_STATE_ADDR 0x59
96 #define BACKLIGHT_STATE_ON_DATA 0xE1
97 #define BACKLIGHT_STATE_OFF_DATA 0xE2
99 #define WAKE_UP_ADDR 0xA4
100 #define WAKE_UP_PME (1 << 0)
101 #define WAKE_UP_MODEM (1 << 1)
102 #define WAKE_UP_LAN (1 << 2)
103 #define WAKE_UP_WLAN (1 << 4)
104 #define WAKE_UP_KEY (1 << 6)
105 #define WAKE_UP_MOUSE (1 << 7)
107 #define WIRELESS_ADDR 0xBB
108 #define WIRELESS_WLAN (1 << 0)
109 #define WIRELESS_BT (1 << 1)
110 #define WIRELESS_WLAN_EXISTS (1 << 2)
111 #define WIRELESS_BT_EXISTS (1 << 3)
112 #define WIRELESS_KILLSWITCH (1 << 4)
114 #define PWM_ADDRESS 0x46
115 #define PWM_DISABLE_ADDR 0x59
116 #define PWM_DISABLE_DATA 0xA5
117 #define PWM_ENABLE_ADDR 0x59
118 #define PWM_ENABLE_DATA 0xA8
120 #define FAN_ADDRESS 0x46
121 #define FAN_DATA 0x81
122 #define FAN_FULL_ON_CMD 0x59
123 #define FAN_FULL_ON_ENABLE 0x76
124 #define FAN_FULL_ON_DISABLE 0x77
126 #define TEMP_CPU 0xB0
127 #define TEMP_CPU_LOCAL 0xB1
128 #define TEMP_CPU_DTS 0xB5
129 #define TEMP_NORTHBRIDGE 0xB6
130 #define TEMP_VGA 0xB4
131 #define TEMP_SKIN 0xB2
133 #define BAT_MANUFACTURER_NAME_ADDR 0x10
134 #define BAT_MANUFACTURER_NAME_LEN 9
135 #define BAT_MODEL_NAME_ADDR 0x19
136 #define BAT_MODEL_NAME_LEN 6
137 #define BAT_SERIAL_NUMBER_ADDR 0xC4
138 #define BAT_SERIAL_NUMBER_LEN 5
139 #define BAT_CHARGE_NOW 0xC2
140 #define BAT_CHARGE_DESIGN 0xCA
141 #define BAT_VOLTAGE_NOW 0xC6
142 #define BAT_VOLTAGE_DESIGN 0xC8
143 #define BAT_CURRENT_NOW 0xD0
144 #define BAT_CURRENT_AVG 0xD2
145 #define BAT_POWER 0xD4
146 #define BAT_CAPACITY 0xCE
147 #define BAT_TEMP 0xD6
148 #define BAT_TEMP_AVG 0xD7
149 #define BAT_STATUS0 0xC1
150 #define BAT_STATUS1 0xF0
151 #define BAT_STATUS2 0xF1
152 #define BAT_STOP_CHARGE1 0xF2
153 #define BAT_STOP_CHARGE2 0xF3
155 #define BAT_S0_DISCHARGE (1 << 0)
156 #define BAT_S0_DISCHRG_CRITICAL (1 << 2)
157 #define BAT_S0_LOW (1 << 3)
158 #define BAT_S0_CHARGING (1 << 1)
159 #define BAT_S0_AC (1 << 7)
160 #define BAT_S1_EXISTS (1 << 0)
161 #define BAT_S1_FULL (1 << 1)
162 #define BAT_S1_EMPTY (1 << 2)
163 #define BAT_S1_LiION_OR_NiMH (1 << 7)
164 #define BAT_S2_LOW_LOW (1 << 0)
165 #define BAT_STOP_CHRG1_BAD_CELL (1 << 1)
166 #define BAT_STOP_CHRG1_COMM_FAIL (1 << 2)
167 #define BAT_STOP_CHRG1_OVERVOLTAGE (1 << 6)
168 #define BAT_STOP_CHRG1_OVERTEMPERATURE (1 << 7)
198 static bool extra_features;
212 static const unsigned char pwm_lookup_table[256] = {
213 0, 0, 0, 1, 1, 1, 2, 253, 254, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6,
214 7, 7, 7, 8, 86, 86, 9, 9, 9, 10, 10, 10, 11, 92, 92, 12, 12, 95,
215 13, 66, 66, 14, 14, 98, 15, 15, 15, 16, 16, 67, 17, 17, 72, 18, 70,
216 75, 19, 90, 90, 73, 73, 73, 21, 21, 91, 91, 91, 96, 23, 94, 94, 94,
217 94, 94, 94, 94, 94, 94, 94, 141, 141, 238, 223, 192, 139, 139, 139,
218 139, 139, 142, 142, 142, 142, 142, 78, 78, 78, 78, 78, 76, 76, 76,
219 76, 76, 79, 79, 79, 79, 79, 79, 79, 20, 20, 20, 20, 20, 22, 22, 22,
220 22, 22, 24, 24, 24, 24, 24, 24, 219, 219, 219, 219, 219, 219, 219,
221 219, 27, 27, 188, 188, 28, 28, 28, 29, 186, 186, 186, 186, 186,
222 186, 186, 186, 186, 186, 31, 31, 31, 31, 31, 32, 32, 32, 41, 33,
223 33, 33, 33, 33, 252, 252, 34, 34, 34, 43, 35, 35, 35, 36, 36, 38,
224 206, 206, 206, 206, 206, 206, 206, 206, 206, 37, 37, 37, 46, 46,
225 47, 47, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 48, 48,
226 48, 48, 48, 40, 40, 40, 49, 42, 42, 42, 42, 42, 42, 42, 42, 44,
227 189, 189, 189, 189, 54, 54, 45, 45, 45, 45, 45, 45, 45, 45, 251,
228 191, 199, 199, 199, 199, 199, 215, 215, 215, 215, 187, 187, 187,
248 return (
s8)ec_read_u8(addr);
251 static u16 ec_read_u16(
u8 addr)
254 lo = ec_read_u8(addr);
255 hi = ec_read_u8(addr + 1);
256 return (hi << 8) + lo;
259 static s16 ec_read_s16(
u8 addr)
261 return (
s16) ec_read_u16(addr);
264 static void ec_read_sequence(
u8 addr,
u8 *
buf,
int len)
267 for (i = 0; i < len; i++)
273 static int set_backlight_level(
int level)
283 static int get_backlight_level(
void)
288 static void set_backlight_state(
bool on)
296 static void pwm_enable_control(
void)
302 static void pwm_disable_control(
void)
308 static void set_pwm(
int pwm)
313 static int get_fan_rpm(
void)
317 return 100 * (
int)value;
330 return get_backlight_level();
335 int ret = set_backlight_level(b->
props.brightness);
346 .get_brightness = bl_get_brightness,
347 .update_status = bl_update_status,
352 static int compal_rfkill_set(
void *
data,
bool blocked)
354 unsigned long radio = (
unsigned long) data;
359 value = (
u8) (result | radio);
361 value = (
u8) (result & ~radio);
367 static void compal_rfkill_poll(
struct rfkill *
rfkill,
void *data)
374 static const struct rfkill_ops compal_rfkill_ops = {
375 .poll = compal_rfkill_poll,
376 .set_block = compal_rfkill_set,
381 #define SIMPLE_MASKED_STORE_SHOW(NAME, ADDR, MASK) \
382 static ssize_t NAME##_show(struct device *dev, \
383 struct device_attribute *attr, char *buf) \
385 return sprintf(buf, "%d\n", ((ec_read_u8(ADDR) & MASK) != 0)); \
387 static ssize_t NAME##_store(struct device *dev, \
388 struct device_attribute *attr, const char *buf, size_t count) \
391 u8 old_val = ec_read_u8(ADDR); \
392 if (sscanf(buf, "%d", &state) != 1 || (state < 0 || state > 1)) \
394 ec_write(ADDR, state ? (old_val | MASK) : (old_val & ~MASK)); \
438 pwm_enable_control();
442 pwm_enable_control();
446 pwm_disable_control();
461 const char *buf,
size_t count)
469 if (val < 0 || val > 255)
484 return sprintf(buf,
"%d\n", get_fan_rpm());
489 #define TEMPERATURE_SHOW_TEMP_AND_LABEL(POSTFIX, ADDRESS, LABEL) \
490 static ssize_t temp_##POSTFIX(struct device *dev, \
491 struct device_attribute *attr, char *buf) \
493 return sprintf(buf, "%d\n", 1000 * (int)ec_read_s8(ADDRESS)); \
495 static ssize_t label_##POSTFIX(struct device *dev, \
496 struct device_attribute *attr, char *buf) \
498 return sprintf(buf, "%s\n", LABEL); \
511 static int bat_status(
void)
525 static int bat_health(
void)
540 static int bat_is_present(
void)
546 static int bat_technology(
void)
555 static int bat_capacity_level(
void)
581 val->
intval = bat_status();
584 val->
intval = bat_health();
587 val->
intval = bat_is_present();
590 val->
intval = bat_technology();
617 val->
intval = bat_capacity_level();
654 0644, wake_up_pme_show, wake_up_pme_store);
656 0644, wake_up_modem_show, wake_up_modem_store);
658 0644, wake_up_lan_show, wake_up_lan_store);
660 0644, wake_up_wlan_show, wake_up_wlan_store);
662 0644, wake_up_key_show, wake_up_key_store);
664 0644, wake_up_mouse_show, wake_up_mouse_store);
684 static struct attribute *compal_attributes[] = {
685 &dev_attr_wake_up_pme.attr,
686 &dev_attr_wake_up_modem.attr,
687 &dev_attr_wake_up_lan.attr,
688 &dev_attr_wake_up_wlan.attr,
689 &dev_attr_wake_up_key.attr,
690 &dev_attr_wake_up_mouse.attr,
693 &sensor_dev_attr_name.dev_attr.attr,
694 &sensor_dev_attr_pwm1_enable.dev_attr.attr,
695 &sensor_dev_attr_pwm1.dev_attr.attr,
696 &sensor_dev_attr_fan1_input.dev_attr.attr,
697 &sensor_dev_attr_temp1_input.dev_attr.attr,
698 &sensor_dev_attr_temp2_input.dev_attr.attr,
699 &sensor_dev_attr_temp3_input.dev_attr.attr,
700 &sensor_dev_attr_temp4_input.dev_attr.attr,
701 &sensor_dev_attr_temp5_input.dev_attr.attr,
702 &sensor_dev_attr_temp6_input.dev_attr.attr,
703 &sensor_dev_attr_temp1_label.dev_attr.attr,
704 &sensor_dev_attr_temp2_label.dev_attr.attr,
705 &sensor_dev_attr_temp3_label.dev_attr.attr,
706 &sensor_dev_attr_temp4_label.dev_attr.attr,
707 &sensor_dev_attr_temp5_label.dev_attr.attr,
708 &sensor_dev_attr_temp6_label.dev_attr.attr,
713 .attrs = compal_attributes
723 .probe = compal_probe,
752 static struct rfkill *wifi_rfkill;
753 static struct rfkill *bt_rfkill;
766 extra_features =
false;
770 static int dmi_check_cb_extra(
const struct dmi_system_id *
id)
772 pr_info(
"Identified laptop model '%s', enabling extra features\n",
774 extra_features =
true;
780 .ident =
"FL90/IFL90",
785 .callback = dmi_check_cb
788 .ident =
"FL90/IFL90",
793 .callback = dmi_check_cb
796 .ident =
"FL91/IFL91",
801 .callback = dmi_check_cb
804 .ident =
"FL92/JFL92",
809 .callback = dmi_check_cb
812 .ident =
"FT00/IFT00",
817 .callback = dmi_check_cb
820 .ident =
"Dell Mini 9",
825 .callback = dmi_check_cb
828 .ident =
"Dell Mini 10",
833 .callback = dmi_check_cb
836 .ident =
"Dell Mini 10v",
841 .callback = dmi_check_cb
844 .ident =
"Dell Mini 1012",
849 .callback = dmi_check_cb
852 .ident =
"Dell Inspiron 11z",
857 .callback = dmi_check_cb
860 .ident =
"Dell Mini 12",
865 .callback = dmi_check_cb
873 .callback = dmi_check_cb_extra
881 .callback = dmi_check_cb_extra
887 static void initialize_power_supply_data(
struct compal_data *data)
891 data->
psy.properties = compal_bat_properties;
892 data->
psy.num_properties =
ARRAY_SIZE(compal_bat_properties);
893 data->
psy.get_property = bat_get_property;
909 static void initialize_fan_control_data(
struct compal_data *data)
916 static int setup_rfkill(
void)
935 goto err_allocate_bt;
939 goto err_register_bt;
955 static int __init compal_init(
void)
960 pr_err(
"ACPI needs to be enabled for this driver to work!\n");
965 pr_err(
"Motherboard not recognized (You could try the module's force-parameter)\n");
978 if (IS_ERR(compalbl_device))
979 return PTR_ERR(compalbl_device);
987 if (!compal_device) {
989 goto err_platform_driver;
994 goto err_platform_device;
996 ret = setup_rfkill();
1006 err_platform_device:
1009 err_platform_driver:
1023 if (!extra_features)
1031 initialize_fan_control_data(data);
1043 &compal_attribute_group);
1049 initialize_power_supply_data(data);
1052 platform_set_drvdata(pdev, data);
1057 static void __exit compal_cleanup(
void)
1074 if (!extra_features)
1077 pr_info(
"Unloading: resetting fan control to motherboard\n");
1078 pwm_disable_control();
1080 data = platform_get_drvdata(pdev);
1084 platform_set_drvdata(pdev,
NULL);