On Sat, Nov 09, 2019 at 12:08:35PM +0100, Thomas de Grivel wrote:
> Everything works except wifi, suspend/resume and screen backlight, and
> mute speakers button.
Hi,
I have an X395 which is basically the same machine.
For Wifi I have temporarily replaced the Intel WiFi with a bwfm(4), the
Dell Wireless DW1820a (note the a), which has two antenna connectors.
There's the DW1830 which has three. My X395 has two connectors, so I
just put in the DW1820a. Both can be purchased cheaply on eBay.
The mute speaker button works for me, but the light doesn't show up.
I will try to have a look at suspend/resume at one of the next OpenBSD
hackathons.
For the screen backlight I have come up with a diff, but it's not yet
ready to be committed, as it should be done in a different fashion.
Still, I have attached the diff if you want to give it a go.
Patrick
diff --git a/sys/dev/acpi/acpivideo.c b/sys/dev/acpi/acpivideo.c
index 9498465a418..a46a99a67f7 100644
--- a/sys/dev/acpi/acpivideo.c
+++ b/sys/dev/acpi/acpivideo.c
@@ -149,7 +149,7 @@ acpi_foundvout(struct aml_node *node, void *arg)
if (node->parent != sc->sc_devnode)
return (0);
- if (aml_searchname(node, "_BCM") && aml_searchname(node, "_BQC")) {
+ if (aml_searchname(node, "_BCM")) {
memset(&aaa, 0, sizeof(aaa));
aaa.aaa_iot = sc->sc_acpi->sc_iot;
aaa.aaa_memt = sc->sc_acpi->sc_memt;
diff --git a/sys/dev/acpi/acpivout.c b/sys/dev/acpi/acpivout.c
index 5fb6973f595..b1957b0c652 100644
--- a/sys/dev/acpi/acpivout.c
+++ b/sys/dev/acpi/acpivout.c
@@ -60,6 +60,7 @@ struct acpivout_softc {
int *sc_bcl;
size_t sc_bcl_len;
+ int sc_bcl_cur;
};
void acpivout_brightness_cycle(struct acpivout_softc *);
@@ -113,10 +114,16 @@ acpivout_attach(struct device *parent, struct device
*self, void *aux)
aml_register_notify(sc->sc_devnode, aaa->aaa_dev,
acpivout_notify, sc, ACPIDEV_NOPOLL);
+ acpivout_get_bcl(sc);
+ if (!sc->sc_bcl_len)
+ return;
+
+ sc->sc_bcl_cur = sc->sc_bcl[sc->sc_bcl_len - 1];
+ sc->sc_bcl_cur = acpivout_get_brightness(sc);
+ acpivout_set_brightness(sc, sc->sc_bcl_cur);
+
ws_get_param = acpivout_get_param;
ws_set_param = acpivout_set_param;
-
- acpivout_get_bcl(sc);
}
int
@@ -130,12 +137,15 @@ acpivout_notify(struct aml_node *node, int notify, void
*arg)
break;
case NOTIFY_BRIGHTNESS_UP:
acpivout_brightness_step(sc, 1);
+ wsdisplay_change_brightness(1);
break;
case NOTIFY_BRIGHTNESS_DOWN:
acpivout_brightness_step(sc, -1);
+ wsdisplay_change_brightness(-1);
break;
case NOTIFY_BRIGHTNESS_ZERO:
acpivout_brightness_zero(sc);
+ wsdisplay_change_brightness(0);
break;
case NOTIFY_DISPLAY_OFF:
/* TODO: D3 state change */
@@ -200,7 +210,9 @@ acpivout_get_brightness(struct acpivout_softc *sc)
struct aml_value res;
int level;
- aml_evalname(sc->sc_acpi, sc->sc_devnode, "_BQC", 0, NULL, &res);
+ if (aml_evalname(sc->sc_acpi, sc->sc_devnode, "_BQC", 0, NULL, &res))
+ return sc->sc_bcl_cur;
+
level = aml_val2int(&res);
aml_freevalue(&res);
DPRINTF(("%s: BQC = %d\n", DEVNAME(sc), level));
@@ -242,6 +254,7 @@ acpivout_set_brightness(struct acpivout_softc *sc, int
level)
aml_evalname(sc->sc_acpi, sc->sc_devnode, "_BCM", 1, &args, &res);
aml_freevalue(&res);
+ sc->sc_bcl_cur = level;
}
void
diff --git a/sys/dev/pci/drm/amd/amdgpu/amdgpu_kms.c
b/sys/dev/pci/drm/amd/amdgpu/amdgpu_kms.c
index 02a90069f8d..4bad51b7d5f 100644
--- a/sys/dev/pci/drm/amd/amdgpu/amdgpu_kms.c
+++ b/sys/dev/pci/drm/amd/amdgpu/amdgpu_kms.c
@@ -1656,7 +1656,7 @@ amdgpu_wsioctl(void *v, u_long cmd, caddr_t data, int
flag, struct proc *p)
case WSDISPLAYIO_PARAM_BRIGHTNESS:
dp->min = 0;
dp->max = bd->props.max_brightness;
- dp->curval = bd->ops->get_brightness(bd);
+ dp->curval = bd->props.brightness;
return (dp->max > dp->min) ? 0 : -1;
}
break;
diff --git a/sys/dev/wscons/wsdisplay.c b/sys/dev/wscons/wsdisplay.c
index 61ccd2dae43..eda5c9d8843 100644
--- a/sys/dev/wscons/wsdisplay.c
+++ b/sys/dev/wscons/wsdisplay.c
@@ -3369,3 +3369,43 @@ mouse_remove(struct wsscreen *scr)
}
#endif /* HAVE_WSMOUSED_SUPPORT */
+
+int
+wsdisplay_change_brightness(int dir)
+{
+ struct wsdisplay_softc *sc;
+ struct wsdisplay_param dp;
+ int step, ret;
+
+ sc = (struct wsdisplay_softc *)device_lookup(&wsdisplay_cd, 0);
+ if (sc == NULL)
+ return ENODEV;
+
+ memset(&dp, 0, sizeof(dp));
+ dp.param = WSDISPLAYIO_PARAM_BRIGHTNESS;
+ ret = wsdisplay_internal_ioctl(sc, NULL, WSDISPLAYIO_GETPARAM,
+ (caddr_t)&dp, 0, NULL);
+ if (ret)
+ return ret;
+
+ step = ((dp.max - dp.min) * 5) / 100;
+ if (step <= 0)
+ step = 1;
+
+ if (dir > 0) {
+ if (dp.max - dp.curval > step)
+ dp.curval += step;
+ else
+ dp.curval = dp.max;
+ } else if (dir < 0) {
+ if (dp.curval - dp.min > step)
+ dp.curval -= step;
+ else
+ dp.curval = dp.min;
+ } else
+ dp.curval = dp.min;
+ wsdisplay_internal_ioctl(sc, NULL, WSDISPLAYIO_SETPARAM,
+ (caddr_t)&dp, FWRITE, NULL);
+
+ return 0;
+}
diff --git a/sys/dev/wscons/wsdisplayvar.h b/sys/dev/wscons/wsdisplayvar.h
index ee36ac26a08..a1ecd376ec8 100644
--- a/sys/dev/wscons/wsdisplayvar.h
+++ b/sys/dev/wscons/wsdisplayvar.h
@@ -243,6 +243,7 @@ const struct wsscreen_descr *
struct wsdisplay_param;
extern int (*ws_get_param)(struct wsdisplay_param *);
extern int (*ws_set_param)(struct wsdisplay_param *);
+extern int wsdisplay_change_brightness(int);
/*
* for use by wskbd