2005-04-16 15:20:36 -07:00
/*
* m68k beeper driver for Linux
*
* Copyright ( c ) 2002 Richard Zidlicky
* Copyright ( c ) 2002 Vojtech Pavlik
* Copyright ( c ) 1992 Orest Zborowski
*
*/
/*
* This program is free software ; you can redistribute it and / or modify it
* under the terms of the GNU General Public License version 2 as published by
* the Free Software Foundation
*/
# include <linux/kernel.h>
# include <linux/module.h>
# include <linux/init.h>
# include <linux/input.h>
2005-12-21 00:52:29 -05:00
# include <linux/platform_device.h>
2005-04-16 15:20:36 -07:00
# include <asm/machdep.h>
# include <asm/io.h>
MODULE_AUTHOR ( " Richard Zidlicky <rz@linux-m68k.org> " ) ;
MODULE_DESCRIPTION ( " m68k beeper driver " ) ;
MODULE_LICENSE ( " GPL " ) ;
2005-12-21 00:52:29 -05:00
static struct platform_device * m68kspkr_platform_device ;
2005-04-16 15:20:36 -07:00
static int m68kspkr_event ( struct input_dev * dev , unsigned int type , unsigned int code , int value )
{
unsigned int count = 0 ;
if ( type ! = EV_SND )
return - 1 ;
switch ( code ) {
case SND_BELL : if ( value ) value = 1000 ;
case SND_TONE : break ;
default : return - 1 ;
}
if ( value > 20 & & value < 32767 )
count = 1193182 / value ;
mach_beep ( count , - 1 ) ;
return 0 ;
}
2005-12-21 00:52:29 -05:00
static int __devinit m68kspkr_probe ( struct platform_device * dev )
{
struct input_dev * input_dev ;
int err ;
input_dev = input_allocate_device ( ) ;
if ( ! input_dev )
return - ENOMEM ;
input_dev - > name = " m68k beeper " ;
input_dev - > phys = " m68k/generic " ;
input_dev - > id . bustype = BUS_HOST ;
input_dev - > id . vendor = 0x001f ;
input_dev - > id . product = 0x0001 ;
input_dev - > id . version = 0x0100 ;
2007-04-12 01:35:32 -04:00
input_dev - > dev . parent = & dev - > dev ;
2005-12-21 00:52:29 -05:00
2007-10-18 23:40:32 -07:00
input_dev - > evbit [ 0 ] = BIT_MASK ( EV_SND ) ;
input_dev - > sndbit [ 0 ] = BIT_MASK ( SND_BELL ) | BIT_MASK ( SND_TONE ) ;
2005-12-21 00:52:29 -05:00
input_dev - > event = m68kspkr_event ;
err = input_register_device ( input_dev ) ;
if ( err ) {
input_free_device ( input_dev ) ;
return err ;
}
platform_set_drvdata ( dev , input_dev ) ;
return 0 ;
}
static int __devexit m68kspkr_remove ( struct platform_device * dev )
{
struct input_dev * input_dev = platform_get_drvdata ( dev ) ;
input_unregister_device ( input_dev ) ;
platform_set_drvdata ( dev , NULL ) ;
/* turn off the speaker */
m68kspkr_event ( NULL , EV_SND , SND_BELL , 0 ) ;
return 0 ;
}
static void m68kspkr_shutdown ( struct platform_device * dev )
{
/* turn off the speaker */
m68kspkr_event ( NULL , EV_SND , SND_BELL , 0 ) ;
}
static struct platform_driver m68kspkr_platform_driver = {
. driver = {
. name = " m68kspkr " ,
. owner = THIS_MODULE ,
} ,
. probe = m68kspkr_probe ,
. remove = __devexit_p ( m68kspkr_remove ) ,
. shutdown = m68kspkr_shutdown ,
} ;
2005-04-16 15:20:36 -07:00
static int __init m68kspkr_init ( void )
{
2005-12-21 00:52:29 -05:00
int err ;
if ( ! mach_beep ) {
2005-09-15 02:01:51 -05:00
printk ( KERN_INFO " m68kspkr: no lowlevel beep support \n " ) ;
return - ENODEV ;
2005-04-16 15:20:36 -07:00
}
2005-12-21 00:52:29 -05:00
err = platform_driver_register ( & m68kspkr_platform_driver ) ;
if ( err )
return err ;
2005-04-16 15:20:36 -07:00
2005-12-21 00:52:29 -05:00
m68kspkr_platform_device = platform_device_alloc ( " m68kspkr " , - 1 ) ;
if ( ! m68kspkr_platform_device ) {
err = - ENOMEM ;
goto err_unregister_driver ;
}
2005-04-16 15:20:36 -07:00
2005-12-21 00:52:29 -05:00
err = platform_device_add ( m68kspkr_platform_device ) ;
if ( err )
goto err_free_device ;
2005-04-16 15:20:36 -07:00
return 0 ;
2005-12-21 00:52:29 -05:00
err_free_device :
platform_device_put ( m68kspkr_platform_device ) ;
err_unregister_driver :
platform_driver_unregister ( & m68kspkr_platform_driver ) ;
return err ;
2005-04-16 15:20:36 -07:00
}
static void __exit m68kspkr_exit ( void )
{
2005-12-21 00:52:29 -05:00
platform_device_unregister ( m68kspkr_platform_device ) ;
platform_driver_unregister ( & m68kspkr_platform_driver ) ;
2005-04-16 15:20:36 -07:00
}
module_init ( m68kspkr_init ) ;
module_exit ( m68kspkr_exit ) ;