.probe = spk_ttyio_synth_probe,
        .release = spk_ttyio_release,
        .synth_immediate = spk_ttyio_synth_immediate,
-       .catch_up = spk_do_catch_up,
+       .catch_up = spk_do_catch_up_unicode,
        .flush = spk_synth_flush,
        .is_alive = spk_synth_is_alive_restart,
        .synth_adjust = NULL,
 
 const char *spk_serial_synth_immediate(struct spk_synth *synth, const char *buff);
 const char *spk_ttyio_synth_immediate(struct spk_synth *synth, const char *buff);
 void spk_do_catch_up(struct spk_synth *synth);
+void spk_do_catch_up_unicode(struct spk_synth *synth);
 void spk_synth_flush(struct spk_synth *synth);
 unsigned char spk_synth_get_index(struct spk_synth *synth);
 int spk_synth_is_alive_nop(struct spk_synth *synth);
 
 };
 
 static int spk_ttyio_out(struct spk_synth *in_synth, const char ch);
+static int spk_ttyio_out_unicode(struct spk_synth *in_synth, u16 ch);
 static void spk_ttyio_send_xchar(char ch);
 static void spk_ttyio_tiocmset(unsigned int set, unsigned int clear);
 static unsigned char spk_ttyio_in(void);
 
 struct spk_io_ops spk_ttyio_ops = {
        .synth_out = spk_ttyio_out,
+       .synth_out_unicode = spk_ttyio_out_unicode,
        .send_xchar = spk_ttyio_send_xchar,
        .tiocmset = spk_ttyio_tiocmset,
        .synth_in = spk_ttyio_in,
        return 0;
 }
 
+static int spk_ttyio_out_unicode(struct spk_synth *in_synth, u16 ch)
+{
+       int ret;
+       if (ch < 0x80)
+               ret = spk_ttyio_out(in_synth, ch);
+       else if (ch < 0x800) {
+               ret  = spk_ttyio_out(in_synth, 0xc0 | (ch >> 6));
+               ret &= spk_ttyio_out(in_synth, 0x80 | (ch & 0x3f));
+       } else {
+               ret  = spk_ttyio_out(in_synth, 0xe0 | (ch >> 12));
+               ret &= spk_ttyio_out(in_synth, 0x80 | ((ch >> 6) & 0x3f));
+               ret &= spk_ttyio_out(in_synth, 0x80 | (ch & 0x3f));
+       }
+       return ret;
+}
+
 static int check_tty(struct tty_struct *tty)
 {
        if (!tty) {
 
 
 struct spk_io_ops {
        int (*synth_out)(struct spk_synth *synth, const char ch);
+       int (*synth_out_unicode)(struct spk_synth *synth, u16 ch);
        void (*send_xchar)(char ch);
        void (*tiocmset)(unsigned int set, unsigned int clear);
        unsigned char (*synth_in)(void);
 
  * For devices that have a "full" notification mechanism, the driver can
  * adapt the loop the way they prefer.
  */
-void spk_do_catch_up(struct spk_synth *synth)
+static void _spk_do_catch_up(struct spk_synth *synth, int unicode)
 {
-       u_char ch;
+       u16 ch;
        unsigned long flags;
        unsigned long jiff_max;
        struct var_t *delay_time;
        int jiffy_delta_val;
        int delay_time_val;
        int full_time_val;
+       int ret;
 
        jiffy_delta = spk_get_var(JIFFY);
        full_time = spk_get_var(FULL);
                        synth->flush(synth);
                        continue;
                }
-               synth_buffer_skip_nonlatin1();
+               if (!unicode)
+                       synth_buffer_skip_nonlatin1();
                if (synth_buffer_empty()) {
                        spin_unlock_irqrestore(&speakup_info.spinlock, flags);
                        break;
                spin_unlock_irqrestore(&speakup_info.spinlock, flags);
                if (ch == '\n')
                        ch = synth->procspeech;
-               if (!synth->io_ops->synth_out(synth, ch)) {
+               if (unicode)
+                       ret = synth->io_ops->synth_out_unicode(synth, ch);
+               else
+                       ret = synth->io_ops->synth_out(synth, ch);
+               if (!ret) {
                        schedule_timeout(msecs_to_jiffies(full_time_val));
                        continue;
                }
        }
        synth->io_ops->synth_out(synth, synth->procspeech);
 }
+
+void spk_do_catch_up(struct spk_synth *synth)
+{
+       _spk_do_catch_up(synth, 0);
+}
 EXPORT_SYMBOL_GPL(spk_do_catch_up);
 
+void spk_do_catch_up_unicode(struct spk_synth *synth)
+{
+       _spk_do_catch_up(synth, 1);
+}
+EXPORT_SYMBOL_GPL(spk_do_catch_up_unicode);
+
 void spk_synth_flush(struct spk_synth *synth)
 {
        synth->io_ops->flush_buffer();