1696Ssundar/*	$NetBSD$	*/
2696Ssundar
3696Ssundar/*
4877Sattila *  Copyright (c) 2005 The NetBSD Foundation.
5696Ssundar *  All rights reserved.
6696Ssundar *
7696Ssundar *  Redistribution and use in source and binary forms, with or without
8877Sattila *  modification, are permitted provided that the following conditions
9696Ssundar *  are met:
10696Ssundar *  1. Redistributions of source code must retain the above copyright
11696Ssundar *     notice, this list of conditions and the following disclaimer.
12696Ssundar *  2. Redistributions in binary form must reproduce the above copyright
13696Ssundar *     notice, this list of conditions and the following disclaimer in the
14877Sattila *     documentation and/or other materials provided with the distribution.
15696Ssundar *
16696Ssundar *  THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17696Ssundar *  ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18877Sattila *  TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19696Ssundar *  PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20696Ssundar *  BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21696Ssundar *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22696Ssundar *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23696Ssundar *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24696Ssundar *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25696Ssundar *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26696Ssundar *  POSSIBILITY OF SUCH DAMAGE.
27696Ssundar */
28696Ssundar
29696Ssundar/*
30696Ssundar * AT Timer
31696Ssundar *
32696Ssundar * This code only allows control over the pitch of the speaker (pcppi(4)).
33696Ssundar */
34
35#include <sys/cdefs.h>
36__KERNEL_RCSID(0, "$NetBSD$");
37
38#include <sys/param.h>
39#include <sys/systm.h>
40#include <sys/kernel.h>
41#include <sys/device.h>
42
43#include <sys/bus.h>
44
45#include <dev/isa/isareg.h>
46
47#include <dev/ic/attimervar.h>
48#include <dev/ic/i8253reg.h>
49
50extern struct cfdriver attimer_cd;
51
52void
53attimer_attach(struct attimer_softc *sc)
54{
55	sc->sc_flags |= ATT_CONFIGURED;
56
57	if (!pmf_device_register(sc->sc_dev, NULL, NULL))
58		aprint_error_dev(sc->sc_dev, "couldn't establish power handler\n");
59}
60
61int
62attimer_detach(device_t self, int flags)
63{
64	struct attimer_softc *sc = device_private(self);
65
66	if ((sc->sc_flags & ATT_ATTACHED) != 0)
67		return EBUSY;
68
69	pmf_device_deregister(self);
70	sc->sc_flags &= ~ATT_CONFIGURED;
71	bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_size);
72	return 0;
73}
74
75/*
76 * This is slightly artificial.  While the code looks fine, I can't help
77 * but pray I'll get the attimer object associated to the pcppi object
78 * that calls the routine.
79 *
80 * There's not much at risk here, as there's about no chance to have a
81 * computer with more than one pcppi/attimer accessible.
82 *
83 * Caller provides locking for this routine.
84 */
85
86device_t
87attimer_attach_speaker(void)
88{
89	int i;
90	struct attimer_softc *sc;
91
92	for (i = 0; i < attimer_cd.cd_ndevs; i++) {
93		sc = device_lookup_private(&attimer_cd, i);
94		if (sc == NULL)
95			continue;
96		if ((sc->sc_flags & ATT_CONFIGURED) &&
97		    !(sc->sc_flags & ATT_ATTACHED)) {
98			sc->sc_flags |= ATT_ATTACHED;
99			return sc->sc_dev;
100		}
101	}
102	return NULL;
103}
104
105void
106attimer_detach_speaker(device_t dev)
107{
108	struct attimer_softc *sc = device_private(dev);
109
110	sc->sc_flags &= ~ATT_ATTACHED;
111}
112
113/*
114 * Caller provides locking for this routine.
115 */
116
117void
118attimer_set_pitch(device_t dev, int pitch)
119{
120	struct attimer_softc *sc = device_private(dev);
121
122	bus_space_write_1(sc->sc_iot, sc->sc_ioh, TIMER_MODE,
123	    TIMER_SEL2 | TIMER_16BIT | TIMER_SQWAVE);
124	bus_space_write_1(sc->sc_iot, sc->sc_ioh, TIMER_CNTR2,
125	    TIMER_DIV(pitch) % 256);
126	bus_space_write_1(sc->sc_iot, sc->sc_ioh, TIMER_CNTR2,
127	    TIMER_DIV(pitch) / 256);
128}
129