1*471aeecfSnaddy /* $OpenBSD: acpicmos.c,v 1.2 2022/04/06 18:59:27 naddy Exp $ */
2c0c10807Skettenis /*
3c0c10807Skettenis * Copyright (c) 2018 Mark Kettenis
4c0c10807Skettenis *
5c0c10807Skettenis * Permission to use, copy, modify, and distribute this software for any
6c0c10807Skettenis * purpose with or without fee is hereby granted, provided that the above
7c0c10807Skettenis * copyright notice and this permission notice appear in all copies.
8c0c10807Skettenis *
9c0c10807Skettenis * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10c0c10807Skettenis * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11c0c10807Skettenis * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12c0c10807Skettenis * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13c0c10807Skettenis * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14c0c10807Skettenis * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15c0c10807Skettenis * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16c0c10807Skettenis */
17c0c10807Skettenis
18c0c10807Skettenis #include <sys/param.h>
19c0c10807Skettenis #include <sys/systm.h>
20c0c10807Skettenis
21c0c10807Skettenis #include <dev/acpi/acpireg.h>
22c0c10807Skettenis #include <dev/acpi/acpivar.h>
23c0c10807Skettenis #include <dev/acpi/dsdt.h>
24c0c10807Skettenis
25c0c10807Skettenis #include <dev/ic/mc146818reg.h>
26c0c10807Skettenis
27c0c10807Skettenis struct acpicmos_softc {
28c0c10807Skettenis struct device sc_dev;
29c0c10807Skettenis struct aml_node *sc_node;
30c0c10807Skettenis };
31c0c10807Skettenis
32c0c10807Skettenis int acpicmos_match(struct device *, void *, void *);
33c0c10807Skettenis void acpicmos_attach(struct device *, struct device *, void *);
34c0c10807Skettenis
35*471aeecfSnaddy const struct cfattach acpicmos_ca = {
36c0c10807Skettenis sizeof(struct acpicmos_softc), acpicmos_match, acpicmos_attach
37c0c10807Skettenis };
38c0c10807Skettenis
39c0c10807Skettenis struct cfdriver acpicmos_cd = {
40c0c10807Skettenis NULL, "acpicmos", DV_DULL
41c0c10807Skettenis };
42c0c10807Skettenis
43c0c10807Skettenis const char *acpicmos_hids[] = {
44c0c10807Skettenis "PNP0B00",
45c0c10807Skettenis "PNP0B01",
46c0c10807Skettenis "PNP0B02",
47c0c10807Skettenis NULL
48c0c10807Skettenis };
49c0c10807Skettenis
50c0c10807Skettenis int acpicmos_opreg_handler(void *, int, uint64_t, int, uint64_t *);
51c0c10807Skettenis
52c0c10807Skettenis int
acpicmos_match(struct device * parent,void * match,void * aux)53c0c10807Skettenis acpicmos_match(struct device *parent, void *match, void *aux)
54c0c10807Skettenis {
55c0c10807Skettenis struct acpi_attach_args *aaa = aux;
56c0c10807Skettenis struct cfdata *cf = match;
57c0c10807Skettenis
58c0c10807Skettenis return acpi_matchhids(aaa, acpicmos_hids, cf->cf_driver->cd_name);
59c0c10807Skettenis }
60c0c10807Skettenis
61c0c10807Skettenis void
acpicmos_attach(struct device * parent,struct device * self,void * aux)62c0c10807Skettenis acpicmos_attach(struct device *parent, struct device *self, void *aux)
63c0c10807Skettenis {
64c0c10807Skettenis struct acpicmos_softc *sc = (struct acpicmos_softc *)self;
65c0c10807Skettenis struct acpi_attach_args *aaa = aux;
66c0c10807Skettenis
67c0c10807Skettenis printf("\n");
68c0c10807Skettenis
69c0c10807Skettenis sc->sc_node = aaa->aaa_node;
70c0c10807Skettenis aml_register_regionspace(sc->sc_node, ACPI_OPREG_CMOS,
71c0c10807Skettenis sc, acpicmos_opreg_handler);
72c0c10807Skettenis }
73c0c10807Skettenis
74c0c10807Skettenis
75c0c10807Skettenis int
acpicmos_opreg_handler(void * cookie,int iodir,uint64_t address,int size,uint64_t * value)76c0c10807Skettenis acpicmos_opreg_handler(void *cookie, int iodir, uint64_t address, int size,
77c0c10807Skettenis uint64_t *value)
78c0c10807Skettenis {
79c0c10807Skettenis /* Only allow 8-bit access. */
80c0c10807Skettenis if (size != 8 || address > 0xff)
81c0c10807Skettenis return -1;
82c0c10807Skettenis
83c0c10807Skettenis if (iodir == ACPI_IOREAD)
84c0c10807Skettenis *value = mc146818_read(NULL, address);
85c0c10807Skettenis else
86c0c10807Skettenis mc146818_write(NULL, address, *value);
87c0c10807Skettenis
88c0c10807Skettenis
89c0c10807Skettenis return 0;
90c0c10807Skettenis }
91