Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 5 May 2023 07:51:31 +0200
From:      Georg Lindenberg <georg.lindenberg@web.de>
To:        "Dmitry N. Medvedev" <dmitry.medvedev@gmail.com>
Cc:        freebsd-acpi@freebsd.org
Subject:   Aw: Re: Re: managing a fan speed via memory address
Message-ID:  <trinity-341ba45a-95df-4524-9775-515c509933d5-1683265891170@msvc-mesg-web109>
In-Reply-To: <CAPf62nHvfXJz1tJ00DpCPtvzXUpZdWotEgK%2BFFWjP2brikTkNQ@mail.gmail.com>
References:  <CAPf62nErnFh7WjseZhjyhgohf2j%2BfLCm5of2yir8T=Eyi54NNA@mail.gmail.com> <CAJ-VmonUyHkBBbQSZsL-ur6LYy0eRs%2Buf-qaSjF_WQwVKAXVUQ@mail.gmail.com> <CAPf62nF8DtCCRvzos9taoh7QW6K0K6whCWfBwq4dLEWgsaBeJA@mail.gmail.com> <trinity-f0eae624-c2cf-4fff-95fa-b9f1536cbc61-1683136944972@3c-app-webde-bs51> <CAPf62nHvfXJz1tJ00DpCPtvzXUpZdWotEgK%2BFFWjP2brikTkNQ@mail.gmail.com>

next in thread | previous in thread | raw e-mail | index | archive | help
If the fan ID is not present in acpidump, then the fan is not in the acpi n=
amespace, and thus it is not visible to the operating system (aka FreeBSD)=
=2E At least according to the acpi documentation=2E :-)

Maybe there is a another way to access the fan (bios?), that I am not awar=
e of=2E
Good luck=2E

> Gesendet: Donnerstag, den 04=2E05=2E2023 um 15:45 Uhr
> Von: "Dmitry N=2E Medvedev" <dmitry=2Emedvedev@gmail=2Ecom>
> An: "Georg Lindenberg" <georg=2Elindenberg@web=2Ede>
> Cc: freebsd-acpi@freebsd=2Eorg
> Betreff: Re: Re: managing a fan speed via memory address
>=20
> hi Georg,
>=20
> it's become even more confusing -- none of the IDs from #1 exist in
> acpidump output :(
>=20
> researching further
>=20
> On Wed, May 3, 2023 at 8:02=E2=80=AFPM Georg Lindenberg <georg=2Elindenb=
erg@web=2Ede>
> wrote:
>=20
> >
> > Hello,
> >
> > ACPI can control fans, but it is up to the hardware manufacturer (OEM)=
 to
> > implement it=2E
> >
> > _______________________________
> > Step 1=2E Check for ACPI fan control
> >
> > The OEM needs to add a device with id "PNP0C0B" to the acpi namespace=
=2E
> > In FreeBSD, you can test this with the command: acpidump -d -t | grep
> > PNP0C0B
> >
> > On Windows, you can download acpi tools at
> > https://acpica=2Eorg/downloads/binary-tools
> > Then use the command: acpidump=2Eexe | findstr PNP0C0B
> >
> > Some fans use IDs which are not documented in the ACPI specification:
> >     "PNP0C0B",         /* Generic Fan */ \
> >     "INT3404",        /* Fan */ \
> >     "INTC1044",        /* Fan for Tiger Lake generation */
> >     "INTC1048",     /* Fan for Alder Lake generation */
> >     "INTC1063",    /* Fan for Meteor Lake generation */
> >     "INTC10A2",    /* Fan for Raptor Lake generation */
> >
> > You might want to search for these strings as well=2E
> >
> > __________________________
> > Step 2=2E Check for version of ACPI
> >
> > Fan version is either 1=2E0 or 4=2E0=2E
> >
> > a) Acpi version 1=2E0
> >
> > If you suceed with step 1=2E, then you can communicate with the fan=2E=
 You can
> > turn it on and off
> > by putting it in power state D0 or D3=2E
> > In C, you would probably use acpi_set_powerstate(dev, ACPI_STATE_D3),
> > or maybe use acpi power methods, like _ON, _OFF, _PR3, _PR0 (haven't
> > tested it)=2E
> >
> > Or maybe an alternative: There is a suggestion on FreeBSD acpi wiki:
> > device_power -- Add a "power" argument to devctl(8) that allows a devi=
ce
> > to be set into various low power or off states=2E
> > Noone has implemented that yet ("not done")=2E :)
> >
> > b) ACPI version 4=2E0
> >
> > To check, whether your fan supports fan levels, you can do this:
> >
> > OEM _must_ provide four predefined acpi methods=2E They are described =
in
> > detail in the acpi
> > specification=2E They are called: _FIF, _FPS, _FSL, _FST
> > So just use:
> > acpidump -d -t | grep _FPS
> > and so on=2E If all four are present, you can use fan levels! :-)
> >
> > In your source code, it could look like this:
> >
> >     ACPI_HANDLE    handle;
> >     ACPI_HANDLE tmp;
> >
> >     /* fans are either acpi 1=2E0 or 4=2E0 compatible, so check now=2E=
 */
