If I'm not mistaken, all wskbd_{get,set}_backlight uses are in the
following drivers: acpicbkbd, acpithinkpad, asmc, pwmleds, and now
my implementation in adb. It is my impression that they are roughly
the same code, I have collected them below to ease their inspection.

I would also like to acknowledge the kind help of jcs@, whom I
approached back when I made my first post on this matter (before
the key shortcuts, wsconsctl only) upon coming across his acpicbkbd(4).

(installed in dev/acpi/amsc.c:319)

int
asmc_get_backlight(struct wskbd_backlight *kbl)
{
  struct asmc_softc *sc = asmc_cd.cd_devs[0];

  KASSERT(sc != NULL);
  kbl->min = 0;
  kbl->max = 0xff;
  kbl->curval = sc->sc_backlight;
  return 0;
}

int
asmc_set_backlight(struct wskbd_backlight *kbl)
{
  struct asmc_softc *sc = asmc_cd.cd_devs[0];

  KASSERT(sc != NULL);
  if (kbl->curval > 0xff)
    return EINVAL;
  sc->sc_backlight = kbl->curval;
  task_add(systq, &sc->sc_task_backlight);
  return 0;
}

(installed in dev/acpi/acpicbkbd.c:94)

int
acpicbkbd_get_backlight(struct wskbd_backlight *kbl)
{
  struct acpicbkbd_softc *sc = acpicbkbd_cd.cd_devs[0];

  KASSERT(sc != NULL);

  kbl->min = 0;
  kbl->max = ACPICBKBD_MAX_BACKLIGHT;
  kbl->curval = sc->sc_backlight;

  return 0;
}

int
acpicbkbd_set_backlight(struct wskbd_backlight *kbl)
{
  struct acpicbkbd_softc *sc = acpicbkbd_cd.cd_devs[0];

  KASSERT(sc != NULL);

  if (kbl->curval > ACPICBKBD_MAX_BACKLIGHT)
    return EINVAL;

  sc->sc_backlight = kbl->curval;

  acpi_addtask(sc->sc_acpi, acpicbkbd_write_backlight, sc, 0);
  acpi_wakeup(sc->sc_acpi);

  return 0;
}

(installed in dev/acpi/acpithinkpad.c:347)

int
thinkpad_get_kbd_backlight(struct wskbd_backlight *kbl)
{
  struct acpithinkpad_softc *sc = acpithinkpad_cd.cd_devs[0];

  KASSERT(sc != NULL);

  kbl->min = 0;
  kbl->max = (sc->sc_thinklight >> 8) & 0x0f;
  kbl->curval = sc->sc_thinklight & 0x0f;

  if (kbl->max == 0)
    return (ENOTTY);

  return 0;
}

int
thinkpad_set_kbd_backlight(struct wskbd_backlight *kbl)
{
  struct acpithinkpad_softc *sc = acpithinkpad_cd.cd_devs[0];
  int maxval;

  KASSERT(sc != NULL);

  maxval = (sc->sc_thinklight >> 8) & 0x0f;

  if (maxval == 0)
    return (ENOTTY);

  if (kbl->curval > maxval)
    return EINVAL;

  sc->sc_thinklight &= ~0xff;
  sc->sc_thinklight |= kbl->curval;
  acpi_addtask(sc->sc_acpi, thinkpad_set_thinklight, sc, 0);
  acpi_wakeup(sc->sc_acpi);
  return 0;
}

(installed in pwmleds.c:102)
int
pwmleds_get_kbd_backlight(struct wskbd_backlight *kbl)
{
  struct pwmleds_softc *sc;
  struct pwm_state ps;
  int error;

  sc = pwmleds_kbd_backlight();
  if (sc == NULL)
    return ENOTTY;

  error = pwm_get_state(sc->sc_pwm, &ps);
  if (error)
    return error;

  kbl->min = 0;
  kbl->max = sc->sc_max_brightness;
  kbl->curval = (ps.ps_enabled) ?
      ((uint64_t)ps.ps_pulse_width * kbl->max) / ps.ps_period : 0;
  return 0;
}

int
pwmleds_set_kbd_backlight(struct wskbd_backlight *kbl)
{
  struct pwmleds_softc *sc;
  struct pwm_state ps;

  sc = pwmleds_kbd_backlight();
  if (sc == NULL)
    return ENOTTY;

  if (kbl->curval < 0 || kbl->curval > sc->sc_max_brightness)
    return EINVAL;

  pwm_init_state(sc->sc_pwm, &ps);
  ps.ps_pulse_width =
      ((uint64_t)kbl->curval * ps.ps_period) / sc->sc_max_brightness;
  ps.ps_enabled = (ps.ps_pulse_width > 0);
  return pwm_set_state(sc->sc_pwm, &ps);
}

Reply via email to