~ubuntu-branches/ubuntu/precise/speakup/precise

« back to all changes in this revision

Viewing changes to src/speakup_acntpc.c

  • Committer: Bazaar Package Importer
  • Author(s): Mario Lang, Samuel Thibault
  • Date: 2008-07-24 21:44:46 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20080724214446-39aov3onb7im4oz1
Tags: 3.0.3+git20080724.dfsg.1-1
[ Samuel Thibault ]
* New upstream snapshot (fixes arm, armel and sparc compilation).
* Fix the clean target into using the given kernel version and path.
* Document how to load speakup from initrd.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
 * originially written by: Kirk Reiser <kirk@braille.uwo.ca>
 
2
 * written by: Kirk Reiser <kirk@braille.uwo.ca>
3
3
 * this version considerably modified by David Borowski, david575@rogers.com
4
 
 
 
4
 *
5
5
 * Copyright (C) 1998-99  Kirk Reiser.
6
6
 * Copyright (C) 2003 David Borowski.
7
7
 *
18
18
 * You should have received a copy of the GNU General Public License
19
19
 * along with this program; if not, write to the Free Software
20
20
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21
 
 
 
21
 *
22
22
 * this code is specificly written as a driver for the speakup screenreview
23
23
 * package and is not a general device driver.
 
24
 * This driver is for the Aicom Acent PC internal synthesizer.
24
25
 */
25
26
 
26
27
#include <linux/jiffies.h>
 
28
#include <linux/sched.h>
 
29
#include <linux/timer.h>
 
30
#include <linux/kthread.h>
27
31
 
28
32
#include "spk_priv.h"
 
33
#include "serialio.h"
 
34
#include "speakup.h"
29
35
#include "speakup_acnt.h" /* local header file for Accent values */
30
36
 
31
 
#define DRV_VERSION "1.8"
 
37
#define DRV_VERSION "2.6"
32
38
#define synth_readable() (inb_p(synth_port_control) & SYNTH_READABLE)
33
39
#define synth_writable() (inb_p(synth_port_control) & SYNTH_WRITABLE)
34
40
#define synth_full() (inb_p(speakup_info.port_tts) == 'F')
37
43
static int synth_probe(struct spk_synth *synth);
38
44
static void accent_release(void);
39
45
static const char *synth_immediate(struct spk_synth *synth, const char *buf);
40
 
static void do_catch_up(struct spk_synth *synth, unsigned long data);
 
46
static void do_catch_up(struct spk_synth *synth);
41
47
static void synth_flush(struct spk_synth *synth);
42
48
 
43
49
static int synth_port_control;
44
50
static int port_forced;
45
51
static unsigned int synth_portlist[] = { 0x2a8, 0 };
46
52
 
47
 
static struct st_string_var stringvars[] = {
48
 
        { CAPS_START, "\033P8" },
49
 
        { CAPS_STOP, "\033P5" },
50
 
        V_LAST_STRING
51
 
};
52
 
static struct st_num_var numvars[] = {
53
 
        { RATE, "\033R%c", 9, 0, 17, 0, 0, "0123456789abcdefgh" },
54
 
        { PITCH, "\033P%d", 5, 0, 9, 0, 0, 0 },
55
 
        { VOL, "\033A%d", 5, 0, 9, 0, 0, 0 },
56
 
        { TONE, "\033V%d", 5, 0, 9, 0, 0, 0 },
57
 
        V_LAST_NUM
 
53
static struct var_t vars[] = {
 
54
        { CAPS_START, .u.s = {"\033P8" }},
 
55
        { CAPS_STOP, .u.s = {"\033P5" }},
 
56
        { RATE, .u.n = {"\033R%c", 9, 0, 17, 0, 0, "0123456789abcdefgh" }},
 
57
        { PITCH, .u.n = {"\033P%d", 5, 0, 9, 0, 0, NULL }},
 
58
        { VOL, .u.n = {"\033A%d", 5, 0, 9, 0, 0, NULL }},
 
59
        { TONE, .u.n = {"\033V%d", 5, 0, 9, 0, 0, NULL }},
 
60
        V_LAST_VAR
58
61
};
59
62
 
60
63
static struct spk_synth synth_acntpc = {
68
71
        .trigger = 50,
69
72
        .jiffies = 50,
70
73
        .full = 1000,
71
 
        .flush_wait = 0,
72
74
        .startup = SYNTH_START,
73
75
        .checkval = SYNTH_CHECK,
74
 
