[patch 5/7] staging: speakup: make input functionality swappable

Okash Khawaja okash.khawaja at gmail.com
Mon Apr 3 16:21:28 EDT 2017


This moves functions which take input from external synth, into struct
spk_io_ops. The calling code then uses serial implementation of those methods
through spk_io_ops. That way we can add a parallel TTY-based implementation and
simply replace serial with TTY. That is what the next patch in this series does.

speakup_decext.c has get_last_char function which reads the most recent
available character from the synth. This patch changes that by defining
read_buff_add callback method of spk_syth and letting that update the last_char
global character read from the synth. read_buff_add is called from ISR, so
there is a possibility for last_char to be stale. Therefore it is marked as
volatile.

Signed-off-by: Okash Khawaja <okash.khawaja at gmail.com>

Index: linux-staging/drivers/staging/speakup/serialio.c
===================================================================
--- linux-staging.orig/drivers/staging/speakup/serialio.c
+++ linux-staging/drivers/staging/speakup/serialio.c
@@ -28,11 +28,15 @@ static int timeouts;
 static int spk_serial_out(struct spk_synth *in_synth, const char ch);
 static void spk_serial_send_xchar(char ch);
 static void spk_serial_tiocmset(unsigned int set, unsigned int clear);
+static unsigned char spk_serial_in(void);
+static unsigned char spk_serial_in_nowait(void);
 
 struct spk_io_ops spk_serial_io_ops = {
 	.synth_out = spk_serial_out,
 	.send_xchar = spk_serial_send_xchar,
 	.tiocmset = spk_serial_tiocmset,
+	.synth_in = spk_serial_in,
+	.synth_in_nowait = spk_serial_in_nowait,
 };
 EXPORT_SYMBOL_GPL(spk_serial_io_ops);
 
@@ -240,7 +244,7 @@ int spk_wait_for_xmitr(struct spk_synth
 	return 1;
 }
 
-unsigned char spk_serial_in(void)
+static unsigned char spk_serial_in(void)
 {
 	int tmout = SPK_SERIAL_TIMEOUT;
 
@@ -253,9 +257,8 @@ unsigned char spk_serial_in(void)
 	}
 	return inb_p(speakup_info.port_tts + UART_RX);
 }
-EXPORT_SYMBOL_GPL(spk_serial_in);
 
-unsigned char spk_serial_in_nowait(void)
+static unsigned char spk_serial_in_nowait(void)
 {
 	unsigned char lsr;
 
@@ -264,7 +267,6 @@ unsigned char spk_serial_in_nowait(void)
 		return 0;
 	return inb_p(speakup_info.port_tts + UART_RX);
 }