> >      if (ACPI_SUCCESS(acpi_get_handle(handle, "_FIF", &tmp)) &&
> >     ACPI_SUCCESS(acpi_get_handle(handle, "_FPS", &tmp)) &&
> >     ACPI_SUCCESS(acpi_get_handle(handle, "_FSL", &tmp)) &&
> >     ACPI_SUCCESS(acpi_get_handle(handle, "_FST", &tmp)))
> >         acpi_fan_initiate_acpi4(dev);
> >
> >     else    /* nothing to do in acpi version 1, really */
> >         acpi_fan_softc=2Eversion =3D 1;
> >
> > 3=2E How to set fan levels
> >
> > As a driver author, you'd need to decide how you'd want to implement t=
he
> > fan level=2E It can be done
> > via /dev/acpi (and also add code to acpiconf (8))=2E Or it can be done=
 via
> > systctls=2E
> >
> > So in your code, you could add a proc sysctl=2E There are multiple way=
s to
> > implement sysctls,
> > one way could be this:
> >
> >     sysctl_ctx_init(&clist);        /* sysctl context */
> >
> >     struct sysctl_oid *fan_oid =3D device_get_sysctl_tree(dev);
> >     SYSCTL_ADD_PROC(&clist, SYSCTL_CHILDREN(fan_oid), OID_AUTO,
> >     "Fan level", CTLTYPE_INT | CTLFLAG_RW, 0, 0,
> >     acpi_fan_level_sysctl, "I" ,"Fan level");
> >
> > Or whatever code you like=2E
> >
> > Then you need a sysctl handler:
> >
> > static int
> > acpi_fan_level_sysctl(SYSCTL_HANDLER_ARGS) {
> >
> > =2E=2E=2E
> > }
> >
> > In the handler function you could "handle" the fan level, and probably=
 call
