1 /* $OpenBSD: acpicmos.c,v 1.1 2018/03/27 21:11:16 kettenis 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 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 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 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 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