-EXPORT_SYMBOL_GPL(spk_serial_in_nowait);
 
 static int spk_serial_out(struct spk_synth *in_synth, const char ch)
 {
Index: linux-staging/drivers/staging/speakup/speakup_audptr.c
===================================================================
--- linux-staging.orig/drivers/staging/speakup/speakup_audptr.c
+++ linux-staging/drivers/staging/speakup/speakup_audptr.c
@@ -138,11 +138,11 @@ static void synth_version(struct spk_syn
 	char synth_id[40] = "";
 
 	synth->synth_immediate(synth, "\x05[Q]");
-	synth_id[test] = spk_serial_in();
+	synth_id[test] = synth->io_ops->synth_in();
 	if (synth_id[test] == 'A') {
 		do {
 			/* read version string from synth */
-			synth_id[++test] = spk_serial_in();
+			synth_id[++test] = synth->io_ops->synth_in();
 		} while (synth_id[test] != '\n' && test < 32);
 		synth_id[++test] = 0x00;
 	}
Index: linux-staging/drivers/staging/speakup/speakup_dectlk.c
===================================================================
--- linux-staging.orig/drivers/staging/speakup/speakup_dectlk.c
+++ linux-staging/drivers/staging/speakup/speakup_dectlk.c
@@ -42,7 +42,7 @@ static inline int synth_full(void)
 static void do_catch_up(struct spk_synth *synth);
 static void synth_flush(struct spk_synth *synth);
 static void read_buff_add(u_char c);
-static unsigned char get_index(void);
+static unsigned char get_index(struct spk_synth *synth);
 
 static int in_escape;
 static int is_flushing;
@@ -163,7 +163,7 @@ static int is_indnum(u_char *ch)
 
 static u_char lastind;
 
-static unsigned char get_index(void)
+static unsigned char get_index(struct spk_synth *synth)
 {
 	u_char rv;
 
Index: linux-staging/drivers/staging/speakup/spk_priv.h
===================================================================
--- linux-staging.orig/drivers/staging/speakup/spk_priv.h
+++ linux-staging/drivers/staging/speakup/spk_priv.h
@@ -43,8 +43,6 @@
 const struct old_serial_port *spk_serial_init(int index);
 void spk_stop_serial_interrupt(void);
 int spk_wait_for_xmitr(struct spk_synth *in_synth);
-unsigned char spk_serial_in(void);
-unsigned char spk_serial_in_nowait(void);
 void spk_serial_release(void);
 void spk_ttyio_release(void);
 
Index: linux-staging/drivers/staging/speakup/spk_types.h
===================================================================
--- linux-staging.orig/drivers/staging/speakup/spk_types.h
+++ linux-staging/drivers/staging/speakup/spk_types.h
@@ -152,6 +152,8 @@ struct spk_io_ops {
 	int (*synth_out)(struct spk_synth *synth, const char ch);
 	void (*send_xchar)(char ch);
 	void (*tiocmset)(unsigned int set, unsigned int clear);
+	unsigned char (*synth_in)(void);
+	unsigned char (*synth_in_nowait)(void);
 };
 
 struct spk_synth {
@@ -182,7 +184,7 @@ struct spk_synth {
 	int (*is_alive)(struct spk_synth *synth);
 	int (*synth_adjust)(struct st_var_header *var);
 	void (*read_buff_add)(u_char);
-	unsigned char (*get_index)(void);
+	unsigned char (*get_index)(struct spk_synth *synth);
 	struct synth_indexing indexing;
 	int alive;
 	struct attribute_group attributes;
Index: linux-staging/drivers/staging/speakup/speakup_decext.c
===================================================================
--- linux-staging.orig/drivers/staging/speakup/speakup_decext.c
+++ linux-staging/drivers/staging/speakup/speakup_decext.c
@@ -30,20 +30,16 @@
 #define DRV_VERSION "2.14"
 #define SYNTH_CLEAR 0x03
 #define PROCSPEECH 0x0b
-static unsigned char last_char;
+static volatile unsigned char last_char;
 
-static inline u_char get_last_char(void)
+static void read_buff_add(u_char ch)
 {
-	u_char avail = inb_p(speakup_info.port_tts + UART_LSR) & UART_LSR_DR;
-
-	if (avail)
-		last_char = inb_p(speakup_info.port_tts + UART_RX);
-	return last_char;
+	last_char = ch;
 }
 
 static inline bool synth_full(void)
 {
-	return get_last_char() == 0x13;
+	return last_char == 0x13;
 }
 
 static void do_catch_up(struct spk_synth *synth);
@@ -135,7 +131,7 @@ static struct spk_synth synth_decext = {
 	.flush = synth_flush,
 	.is_alive = spk_synth_is_alive_restart,
 	.synth_adjust = NULL,
-	.read_buff_add = NULL,
+	.read_buff_add = read_buff_add,
 	.get_index = NULL,
 	.indexing = {
 		.command = NULL,
Index: linux-staging/drivers/staging/speakup/speakup_dtlk.c
===================================================================
--- linux-staging.orig/drivers/staging/speakup/speakup_dtlk.c
+++ linux-staging/drivers/staging/speakup/speakup_dtlk.c
@@ -37,6 +37,7 @@ static void dtlk_release(void);
 static const char *synth_immediate(struct spk_synth *synth, const char *buf);
 static void do_catch_up(struct spk_synth *synth);
 static void synth_flush(struct spk_synth *synth);
+static unsigned char get_index(struct spk_synth *synth);
 
 static int synth_lpc;
 static int port_forced;
@@ -138,7 +139,7 @@ static struct spk_synth synth_dtlk = {
 	.is_alive = spk_synth_is_alive_nop,
 	.synth_adjust = NULL,
 	.read_buff_add = NULL,
-	.get_index = spk_serial_in_nowait,
+	.get_index = get_index,
 	.indexing = {
 		.command = "\x01%di",
 		.lowindex = 1,
@@ -169,6 +170,11 @@ static inline bool synth_full(void)
 	return (synth_status & TTS_ALMOST_FULL) != 0;
 }
 
+static unsigned char get_index(struct spk_synth *synth)
+{
+	return synth->io_ops->synth_in_nowait();
+}
+
 static void spk_out(const char ch)
 {
 	int timeout = SPK_XMITR_TIMEOUT;
Index: linux-staging/drivers/staging/speakup/speakup_ltlk.c
===================================================================
--- linux-staging.orig/drivers/staging/speakup/speakup_ltlk.c
+++ linux-staging/drivers/staging/speakup/speakup_ltlk.c
@@ -27,6 +27,7 @@
 #define PROCSPEECH 0x0d
 
 static int synth_probe(struct spk_synth *synth);
+static unsigned char get_index(struct spk_synth *synth);
 
 static struct var_t vars[] = {
 	{ CAPS_START, .u.s = {"\x01+35p" } },
@@ -120,7 +121,7 @@ static struct spk_synth synth_ltlk = {
 	.is_alive = spk_synth_is_alive_restart,
 	.synth_adjust = NULL,
 	.read_buff_add = NULL,
-	.get_index = spk_serial_in_nowait,
+	.get_index = get_index,
 	.indexing = {
 		.command = "\x01%di",
 		.lowindex = 1,
@@ -133,6 +134,11 @@ static struct spk_synth synth_ltlk = {
 	},
 };
 
+static unsigned char get_index(struct spk_synth *synth)
+{
+	return synth->io_ops->synth_in_nowait();
+}
+
 /* interrogate the LiteTalk and print its settings */
 static void synth_interrogate(struct spk_synth *synth)
 {
@@ -141,7 +147,7 @@ static void synth_interrogate(struct spk
 
 	synth->synth_immediate(synth, "\x18\x01?");
 	for (i = 0; i < 50; i++) {
-		buf[i] = spk_serial_in();
+		buf[i] = synth->io_ops->synth_in();
 		if (i > 2 && buf[i] == 0x7f)
 			break;
 	}
Index: linux-staging/drivers/staging/speakup/speakup_soft.c
===================================================================
--- linux-staging.orig/drivers/staging/speakup/speakup_soft.c
+++ linux-staging/drivers/staging/speakup/speakup_soft.c
@@ -36,7 +36,7 @@
 static int softsynth_probe(struct spk_synth *synth);
 static void softsynth_release(void);
 static int softsynth_is_alive(struct spk_synth *synth);
-static unsigned char get_index(void);
+static unsigned char get_index(struct spk_synth *synth);
 
 static struct miscdevice synth_device, synthu_device;
 static int init_pos;
@@ -340,7 +340,7 @@ static unsigned int softsynth_poll(struc
 	return ret;
 }
 
-static unsigned char get_index(void)
+static unsigned char get_index(struct spk_synth *synth)
 {
 	int rv;
 
Index: linux-staging/drivers/staging/speakup/speakup_spkout.c
===================================================================
--- linux-staging.orig/drivers/staging/speakup/speakup_spkout.c
+++ linux-staging/drivers/staging/speakup/speakup_spkout.c
@@ -27,6 +27,7 @@
 #define PROCSPEECH '\r'
 
 static void synth_flush(struct spk_synth *synth);
+static unsigned char get_index(struct spk_synth *synth);
 
 static struct var_t vars[] = {
 	{ CAPS_START, .u.s = {"\x05P+" } },
@@ -111,7 +112,7 @@ static struct spk_synth synth_spkout = {
 	.is_alive = spk_synth_is_alive_restart,
 	.synth_adjust = NULL,
 	.read_buff_add = NULL,
-	.get_index = spk_serial_in_nowait,
+	.get_index = get_index,
 	.indexing = {
 		.command = "\x05[%c",
 		.lowindex = 1,
@@ -124,6 +125,11 @@ static struct spk_synth synth_spkout = {
 	},
 };
 
+static unsigned char get_index(struct spk_synth *synth)
+{
+	return synth->io_ops->synth_in_nowait();
+}
+
 static void synth_flush(struct spk_synth *synth)
 {
 	synth->io_ops->send_xchar(SYNTH_CLEAR);
Index: linux-staging/drivers/staging/speakup/synth.c
===================================================================
--- linux-staging.orig/drivers/staging/speakup/synth.c
+++ linux-staging/drivers/staging/speakup/synth.c
@@ -249,7 +249,7 @@ void spk_reset_index_count(int sc)
 	if (first)
 		first = 0;
 	else
-		synth->get_index();
+		synth->get_index(synth);
 	index_count = 0;
 	sentence_count = sc;
 }
@@ -282,7 +282,7 @@ void synth_insert_next_index(int sent_nu
 
 void spk_get_index_count(int *linecount, int *sentcount)
 {
-	int ind = synth->get_index();
+	int ind = synth->get_index(synth);
 
 	if (ind) {
 		sentence_count = ind % 10;



More information about the Speakup mailing list