drivers/accessibility/speakup/speakup_soft.c

Source file repositories/reference/linux-study-clean/drivers/accessibility/speakup/speakup_soft.c

File Facts

System
Linux kernel
Corpus path
drivers/accessibility/speakup/speakup_soft.c
Extension
.c
Size
14008 bytes
Lines
492
Domain
Driver Families
Bucket
drivers/accessibility
Inferred role
Driver Families: operation-table or driver-model contract
Status
pattern implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

static const struct file_operations softsynth_fops = {
	.owner = THIS_MODULE,
	.poll = softsynth_poll,
	.read = softsynth_read,
	.write = softsynth_write,
	.open = softsynth_open,
	.release = softsynth_close,
};

static const struct file_operations softsynthu_fops = {
	.owner = THIS_MODULE,
	.poll = softsynth_poll,
	.read = softsynthu_read,
	.write = softsynth_write,
	.open = softsynth_open,
	.release = softsynth_close,
};

static int softsynth_probe(struct spk_synth *synth)
{
	if (misc_registered != 0)
		return 0;
	memset(&synth_device, 0, sizeof(synth_device));
	synth_device.minor = MISC_DYNAMIC_MINOR;
	synth_device.name = "softsynth";
	synth_device.fops = &softsynth_fops;
	if (misc_register(&synth_device)) {
		pr_warn("Couldn't initialize miscdevice /dev/softsynth.\n");
		return -ENODEV;
	}

	memset(&synthu_device, 0, sizeof(synthu_device));
	synthu_device.minor = MISC_DYNAMIC_MINOR;
	synthu_device.name = "softsynthu";
	synthu_device.fops = &softsynthu_fops;
	if (misc_register(&synthu_device)) {
		misc_deregister(&synth_device);
		pr_warn("Couldn't initialize miscdevice /dev/softsynthu.\n");
		return -ENODEV;
	}

	misc_registered = 1;
	pr_info("initialized device: /dev/softsynth, node (MAJOR 10, MINOR %d)\n",
		synth_device.minor);
	pr_info("initialized device: /dev/softsynthu, node (MAJOR 10, MINOR %d)\n",
		synthu_device.minor);
	return 0;
}

static void softsynth_release(struct spk_synth *synth)
{
	misc_deregister(&synth_device);
	misc_deregister(&synthu_device);
	misc_registered = 0;
	pr_info("unregistered /dev/softsynth\n");
	pr_info("unregistered /dev/softsynthu\n");
}

static int softsynth_is_alive(struct spk_synth *synth)
{
	if (synth_soft.alive)
		return 1;
	return 0;
}

static int softsynth_adjust(struct spk_synth *synth, struct st_var_header *var)
{
	struct st_var_header *punc_level_var;
	struct var_t *var_data;

	if (var->var_id != PUNC_LEVEL)
		return 0;

	/* We want to set the the speech synthesis punctuation level
	 * accordingly, so it properly tunes speaking A_PUNC characters */
	var_data = var->data;
	if (!var_data)
		return 0;
	punc_level_var = spk_get_var_header(PUNCT);
	if (!punc_level_var)
		return 0;
	spk_set_num_var(var_data->u.n.value, punc_level_var, E_SET);

	return 1;
}

module_param_named(start, synth_soft.startup, short, 0444);
module_param_named(direct, vars[DIRECT_ID].u.n.default_val, int, 0444);
module_param_named(rate, vars[RATE_ID].u.n.default_val, int, 0444);
module_param_named(pitch, vars[PITCH_ID].u.n.default_val, int, 0444);

Annotation

Implementation Notes