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