smu.c (204692) | smu.c (205506) |
---|---|
1/*- 2 * Copyright (c) 2009 Nathan Whitehorn 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 12 unchanged lines hidden (view full) --- 21 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 22 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 */ 27 28#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 2009 Nathan Whitehorn 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 12 unchanged lines hidden (view full) --- 21 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 22 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 */ 27 28#include <sys/cdefs.h> |
29__FBSDID("$FreeBSD: head/sys/powerpc/powermac/smu.c 204692 2010-03-04 06:36:00Z nwhitehorn $"); | 29__FBSDID("$FreeBSD: head/sys/powerpc/powermac/smu.c 205506 2010-03-23 03:14:44Z nwhitehorn $"); |
30 31#include <sys/param.h> 32#include <sys/bus.h> 33#include <sys/systm.h> 34#include <sys/module.h> 35#include <sys/conf.h> 36#include <sys/cpu.h> | 30 31#include <sys/param.h> 32#include <sys/bus.h> 33#include <sys/systm.h> 34#include <sys/module.h> 35#include <sys/conf.h> 36#include <sys/cpu.h> |
37#include <sys/clock.h> |
|
37#include <sys/ctype.h> 38#include <sys/kernel.h> 39#include <sys/kthread.h> 40#include <sys/reboot.h> 41#include <sys/rman.h> 42#include <sys/sysctl.h> 43#include <sys/unistd.h> 44 45#include <machine/bus.h> 46#include <machine/intr_machdep.h> 47#include <machine/md_var.h> 48 49#include <dev/led/led.h> 50#include <dev/ofw/openfirm.h> 51#include <dev/ofw/ofw_bus.h> 52#include <powerpc/powermac/macgpiovar.h> 53 | 38#include <sys/ctype.h> 39#include <sys/kernel.h> 40#include <sys/kthread.h> 41#include <sys/reboot.h> 42#include <sys/rman.h> 43#include <sys/sysctl.h> 44#include <sys/unistd.h> 45 46#include <machine/bus.h> 47#include <machine/intr_machdep.h> 48#include <machine/md_var.h> 49 50#include <dev/led/led.h> 51#include <dev/ofw/openfirm.h> 52#include <dev/ofw/ofw_bus.h> 53#include <powerpc/powermac/macgpiovar.h> 54 |
55#include "clock_if.h" 56 |
|
54struct smu_cmd { 55 volatile uint8_t cmd; 56 uint8_t len; 57 uint8_t data[254]; 58 59 STAILQ_ENTRY(smu_cmd) cmd_q; 60}; 61 --- 73 unchanged lines hidden (view full) --- 135static int smu_probe(device_t); 136static int smu_attach(device_t); 137 138/* cpufreq notification hooks */ 139 140static void smu_cpufreq_pre_change(device_t, const struct cf_level *level); 141static void smu_cpufreq_post_change(device_t, const struct cf_level *level); 142 | 57struct smu_cmd { 58 volatile uint8_t cmd; 59 uint8_t len; 60 uint8_t data[254]; 61 62 STAILQ_ENTRY(smu_cmd) cmd_q; 63}; 64 --- 73 unchanged lines hidden (view full) --- 138static int smu_probe(device_t); 139static int smu_attach(device_t); 140 141/* cpufreq notification hooks */ 142 143static void smu_cpufreq_pre_change(device_t, const struct cf_level *level); 144static void smu_cpufreq_post_change(device_t, const struct cf_level *level); 145 |
146/* clock interface */ 147static int smu_gettime(device_t dev, struct timespec *ts); 148static int smu_settime(device_t dev, struct timespec *ts); 149 |
|
143/* utility functions */ 144static int smu_run_cmd(device_t dev, struct smu_cmd *cmd, int wait); 145static int smu_get_datablock(device_t dev, int8_t id, uint8_t *buf, 146 size_t len); 147static void smu_attach_fans(device_t dev, phandle_t fanroot); 148static void smu_attach_sensors(device_t dev, phandle_t sensroot); 149static void smu_fan_management_proc(void *xdev); 150static void smu_manage_fans(device_t smu); --- 4 unchanged lines hidden (view full) --- 155/* where to find the doorbell GPIO */ 156 157static device_t smu_doorbell = NULL; 158 159static device_method_t smu_methods[] = { 160 /* Device interface */ 161 DEVMETHOD(device_probe, smu_probe), 162 DEVMETHOD(device_attach, smu_attach), | 150/* utility functions */ 151static int smu_run_cmd(device_t dev, struct smu_cmd *cmd, int wait); 152static int smu_get_datablock(device_t dev, int8_t id, uint8_t *buf, 153 size_t len); 154static void smu_attach_fans(device_t dev, phandle_t fanroot); 155static void smu_attach_sensors(device_t dev, phandle_t sensroot); 156static void smu_fan_management_proc(void *xdev); 157static void smu_manage_fans(device_t smu); --- 4 unchanged lines hidden (view full) --- 162/* where to find the doorbell GPIO */ 163 164static device_t smu_doorbell = NULL; 165 166static device_method_t smu_methods[] = { 167 /* Device interface */ 168 DEVMETHOD(device_probe, smu_probe), 169 DEVMETHOD(device_attach, smu_attach), |
170 171 /* Clock interface */ 172 DEVMETHOD(clock_gettime, smu_gettime), 173 DEVMETHOD(clock_settime, smu_settime), |
|
163 { 0, 0 }, 164}; 165 166static driver_t smu_driver = { 167 "smu", 168 smu_methods, 169 sizeof(struct smu_softc) 170}; --- 16 unchanged lines hidden (view full) --- 187#define SMU_MISC 0xee 188#define SMU_MISC_GET_DATA 0x02 189#define SMU_MISC_LED_CTRL 0x04 190#define SMU_POWER 0xaa 191#define SMU_POWER_EVENTS 0x8f 192#define SMU_PWR_GET_POWERUP 0x00 193#define SMU_PWR_SET_POWERUP 0x01 194#define SMU_PWR_CLR_POWERUP 0x02 | 174 { 0, 0 }, 175}; 176 177static driver_t smu_driver = { 178 "smu", 179 smu_methods, 180 sizeof(struct smu_softc) 181}; --- 16 unchanged lines hidden (view full) --- 198#define SMU_MISC 0xee 199#define SMU_MISC_GET_DATA 0x02 200#define SMU_MISC_LED_CTRL 0x04 201#define SMU_POWER 0xaa 202#define SMU_POWER_EVENTS 0x8f 203#define SMU_PWR_GET_POWERUP 0x00 204#define SMU_PWR_SET_POWERUP 0x01 205#define SMU_PWR_CLR_POWERUP 0x02 |
206#define SMU_RTC 0x8e 207#define SMU_RTC_GET 0x81 208#define SMU_RTC_SET 0x80 |
|
195 196/* Power event types */ 197#define SMU_WAKEUP_KEYPRESS 0x01 198#define SMU_WAKEUP_AC_INSERT 0x02 199#define SMU_WAKEUP_AC_CHANGE 0x04 200#define SMU_WAKEUP_RING 0x10 201 202/* Data blocks */ --- 141 unchanged lines hidden (view full) --- 344 sc->sc_doorbellirq = bus_alloc_resource_any(smu_doorbell, SYS_RES_IRQ, 345 &sc->sc_doorbellirqid, RF_ACTIVE); 346 bus_setup_intr(smu_doorbell, sc->sc_doorbellirq, 347 INTR_TYPE_MISC | INTR_MPSAFE, NULL, smu_doorbell_intr, dev, 348 &sc->sc_doorbellirqcookie); 349 powerpc_config_intr(rman_get_start(sc->sc_doorbellirq), 350 INTR_TRIGGER_EDGE, INTR_POLARITY_LOW); 351 | 209 210/* Power event types */ 211#define SMU_WAKEUP_KEYPRESS 0x01 212#define SMU_WAKEUP_AC_INSERT 0x02 213#define SMU_WAKEUP_AC_CHANGE 0x04 214#define SMU_WAKEUP_RING 0x10 215 216/* Data blocks */ --- 141 unchanged lines hidden (view full) --- 358 sc->sc_doorbellirq = bus_alloc_resource_any(smu_doorbell, SYS_RES_IRQ, 359 &sc->sc_doorbellirqid, RF_ACTIVE); 360 bus_setup_intr(smu_doorbell, sc->sc_doorbellirq, 361 INTR_TYPE_MISC | INTR_MPSAFE, NULL, smu_doorbell_intr, dev, 362 &sc->sc_doorbellirqcookie); 363 powerpc_config_intr(rman_get_start(sc->sc_doorbellirq), 364 INTR_TRIGGER_EDGE, INTR_POLARITY_LOW); 365 |
366 /* 367 * Connect RTC interface. 368 */ 369 clock_register(dev, 1000); 370 |
|
352 return (0); 353} 354 355static void 356smu_send_cmd(device_t dev, struct smu_cmd *cmd) 357{ 358 struct smu_softc *sc; 359 --- 678 unchanged lines hidden (view full) --- 1038 1039 cmd.len = 3; 1040 cmd.data[1] = 0; 1041 cmd.data[2] = SMU_WAKEUP_AC_INSERT; 1042 1043 return (smu_run_cmd(smu, &cmd, 1)); 1044} 1045 | 371 return (0); 372} 373 374static void 375smu_send_cmd(device_t dev, struct smu_cmd *cmd) 376{ 377 struct smu_softc *sc; 378 --- 678 unchanged lines hidden (view full) --- 1057 1058 cmd.len = 3; 1059 cmd.data[1] = 0; 1060 cmd.data[2] = SMU_WAKEUP_AC_INSERT; 1061 1062 return (smu_run_cmd(smu, &cmd, 1)); 1063} 1064 |
1065static int 1066smu_gettime(device_t dev, struct timespec *ts) 1067{ 1068 struct smu_cmd cmd; 1069 struct clocktime ct; 1070 1071 cmd.cmd = SMU_RTC; 1072 cmd.len = 1; 1073 cmd.data[0] = SMU_RTC_GET; 1074 1075 if (smu_run_cmd(dev, &cmd, 1) != 0) 1076 return (ENXIO); 1077 1078 ct.nsec = 0; 1079 ct.sec = bcd2bin(cmd.data[0]); 1080 ct.min = bcd2bin(cmd.data[1]); 1081 ct.hour = bcd2bin(cmd.data[2]); 1082 ct.dow = bcd2bin(cmd.data[3]); 1083 ct.day = bcd2bin(cmd.data[4]); 1084 ct.mon = bcd2bin(cmd.data[5]); 1085 ct.year = bcd2bin(cmd.data[6]) + 2000; 1086 1087 return (clock_ct_to_ts(&ct, ts)); 1088} 1089 1090static int 1091smu_settime(device_t dev, struct timespec *ts) 1092{ 1093 struct smu_cmd cmd; 1094 struct clocktime ct; 1095 1096 cmd.cmd = SMU_RTC; 1097 cmd.len = 8; 1098 cmd.data[0] = SMU_RTC_SET; 1099 1100 clock_ts_to_ct(ts, &ct); 1101 1102 cmd.data[1] = bin2bcd(ct.sec); 1103 cmd.data[2] = bin2bcd(ct.min); 1104 cmd.data[3] = bin2bcd(ct.hour); 1105 cmd.data[4] = bin2bcd(ct.dow); 1106 cmd.data[5] = bin2bcd(ct.day); 1107 cmd.data[6] = bin2bcd(ct.mon); 1108 cmd.data[7] = bin2bcd(ct.year - 2000); 1109 1110 return (smu_run_cmd(dev, &cmd, 1)); 1111} 1112 |
|