1*c7fb772bSthorpej /* $NetBSD: hpcioman.c,v 1.21 2021/08/07 16:19:11 thorpej Exp $ */
226b0905dStakemura
326b0905dStakemura /*-
426b0905dStakemura * Copyright (c) 1999-2001 The NetBSD Foundation, Inc.
526b0905dStakemura * All rights reserved.
626b0905dStakemura *
726b0905dStakemura * This code is derived from software contributed to The NetBSD Foundation
826b0905dStakemura * by UCHIYAMA Yasushi.
926b0905dStakemura *
1026b0905dStakemura * Redistribution and use in source and binary forms, with or without
1126b0905dStakemura * modification, are permitted provided that the following conditions
1226b0905dStakemura * are met:
1326b0905dStakemura * 1. Redistributions of source code must retain the above copyright
1426b0905dStakemura * notice, this list of conditions and the following disclaimer.
1526b0905dStakemura * 2. Redistributions in binary form must reproduce the above copyright
1626b0905dStakemura * notice, this list of conditions and the following disclaimer in the
1726b0905dStakemura * documentation and/or other materials provided with the distribution.
1826b0905dStakemura *
1926b0905dStakemura * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
2026b0905dStakemura * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
2126b0905dStakemura * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2226b0905dStakemura * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
2326b0905dStakemura * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2426b0905dStakemura * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2526b0905dStakemura * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2626b0905dStakemura * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2726b0905dStakemura * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2826b0905dStakemura * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2926b0905dStakemura * POSSIBILITY OF SUCH DAMAGE.
3026b0905dStakemura */
3126b0905dStakemura
32b84f53efSlukem #include <sys/cdefs.h>
33*c7fb772bSthorpej __KERNEL_RCSID(0, "$NetBSD: hpcioman.c,v 1.21 2021/08/07 16:19:11 thorpej Exp $");
34b84f53efSlukem
3526b0905dStakemura #include <sys/param.h>
3626b0905dStakemura #include <sys/systm.h>
3726b0905dStakemura #include <sys/device.h>
3826b0905dStakemura
3926b0905dStakemura #include <machine/config_hook.h>
4026b0905dStakemura #include <machine/platid.h>
4126b0905dStakemura #include <machine/platid_mask.h>
4226b0905dStakemura
43a2a38285Sad #include <sys/bus.h>
4426b0905dStakemura #include <dev/hpc/hpciovar.h>
4526b0905dStakemura #include <dev/hpc/hpciomanvar.h>
4626b0905dStakemura
4726b0905dStakemura #include "locators.h"
4826b0905dStakemura
49529e91fcScegger int hpcioman_match(device_t, cfdata_t, void *);
50529e91fcScegger void hpcioman_attach(device_t, device_t, void *);
5126b0905dStakemura int hpcioman_print(void *, const char *);
52cbab9cadSchs int hpcioman_search(device_t, cfdata_t, const int *, void *);
5326b0905dStakemura
54cbab9cadSchs CFATTACH_DECL_NEW(hpcioman, 0,
55c9b3657cSthorpej hpcioman_match, hpcioman_attach, NULL, NULL);
5626b0905dStakemura
5726b0905dStakemura int
hpcioman_match(device_t parent,cfdata_t cf,void * aux)58529e91fcScegger hpcioman_match(device_t parent, cfdata_t cf, void *aux)
5926b0905dStakemura {
60a8304325Stakemura struct hpcio_attach_args *haa = aux;
6126b0905dStakemura platid_mask_t mask;
6226b0905dStakemura
63a8304325Stakemura if (strcmp(haa->haa_busname, HPCIO_BUSNAME))
64859a6a49Such return (0);
6526b0905dStakemura /* select platform */
6626b0905dStakemura mask = PLATID_DEREF(cf->cf_loc[HPCIOIFCF_PLATFORM]);
6726b0905dStakemura
68859a6a49Such return (platid_match(&platid, &mask));
6926b0905dStakemura }
7026b0905dStakemura
7126b0905dStakemura void
hpcioman_attach(device_t parent,device_t self,void * aux)72529e91fcScegger hpcioman_attach(device_t parent, device_t self, void *aux)
7326b0905dStakemura {
7426b0905dStakemura printf("\n");
7526b0905dStakemura
762685996bSthorpej config_search(self, aux,
77*c7fb772bSthorpej CFARGS(.search = hpcioman_search));
7826b0905dStakemura }
7926b0905dStakemura
8026b0905dStakemura int
hpcioman_search(device_t parent,cfdata_t cf,const int * ldesc,void * aux)81cbab9cadSchs hpcioman_search(device_t parent, cfdata_t cf, const int *ldesc, void *aux)
8226b0905dStakemura {
8326b0905dStakemura struct hpcio_attach_args *haa = aux;
8426b0905dStakemura struct hpcioman_attach_args hma;
8526b0905dStakemura
8626b0905dStakemura /* get io chip */
8726b0905dStakemura hma.hma_hc = (*haa->haa_getchip)(haa->haa_sc, cf->cf_iochip);
8826b0905dStakemura
8926b0905dStakemura /* interrupt mode */
9026b0905dStakemura if (cf->cf_level != HPCIOMANCF_LEVEL_DEFAULT) {
913d94c421Stakemura switch (cf->cf_hold) {
923d94c421Stakemura case 1:
933d94c421Stakemura hma.hma_intr_mode = HPCIO_INTR_HOLD;
943d94c421Stakemura break;
953d94c421Stakemura case 0:
963d94c421Stakemura case HPCIOMANCF_HOLD_DEFAULT:
973d94c421Stakemura default:
983d94c421Stakemura hma.hma_intr_mode = HPCIO_INTR_THROUGH;
993d94c421Stakemura break;
1003d94c421Stakemura }
10126b0905dStakemura hma.hma_intr_mode |= HPCIO_INTR_LEVEL;
10226b0905dStakemura if (cf->cf_level == 0)
10326b0905dStakemura hma.hma_intr_mode |= HPCIO_INTR_LOW;
10426b0905dStakemura else
10526b0905dStakemura hma.hma_intr_mode |= HPCIO_INTR_HIGH;
10626b0905dStakemura } else {
1073d94c421Stakemura switch (cf->cf_hold) {
1083d94c421Stakemura case 0:
1093d94c421Stakemura hma.hma_intr_mode = HPCIO_INTR_THROUGH;
1103d94c421Stakemura break;
1113d94c421Stakemura case 1:
1123d94c421Stakemura case HPCIOMANCF_HOLD_DEFAULT:
1133d94c421Stakemura default:
1143d94c421Stakemura hma.hma_intr_mode = HPCIO_INTR_HOLD;
1153d94c421Stakemura break;
1163d94c421Stakemura }
11726b0905dStakemura hma.hma_intr_mode |= HPCIO_INTR_EDGE;
11826b0905dStakemura switch (cf->cf_edge) {
11926b0905dStakemura case 1:
12026b0905dStakemura hma.hma_intr_mode |= HPCIO_INTR_POSEDGE;
12126b0905dStakemura break;
12226b0905dStakemura case 2:
12326b0905dStakemura hma.hma_intr_mode |= HPCIO_INTR_NEGEDGE;
12426b0905dStakemura break;
12526b0905dStakemura case 0:
12626b0905dStakemura case 3:
12726b0905dStakemura case HPCIOMANCF_EDGE_DEFAULT:
12826b0905dStakemura hma.hma_intr_mode |= HPCIO_INTR_POSEDGE;
12926b0905dStakemura hma.hma_intr_mode |= HPCIO_INTR_NEGEDGE;
13026b0905dStakemura break;
13126b0905dStakemura default:
13226b0905dStakemura printf("%s(%d): invalid configuration, edge=%d",
13326b0905dStakemura __FILE__, __LINE__, cf->cf_edge);
13426b0905dStakemura break;
13526b0905dStakemura }
13626b0905dStakemura }
13726b0905dStakemura
13826b0905dStakemura hma.hma_type = cf->cf_type;
13926b0905dStakemura hma.hma_id = cf->cf_id;
14026b0905dStakemura hma.hma_port = cf->cf_port;
14126b0905dStakemura if (cf->cf_active == 0) {
14226b0905dStakemura hma.hma_on = 0;
14326b0905dStakemura hma.hma_off = 1;
14426b0905dStakemura } else {
14526b0905dStakemura hma.hma_on = 1;
14626b0905dStakemura hma.hma_off = 0;
14726b0905dStakemura }
14826b0905dStakemura hma.hma_initvalue = -1; /* none */
14926b0905dStakemura if (cf->cf_initvalue != HPCIOMANCF_INITVALUE_DEFAULT) {
15026b0905dStakemura if (cf->cf_initvalue == 0)
15126b0905dStakemura hma.hma_initvalue = hma.hma_off;
15226b0905dStakemura else
15326b0905dStakemura hma.hma_initvalue = hma.hma_on;
15426b0905dStakemura }
1553d94c421Stakemura hma.hma_connect = cf->cf_connect;
15626b0905dStakemura
157*c7fb772bSthorpej config_attach(parent, cf, &hma, hpcioman_print, CFARGS_NONE);
15826b0905dStakemura
15926b0905dStakemura return (0);
16026b0905dStakemura }
16126b0905dStakemura
16226b0905dStakemura int
hpcioman_print(void * aux,const char * pnp)16326b0905dStakemura hpcioman_print(void *aux, const char *pnp)
16426b0905dStakemura {
16526b0905dStakemura struct hpcioman_attach_args *hma = aux;
16626b0905dStakemura int type = hma->hma_type;
16726b0905dStakemura
16826b0905dStakemura if (!pnp) {
169703e7687Sthorpej aprint_normal(" iochip %s, port %d, type %d, id %d",
17026b0905dStakemura hma->hma_hc ? hma->hma_hc->hc_name : "not found",
17126b0905dStakemura hma->hma_port, type, hma->hma_id);
17226b0905dStakemura if (type == CONFIG_HOOK_BUTTONEVENT ||
17326b0905dStakemura type == CONFIG_HOOK_PMEVENT ||
1743d94c421Stakemura type == CONFIG_HOOK_EVENT ||
1753d94c421Stakemura type == CONFIG_HOOK_PCIINTR) {
17626b0905dStakemura if (hma->hma_intr_mode & HPCIO_INTR_EDGE)
177703e7687Sthorpej aprint_normal (", interrupt edge [%s%s]",
178859a6a49Such (hma->hma_intr_mode&HPCIO_INTR_POSEDGE)
179859a6a49Such ? "p" : "",
180859a6a49Such (hma->hma_intr_mode&HPCIO_INTR_NEGEDGE)
181859a6a49Such ? "n" : "");
18226b0905dStakemura else
183703e7687Sthorpej aprint_normal (", interrupt level %s",
184859a6a49Such (hma->hma_intr_mode&HPCIO_INTR_HIGH) ?
185859a6a49Such "high" : "low");
18626b0905dStakemura }
18726b0905dStakemura if (hma->hma_initvalue != -1)
188703e7687Sthorpej aprint_normal(", initial value %d", hma->hma_initvalue);
18926b0905dStakemura if (hma->hma_on == 0)
190703e7687Sthorpej aprint_normal(", active low");
19126b0905dStakemura }
19226b0905dStakemura
193859a6a49Such return (QUIET);
19426b0905dStakemura }
195