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

Subversion Repositories test_project

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 62 marcus.erl
/*
2
 * Generic IXP4xx beeper driver
3
 *
4
 * Copyright (C) 2005 Tower Technologies
5
 *
6
 * based on nslu2-io.c
7
 *  Copyright (C) 2004 Karen Spearel
8
 *
9
 * Author: Alessandro Zummo <a.zummo@towertech.it>
10
 * Maintainers: http://www.nslu2-linux.org/
11
 *
12
 * This program is free software; you can redistribute it and/or modify
13
 * it under the terms of the GNU General Public License version 2 as
14
 * published by the Free Software Foundation.
15
 *
16
 */
17
 
18
#include <linux/module.h>
19
#include <linux/input.h>
20
#include <linux/delay.h>
21
#include <linux/platform_device.h>
22
#include <linux/interrupt.h>
23
#include <asm/hardware.h>
24
 
25
MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>");
26
MODULE_DESCRIPTION("ixp4xx beeper driver");
27
MODULE_LICENSE("GPL");
28
 
29
static DEFINE_SPINLOCK(beep_lock);
30
 
31
static void ixp4xx_spkr_control(unsigned int pin, unsigned int count)
32
{
33
        unsigned long flags;
34
 
35
        spin_lock_irqsave(&beep_lock, flags);
36
 
37
         if (count) {
38
                gpio_line_config(pin, IXP4XX_GPIO_OUT);
39
                gpio_line_set(pin, IXP4XX_GPIO_LOW);
40
 
41
                *IXP4XX_OSRT2 = (count & ~IXP4XX_OST_RELOAD_MASK) | IXP4XX_OST_ENABLE;
42
        } else {
43
                gpio_line_config(pin, IXP4XX_GPIO_IN);
44
                gpio_line_set(pin, IXP4XX_GPIO_HIGH);
45
 
46
                *IXP4XX_OSRT2 = 0;
47
        }
48
 
49
        spin_unlock_irqrestore(&beep_lock, flags);
50
}
51
 
52
static int ixp4xx_spkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
53
{
54
        unsigned int pin = (unsigned int) input_get_drvdata(dev);
55
        unsigned int count = 0;
56
 
57
        if (type != EV_SND)
58
                return -1;
59
 
60
        switch (code) {
61
                case SND_BELL:
62
                        if (value)
63
                                value = 1000;
64
                case SND_TONE:
65
                        break;
66
                default:
67
                        return -1;
68
        }
69
 
70
        if (value > 20 && value < 32767)
71
#ifndef FREQ
72
                count = (ixp4xx_get_board_tick_rate() / (value * 4)) - 1;
73
#else
74
                count = (FREQ / (value * 4)) - 1;
75
#endif
76
 
77
        ixp4xx_spkr_control(pin, count);
78
 
79
        return 0;
80
}
81
 
82
static irqreturn_t ixp4xx_spkr_interrupt(int irq, void *dev_id)
83
{
84
        /* clear interrupt */
85
        *IXP4XX_OSST = IXP4XX_OSST_TIMER_2_PEND;
86
 
87
        /* flip the beeper output */
88
        *IXP4XX_GPIO_GPOUTR ^= (1 << (unsigned int) dev_id);
89
 
90
        return IRQ_HANDLED;
91
}
92
 
93
static int __devinit ixp4xx_spkr_probe(struct platform_device *dev)
94
{
95
        struct input_dev *input_dev;
96
        int err;
97
 
98
        input_dev = input_allocate_device();
99
        if (!input_dev)
100
                return -ENOMEM;
101
 
102
        input_set_drvdata(input_dev, (void *) dev->id);
103
 
104
        input_dev->name = "ixp4xx beeper",
105
        input_dev->phys = "ixp4xx/gpio";
106
        input_dev->id.bustype = BUS_HOST;
107
        input_dev->id.vendor  = 0x001f;
108
        input_dev->id.product = 0x0001;
109
        input_dev->id.version = 0x0100;
110
        input_dev->dev.parent = &dev->dev;
111
 
112
        input_dev->evbit[0] = BIT_MASK(EV_SND);
113
        input_dev->sndbit[0] = BIT_MASK(SND_BELL) | BIT_MASK(SND_TONE);
114
        input_dev->event = ixp4xx_spkr_event;
115
 
116
        err = request_irq(IRQ_IXP4XX_TIMER2, &ixp4xx_spkr_interrupt,
117
                          IRQF_DISABLED | IRQF_TIMER, "ixp4xx-beeper", (void *) dev->id);
118
        if (err)
119
                goto err_free_device;
120
 
121
        err = input_register_device(input_dev);
122
        if (err)
123
                goto err_free_irq;
124
 
125
        platform_set_drvdata(dev, input_dev);
126
 
127
        return 0;
128
 
129
 err_free_irq:
130
        free_irq(IRQ_IXP4XX_TIMER2, dev);
131
 err_free_device:
132
        input_free_device(input_dev);
133
 
134
        return err;
135
}
136
 
137
static int __devexit ixp4xx_spkr_remove(struct platform_device *dev)
138
{
139
        struct input_dev *input_dev = platform_get_drvdata(dev);
140
        unsigned int pin = (unsigned int) input_get_drvdata(input_dev);
141
 
142
        input_unregister_device(input_dev);
143
        platform_set_drvdata(dev, NULL);
144
 
145
        /* turn the speaker off */
146
        disable_irq(IRQ_IXP4XX_TIMER2);
147
        ixp4xx_spkr_control(pin, 0);
148
 
149
        free_irq(IRQ_IXP4XX_TIMER2, dev);
150
 
151
        return 0;
152
}
153
 
154
static void ixp4xx_spkr_shutdown(struct platform_device *dev)
155
{
156
        struct input_dev *input_dev = platform_get_drvdata(dev);
157
        unsigned int pin = (unsigned int) input_get_drvdata(input_dev);
158
 
159
        /* turn off the speaker */
160
        disable_irq(IRQ_IXP4XX_TIMER2);
161
        ixp4xx_spkr_control(pin, 0);
162
}
163
 
164
static struct platform_driver ixp4xx_spkr_platform_driver = {
165
        .driver         = {
166
                .name   = "ixp4xx-beeper",
167
                .owner  = THIS_MODULE,
168
        },
169
        .probe          = ixp4xx_spkr_probe,
170
        .remove         = __devexit_p(ixp4xx_spkr_remove),
171
        .shutdown       = ixp4xx_spkr_shutdown,
172
};
173
 
174
static int __init ixp4xx_spkr_init(void)
175
{
176
        return platform_driver_register(&ixp4xx_spkr_platform_driver);
177
}
178
 
179
static void __exit ixp4xx_spkr_exit(void)
180
{
181
        platform_driver_unregister(&ixp4xx_spkr_platform_driver);
182
}
183
 
184
module_init(ixp4xx_spkr_init);
185
module_exit(ixp4xx_spkr_exit);

powered by: WebSVN 2.1.0

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