root/drivers/input/misc/pcspkr.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. pcspkr_event
  2. pcspkr_probe
  3. pcspkr_remove
  4. pcspkr_suspend
  5. pcspkr_shutdown

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  *  PC Speaker beeper driver for Linux
   4  *
   5  *  Copyright (c) 2002 Vojtech Pavlik
   6  *  Copyright (c) 1992 Orest Zborowski
   7  */
   8 
   9 
  10 #include <linux/kernel.h>
  11 #include <linux/module.h>
  12 #include <linux/i8253.h>
  13 #include <linux/input.h>
  14 #include <linux/platform_device.h>
  15 #include <linux/timex.h>
  16 #include <linux/io.h>
  17 
  18 MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
  19 MODULE_DESCRIPTION("PC Speaker beeper driver");
  20 MODULE_LICENSE("GPL");
  21 MODULE_ALIAS("platform:pcspkr");
  22 
  23 static int pcspkr_event(struct input_dev *dev, unsigned int type,
  24                         unsigned int code, int value)
  25 {
  26         unsigned int count = 0;
  27         unsigned long flags;
  28 
  29         if (type != EV_SND)
  30                 return -EINVAL;
  31 
  32         switch (code) {
  33         case SND_BELL:
  34                 if (value)
  35                         value = 1000;
  36         case SND_TONE:
  37                 break;
  38         default:
  39                 return -EINVAL;
  40         }
  41 
  42         if (value > 20 && value < 32767)
  43                 count = PIT_TICK_RATE / value;
  44 
  45         raw_spin_lock_irqsave(&i8253_lock, flags);
  46 
  47         if (count) {
  48                 /* set command for counter 2, 2 byte write */
  49                 outb_p(0xB6, 0x43);
  50                 /* select desired HZ */
  51                 outb_p(count & 0xff, 0x42);
  52                 outb((count >> 8) & 0xff, 0x42);
  53                 /* enable counter 2 */
  54                 outb_p(inb_p(0x61) | 3, 0x61);
  55         } else {
  56                 /* disable counter 2 */
  57                 outb(inb_p(0x61) & 0xFC, 0x61);
  58         }
  59 
  60         raw_spin_unlock_irqrestore(&i8253_lock, flags);
  61 
  62         return 0;
  63 }
  64 
  65 static int pcspkr_probe(struct platform_device *dev)
  66 {
  67         struct input_dev *pcspkr_dev;
  68         int err;
  69 
  70         pcspkr_dev = input_allocate_device();
  71         if (!pcspkr_dev)
  72                 return -ENOMEM;
  73 
  74         pcspkr_dev->name = "PC Speaker";
  75         pcspkr_dev->phys = "isa0061/input0";
  76         pcspkr_dev->id.bustype = BUS_ISA;
  77         pcspkr_dev->id.vendor = 0x001f;
  78         pcspkr_dev->id.product = 0x0001;
  79         pcspkr_dev->id.version = 0x0100;
  80         pcspkr_dev->dev.parent = &dev->dev;
  81 
  82         pcspkr_dev->evbit[0] = BIT_MASK(EV_SND);
  83         pcspkr_dev->sndbit[0] = BIT_MASK(SND_BELL) | BIT_MASK(SND_TONE);
  84         pcspkr_dev->event = pcspkr_event;
  85 
  86         err = input_register_device(pcspkr_dev);
  87         if (err) {
  88                 input_free_device(pcspkr_dev);
  89                 return err;
  90         }
  91 
  92         platform_set_drvdata(dev, pcspkr_dev);
  93 
  94         return 0;
  95 }
  96 
  97 static int pcspkr_remove(struct platform_device *dev)
  98 {
  99         struct input_dev *pcspkr_dev = platform_get_drvdata(dev);
 100 
 101         input_unregister_device(pcspkr_dev);
 102         /* turn off the speaker */
 103         pcspkr_event(NULL, EV_SND, SND_BELL, 0);
 104 
 105         return 0;
 106 }
 107 
 108 static int pcspkr_suspend(struct device *dev)
 109 {
 110         pcspkr_event(NULL, EV_SND, SND_BELL, 0);
 111 
 112         return 0;
 113 }
 114 
 115 static void pcspkr_shutdown(struct platform_device *dev)
 116 {
 117         /* turn off the speaker */
 118         pcspkr_event(NULL, EV_SND, SND_BELL, 0);
 119 }
 120 
 121 static const struct dev_pm_ops pcspkr_pm_ops = {
 122         .suspend = pcspkr_suspend,
 123 };
 124 
 125 static struct platform_driver pcspkr_platform_driver = {
 126         .driver         = {
 127                 .name   = "pcspkr",
 128                 .pm     = &pcspkr_pm_ops,
 129         },
 130         .probe          = pcspkr_probe,
 131         .remove         = pcspkr_remove,
 132         .shutdown       = pcspkr_shutdown,
 133 };
 134 module_platform_driver(pcspkr_platform_driver);
 135 

/* [<][>][^][v][top][bottom][index][help] */