> > acpi_evaluate_object() on the _FIF, _FPS, _FSL, and _FST methods=2E
> >
> > Unfortunately, my laptops don't support fans at all=2E So I can't real=
ly
> > write a fan driver=2E
> > I think it is a good beginners task=2E
> >
> > Basically, if your fan has three or four pins, it might support fan
> > levels=2E The first two pins are
> > used for electricity=2E The third pin is used to upscale or downscale =
the
> > power (voltage?),
> > thus increasing or decreasing the fan speed=2E There is no magic to th=
is=2E
> >
> > 4=2E Sceleton acpi driver
> >
> > If you need a sceleton acpi driver, that shouldn't be a problem=2E
> > FreeBSD puts all acpi drivers (modules) into the acpi subsystem
> > (sys/dev/acpica), instead
> > of giving them a separate makefile in sys/modules=2E
> >
> > This was my first attempt, without ever testing anything (bugs to be
> > expected): :-)
> >
> > #include "opt_acpi=2Eh"
> > #include <sys/param=2Eh>
> > #include <sys/kernel=2Eh>
> > #include <sys/module=2Eh>
> >
> > /* for testing, aka printf */
> > #include <sys/types=2Eh>
> > #include <sys/systm=2Eh>
> >
> > #include <contrib/dev/acpica/include/acpi=2Eh>
> > #include <dev/acpica/acpivar=2Eh>
> > #include <dev/acpica/acpiio=2Eh>
> >
> > /* Hooks for the ACPI CA debugging infrastructure */
> > #define    _COMPONENT    ACPI_FAN
> > ACPI_MODULE_NAME("FAN")
> >
> > /* driver software context */
> > struct acpi_fan_softc {
> >     device_t    dev;
> >     int            version;    /* either ACPI 1=2E0 or 4=2E0 */
> > };
> >
> > static device_method_t acpi_fan_methods[] =3D {
> >     /* Device interface */
> >     DEVMETHOD(device_probe,        acpi_fan_probe),
> >     DEVMETHOD(device_attach,    acpi_fan_attach),
> >     DEVMETHOD(device_detach,    acpi_fan_detach),
> >     DEVMETHOD_END
> > };
> >
> > static int
> > acpi_fan_probe(device_t dev)
> > {
> >     static char *fan_ids[] =3D { \
> >     "PNP0C0B",         /* Generic Fan */ \
> >     "INT3404",        /* Fan */ \
> >     "INTC1044",        /* Fan for Tiger Lake generation */ \
> >     "INTC1048",     /* Fan for Alder Lake generation */ \
> >     "INTC1063",     /* Fan for Meteor Lake generation */ \
> >     "INTC10A2",     /* Fan for Raptor Lake generation */ \
> >     NULL };
> >     int rv;
> >
> >     if (acpi_disabled("fan"))
> >     return (ENXIO);
> >     rv =3D ACPI_ID_PROBE(device_get_parent(dev), dev, fan_ids, NULL);
> >     if (rv <=3D 0)
> >     device_set_desc(dev, "ACPI FAN");
> >     return (rv);
> > }
> >
> > static int
> > acpi_fan_attach(device_t dev)
> > {
> >     int    error;
> >     ACPI_HANDLE    handle;
> >     ACPI_HANDLE tmp;
> >     struct acpi_fan_softc *sc;
> >
> >     sc =3D device_get_softc(dev);
> >     handle =3D acpi_get_handle(dev);
> >
> >     /* fans are either acpi 1=2E0 or 4=2E0 compatible, so check now=2E=
 */
> >     if (ACPI_SUCCESS(acpi_get_handle(handle, "_FIF", &tmp)) &&
> >     ACPI_SUCCESS(acpi_get_handle(handle, "_FPS", &tmp)) &&
> >     ACPI_SUCCESS(acpi_get_handle(handle, "_FSL", &tmp)) &&
> >     ACPI_SUCCESS(acpi_get_handle(handle, "_FST", &tmp)))
> >         acpi_fan_softc=2Eversion =3D 4;
> >
> >     else    /* nothing to do in acpi version 1, really */
> >         acpi_fan_softc=2Eversion =3D 1;
> >
> >   return 0;
> > }
> >
> > static int
> > acpi_fan_detach(device_t dev) {
> >     sysctl_ctx_free(&clist);
> >     return 0;
> > }
> >
> >
> > static driver_t acpi_fan_driver =3D {
> >     "fan",
> >     acpi_fan_methods,
> >     sizeof(struct acpi_fan_softc),
> > };
> > DRIVER_MODULE(acpi_fan, acpi, acpi_fan_driver, 0, 0);
> > MODULE_DEPEND(acpi_fan, acpi, 1, 1, 1);
> >
> > _____________________
> > 5=2E How linux does it
> >
> > You can check linux fan driver on github:
> > https://github=2Ecom/torvalds/linux/tree/master/drivers/acpi
> >
> > They separate the driver into three files=2E
> > fan=2Eh
> > fan_attr=2Ec
> > fan_core=2Ec
> >
> > It's ok to learn from linux=2E :-)
> >
> >
> > Sorry for long message=2E
> > Georg=2E
> > *Gesendet:* Mittwoch, 03=2E Mai 2023 um 02:26 Uhr
> > *Von:* "Dmitry N=2E Medvedev" <dmitry=2Emedvedev@gmail=2Ecom>
> > *An:* "Adrian Chadd" <adrian@freebsd=2Eorg>
> > *Cc:* freebsd-acpi@freebsd=2Eorg
> > *Betreff:* Re: managing a fan speed via memory address
> > good morning Adrian,
> >
> > 1=2E I am just learning :) Not 100% sure ACPI has anything to do with =
fan
> > control ( still it looks that it actually does )
> > -- found the Advanced Configuration and Power Interface Specification =
PDF=2E
> > Will spend some time grasping the ideas
> > 2=2E to quickly write any driver I will have to first find out how to =
do it
> > :) any guidance ( preferable in textual form will be greatly appreciat=
ed )
> > will learn it :)
> > 3=2E there isn't a single thermal sensor, but the SAS disks report the=
ir
> > temperatures
> > ( via dmidecode if I am not mistaken, or some other program -- I will =
be
> > more sure tomorrow morning )=2E
> > so, theoretically I could be able to read their temperature and decide=
 if
> > I would like to send more power to the fan=2E
> >
> > On Wed, May 3, 2023 at 2:14=E2=80=AFAM Adrian Chadd <adrian@freebsd=2E=
org> wrote:
> >
> >> Is it not an ACPI driver? If not, you could write a quick fan driver!
> >>
> >> Is there a thermal sensor(s) you could read to see how warm they get?
> >>
> >>
> >>
> >> -adrian
> >>
> >>
> >> On Tue, 2 May 2023 at 17:06, Dmitry N=2E Medvedev <
> >> dmitry=2Emedvedev@gmail=2Ecom> wrote:
> >>
> >>> good morning,
> >>>
> >>> Recently I have learned about the dmidecode program and found the
> >>> address of the FRNTFAN port in my HP Z420 machine: 0x0037=2E
> >>> Since I am a complete newbie, I would like to learn if there is a wa=
y to
> >>> read and change the value at this address=2E
> >>> I need a bit of guidance=2E
> >>>
> >>> *The context*: I have added 8 SAS disks to the machine, put noctua f=
an
> >>> in front of them and connected the fan to the FRNTFAN port on the
> >>> motherboard=2E
> >>> It looks like the fan works, but I am sure the disks would benefit i=
f
> >>> the fan produced more pressure=2E Which I fantasize I could do via c=
hanging
> >>> the value at the said address=2E
> >>> Not sure, of course=2E
> >>>
> >>> best regards,
> >>> Dmitry N=2E Medvedev
> >>>
> >>



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?trinity-341ba45a-95df-4524-9775-515c509933d5-1683265891170>