root/drivers/input/misc/sparcspkr.c

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

DEFINITIONS

This source file includes following definitions.
  1. bbc_count_to_reg
  2. bbc_spkr_event
  3. grover_spkr_event
  4. sparcspkr_probe
  5. sparcspkr_shutdown
  6. bbc_beep_probe
  7. bbc_remove
  8. grover_beep_probe
  9. grover_remove
  10. sparcspkr_init
  11. sparcspkr_exit

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  *  Driver for PC-speaker like devices found on various Sparc systems.
   4  *
   5  *  Copyright (c) 2002 Vojtech Pavlik
   6  *  Copyright (c) 2002, 2006, 2008 David S. Miller (davem@davemloft.net)
   7  */
   8 #include <linux/kernel.h>
   9 #include <linux/module.h>
  10 #include <linux/init.h>
  11 #include <linux/input.h>
  12 #include <linux/of_device.h>
  13 #include <linux/slab.h>
  14 
  15 #include <asm/io.h>
  16 
  17 MODULE_AUTHOR("David S. Miller <davem@davemloft.net>");
  18 MODULE_DESCRIPTION("Sparc Speaker beeper driver");
  19 MODULE_LICENSE("GPL");
  20 
  21 struct grover_beep_info {
  22         void __iomem    *freq_regs;
  23         void __iomem    *enable_reg;
  24 };
  25 
  26 struct bbc_beep_info {
  27         u32             clock_freq;
  28         void __iomem    *regs;
  29 };
  30 
  31 struct sparcspkr_state {
  32         const char              *name;
  33         int (*event)(struct input_dev *dev, unsigned int type, unsigned int code, int value);
  34         spinlock_t              lock;
  35         struct input_dev        *input_dev;
  36         union {
  37                 struct grover_beep_info grover;
  38                 struct bbc_beep_info bbc;
  39         } u;
  40 };
  41 
  42 static u32 bbc_count_to_reg(struct bbc_beep_info *info, unsigned int count)
  43 {
  44         u32 val, clock_freq = info->clock_freq;
  45         int i;
  46 
  47         if (!count)
  48                 return 0;
  49 
  50         if (count <= clock_freq >> 20)
  51                 return 1 << 18;
  52 
  53         if (count >= clock_freq >> 12)
  54                 return 1 << 10;
  55 
  56         val = 1 << 18;
  57         for (i = 19; i >= 11; i--) {
  58                 val >>= 1;
  59                 if (count <= clock_freq >> i)
  60                         break;
  61         }
  62 
  63         return val;
  64 }
  65 
  66 static int bbc_spkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
  67 {
  68         struct sparcspkr_state *state = dev_get_drvdata(dev->dev.parent);
  69         struct bbc_beep_info *info = &state->u.bbc;
  70         unsigned int count = 0;
  71         unsigned long flags;
  72 
  73         if (type != EV_SND)
  74                 return -1;
  75 
  76         switch (code) {
  77                 case SND_BELL: if (value) value = 1000;
  78                 case SND_TONE: break;
  79                 default: return -1;
  80         }
  81 
  82         if (value > 20 && value < 32767)
  83                 count = 1193182 / value;
  84 
  85         count = bbc_count_to_reg(info, count);
  86 
  87         spin_lock_irqsave(&state->lock, flags);
  88 
  89         if (count) {
  90                 sbus_writeb(0x01,                 info->regs + 0);
  91                 sbus_writeb(0x00,                 info->regs + 2);
  92                 sbus_writeb((count >> 16) & 0xff, info->regs + 3);
  93                 sbus_writeb((count >>  8) & 0xff, info->regs + 4);
  94                 sbus_writeb(0x00,                 info->regs + 5);
  95         } else {
  96                 sbus_writeb(0x00,                 info->regs + 0);
  97         }
  98 
  99         spin_unlock_irqrestore(&state->lock, flags);
 100 
 101         return 0;
 102 }
 103 
 104 static int grover_spkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
 105 {
 106         struct sparcspkr_state *state = dev_get_drvdata(dev->dev.parent);
 107         struct grover_beep_info *info = &state->u.grover;
 108         unsigned int count = 0;
 109         unsigned long flags;
 110 
 111         if (type != EV_SND)
 112                 return -1;
 113 
 114         switch (code) {
 115                 case SND_BELL: if (value) value = 1000;
 116                 case SND_TONE: break;
 117                 default: return -1;
 118         }
 119 
 120         if (value > 20 && value < 32767)
 121                 count = 1193182 / value;
 122 
 123         spin_lock_irqsave(&state->lock, flags);
 124 
 125         if (count) {
 126                 /* enable counter 2 */
 127                 sbus_writeb(sbus_readb(info->enable_reg) | 3, info->enable_reg);
 128                 /* set command for counter 2, 2 byte write */
 129                 sbus_writeb(0xB6, info->freq_regs + 1);
 130                 /* select desired HZ */
 131                 sbus_writeb(count & 0xff, info->freq_regs + 0);
 132                 sbus_writeb((count >> 8) & 0xff, info->freq_regs + 0);
 133         } else {
 134                 /* disable counter 2 */
 135                 sbus_writeb(sbus_readb(info->enable_reg) & 0xFC, info->enable_reg);
 136         }
 137 
 138         spin_unlock_irqrestore(&state->lock, flags);
 139 
 140         return 0;
 141 }
 142 
 143 static int sparcspkr_probe(struct device *dev)
 144 {
 145         struct sparcspkr_state *state = dev_get_drvdata(dev);
 146         struct input_dev *input_dev;
 147         int error;
 148 
 149         input_dev = input_allocate_device();
 150         if (!input_dev)
 151                 return -ENOMEM;
 152 
 153         input_dev->name = state->name;
 154         input_dev->phys = "sparc/input0";
 155         input_dev->id.bustype = BUS_ISA;
 156         input_dev->id.vendor = 0x001f;
 157         input_dev->id.product = 0x0001;
 158         input_dev->id.version = 0x0100;
 159         input_dev->dev.parent = dev;
 160 
 161         input_dev->evbit[0] = BIT_MASK(EV_SND);
 162         input_dev->sndbit[0] = BIT_MASK(SND_BELL) | BIT_MASK(SND_TONE);
 163 
 164         input_dev->event = state->event;
 165 
 166         error = input_register_device(input_dev);
 167         if (error) {
 168                 input_free_device(input_dev);
 169                 return error;
 170         }
 171 
 172         state->input_dev = input_dev;
 173 
 174         return 0;
 175 }
 176 
 177 static void sparcspkr_shutdown(struct platform_device *dev)
 178 {
 179         struct sparcspkr_state *state = platform_get_drvdata(dev);
 180         struct input_dev *input_dev = state->input_dev;
 181 
 182         /* turn off the speaker */
 183         state->event(input_dev, EV_SND, SND_BELL, 0);
 184 }
 185 
 186 static int bbc_beep_probe(struct platform_device *op)
 187 {
 188         struct sparcspkr_state *state;
 189         struct bbc_beep_info *info;
 190         struct device_node *dp;
 191         int err = -ENOMEM;
 192 
 193         state = kzalloc(sizeof(*state), GFP_KERNEL);
 194         if (!state)
 195                 goto out_err;
 196 
 197         state->name = "Sparc BBC Speaker";
 198         state->event = bbc_spkr_event;
 199         spin_lock_init(&state->lock);
 200 
 201         dp = of_find_node_by_path("/");
 202         err = -ENODEV;
 203         if (!dp)
 204                 goto out_free;
 205 
 206         info = &state->u.bbc;
 207         info->clock_freq = of_getintprop_default(dp, "clock-frequency", 0);
 208         if (!info->clock_freq)
 209                 goto out_free;
 210 
 211         info->regs = of_ioremap(&op->resource[0], 0, 6, "bbc beep");
 212         if (!info->regs)
 213                 goto out_free;
 214 
 215         platform_set_drvdata(op, state);
 216 
 217         err = sparcspkr_probe(&op->dev);
 218         if (err)
 219                 goto out_clear_drvdata;
 220 
 221         return 0;
 222 
 223 out_clear_drvdata:
 224         of_iounmap(&op->resource[0], info->regs, 6);
 225 
 226 out_free:
 227         kfree(state);
 228 out_err:
 229         return err;
 230 }
 231 
 232 static int bbc_remove(struct platform_device *op)
 233 {
 234         struct sparcspkr_state *state = platform_get_drvdata(op);
 235         struct input_dev *input_dev = state->input_dev;
 236         struct bbc_beep_info *info = &state->u.bbc;
 237 
 238         /* turn off the speaker */
 239         state->event(input_dev, EV_SND, SND_BELL, 0);
 240 
 241         input_unregister_device(input_dev);
 242 
 243         of_iounmap(&op->resource[0], info->regs, 6);
 244 
 245         kfree(state);
 246 
 247         return 0;
 248 }
 249 
 250 static const struct of_device_id bbc_beep_match[] = {
 251         {
 252                 .name = "beep",
 253                 .compatible = "SUNW,bbc-beep",
 254         },
 255         {},
 256 };
 257 MODULE_DEVICE_TABLE(of, bbc_beep_match);
 258 
 259 static struct platform_driver bbc_beep_driver = {
 260         .driver = {
 261                 .name = "bbcbeep",
 262                 .of_match_table = bbc_beep_match,
 263         },
 264         .probe          = bbc_beep_probe,
 265         .remove         = bbc_remove,
 266         .shutdown       = sparcspkr_shutdown,
 267 };
 268 
 269 static int grover_beep_probe(struct platform_device *op)
 270 {
 271         struct sparcspkr_state *state;
 272         struct grover_beep_info *info;
 273         int err = -ENOMEM;
 274 
 275         state = kzalloc(sizeof(*state), GFP_KERNEL);
 276         if (!state)
 277                 goto out_err;
 278 
 279         state->name = "Sparc Grover Speaker";
 280         state->event = grover_spkr_event;
 281         spin_lock_init(&state->lock);
 282 
 283         info = &state->u.grover;
 284         info->freq_regs = of_ioremap(&op->resource[2], 0, 2, "grover beep freq");
 285         if (!info->freq_regs)
 286                 goto out_free;
 287 
 288         info->enable_reg = of_ioremap(&op->resource[3], 0, 1, "grover beep enable");
 289         if (!info->enable_reg)
 290                 goto out_unmap_freq_regs;
 291 
 292         platform_set_drvdata(op, state);
 293 
 294         err = sparcspkr_probe(&op->dev);
 295         if (err)
 296                 goto out_clear_drvdata;
 297 
 298         return 0;
 299 
 300 out_clear_drvdata:
 301         of_iounmap(&op->resource[3], info->enable_reg, 1);
 302 
 303 out_unmap_freq_regs:
 304         of_iounmap(&op->resource[2], info->freq_regs, 2);
 305 out_free:
 306         kfree(state);
 307 out_err:
 308         return err;
 309 }
 310 
 311 static int grover_remove(struct platform_device *op)
 312 {
 313         struct sparcspkr_state *state = platform_get_drvdata(op);
 314         struct grover_beep_info *info = &state->u.grover;
 315         struct input_dev *input_dev = state->input_dev;
 316 
 317         /* turn off the speaker */
 318         state->event(input_dev, EV_SND, SND_BELL, 0);
 319 
 320         input_unregister_device(input_dev);
 321 
 322         of_iounmap(&op->resource[3], info->enable_reg, 1);
 323         of_iounmap(&op->resource[2], info->freq_regs, 2);
 324 
 325         kfree(state);
 326 
 327         return 0;
 328 }
 329 
 330 static const struct of_device_id grover_beep_match[] = {
 331         {
 332                 .name = "beep",
 333                 .compatible = "SUNW,smbus-beep",
 334         },
 335         {},
 336 };
 337 MODULE_DEVICE_TABLE(of, grover_beep_match);
 338 
 339 static struct platform_driver grover_beep_driver = {
 340         .driver = {
 341                 .name = "groverbeep",
 342                 .of_match_table = grover_beep_match,
 343         },
 344         .probe          = grover_beep_probe,
 345         .remove         = grover_remove,
 346         .shutdown       = sparcspkr_shutdown,
 347 };
 348 
 349 static struct platform_driver * const drivers[] = {
 350         &bbc_beep_driver,
 351         &grover_beep_driver,
 352 };
 353 
 354 static int __init sparcspkr_init(void)
 355 {
 356         return platform_register_drivers(drivers, ARRAY_SIZE(drivers));
 357 }
 358 
 359 static void __exit sparcspkr_exit(void)
 360 {
 361         platform_unregister_drivers(drivers, ARRAY_SIZE(drivers));
 362 }
 363 
 364 module_init(sparcspkr_init);
 365 module_exit(sparcspkr_exit);

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