0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/kernel.h>
0009 #include <linux/module.h>
0010 #include <linux/init.h>
0011 #include <linux/input.h>
0012 #include <linux/of_device.h>
0013 #include <linux/slab.h>
0014
0015 #include <asm/io.h>
0016
0017 MODULE_AUTHOR("David S. Miller <davem@davemloft.net>");
0018 MODULE_DESCRIPTION("Sparc Speaker beeper driver");
0019 MODULE_LICENSE("GPL");
0020
0021 struct grover_beep_info {
0022 void __iomem *freq_regs;
0023 void __iomem *enable_reg;
0024 };
0025
0026 struct bbc_beep_info {
0027 u32 clock_freq;
0028 void __iomem *regs;
0029 };
0030
0031 struct sparcspkr_state {
0032 const char *name;
0033 int (*event)(struct input_dev *dev, unsigned int type, unsigned int code, int value);
0034 spinlock_t lock;
0035 struct input_dev *input_dev;
0036 union {
0037 struct grover_beep_info grover;
0038 struct bbc_beep_info bbc;
0039 } u;
0040 };
0041
0042 static u32 bbc_count_to_reg(struct bbc_beep_info *info, unsigned int count)
0043 {
0044 u32 val, clock_freq = info->clock_freq;
0045 int i;
0046
0047 if (!count)
0048 return 0;
0049
0050 if (count <= clock_freq >> 20)
0051 return 1 << 18;
0052
0053 if (count >= clock_freq >> 12)
0054 return 1 << 10;
0055
0056 val = 1 << 18;
0057 for (i = 19; i >= 11; i--) {
0058 val >>= 1;
0059 if (count <= clock_freq >> i)
0060 break;
0061 }
0062
0063 return val;
0064 }
0065
0066 static int bbc_spkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
0067 {
0068 struct sparcspkr_state *state = dev_get_drvdata(dev->dev.parent);
0069 struct bbc_beep_info *info = &state->u.bbc;
0070 unsigned int count = 0;
0071 unsigned long flags;
0072
0073 if (type != EV_SND)
0074 return -1;
0075
0076 switch (code) {
0077 case SND_BELL: if (value) value = 1000;
0078 case SND_TONE: break;
0079 default: return -1;
0080 }
0081
0082 if (value > 20 && value < 32767)
0083 count = 1193182 / value;
0084
0085 count = bbc_count_to_reg(info, count);
0086
0087 spin_lock_irqsave(&state->lock, flags);
0088
0089 if (count) {
0090 sbus_writeb(0x01, info->regs + 0);
0091 sbus_writeb(0x00, info->regs + 2);
0092 sbus_writeb((count >> 16) & 0xff, info->regs + 3);
0093 sbus_writeb((count >> 8) & 0xff, info->regs + 4);
0094 sbus_writeb(0x00, info->regs + 5);
0095 } else {
0096 sbus_writeb(0x00, info->regs + 0);
0097 }
0098
0099 spin_unlock_irqrestore(&state->lock, flags);
0100
0101 return 0;
0102 }
0103
0104 static int grover_spkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
0105 {
0106 struct sparcspkr_state *state = dev_get_drvdata(dev->dev.parent);
0107 struct grover_beep_info *info = &state->u.grover;
0108 unsigned int count = 0;
0109 unsigned long flags;
0110
0111 if (type != EV_SND)
0112 return -1;
0113
0114 switch (code) {
0115 case SND_BELL: if (value) value = 1000;
0116 case SND_TONE: break;
0117 default: return -1;
0118 }
0119
0120 if (value > 20 && value < 32767)
0121 count = 1193182 / value;
0122
0123 spin_lock_irqsave(&state->lock, flags);
0124
0125 if (count) {
0126
0127 sbus_writeb(sbus_readb(info->enable_reg) | 3, info->enable_reg);
0128
0129 sbus_writeb(0xB6, info->freq_regs + 1);
0130
0131 sbus_writeb(count & 0xff, info->freq_regs + 0);
0132 sbus_writeb((count >> 8) & 0xff, info->freq_regs + 0);
0133 } else {
0134
0135 sbus_writeb(sbus_readb(info->enable_reg) & 0xFC, info->enable_reg);
0136 }
0137
0138 spin_unlock_irqrestore(&state->lock, flags);
0139
0140 return 0;
0141 }
0142
0143 static int sparcspkr_probe(struct device *dev)
0144 {
0145 struct sparcspkr_state *state = dev_get_drvdata(dev);
0146 struct input_dev *input_dev;
0147 int error;
0148
0149 input_dev = input_allocate_device();
0150 if (!input_dev)
0151 return -ENOMEM;
0152
0153 input_dev->name = state->name;
0154 input_dev->phys = "sparc/input0";
0155 input_dev->id.bustype = BUS_ISA;
0156 input_dev->id.vendor = 0x001f;
0157 input_dev->id.product = 0x0001;
0158 input_dev->id.version = 0x0100;
0159 input_dev->dev.parent = dev;
0160
0161 input_dev->evbit[0] = BIT_MASK(EV_SND);
0162 input_dev->sndbit[0] = BIT_MASK(SND_BELL) | BIT_MASK(SND_TONE);
0163
0164 input_dev->event = state->event;
0165
0166 error = input_register_device(input_dev);
0167 if (error) {
0168 input_free_device(input_dev);
0169 return error;
0170 }
0171
0172 state->input_dev = input_dev;
0173
0174 return 0;
0175 }
0176
0177 static void sparcspkr_shutdown(struct platform_device *dev)
0178 {
0179 struct sparcspkr_state *state = platform_get_drvdata(dev);
0180 struct input_dev *input_dev = state->input_dev;
0181
0182
0183 state->event(input_dev, EV_SND, SND_BELL, 0);
0184 }
0185
0186 static int bbc_beep_probe(struct platform_device *op)
0187 {
0188 struct sparcspkr_state *state;
0189 struct bbc_beep_info *info;
0190 struct device_node *dp;
0191 int err = -ENOMEM;
0192
0193 state = kzalloc(sizeof(*state), GFP_KERNEL);
0194 if (!state)
0195 goto out_err;
0196
0197 state->name = "Sparc BBC Speaker";
0198 state->event = bbc_spkr_event;
0199 spin_lock_init(&state->lock);
0200
0201 dp = of_find_node_by_path("/");
0202 err = -ENODEV;
0203 if (!dp)
0204 goto out_free;
0205
0206 info = &state->u.bbc;
0207 info->clock_freq = of_getintprop_default(dp, "clock-frequency", 0);
0208 of_node_put(dp);
0209 if (!info->clock_freq)
0210 goto out_free;
0211
0212 info->regs = of_ioremap(&op->resource[0], 0, 6, "bbc beep");
0213 if (!info->regs)
0214 goto out_free;
0215
0216 platform_set_drvdata(op, state);
0217
0218 err = sparcspkr_probe(&op->dev);
0219 if (err)
0220 goto out_clear_drvdata;
0221
0222 return 0;
0223
0224 out_clear_drvdata:
0225 of_iounmap(&op->resource[0], info->regs, 6);
0226
0227 out_free:
0228 kfree(state);
0229 out_err:
0230 return err;
0231 }
0232
0233 static int bbc_remove(struct platform_device *op)
0234 {
0235 struct sparcspkr_state *state = platform_get_drvdata(op);
0236 struct input_dev *input_dev = state->input_dev;
0237 struct bbc_beep_info *info = &state->u.bbc;
0238
0239
0240 state->event(input_dev, EV_SND, SND_BELL, 0);
0241
0242 input_unregister_device(input_dev);
0243
0244 of_iounmap(&op->resource[0], info->regs, 6);
0245
0246 kfree(state);
0247
0248 return 0;
0249 }
0250
0251 static const struct of_device_id bbc_beep_match[] = {
0252 {
0253 .name = "beep",
0254 .compatible = "SUNW,bbc-beep",
0255 },
0256 {},
0257 };
0258 MODULE_DEVICE_TABLE(of, bbc_beep_match);
0259
0260 static struct platform_driver bbc_beep_driver = {
0261 .driver = {
0262 .name = "bbcbeep",
0263 .of_match_table = bbc_beep_match,
0264 },
0265 .probe = bbc_beep_probe,
0266 .remove = bbc_remove,
0267 .shutdown = sparcspkr_shutdown,
0268 };
0269
0270 static int grover_beep_probe(struct platform_device *op)
0271 {
0272 struct sparcspkr_state *state;
0273 struct grover_beep_info *info;
0274 int err = -ENOMEM;
0275
0276 state = kzalloc(sizeof(*state), GFP_KERNEL);
0277 if (!state)
0278 goto out_err;
0279
0280 state->name = "Sparc Grover Speaker";
0281 state->event = grover_spkr_event;
0282 spin_lock_init(&state->lock);
0283
0284 info = &state->u.grover;
0285 info->freq_regs = of_ioremap(&op->resource[2], 0, 2, "grover beep freq");
0286 if (!info->freq_regs)
0287 goto out_free;
0288
0289 info->enable_reg = of_ioremap(&op->resource[3], 0, 1, "grover beep enable");
0290 if (!info->enable_reg)
0291 goto out_unmap_freq_regs;
0292
0293 platform_set_drvdata(op, state);
0294
0295 err = sparcspkr_probe(&op->dev);
0296 if (err)
0297 goto out_clear_drvdata;
0298
0299 return 0;
0300
0301 out_clear_drvdata:
0302 of_iounmap(&op->resource[3], info->enable_reg, 1);
0303
0304 out_unmap_freq_regs:
0305 of_iounmap(&op->resource[2], info->freq_regs, 2);
0306 out_free:
0307 kfree(state);
0308 out_err:
0309 return err;
0310 }
0311
0312 static int grover_remove(struct platform_device *op)
0313 {
0314 struct sparcspkr_state *state = platform_get_drvdata(op);
0315 struct grover_beep_info *info = &state->u.grover;
0316 struct input_dev *input_dev = state->input_dev;
0317
0318
0319 state->event(input_dev, EV_SND, SND_BELL, 0);
0320
0321 input_unregister_device(input_dev);
0322
0323 of_iounmap(&op->resource[3], info->enable_reg, 1);
0324 of_iounmap(&op->resource[2], info->freq_regs, 2);
0325
0326 kfree(state);
0327
0328 return 0;
0329 }
0330
0331 static const struct of_device_id grover_beep_match[] = {
0332 {
0333 .name = "beep",
0334 .compatible = "SUNW,smbus-beep",
0335 },
0336 {},
0337 };
0338 MODULE_DEVICE_TABLE(of, grover_beep_match);
0339
0340 static struct platform_driver grover_beep_driver = {
0341 .driver = {
0342 .name = "groverbeep",
0343 .of_match_table = grover_beep_match,
0344 },
0345 .probe = grover_beep_probe,
0346 .remove = grover_remove,
0347 .shutdown = sparcspkr_shutdown,
0348 };
0349
0350 static struct platform_driver * const drivers[] = {
0351 &bbc_beep_driver,
0352 &grover_beep_driver,
0353 };
0354
0355 static int __init sparcspkr_init(void)
0356 {
0357 return platform_register_drivers(drivers, ARRAY_SIZE(drivers));
0358 }
0359
0360 static void __exit sparcspkr_exit(void)
0361 {
0362 platform_unregister_drivers(drivers, ARRAY_SIZE(drivers));
0363 }
0364
0365 module_init(sparcspkr_init);
0366 module_exit(sparcspkr_exit);