OpenCores
URL https://opencores.org/ocsvn/test_project/test_project/trunk

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [drivers/] [input/] [misc/] [sparcspkr.c] - Blame information for rev 62

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 62 marcus.erl
/*
2
 *  Driver for PC-speaker like devices found on various Sparc systems.
3
 *
4
 *  Copyright (c) 2002 Vojtech Pavlik
5
 *  Copyright (c) 2002, 2006 David S. Miller (davem@davemloft.net)
6
 */
7
#include <linux/kernel.h>
8
#include <linux/module.h>
9
#include <linux/init.h>
10
#include <linux/input.h>
11
#include <linux/platform_device.h>
12
 
13
#include <asm/io.h>
14
#include <asm/ebus.h>
15
#include <asm/isa.h>
16
 
17
MODULE_AUTHOR("David S. Miller <davem@davemloft.net>");
18
MODULE_DESCRIPTION("Sparc Speaker beeper driver");
19
MODULE_LICENSE("GPL");
20
 
21
struct sparcspkr_state {
22
        const char              *name;
23
        unsigned long           iobase;
24
        int (*event)(struct input_dev *dev, unsigned int type, unsigned int code, int value);
25
        spinlock_t              lock;
26
        struct input_dev        *input_dev;
27
};
28
 
29
static int ebus_spkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
30
{
31
        struct sparcspkr_state *state = dev_get_drvdata(dev->dev.parent);
32
        unsigned int count = 0;
33
        unsigned long flags;
34
 
35
        if (type != EV_SND)
36
                return -1;
37
 
38
        switch (code) {
39
                case SND_BELL: if (value) value = 1000;
40
                case SND_TONE: break;
41
                default: return -1;
42
        }
43
 
44
        if (value > 20 && value < 32767)
45
                count = 1193182 / value;
46
 
47
        spin_lock_irqsave(&state->lock, flags);
48
 
49
        /* EBUS speaker only has on/off state, the frequency does not
50
         * appear to be programmable.
51
         */
52
        if (state->iobase & 0x2UL)
53
                outb(!!count, state->iobase);
54
        else
55
                outl(!!count, state->iobase);
56
 
57
        spin_unlock_irqrestore(&state->lock, flags);
58
 
59
        return 0;
60
}
61
 
62
static int isa_spkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
63
{
64
        struct sparcspkr_state *state = dev_get_drvdata(dev->dev.parent);
65
        unsigned int count = 0;
66
        unsigned long flags;
67
 
68
        if (type != EV_SND)
69
                return -1;
70
 
71
        switch (code) {
72
                case SND_BELL: if (value) value = 1000;
73
                case SND_TONE: break;
74
                default: return -1;
75
        }
76
 
77
        if (value > 20 && value < 32767)
78
                count = 1193182 / value;
79
 
80
        spin_lock_irqsave(&state->lock, flags);
81
 
82
        if (count) {
83
                /* enable counter 2 */
84
                outb(inb(state->iobase + 0x61) | 3, state->iobase + 0x61);
85
                /* set command for counter 2, 2 byte write */
86
                outb(0xB6, state->iobase + 0x43);
87
                /* select desired HZ */
88
                outb(count & 0xff, state->iobase + 0x42);
89
                outb((count >> 8) & 0xff, state->iobase + 0x42);
90
        } else {
91
                /* disable counter 2 */
92
                outb(inb_p(state->iobase + 0x61) & 0xFC, state->iobase + 0x61);
93
        }
94
 
95
        spin_unlock_irqrestore(&state->lock, flags);
96
 
97
        return 0;
98
}
99
 
100
static int __devinit sparcspkr_probe(struct device *dev)
101
{
102
        struct sparcspkr_state *state = dev_get_drvdata(dev);
103
        struct input_dev *input_dev;
104
        int error;
105
 
106
        input_dev = input_allocate_device();
107
        if (!input_dev)
108
                return -ENOMEM;
109
 
110
        input_dev->name = state->name;
111
        input_dev->phys = "sparc/input0";
112
        input_dev->id.bustype = BUS_ISA;
113
        input_dev->id.vendor = 0x001f;
114
        input_dev->id.product = 0x0001;
115
        input_dev->id.version = 0x0100;
116
        input_dev->dev.parent = dev;
117
 
118
        input_dev->evbit[0] = BIT_MASK(EV_SND);
119
        input_dev->sndbit[0] = BIT_MASK(SND_BELL) | BIT_MASK(SND_TONE);
120
 
121
        input_dev->event = state->event;
122
 
123
        error = input_register_device(input_dev);
124
        if (error) {
125
                input_free_device(input_dev);
126
                return error;
127
        }
128
 
129
        state->input_dev = input_dev;
130
 
131
        return 0;
132
}
133
 
