Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * PC-Speaker driver for Linux
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * Copyright (C) 1997-2001  David Woodhouse
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  * Copyright (C) 2001-2008  Stas Sergeev
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <sound/core.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <sound/initval.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <sound/pcm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/input.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <linux/bitops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include <linux/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include "pcsp_input.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include "pcsp.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) MODULE_AUTHOR("Stas Sergeev <stsp@users.sourceforge.net>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) MODULE_DESCRIPTION("PC-Speaker driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) MODULE_SUPPORTED_DEVICE("{{PC-Speaker, pcsp}}");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) MODULE_ALIAS("platform:pcspkr");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) static int index = SNDRV_DEFAULT_IDX1;	/* Index 0-MAX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) static char *id = SNDRV_DEFAULT_STR1;	/* ID for this card */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) static bool enable = SNDRV_DEFAULT_ENABLE1;	/* Enable this card */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) static bool nopcm;	/* Disable PCM capability of the driver */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) module_param(index, int, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) MODULE_PARM_DESC(index, "Index value for pcsp soundcard.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) module_param(id, charp, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) MODULE_PARM_DESC(id, "ID string for pcsp soundcard.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) module_param(enable, bool, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) MODULE_PARM_DESC(enable, "Enable PC-Speaker sound.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) module_param(nopcm, bool, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) MODULE_PARM_DESC(nopcm, "Disable PC-Speaker PCM sound. Only beeps remain.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) struct snd_pcsp pcsp_chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) static int snd_pcsp_create(struct snd_card *card)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 	static const struct snd_device_ops ops = { };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 	unsigned int resolution = hrtimer_resolution;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 	int err, div, min_div, order;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 	if (!nopcm) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 		if (resolution > PCSP_MAX_PERIOD_NS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 			printk(KERN_ERR "PCSP: Timer resolution is not sufficient "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 				"(%unS)\n", resolution);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 			printk(KERN_ERR "PCSP: Make sure you have HPET and ACPI "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 				"enabled.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 			printk(KERN_ERR "PCSP: Turned into nopcm mode.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 			nopcm = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 	if (loops_per_jiffy >= PCSP_MIN_LPJ && resolution <= PCSP_MIN_PERIOD_NS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 		min_div = MIN_DIV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 		min_div = MAX_DIV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) #if PCSP_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	printk(KERN_DEBUG "PCSP: lpj=%li, min_div=%i, res=%u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	       loops_per_jiffy, min_div, resolution);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	div = MAX_DIV / min_div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	order = fls(div) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	pcsp_chip.max_treble = min(order, PCSP_MAX_TREBLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	pcsp_chip.treble = min(pcsp_chip.max_treble, PCSP_DEFAULT_TREBLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	pcsp_chip.playback_ptr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	pcsp_chip.period_ptr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	atomic_set(&pcsp_chip.timer_active, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	pcsp_chip.enable = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	pcsp_chip.pcspkr = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	spin_lock_init(&pcsp_chip.substream_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	pcsp_chip.card = card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	pcsp_chip.port = 0x61;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	pcsp_chip.irq = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	pcsp_chip.dma = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	/* Register device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, &pcsp_chip, &ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) static int snd_card_pcsp_probe(int devnum, struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	struct snd_card *card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	if (devnum != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 	hrtimer_init(&pcsp_chip.timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	pcsp_chip.timer.function = pcsp_do_timer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	err = snd_card_new(dev, index, id, THIS_MODULE, 0, &card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	err = snd_pcsp_create(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 		goto free_card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	if (!nopcm) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 		err = snd_pcsp_new_pcm(&pcsp_chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 		if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 			goto free_card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	err = snd_pcsp_new_mixer(&pcsp_chip, nopcm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 		goto free_card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 	strcpy(card->driver, "PC-Speaker");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	strcpy(card->shortname, "pcsp");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	sprintf(card->longname, "Internal PC-Speaker at port 0x%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 		pcsp_chip.port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	err = snd_card_register(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 		goto free_card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) free_card:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	snd_card_free(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) static int alsa_card_pcsp_init(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 	err = snd_card_pcsp_probe(0, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 		printk(KERN_ERR "PC-Speaker initialization failed.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	/* Well, CONFIG_DEBUG_PAGEALLOC makes the sound horrible. Lets alert */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	if (debug_pagealloc_enabled()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 		printk(KERN_WARNING "PCSP: CONFIG_DEBUG_PAGEALLOC is enabled, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 		       "which may make the sound noisy.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) static void alsa_card_pcsp_exit(struct snd_pcsp *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	snd_card_free(chip->card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) static int pcsp_probe(struct platform_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	err = pcspkr_input_init(&pcsp_chip.input_dev, &dev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 	err = alsa_card_pcsp_init(&dev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 	if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 		pcspkr_input_remove(pcsp_chip.input_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 	platform_set_drvdata(dev, &pcsp_chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) static int pcsp_remove(struct platform_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 	struct snd_pcsp *chip = platform_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 	pcspkr_input_remove(chip->input_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	alsa_card_pcsp_exit(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) static void pcsp_stop_beep(struct snd_pcsp *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 	pcsp_sync_stop(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 	pcspkr_stop_sound();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) #ifdef CONFIG_PM_SLEEP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) static int pcsp_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 	struct snd_pcsp *chip = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 	pcsp_stop_beep(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) static SIMPLE_DEV_PM_OPS(pcsp_pm, pcsp_suspend, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) #define PCSP_PM_OPS	&pcsp_pm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) #define PCSP_PM_OPS	NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) #endif	/* CONFIG_PM_SLEEP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) static void pcsp_shutdown(struct platform_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 	struct snd_pcsp *chip = platform_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 	pcsp_stop_beep(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) static struct platform_driver pcsp_platform_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 	.driver		= {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 		.name	= "pcspkr",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 		.pm	= PCSP_PM_OPS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 	.probe		= pcsp_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 	.remove		= pcsp_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 	.shutdown	= pcsp_shutdown,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) static int __init pcsp_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 	if (!enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 	return platform_driver_register(&pcsp_platform_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) static void __exit pcsp_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 	platform_driver_unregister(&pcsp_platform_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) module_init(pcsp_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) module_exit(pcsp_exit);