27 #include <linux/sched.h>
36 #define DRV_VERSION "2.10"
37 #define PROCSPEECH 0x00
40 static void dtlk_release(
void);
46 static int port_forced;
47 static unsigned int synth_portlist[] = {
48 0x25e, 0x29e, 0x2de, 0x31e, 0x35e, 0x39e, 0
50 static u_char synth_status;
52 static struct var_t vars[] = {
55 {
RATE, .u.n = {
"\x01%ds", 8, 0, 9, 0, 0,
NULL } },
56 {
PITCH, .u.n = {
"\x01%dp", 50, 0, 99, 0, 0,
NULL } },
57 {
VOL, .u.n = {
"\x01%dv", 5, 0, 9, 0, 0,
NULL } },
58 {
TONE, .u.n = {
"\x01%dx", 1, 0, 2, 0, 0,
NULL } },
59 {
PUNCT, .u.n = {
"\x01%db", 7, 0, 15, 0, 0,
NULL } },
60 {
VOICE, .u.n = {
"\x01%do", 0, 0, 7, 0, 0,
NULL } },
103 static struct attribute *synth_attrs[] = {
104 &caps_start_attribute.
attr,
105 &caps_stop_attribute.
attr,
106 &freq_attribute.
attr,
107 &pitch_attribute.
attr,
108 &punct_attribute.
attr,
109 &rate_attribute.
attr,
110 &tone_attribute.
attr,
111 &voice_attribute.
attr,
113 &delay_time_attribute.
attr,
114 &direct_attribute.
attr,
115 &full_time_attribute.
attr,
116 &jiffy_delta_attribute.
attr,
117 &trigger_time_attribute.
attr,
124 .long_name =
"DoubleTalk PC",
125 .init =
"\x01@\x01\x31y",
135 .probe = synth_probe,
136 .release = dtlk_release,
138 .catch_up = do_catch_up,
139 .flush = synth_flush,
141 .synth_adjust =
NULL,
142 .read_buff_add =
NULL,
145 .command =
"\x01%di",
151 .attrs = synth_attrs,
156 static inline bool synth_readable(
void)
162 static inline bool synth_writable(
void)
168 static inline bool synth_full(
void)
174 static void spk_out(
const char ch)
177 while (!synth_writable()) {
184 while (synth_writable()) {
195 unsigned long jiff_max;
196 struct var_t *jiffy_delta;
197 struct var_t *delay_time;
204 jiffy_delta_val = jiffy_delta->
u.
n.value;
206 jiff_max =
jiffies + jiffy_delta_val;
220 delay_time_val = delay_time->
u.
n.value;
233 if ((jiffies >= jiff_max) && (ch ==
SPACE)) {
236 delay_time_val = delay_time->
u.
n.value;
237 jiffy_delta_val = jiffy_delta->
u.
n.value;
240 jiff_max =
jiffies + jiffy_delta_val;
246 static const char *synth_immediate(
struct spk_synth *synth,
const char *
buf)
249 while ((ch = (
u_char)*buf)) {
260 static void synth_flush(
struct spk_synth *synth)
263 while (synth_writable())
267 static char synth_read_tts(
void)
270 while (!synth_readable())
272 ch = synth_status & 0x7f;
274 while (synth_readable())
286 synth_immediate(synth,
"\x18\x01?");
287 for (total = 0, i = 0; i < 50; i++) {
288 buf[total] = synth_read_tts();
289 if (total > 2 && buf[total] == 0x7f)
296 status.serial_number = t[0] + t[1]*256;
298 for (i = 0; *t !=
'\r'; t++) {
300 if (i <
sizeof(
status.rom_version)-1)
307 status.formant_freq = *t++;
313 status.ext_dict_loaded = *t++;
314 status.ext_dict_status = *t++;
316 status.articulation = *t++;
322 static int synth_probe(
struct spk_synth *synth)
324 unsigned int port_val = 0;
327 pr_info(
"Probing for DoubleTalk.\n");
330 pr_info(
"probe forced to %x by kernel command line\n",
332 if ((port_forced & 0xf) != 0xf)
333 pr_info(
"warning: port base should probably end with f\n");
336 pr_warn(
"sorry, port already reserved\n");
342 for (i = 0; synth_portlist[
i]; i++) {
346 port_val =
inw(synth_portlist[i]) & 0xfbff;
347 if (port_val == 0x107f) {
348 synth_lpc = synth_portlist[
i];
357 if (port_val != 0x107f) {
358 pr_info(
"DoubleTalk PC: not found\n");
362 while (
inw_p(synth_lpc) != 0x147f)
364 sp = synth_interrogate(synth);
365 pr_info(
"%s: %03x-%03x, ROM ver %s, s/n %u, driver: %s\n",
372 static void dtlk_release(
void)
385 static int __init dtlk_init(
void)
390 static void __exit dtlk_exit(
void)