134
static int __devexit sparcspkr_remove(struct of_device *dev)
135
{
136
        struct sparcspkr_state *state = dev_get_drvdata(&dev->dev);
137
        struct input_dev *input_dev = state->input_dev;
138
 
139
        /* turn off the speaker */
140
        state->event(input_dev, EV_SND, SND_BELL, 0);
141
 
142
        input_unregister_device(input_dev);
143
 
144
        dev_set_drvdata(&dev->dev, NULL);
145
        kfree(state);
146
 
147
        return 0;
148
}
149
 
150
static int sparcspkr_shutdown(struct of_device *dev)
151
{
152
        struct sparcspkr_state *state = dev_get_drvdata(&dev->dev);
153
        struct input_dev *input_dev = state->input_dev;
154
 
155
        /* turn off the speaker */
156
        state->event(input_dev, EV_SND, SND_BELL, 0);
157
 
158
        return 0;
159
}
160
 
161
static int __devinit ebus_beep_probe(struct of_device *dev, const struct of_device_id *match)
162
{
163
        struct linux_ebus_device *edev = to_ebus_device(&dev->dev);
164
        struct sparcspkr_state *state;
165
        int err;
166
 
167
        state = kzalloc(sizeof(*state), GFP_KERNEL);
168
        if (!state)
169
                return -ENOMEM;
170
 
171
        state->name = "Sparc EBUS Speaker";
172
        state->iobase = edev->resource[0].start;
173
        state->event = ebus_spkr_event;
174
        spin_lock_init(&state->lock);
175
 
176
        dev_set_drvdata(&dev->dev, state);
177
 
178
        err = sparcspkr_probe(&dev->dev);
179
        if (err) {
180
                dev_set_drvdata(&dev->dev, NULL);
181
                kfree(state);
182
        }
183
 
184
        return 0;
185
}
186
 
187
static struct of_device_id ebus_beep_match[] = {
188
        {
189
                .name = "beep",
190
        },
191
        {},
192
};
193
 
194
static struct of_platform_driver ebus_beep_driver = {
195
        .name           = "beep",
196
        .match_table    = ebus_beep_match,
197
        .probe          = ebus_beep_probe,
198
        .remove         = __devexit_p(sparcspkr_remove),
199
        .shutdown       = sparcspkr_shutdown,
200
};
201
 
202
static int __devinit isa_beep_probe(struct of_device *dev, const struct of_device_id *match)
203
{
204
        struct sparc_isa_device *idev = to_isa_device(&dev->dev);
205
        struct sparcspkr_state *state;
206
        int err;
207
 
208
        state = kzalloc(sizeof(*state), GFP_KERNEL);
209
        if (!state)
210
                return -ENOMEM;
211
 
212
        state->name = "Sparc ISA Speaker";
213
        state->iobase = idev->resource.start;
214
        state->event = isa_spkr_event;
215
        spin_lock_init(&state->lock);
216
 
217
        dev_set_drvdata(&dev->dev, state);
218
 
219
        err = sparcspkr_probe(&dev->dev);
220
        if (err) {
221
                dev_set_drvdata(&dev->dev, NULL);
222
                kfree(state);
223
        }
224
 
225
        return 0;
226
}
227
 
228
static struct of_device_id isa_beep_match[] = {
229
        {
230
                .name = "dma",
231
        },
232
        {},
233
};
234
 
235
static struct of_platform_driver isa_beep_driver = {
236
        .name           = "beep",
237
        .match_table    = isa_beep_match,
238
        .probe          = isa_beep_probe,
239
        .remove         = __devexit_p(sparcspkr_remove),
240
        .shutdown       = sparcspkr_shutdown,
241
};
242
 
243
static int __init sparcspkr_init(void)
244
{
245
        int err = of_register_driver(&ebus_beep_driver, &ebus_bus_type);
246
 
247
        if (!err) {
248
                err = of_register_driver(&isa_beep_driver, &isa_bus_type);
249
                if (err)
250
                        of_unregister_driver(&ebus_beep_driver);
251
        }
252
 
253
        return err;
254
}
255
 
256
static void __exit sparcspkr_exit(void)
257
{
258
        of_unregister_driver(&ebus_beep_driver);
259
        of_unregister_driver(&isa_beep_driver);
260
}
261
 
262
module_init(sparcspkr_init);
263
module_exit(sparcspkr_exit);

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.