-/* $OpenBSD: adb.c,v 1.46 2022/07/02 08:50:41 visa Exp $ */
+/* $OpenBSD: adb.c,v 1.47 2022/10/21 22:42:36 gkoehler Exp $ */
/* $NetBSD: adb.c,v 1.6 1999/08/16 06:28:09 tsubai Exp $ */
/* $NetBSD: adb_direct.c,v 1.14 2000/06/08 22:10:45 tsubai Exp $ */
#include <sys/fcntl.h>
#include <sys/proc.h>
#include <sys/signalvar.h>
+#include <sys/task.h>
#include <sys/timeout.h>
#include <sys/systm.h>
void adb_cuda_autopoll(void);
void adb_cuda_fileserver_mode(void);
+#ifndef SMALL_KERNEL
+void adb_shutdown(void *);
+struct task adb_shutdown_task = TASK_INITIALIZER(adb_shutdown, NULL);
+#endif
+
#ifdef ADB_DEBUG
/*
* print_single
}
}
+#ifndef SMALL_KERNEL
+void
+adb_shutdown(void *arg)
+{
+ extern int allowpowerdown;
+
+ if (allowpowerdown == 1) {
+ allowpowerdown = 0;
+ prsignal(initprocess, SIGUSR2);
+ }
+}
+#endif /* !SMALL_KERNEL */
+
+void
+adb_lid_closed_intr(void)
+{
+#ifndef SMALL_KERNEL
+ switch (lid_action) {
+ case 1:
+ /* Suspend. */
+ break;
+ case 2:
+ /* Hibernate. */
+ break;
+ }
+#endif
+}
+
+void
+adb_power_button_intr(void)
+{
+#ifndef SMALL_KERNEL
+ switch (pwr_action) {
+ case 1:
+ task_add(systq, &adb_shutdown_task);
+ break;
+ case 2:
+ /* Suspend. */
+ break;
+ }
+#endif
+}
+
/*
* This is my version of the ADBOp routine. It mainly just calls the
adbHardware = ADB_HW_CUDA;
else if (strcmp(ca->ca_name, "via-pmu") == 0) {
adbHardware = ADB_HW_PMU;
+ pm_in_adbattach(sc->sc_dev.dv_xname);
/*
* Bus reset can take a long time if no adb devices are
-/* $OpenBSD: pm_direct.c,v 1.31 2022/09/18 21:36:41 gkoehler Exp $ */
+/* $OpenBSD: pm_direct.c,v 1.32 2022/10/21 22:42:36 gkoehler Exp $ */
/* $NetBSD: pm_direct.c,v 1.9 2000/06/08 22:10:46 tsubai Exp $ */
/*
#include <sys/param.h>
#include <sys/device.h>
#include <sys/systm.h>
+#include <sys/sensors.h>
#include <machine/cpu.h>
-1, -1, -1, -1, -1, -1, -1, -1,
};
+int pm_old_env;
+struct ksensor pm_lid_sens;
+struct ksensordev pm_sensdev;
/*
* Define the private functions
void pm_adb_get_TALK_result(PMData *);
void pm_adb_get_ADB_data(PMData *);
+void pm_env_intr(PMData *);
+
+
+extern int hw_power;
/*
* These variables are in adb_direct.c.
return rval;
}
+void
+pm_in_adbattach(const char *devname)
+{
+ /* A PowerBook (including iBook) has a lid. */
+ if (strncmp(hw_prod, "PowerBook", 9) == 0) {
+ strlcpy(pm_sensdev.xname, devname,
+ sizeof(pm_sensdev.xname));
+ strlcpy(pm_lid_sens.desc, "lid open",
+ sizeof(pm_lid_sens.desc));
+ pm_lid_sens.type = SENSOR_INDICATOR;
+ sensor_attach(&pm_sensdev, &pm_lid_sens);
+ sensordev_install(&pm_sensdev);
+ pm_lid_sens.value = 1; /* This is a guess. */
+ }
+}
/*
* My PM interrupt routine for the PB Duo series and the PB 5XX series
case 0x16: /* ADB device event */
case 0x18:
case 0x1e:
- case PMU_INT_WAKEUP:
pm_adb_get_ADB_data(&pmdata);
break;
+ case PMU_INT_ENVIRONMENT:
+ pm_env_intr(&pmdata);
+ break;
default:
#ifdef ADB_DEBUG
if (adb_debug)
adb_pass_up(&packet);
}
+void
+pm_env_intr(PMData *pmdata)
+{
+ int env, old;
+
+ /* We might have 3 bytes data[3..5], but use only data[3]. */
+ if (pmdata->num_data < 3)
+ return;
+ env = pmdata->data[3];
+ old = pm_old_env;
+
+ pm_lid_sens.value = !(env & PMU_ENV_LID_CLOSED);
+ if (!(old & PMU_ENV_LID_CLOSED) && (env & PMU_ENV_LID_CLOSED))
+ adb_lid_closed_intr();
+
+ hw_power = !!(env & PMU_ENV_AC_POWER);
+
+ /*
+ * Act if one presses and releases the power button on a Mac
+ * with no ADB keyboard.
+ */
+ if ((old & PMU_ENV_POWER_BUTTON) && !(env & PMU_ENV_POWER_BUTTON))
+ adb_power_button_intr();
+
+ pm_old_env = env;
+}
+
void
pm_adb_restart(void)
{
pmgrop(&p);
info->flags = p.data[1];
+ hw_power = !!(info->flags & PMU_PWR_AC_PRESENT);
switch (p.data[0]) {
case 3:
-/* $OpenBSD: pm_direct.h,v 1.14 2022/09/18 21:36:41 gkoehler Exp $ */
+/* $OpenBSD: pm_direct.h,v 1.15 2022/10/21 22:42:36 gkoehler Exp $ */
/* $NetBSD: pm_direct.h,v 1.7 2005/01/07 04:59:58 briggs Exp $ */
/*
} PMData;
int pmgrop(PMData *);
+void pm_in_adbattach(const char *);
int pm_adb_op(u_char *, void *, void *, int);
void pm_adb_restart(void);
void pm_adb_poweroff(void);
#define PMU_INT_SNDBRT 0x08 /* sound/brightness up/down buttons */
#define PMU_INT_ADB 0x10 /* ADB autopoll or reply data */
#define PMU_INT_BATTERY 0x20
-#define PMU_INT_WAKEUP 0x40
+#define PMU_INT_ENVIRONMENT 0x40
#define PMU_INT_TICK 0x80 /* 1-second tick interrupt */
#define PMU_INT_ALL 0xff /* Mask of all interrupts */
#define PMU_POW_IRLED 0x04 /* IR led power (on wallstreet) */
#define PMU_POW_MEDIABAY 0x08 /* media bay power (wallstreet/lombard ?) */
+/* Bits from PMU_INT_ENVIRONMENT */
+#define PMU_ENV_LID_CLOSED 0x01 /* The lid is closed */
+#define PMU_ENV_AC_POWER 0x04 /* AC is plugged in */
+#define PMU_ENV_POWER_BUTTON 0x08 /* power button on ADB-less Macs */
+#define PMU_ENV_BATTERY 0x10
+#define PMU_ENV_OVER_TEMP 0x20
+
/* PMU PMU_POWER_EVENTS commands */
enum {
PMU_PWR_GET_POWERUP_EVENTS = 0x00,
-/* $OpenBSD: cpu.h,v 1.14 2013/10/09 17:43:50 mpi Exp $ */
+/* $OpenBSD: cpu.h,v 1.15 2022/10/21 22:42:36 gkoehler Exp $ */
/* $NetBSD: cpu.h,v 1.1 1996/09/30 16:34:21 ws Exp $ */
/*
*/
#define CPU_ALLOWAPERTURE 1 /* allow mmap of /dev/xf86 */
#define CPU_ALTIVEC 2 /* altivec is present */
-#define CPU_MAXID 3 /* number of valid machdep ids */
+#define CPU_LIDACTION 3 /* action caused by lid close */
+#define CPU_PWRACTION 4 /* action caused by power button */
+#define CPU_MAXID 5 /* number of valid machdep ids */
#define CTL_MACHDEP_NAMES { \
{ 0, 0 }, \
{ "allowaperture", CTLTYPE_INT }, \
{ "altivec", CTLTYPE_INT }, \
+ { "lidaction", CTLTYPE_INT }, \
+ { "pwraction", CTLTYPE_INT }, \
}
#ifdef _KERNEL
extern u_int32_t ticks_per_sec;
extern u_int32_t ns_per_tick;
+extern int lid_action;
+extern int pwr_action;
+
#endif /* _KERNEL */
#endif /* _MACHINE_CPU_H_ */
-/* $OpenBSD: machdep.c,v 1.197 2022/10/21 21:26:49 gkoehler Exp $ */
+/* $OpenBSD: machdep.c,v 1.198 2022/10/21 22:42:36 gkoehler Exp $ */
/* $NetBSD: machdep.c,v 1.4 1996/10/16 19:33:11 ws Exp $ */
/*
#ifdef APERTURE
int allowaperture = 0;
#endif
+int lid_action = 1;
+int pwr_action = 1;
void dumpsys(void);
int lcsplx(int ipl); /* called from LCore */
return EJUSTRETURN;
}
+const struct sysctl_bounded_args cpuctl_vars[] = {
+ { CPU_ALTIVEC, &ppc_altivec, SYSCTL_INT_READONLY },
+ { CPU_LIDACTION, &lid_action, 0, 2 },
+ { CPU_PWRACTION, &pwr_action, 0, 2 },
+};
+
/*
* Machine dependent system variables.
- * None for now.
*/
int
cpu_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
#else
return (sysctl_rdint(oldp, oldlenp, newp, 0));
#endif
- case CPU_ALTIVEC:
- return (sysctl_rdint(oldp, oldlenp, newp, ppc_altivec));
default:
- return EOPNOTSUPP;
+ return (sysctl_bounded_arr(cpuctl_vars, nitems(cpuctl_vars),
+ name, namelen, oldp, oldlenp, newp, newlen));
}
}
-/* $OpenBSD: adb.h,v 1.5 2011/06/16 10:44:33 mpi Exp $ */
+/* $OpenBSD: adb.h,v 1.6 2022/10/21 22:42:36 gkoehler Exp $ */
/* $NetBSD: adbsys.h,v 1.4 2000/12/19 02:59:24 tsubai Exp $ */
/*-
} ADBDataBlock;
int adbprint(void *, const char *);
+void adb_lid_closed_intr(void);
+void adb_power_button_intr(void);
int adb_op_sync(Ptr, short);
int set_adb_info(ADBSetInfoBlock *, int);
-/* $OpenBSD: akbd.c,v 1.15 2022/04/06 18:59:27 naddy Exp $ */
+/* $OpenBSD: akbd.c,v 1.16 2022/10/21 22:42:36 gkoehler Exp $ */
/* $NetBSD: akbd.c,v 1.17 2005/01/15 16:00:59 chs Exp $ */
/*
case 2:
/*
* The reset (or power) key sends 0x7f7f on press and
- * 0xffff on release, and we ignore it.
+ * 0xffff on release.
*/
if (event->bytes[0] == event->bytes[1] &&
ADBK_KEYVAL(event->bytes[0]) == ADBK_RESET) {
- if (event->bytes[0] == ADBK_KEYDOWN(ADBK_RESET))
+ if (event->bytes[0] == ADBK_KEYDOWN(ADBK_RESET)) {
SET(sc->sc_caps, CL_DOWN_RESET);
- else {
+ adb_power_button_intr();
+ } else {
if (ISSET(sc->sc_caps, CL_DOWN_RESET))
CLR(sc->sc_caps, CL_DOWN_RESET);
else if (ISSET(sc->sc_caps, CL_DOWN_ADB)) {