Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2)  * via-pmu LED class device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  * This program is free software; you can redistribute it and/or modify
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  * it under the terms of the GNU General Public License as published by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  * the Free Software Foundation; either version 2 of the License, or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  * (at your option) any later version.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)  * This program is distributed in the hope that it will be useful, but
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12)  * WITHOUT ANY WARRANTY; without even the implied warranty of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13)  * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14)  * NON INFRINGEMENT.  See the GNU General Public License for more
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15)  * details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17)  * You should have received a copy of the GNU General Public License
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18)  * along with this program; if not, write to the Free Software
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19)  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #include <linux/leds.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) #include <linux/adb.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) #include <linux/pmu.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) #include <asm/prom.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) static spinlock_t pmu_blink_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) static struct adb_request pmu_blink_req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) /* -1: no change, 0: request off, 1: request on */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) static int requested_change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) static void pmu_req_done(struct adb_request * req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 	spin_lock_irqsave(&pmu_blink_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 	/* if someone requested a change in the meantime
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 	 * (we only see the last one which is fine)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 	 * then apply it now */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 	if (requested_change != -1 && !pmu_sys_suspended)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 		pmu_request(&pmu_blink_req, NULL, 4, 0xee, 4, 0, requested_change);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	/* reset requested change */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 	requested_change = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 	spin_unlock_irqrestore(&pmu_blink_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) static void pmu_led_set(struct led_classdev *led_cdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 			enum led_brightness brightness)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 	spin_lock_irqsave(&pmu_blink_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	switch (brightness) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 	case LED_OFF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 		requested_change = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 	case LED_FULL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 		requested_change = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	/* if request isn't done, then don't do anything */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	if (pmu_blink_req.complete && !pmu_sys_suspended)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 		pmu_request(&pmu_blink_req, NULL, 4, 0xee, 4, 0, requested_change);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70)  out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71)  	spin_unlock_irqrestore(&pmu_blink_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) static struct led_classdev pmu_led = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	.name = "pmu-led::front",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) #ifdef CONFIG_ADB_PMU_LED_DISK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	.default_trigger = "disk-activity",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	.brightness_set = pmu_led_set,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) static int __init via_pmu_led_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	struct device_node *dt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	const char *model;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	/* only do this on keylargo based models */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	if (pmu_get_model() != PMU_KEYLARGO_BASED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	dt = of_find_node_by_path("/");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	if (dt == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	model = of_get_property(dt, "model", NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	if (model == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 		of_node_put(dt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	if (strncmp(model, "PowerBook", strlen("PowerBook")) != 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	    strncmp(model, "iBook", strlen("iBook")) != 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	    strcmp(model, "PowerMac7,2") != 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	    strcmp(model, "PowerMac7,3") != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 		of_node_put(dt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 		/* ignore */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	of_node_put(dt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	spin_lock_init(&pmu_blink_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	/* no outstanding req */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	pmu_blink_req.complete = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	pmu_blink_req.done = pmu_req_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	return led_classdev_register(NULL, &pmu_led);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) late_initcall(via_pmu_led_init);