2005-04-17 02:20:36 +04:00
/*
* common keywest i2c layer
*
* Copyright ( c ) by Takashi Iwai < tiwai @ suse . de >
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation ; either version 2 of the License , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write to the Free Software
* Foundation , Inc . , 59 Temple Place , Suite 330 , Boston , MA 02111 - 1307 USA
*/
# include <linux/init.h>
# include <linux/i2c.h>
# include <linux/delay.h>
# include <sound/core.h>
# include "pmac.h"
/*
* we have to keep a static variable here since i2c attach_adapter
* callback cannot pass a private data .
*/
2005-11-17 17:09:46 +03:00
static struct pmac_keywest * keywest_ctx ;
2005-04-17 02:20:36 +04:00
2009-04-21 00:56:59 +04:00
static int keywest_probe ( struct i2c_client * client ,
const struct i2c_device_id * id )
{
i2c_set_clientdata ( client , keywest_ctx ) ;
return 0 ;
}
/*
* This is kind of a hack , best would be to turn powermac to fixed i2c
* bus numbers and declare the sound device as part of platform
* initialization
*/
2005-04-17 02:20:36 +04:00
static int keywest_attach_adapter ( struct i2c_adapter * adapter )
{
2009-04-21 00:56:59 +04:00
struct i2c_board_info info ;
2005-04-17 02:20:36 +04:00
if ( ! keywest_ctx )
return - EINVAL ;
2009-05-14 16:37:21 +04:00
if ( strncmp ( adapter - > name , " mac-io " , 6 ) )
2005-04-17 02:20:36 +04:00
return 0 ; /* ignored */
2009-04-21 00:56:59 +04:00
memset ( & info , 0 , sizeof ( struct i2c_board_info ) ) ;
strlcpy ( info . type , " keywest " , I2C_NAME_SIZE ) ;
info . addr = keywest_ctx - > addr ;
keywest_ctx - > client = i2c_new_device ( adapter , & info ) ;
2009-10-01 09:46:33 +04:00
if ( ! keywest_ctx - > client )
return - ENODEV ;
/*
* We know the driver is already loaded , so the device should be
* already bound . If not it means binding failed , and then there
* is no point in keeping the device instantiated .
*/
2013-09-29 12:51:04 +04:00
if ( ! keywest_ctx - > client - > dev . driver ) {
2009-10-01 09:46:33 +04:00
i2c_unregister_device ( keywest_ctx - > client ) ;
keywest_ctx - > client = NULL ;
return - ENODEV ;
}
2005-04-17 02:20:36 +04:00
2009-04-21 00:56:59 +04:00
/*
* Let i2c - core delete that device on driver removal .
* This is safe because i2c - core holds the core_lock mutex for us .
*/
list_add_tail ( & keywest_ctx - > client - > detected ,
2013-09-29 12:51:04 +04:00
& to_i2c_driver ( keywest_ctx - > client - > dev . driver ) - > clients ) ;
2005-04-17 02:20:36 +04:00
return 0 ;
}
2009-04-21 00:56:59 +04:00
static int keywest_remove ( struct i2c_client * client )
2005-04-17 02:20:36 +04:00
{
if ( ! keywest_ctx )
return 0 ;
if ( client = = keywest_ctx - > client )
keywest_ctx - > client = NULL ;
return 0 ;
}
2009-04-21 00:56:59 +04:00
static const struct i2c_device_id keywest_i2c_id [ ] = {
{ " keywest " , 0 } ,
{ }
} ;
2009-10-01 20:08:18 +04:00
static struct i2c_driver keywest_driver = {
2009-04-21 00:56:59 +04:00
. driver = {
. name = " PMac Keywest Audio " ,
} ,
. attach_adapter = keywest_attach_adapter ,
. probe = keywest_probe ,
. remove = keywest_remove ,
. id_table = keywest_i2c_id ,
} ;
2005-04-17 02:20:36 +04:00
/* exported */
2005-11-17 17:09:46 +03:00
void snd_pmac_keywest_cleanup ( struct pmac_keywest * i2c )
2005-04-17 02:20:36 +04:00
{
if ( keywest_ctx & & keywest_ctx = = i2c ) {
i2c_del_driver ( & keywest_driver ) ;
keywest_ctx = NULL ;
}
}
2012-12-06 21:35:23 +04:00
int snd_pmac_tumbler_post_init ( void )
2005-04-17 02:20:36 +04:00
{
int err ;
2006-09-18 00:00:51 +04:00
if ( ! keywest_ctx | | ! keywest_ctx - > client )
return - ENXIO ;
2005-04-17 02:20:36 +04:00
if ( ( err = keywest_ctx - > init_client ( keywest_ctx ) ) < 0 ) {
snd_printk ( KERN_ERR " tumbler: %i :cannot initialize the MCS \n " , err ) ;
return err ;
}
return 0 ;
}
/* exported */
2012-12-06 21:35:23 +04:00
int snd_pmac_keywest_init ( struct pmac_keywest * i2c )
2005-04-17 02:20:36 +04:00
{
int err ;
if ( keywest_ctx )
return - EBUSY ;
keywest_ctx = i2c ;
if ( ( err = i2c_add_driver ( & keywest_driver ) ) ) {
snd_printk ( KERN_ERR " cannot register keywest i2c driver \n " ) ;
return err ;
}
return 0 ;
}