Lines Matching +full:kbd +full:- +full:led +full:- +full:backlight
1 // SPDX-License-Identifier: GPL-2.0-only
3 * drivers/hwmon/applesmc.c - driver for Apple's SMC (accelerometer, temperature
4 * sensors, fan control, keyboard backlight control) used in Intel-based Apple
29 #include <linux/hwmon-sysfs.h>
42 #define APPLESMC_NR_PORTS 32 /* 0x300-0x31f */
59 #define KEY_COUNT_KEY "#KEY" /* r-o ui32 */
61 #define LIGHT_SENSOR_LEFT_KEY "ALV0" /* r-o {alv (6-10 bytes) */
62 #define LIGHT_SENSOR_RIGHT_KEY "ALV1" /* r-o {alv (6-10 bytes) */
63 #define BACKLIGHT_KEY "LKSB" /* w-o {lkb (2 bytes) */
65 #define CLAMSHELL_KEY "MSLD" /* r-o ui8 (unused) */
67 #define MOTION_SENSOR_X_KEY "MO_X" /* r-o sp78 (2 bytes) */
68 #define MOTION_SENSOR_Y_KEY "MO_Y" /* r-o sp78 (2 bytes) */
69 #define MOTION_SENSOR_Z_KEY "MO_Z" /* r-o sp78 (2 bytes) */
72 #define FANS_COUNT "FNum" /* r-o ui8 */
73 #define FANS_MANUAL "FS! " /* r-w ui16 */
74 #define FAN_ID_FMT "F%dID" /* r-o char[16] */
83 "F%dSf", /* safe speed - not all models */
94 #define to_index(attr) (to_sensor_dev_attr(attr)->index & 0xffff)
95 #define to_option(attr) (to_sensor_dev_attr(attr)->index >> 16)
112 /* AppleSMC entry - cached register information */
114 char key[5]; /* four-letter key code */
117 char type[5]; /* four-letter type code */
132 bool has_key_backlight; /* has keyboard backlight */
180 return -EIO; in wait_status()
183 /* send_byte - Write to SMC data port. Callers must hold applesmc_lock. */
206 /* send_command - Write a command to the SMC. Callers must hold applesmc_lock. */
244 return -EIO; in send_argument()
260 return -EIO; in read_smc()
266 return -EIO; in read_smc()
273 return -EIO; in read_smc()
303 return -EIO; in write_smc()
308 return -EIO; in write_smc()
314 return -EIO; in write_smc()
338 * All functions below are concurrency safe - callers should NOT hold lock.
346 if (entry->len != len) in applesmc_read_entry()
347 return -EINVAL; in applesmc_read_entry()
349 ret = read_smc(APPLESMC_READ_CMD, entry->key, buf, len); in applesmc_read_entry()
360 if (entry->len != len) in applesmc_write_entry()
361 return -EINVAL; in applesmc_write_entry()
363 ret = write_smc(APPLESMC_WRITE_CMD, entry->key, buf, len); in applesmc_write_entry()
375 if (cache->valid) in applesmc_get_entry_by_index()
380 if (cache->valid) in applesmc_get_entry_by_index()
390 memcpy(cache->key, key, 4); in applesmc_get_entry_by_index()
391 cache->len = info[0]; in applesmc_get_entry_by_index()
392 memcpy(cache->type, &info[1], 4); in applesmc_get_entry_by_index()
393 cache->flags = info[5]; in applesmc_get_entry_by_index()
394 cache->valid = true; in applesmc_get_entry_by_index()
409 int middle = begin + (end - begin) / 2; in applesmc_get_lower_bound()
415 if (strcmp(entry->key, key) < 0) in applesmc_get_lower_bound()
431 int middle = begin + (end - begin) / 2; in applesmc_get_upper_bound()
437 if (strcmp(key, entry->key) < 0) in applesmc_get_upper_bound()
458 if (end - begin != 1) in applesmc_get_entry_by_key()
459 return ERR_PTR(-EINVAL); in applesmc_get_entry_by_key()
491 if (IS_ERR(entry) && PTR_ERR(entry) != -EINVAL) in applesmc_has_key()
499 * applesmc_read_s16 - Read 16-bit signed big endian register
515 * applesmc_device_init - initialize the accelerometer. Can sleep.
525 for (total = INIT_TIMEOUT_MSECS; total > 0; total -= INIT_WAIT_MSECS) { in applesmc_device_init()
543 if (s->index) in applesmc_init_index()
546 s->index = kcalloc(s->temp_count, sizeof(s->index[0]), GFP_KERNEL); in applesmc_init_index()
547 if (!s->index) in applesmc_init_index()
548 return -ENOMEM; in applesmc_init_index()
550 for (i = s->temp_begin; i < s->temp_end; i++) { in applesmc_init_index()
554 if (strcmp(entry->type, TEMP_SENSOR_TYPE)) in applesmc_init_index()
556 s->index[s->index_count++] = entry->key; in applesmc_init_index()
563 * applesmc_init_smcreg_try - Try to initialize register cache. Idempotent.
573 if (s->init_complete) in applesmc_init_smcreg_try()
580 if (s->cache && s->key_count != count) { in applesmc_init_smcreg_try()
582 s->key_count, count); in applesmc_init_smcreg_try()
583 kfree(s->cache); in applesmc_init_smcreg_try()
584 s->cache = NULL; in applesmc_init_smcreg_try()
586 s->key_count = count; in applesmc_init_smcreg_try()
588 if (!s->cache) in applesmc_init_smcreg_try()
589 s->cache = kcalloc(s->key_count, sizeof(*s->cache), GFP_KERNEL); in applesmc_init_smcreg_try()
590 if (!s->cache) in applesmc_init_smcreg_try()
591 return -ENOMEM; in applesmc_init_smcreg_try()
596 s->fan_count = tmp[0]; in applesmc_init_smcreg_try()
597 if (s->fan_count > 10) in applesmc_init_smcreg_try()
598 s->fan_count = 10; in applesmc_init_smcreg_try()
600 ret = applesmc_get_lower_bound(&s->temp_begin, "T"); in applesmc_init_smcreg_try()
603 ret = applesmc_get_lower_bound(&s->temp_end, "U"); in applesmc_init_smcreg_try()
606 s->temp_count = s->temp_end - s->temp_begin; in applesmc_init_smcreg_try()
618 ret = applesmc_has_key(MOTION_SENSOR_KEY, &s->has_accelerometer); in applesmc_init_smcreg_try()
621 ret = applesmc_has_key(BACKLIGHT_KEY, &s->has_key_backlight); in applesmc_init_smcreg_try()
625 s->num_light_sensors = left_light_sensor + right_light_sensor; in applesmc_init_smcreg_try()
626 s->init_complete = true; in applesmc_init_smcreg_try()
628 pr_info("key=%d fan=%d temp=%d index=%d acc=%d lux=%d kbd=%d\n", in applesmc_init_smcreg_try()
629 s->key_count, s->fan_count, s->temp_count, s->index_count, in applesmc_init_smcreg_try()
630 s->has_accelerometer, in applesmc_init_smcreg_try()
631 s->num_light_sensors, in applesmc_init_smcreg_try()
632 s->has_key_backlight); in applesmc_init_smcreg_try()
647 * applesmc_init_smcreg - Initialize register cache.
685 /* Synchronize device with memorized backlight state */
714 * applesmc_calibrate - Set our "resting" values. Callers must
721 rest_x = -rest_x; in applesmc_calibrate()
733 x = -x; in applesmc_idev_poll()
734 input_report_abs(idev, ABS_X, x - rest_x); in applesmc_idev_poll()
735 input_report_abs(idev, ABS_Y, y - rest_y); in applesmc_idev_poll()
783 if (entry->len > 10) in applesmc_light_show()
784 return -ENXIO; in applesmc_light_show()
785 data_length = entry->len; in applesmc_light_show()
792 /* newer macbooks report a single 10-bit bigendian value */ in applesmc_light_show()
867 return -EINVAL; /* Bigger than a 14-bit value */ in applesmc_store_fan_speed()
907 return -EINVAL; in applesmc_store_fan_manual()
979 dev_dbg(led_cdev->dev, "work was already on the queue.\n"); in applesmc_brightness_set()
1007 ret = applesmc_read_entry(entry, sysfsbuf, entry->len); in applesmc_key_at_index_read_show()
1011 return entry->len; in applesmc_key_at_index_read_show()
1023 return sysfs_emit(sysfsbuf, "%d\n", entry->len); in applesmc_key_at_index_data_length_show()
1035 return sysfs_emit(sysfsbuf, "%s\n", entry->type); in applesmc_key_at_index_type_show()
1047 return sysfs_emit(sysfsbuf, "%s\n", entry->key); in applesmc_key_at_index_name_show()
1063 return -EINVAL; in applesmc_key_at_index_store()
1071 .default_trigger = "nand-disk",
1117 * applesmc_destroy_nodes - remove files and free associated memory
1124 for (grp = groups; grp->nodes; grp++) { in applesmc_destroy_nodes()
1125 for (node = grp->nodes; node->sda.dev_attr.attr.name; node++) in applesmc_destroy_nodes()
1126 sysfs_remove_file(&pdev->dev.kobj, in applesmc_destroy_nodes()
1127 &node->sda.dev_attr.attr); in applesmc_destroy_nodes()
1128 kfree(grp->nodes); in applesmc_destroy_nodes()
1129 grp->nodes = NULL; in applesmc_destroy_nodes()
1134 * applesmc_create_nodes - create a two-dimensional group of sysfs files
1143 for (grp = groups; grp->format; grp++) { in applesmc_create_nodes()
1144 grp->nodes = kcalloc(num + 1, sizeof(*node), GFP_KERNEL); in applesmc_create_nodes()
1145 if (!grp->nodes) { in applesmc_create_nodes()
1146 ret = -ENOMEM; in applesmc_create_nodes()
1150 node = &grp->nodes[i]; in applesmc_create_nodes()
1151 scnprintf(node->name, sizeof(node->name), grp->format, in applesmc_create_nodes()
1153 node->sda.index = (grp->option << 16) | (i & 0xffff); in applesmc_create_nodes()
1154 node->sda.dev_attr.show = grp->show; in applesmc_create_nodes()
1155 node->sda.dev_attr.store = grp->store; in applesmc_create_nodes()
1156 attr = &node->sda.dev_attr.attr; in applesmc_create_nodes()
1158 attr->name = node->name; in applesmc_create_nodes()
1159 attr->mode = 0444 | (grp->store ? 0200 : 0); in applesmc_create_nodes()
1160 ret = sysfs_create_file(&pdev->dev.kobj, attr); in applesmc_create_nodes()
1162 attr->name = NULL; in applesmc_create_nodes()
1188 ret = -ENOMEM; in applesmc_create_accelerometer()
1196 applesmc_idev->name = "applesmc"; in applesmc_create_accelerometer()
1197 applesmc_idev->id.bustype = BUS_HOST; in applesmc_create_accelerometer()
1198 applesmc_idev->dev.parent = &pdev->dev; in applesmc_create_accelerometer()
1200 -256, 256, APPLESMC_INPUT_FUZZ, APPLESMC_INPUT_FLAT); in applesmc_create_accelerometer()
1202 -256, 256, APPLESMC_INPUT_FUZZ, APPLESMC_INPUT_FLAT); in applesmc_create_accelerometer()
1254 applesmc_led_wq = create_singlethread_workqueue("applesmc-led"); in applesmc_create_key_backlight()
1256 return -ENOMEM; in applesmc_create_key_backlight()
1257 return led_classdev_register(&pdev->dev, &applesmc_backlight); in applesmc_create_key_backlight()
1315 ret = -ENODEV; in applesmc_init()
1321 ret = -ENXIO; in applesmc_init()
1365 hwmon_dev = hwmon_device_register(&pdev->dev); in applesmc_init()