        .string_vars = stringvars,
75
 
        .num_vars = numvars,
 
76
        .vars = vars,
76
77
        .probe = synth_probe,
77
78
        .release = accent_release,
78
79
        .synth_immediate = synth_immediate,
79
80
        .catch_up = do_catch_up,
80
 
        .start = NULL,
81
81
        .flush = synth_flush,
82
82
        .is_alive = spk_synth_is_alive_nop,
83
83
        .synth_adjust = NULL,
95
95
{
96
96
        u_char ch;
97
97
        while ((ch = *buf)) {
 
98
                int timeout = SPK_XMITR_TIMEOUT;
98
99
                if (ch == '\n')
99
100
                        ch = PROCSPEECH;
100
101
                if (synth_full())
101
102
                        return buf;
102
 
                while (synth_writable())
103
 
                        cpu_relax();
 
103
                while (synth_writable()) {
 
104
                        if (!--timeout)
 
105
                                return buf;
 
106
                        udelay(1);
 
107
                }
104
108
                outb_p(ch, speakup_info.port_tts);
105
109
                buf++;
106
110
        }
107
111
        return 0;
108
112
}
109
113
 
110
 
static void do_catch_up(struct spk_synth *synth, unsigned long data)
 
114
static void do_catch_up(struct spk_synth *synth)
111
115
{
112
 
        unsigned long jiff_max = jiffies+speakup_info.jiffy_delta;
113
116
        u_char ch;
114
 
        synth_stop_timer();
115
 
        while (speakup_info.buff_out < speakup_info.buff_in) {
 
117
        unsigned long flags;
 
118
        int timeout;
 
119
        struct var_t *full_time;
 
120
 
 
121
        while (!kthread_should_stop()) {
 
122
                spk_lock(flags);
 
123
                if (speakup_info.flushing) {
 
124
                        speakup_info.flushing = 0;
 
125
                        spk_unlock(flags);
 
126
                        synth->flush(synth);
 
127
                        continue;
 
128
                }
 
129
                if (synth_buffer_empty()) {
 
130
                        spk_unlock(flags);
 
131
                        break;
 
132
                }
 
133
                set_current_state(TASK_INTERRUPTIBLE);
 
134
                spk_unlock(flags);
116
135
                if (synth_full()) {
117
 
                        synth_delay(speakup_info.full_time);
118
 
                        return;
119
 
                }
120
 
                while (synth_writable())
121
 
                        cpu_relax();
122
 
                ch = *speakup_info.buff_out++;
 
136
                        full_time = get_var(FULL);
 
137
                        schedule_timeout(msecs_to_jiffies(full_time->u.n.value));
 
138
                        continue;
 
139
                }
 
140
                set_current_state(TASK_RUNNING);
 
141
                timeout = SPK_XMITR_TIMEOUT;
 
142
                while (synth_writable()) {
 
143
                        if (!--timeout)
 
144
                                break;
 
145
                        udelay(1);
 
146
                }
 
147
                spk_lock(flags);
 
148
                ch = synth_buffer_getc();
 
149
                spk_unlock(flags);
123
150
                if (ch == '\n')
124
151
                        ch = PROCSPEECH;
125
152
                outb_p(ch, speakup_info.port_tts);
126
 
                if (jiffies >= jiff_max && ch == SPACE) {
127
 
                        while (synth_writable())
128
 
                                cpu_relax();
129
 
                        outb_p(PROCSPEECH, speakup_info.port_tts);
130
 
                        synth_delay(speakup_info.delay_time);
131
 
                        return;
132
 
                }
133
 
        }
134
 
        while (synth_writable())
135
 
                cpu_relax();
 
153
        }
 
154
        timeout = SPK_XMITR_TIMEOUT;
 
155
        while (synth_writable()) {
 
156
                if (!--timeout)
 
157
                        break;
 
158
                udelay(1);
 
159
        }
136
160
        outb_p(PROCSPEECH, speakup_info.port_tts);
137
 
        synth_done();
138
161
}
139
162
 
140
163
static void synth_flush(struct spk_synth *synth)
186
209
        pr_info("%s: %03x-%03x, driver version %s,\n", synth->long_name,
187
210
                synth_port_control, synth_port_control+SYNTH_IO_EXTENT-1,
188
211
                synth->version);
 
212
        synth->alive = 1;
189
213
        return 0;
190
214
}
191
215