synth.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485
  1. #include <linux/types.h>
  2. #include <linux/ctype.h> /* for isdigit() and friends */
  3. #include <linux/fs.h>
  4. #include <linux/mm.h> /* for verify_area */
  5. #include <linux/errno.h> /* for -EBUSY */
  6. #include <linux/ioport.h> /* for check_region, request_region */
  7. #include <linux/interrupt.h>
  8. #include <linux/delay.h> /* for loops_per_sec */
  9. #include <linux/kmod.h>
  10. #include <linux/jiffies.h>
  11. #include <linux/uaccess.h> /* for copy_from_user */
  12. #include <linux/sched.h>
  13. #include <linux/timer.h>
  14. #include <linux/kthread.h>
  15. #include "spk_priv.h"
  16. #include "speakup.h"
  17. #include "serialio.h"
  18. #define MAXSYNTHS 16 /* Max number of synths in array. */
  19. static struct spk_synth *synths[MAXSYNTHS];
  20. struct spk_synth *synth;
  21. char spk_pitch_buff[32] = "";
  22. static int module_status;
  23. bool spk_quiet_boot;
  24. struct speakup_info_t speakup_info = {
  25. /*
  26. * This spinlock is used to protect the entire speakup machinery, and
  27. * must be taken at each kernel->speakup transition and released at
  28. * each corresponding speakup->kernel transition.
  29. *
  30. * The progression thread only interferes with the speakup machinery
  31. * through the synth buffer, so only needs to take the lock
  32. * while tinkering with the buffer.
  33. *
  34. * We use spin_lock/trylock_irqsave and spin_unlock_irqrestore with this
  35. * spinlock because speakup needs to disable the keyboard IRQ.
  36. */
  37. .spinlock = __SPIN_LOCK_UNLOCKED(speakup_info.spinlock),
  38. .flushing = 0,
  39. };
  40. EXPORT_SYMBOL_GPL(speakup_info);
  41. static int do_synth_init(struct spk_synth *in_synth);
  42. int spk_serial_synth_probe(struct spk_synth *synth)
  43. {
  44. const struct old_serial_port *ser;
  45. int failed = 0;
  46. if ((synth->ser >= SPK_LO_TTY) && (synth->ser <= SPK_HI_TTY)) {
  47. ser = spk_serial_init(synth->ser);
  48. if (ser == NULL) {
  49. failed = -1;
  50. } else {
  51. outb_p(0, ser->port);
  52. mdelay(1);
  53. outb_p('\r', ser->port);
  54. }
  55. } else {
  56. failed = -1;
  57. pr_warn("ttyS%i is an invalid port\n", synth->ser);
  58. }
  59. if (failed) {
  60. pr_info("%s: not found\n", synth->long_name);
  61. return -ENODEV;
  62. }
  63. pr_info("%s: ttyS%i, Driver Version %s\n",
  64. synth->long_name, synth->ser, synth->version);
  65. synth->alive = 1;
  66. return 0;
  67. }
  68. EXPORT_SYMBOL_GPL(spk_serial_synth_probe);
  69. /* Main loop of the progression thread: keep eating from the buffer
  70. * and push to the serial port, waiting as needed
  71. *
  72. * For devices that have a "full" notification mechanism, the driver can
  73. * adapt the loop the way they prefer.
  74. */
  75. void spk_do_catch_up(struct spk_synth *synth)
  76. {
  77. u_char ch;
  78. unsigned long flags;
  79. unsigned long jiff_max;
  80. struct var_t *delay_time;
  81. struct var_t *full_time;
  82. struct var_t *jiffy_delta;
  83. int jiffy_delta_val;
  84. int delay_time_val;
  85. int full_time_val;
  86. jiffy_delta = spk_get_var(JIFFY);
  87. full_time = spk_get_var(FULL);
  88. delay_time = spk_get_var(DELAY);
  89. spin_lock_irqsave(&speakup_info.spinlock, flags);
  90. jiffy_delta_val = jiffy_delta->u.n.value;
  91. spin_unlock_irqrestore(&speakup_info.spinlock, flags);
  92. jiff_max = jiffies + jiffy_delta_val;
  93. while (!kthread_should_stop()) {
  94. spin_lock_irqsave(&speakup_info.spinlock, flags);
  95. if (speakup_info.flushing) {
  96. speakup_info.flushing = 0;
  97. spin_unlock_irqrestore(&speakup_info.spinlock, flags);
  98. synth->flush(synth);
  99. continue;
  100. }
  101. if (synth_buffer_empty()) {
  102. spin_unlock_irqrestore(&speakup_info.spinlock, flags);
  103. break;
  104. }
  105. ch = synth_buffer_peek();
  106. set_current_state(TASK_INTERRUPTIBLE);
  107. full_time_val = full_time->u.n.value;
  108. spin_unlock_irqrestore(&speakup_info.spinlock, flags);
  109. if (ch == '\n')
  110. ch = synth->procspeech;
  111. if (!spk_serial_out(ch)) {
  112. schedule_timeout(msecs_to_jiffies(full_time_val));
  113. continue;
  114. }
  115. if (time_after_eq(jiffies, jiff_max) && (ch == SPACE)) {
  116. spin_lock_irqsave(&speakup_info.spinlock, flags);
  117. jiffy_delta_val = jiffy_delta->u.n.value;
  118. delay_time_val = delay_time->u.n.value;
  119. full_time_val = full_time->u.n.value;
  120. spin_unlock_irqrestore(&speakup_info.spinlock, flags);
  121. if (spk_serial_out(synth->procspeech))
  122. schedule_timeout(
  123. msecs_to_jiffies(delay_time_val));
  124. else
  125. schedule_timeout(
  126. msecs_to_jiffies(full_time_val));
  127. jiff_max = jiffies + jiffy_delta_val;
  128. }
  129. set_current_state(TASK_RUNNING);
  130. spin_lock_irqsave(&speakup_info.spinlock, flags);
  131. synth_buffer_getc();
  132. spin_unlock_irqrestore(&speakup_info.spinlock, flags);
  133. }
  134. spk_serial_out(synth->procspeech);
  135. }
  136. EXPORT_SYMBOL_GPL(spk_do_catch_up);
  137. const char *spk_synth_immediate(struct spk_synth *synth, const char *buff)
  138. {
  139. u_char ch;
  140. while ((ch = *buff)) {
  141. if (ch == '\n')
  142. ch = synth->procspeech;
  143. if (spk_wait_for_xmitr())
  144. outb(ch, speakup_info.port_tts);
  145. else
  146. return buff;
  147. buff++;
  148. }
  149. return NULL;
  150. }
  151. EXPORT_SYMBOL_GPL(spk_synth_immediate);
  152. void spk_synth_flush(struct spk_synth *synth)
  153. {
  154. spk_serial_out(synth->clear);
  155. }
  156. EXPORT_SYMBOL_GPL(spk_synth_flush);
  157. int spk_synth_is_alive_nop(struct spk_synth *synth)
  158. {
  159. synth->alive = 1;
  160. return 1;
  161. }
  162. EXPORT_SYMBOL_GPL(spk_synth_is_alive_nop);
  163. int spk_synth_is_alive_restart(struct spk_synth *synth)
  164. {
  165. if (synth->alive)
  166. return 1;
  167. if (!synth->alive && spk_wait_for_xmitr() > 0) {
  168. /* restart */
  169. synth->alive = 1;
  170. synth_printf("%s", synth->init);
  171. return 2; /* reenabled */
  172. }
  173. pr_warn("%s: can't restart synth\n", synth->long_name);
  174. return 0;
  175. }
  176. EXPORT_SYMBOL_GPL(spk_synth_is_alive_restart);
  177. static void thread_wake_up(u_long data)
  178. {
  179. wake_up_interruptible_all(&speakup_event);
  180. }
  181. static DEFINE_TIMER(thread_timer, thread_wake_up, 0, 0);
  182. void synth_start(void)
  183. {
  184. struct var_t *trigger_time;
  185. if (!synth->alive) {
  186. synth_buffer_clear();
  187. return;
  188. }
  189. trigger_time = spk_get_var(TRIGGER);
  190. if (!timer_pending(&thread_timer))
  191. mod_timer(&thread_timer, jiffies +
  192. msecs_to_jiffies(trigger_time->u.n.value));
  193. }
  194. void spk_do_flush(void)
  195. {
  196. if (!synth)
  197. return;
  198. speakup_info.flushing = 1;
  199. synth_buffer_clear();
  200. if (synth->alive) {
  201. if (spk_pitch_shift) {
  202. synth_printf("%s", spk_pitch_buff);
  203. spk_pitch_shift = 0;
  204. }
  205. }
  206. wake_up_interruptible_all(&speakup_event);
  207. wake_up_process(speakup_task);
  208. }
  209. void synth_write(const char *buf, size_t count)
  210. {
  211. while (count--)
  212. synth_buffer_add(*buf++);
  213. synth_start();
  214. }
  215. void synth_printf(const char *fmt, ...)
  216. {
  217. va_list args;
  218. unsigned char buf[160], *p;
  219. int r;
  220. va_start(args, fmt);
  221. r = vsnprintf(buf, sizeof(buf), fmt, args);
  222. va_end(args);
  223. if (r > sizeof(buf) - 1)
  224. r = sizeof(buf) - 1;
  225. p = buf;
  226. while (r--)
  227. synth_buffer_add(*p++);
  228. synth_start();
  229. }
  230. EXPORT_SYMBOL_GPL(synth_printf);
  231. static int index_count;
  232. static int sentence_count;
  233. void spk_reset_index_count(int sc)
  234. {
  235. static int first = 1;
  236. if (first)
  237. first = 0;
  238. else
  239. synth->get_index();
  240. index_count = 0;
  241. sentence_count = sc;
  242. }
  243. int synth_supports_indexing(void)
  244. {
  245. if (synth->get_index != NULL)
  246. return 1;
  247. return 0;
  248. }
  249. void synth_insert_next_index(int sent_num)
  250. {
  251. int out;
  252. if (synth->alive) {
  253. if (sent_num == 0) {
  254. synth->indexing.currindex++;
  255. index_count++;
  256. if (synth->indexing.currindex >
  257. synth->indexing.highindex)
  258. synth->indexing.currindex =
  259. synth->indexing.lowindex;
  260. }
  261. out = synth->indexing.currindex * 10 + sent_num;
  262. synth_printf(synth->indexing.command, out, out);
  263. }
  264. }
  265. void spk_get_index_count(int *linecount, int *sentcount)
  266. {
  267. int ind = synth->get_index();
  268. if (ind) {
  269. sentence_count = ind % 10;
  270. if ((ind / 10) <= synth->indexing.currindex)
  271. index_count = synth->indexing.currindex-(ind/10);
  272. else
  273. index_count = synth->indexing.currindex
  274. -synth->indexing.lowindex
  275. + synth->indexing.highindex-(ind/10)+1;
  276. }
  277. *sentcount = sentence_count;
  278. *linecount = index_count;
  279. }
  280. static struct resource synth_res;
  281. int synth_request_region(unsigned long start, unsigned long n)
  282. {
  283. struct resource *parent = &ioport_resource;
  284. memset(&synth_res, 0, sizeof(synth_res));
  285. synth_res.name = synth->name;
  286. synth_res.start = start;
  287. synth_res.end = start + n - 1;
  288. synth_res.flags = IORESOURCE_BUSY;
  289. return request_resource(parent, &synth_res);
  290. }
  291. EXPORT_SYMBOL_GPL(synth_request_region);
  292. int synth_release_region(unsigned long start, unsigned long n)
  293. {
  294. return release_resource(&synth_res);
  295. }
  296. EXPORT_SYMBOL_GPL(synth_release_region);
  297. struct var_t synth_time_vars[] = {
  298. { DELAY, .u.n = {NULL, 100, 100, 2000, 0, 0, NULL } },
  299. { TRIGGER, .u.n = {NULL, 20, 10, 2000, 0, 0, NULL } },
  300. { JIFFY, .u.n = {NULL, 50, 20, 200, 0, 0, NULL } },
  301. { FULL, .u.n = {NULL, 400, 200, 60000, 0, 0, NULL } },
  302. V_LAST_VAR
  303. };
  304. /* called by: speakup_init() */
  305. int synth_init(char *synth_name)
  306. {
  307. int i;
  308. int ret = 0;
  309. struct spk_synth *synth = NULL;
  310. if (synth_name == NULL)
  311. return 0;
  312. if (strcmp(synth_name, "none") == 0) {
  313. mutex_lock(&spk_mutex);
  314. synth_release();
  315. mutex_unlock(&spk_mutex);
  316. return 0;
  317. }
  318. mutex_lock(&spk_mutex);
  319. /* First, check if we already have it loaded. */
  320. for (i = 0; i < MAXSYNTHS && synths[i] != NULL; i++)
  321. if (strcmp(synths[i]->name, synth_name) == 0)
  322. synth = synths[i];
  323. /* If we got one, initialize it now. */
  324. if (synth)
  325. ret = do_synth_init(synth);
  326. else
  327. ret = -ENODEV;
  328. mutex_unlock(&spk_mutex);
  329. return ret;
  330. }
  331. /* called by: synth_add() */
  332. static int do_synth_init(struct spk_synth *in_synth)
  333. {
  334. struct var_t *var;
  335. synth_release();
  336. if (in_synth->checkval != SYNTH_CHECK)
  337. return -EINVAL;
  338. synth = in_synth;
  339. synth->alive = 0;
  340. pr_warn("synth probe\n");
  341. if (synth->probe(synth) < 0) {
  342. pr_warn("%s: device probe failed\n", in_synth->name);
  343. synth = NULL;
  344. return -ENODEV;
  345. }
  346. synth_time_vars[0].u.n.value =
  347. synth_time_vars[0].u.n.default_val = synth->delay;
  348. synth_time_vars[1].u.n.value =
  349. synth_time_vars[1].u.n.default_val = synth->trigger;
  350. synth_time_vars[2].u.n.value =
  351. synth_time_vars[2].u.n.default_val = synth->jiffies;
  352. synth_time_vars[3].u.n.value =
  353. synth_time_vars[3].u.n.default_val = synth->full;
  354. synth_printf("%s", synth->init);
  355. for (var = synth->vars;
  356. (var->var_id >= 0) && (var->var_id < MAXVARS); var++)
  357. speakup_register_var(var);
  358. if (!spk_quiet_boot)
  359. synth_printf("%s found\n", synth->long_name);
  360. if (synth->attributes.name
  361. && sysfs_create_group(speakup_kobj, &(synth->attributes)) < 0)
  362. return -ENOMEM;
  363. synth_flags = synth->flags;
  364. wake_up_interruptible_all(&speakup_event);
  365. if (speakup_task)
  366. wake_up_process(speakup_task);
  367. return 0;
  368. }
  369. void synth_release(void)
  370. {
  371. struct var_t *var;
  372. unsigned long flags;
  373. if (synth == NULL)
  374. return;
  375. spin_lock_irqsave(&speakup_info.spinlock, flags);
  376. pr_info("releasing synth %s\n", synth->name);
  377. synth->alive = 0;
  378. del_timer(&thread_timer);
  379. spin_unlock_irqrestore(&speakup_info.spinlock, flags);
  380. if (synth->attributes.name)
  381. sysfs_remove_group(speakup_kobj, &(synth->attributes));
  382. for (var = synth->vars; var->var_id != MAXVARS; var++)
  383. speakup_unregister_var(var->var_id);
  384. spk_stop_serial_interrupt();
  385. synth->release();
  386. synth = NULL;
  387. }
  388. /* called by: all_driver_init() */
  389. int synth_add(struct spk_synth *in_synth)
  390. {
  391. int i;
  392. int status = 0;
  393. mutex_lock(&spk_mutex);
  394. for (i = 0; i < MAXSYNTHS && synths[i] != NULL; i++)
  395. /* synth_remove() is responsible for rotating the array down */
  396. if (in_synth == synths[i]) {
  397. mutex_unlock(&spk_mutex);
  398. return 0;
  399. }
  400. if (i == MAXSYNTHS) {
  401. pr_warn("Error: attempting to add a synth past end of array\n");
  402. mutex_unlock(&spk_mutex);
  403. return -1;
  404. }
  405. synths[i++] = in_synth;
  406. synths[i] = NULL;
  407. if (in_synth->startup)
  408. status = do_synth_init(in_synth);
  409. mutex_unlock(&spk_mutex);
  410. return status;
  411. }
  412. EXPORT_SYMBOL_GPL(synth_add);
  413. void synth_remove(struct spk_synth *in_synth)
  414. {
  415. int i;
  416. mutex_lock(&spk_mutex);
  417. if (synth == in_synth)
  418. synth_release();
  419. for (i = 0; synths[i] != NULL; i++) {
  420. if (in_synth == synths[i])
  421. break;
  422. }
  423. for ( ; synths[i] != NULL; i++) /* compress table */
  424. synths[i] = synths[i+1];
  425. module_status = 0;
  426. mutex_unlock(&spk_mutex);
  427. }
  428. EXPORT_SYMBOL_GPL(synth_remove);
  429. short spk_punc_masks[] = { 0, SOME, MOST, PUNC, PUNC|B_SYM };