2019-05-29 07:17:59 -07:00
// SPDX-License-Identifier: GPL-2.0-only
2015-06-11 14:11:47 +05:30
/*
* hdac - ext - bus . c - HD - audio extended core bus functions .
*
* Copyright ( C ) 2014 - 2015 Intel Corp
* Author : Jeeja KP < jeeja . kp @ intel . com >
* ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
*
* ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
*/
# include <linux/module.h>
# include <linux/slab.h>
2015-10-13 14:57:49 +05:30
# include <linux/io.h>
2015-06-11 14:11:47 +05:30
# include <sound/hdaudio_ext.h>
MODULE_DESCRIPTION ( " HDA extended core " ) ;
MODULE_LICENSE ( " GPL v2 " ) ;
/**
* snd_hdac_ext_bus_init - initialize a HD - audio extended bus
2020-01-13 14:56:38 -06:00
* @ bus : the pointer to HDAC bus object
2015-06-11 14:11:47 +05:30
* @ dev : device pointer
* @ ops : bus verb operators
2020-01-13 14:56:38 -06:00
* @ ext_ops : operators used for ASoC HDA codec drivers
2015-06-11 14:11:47 +05:30
*
* Returns 0 if successful , or a negative error code .
*/
2018-06-01 22:53:50 -05:00
int snd_hdac_ext_bus_init ( struct hdac_bus * bus , struct device * dev ,
2015-06-11 14:11:47 +05:30
const struct hdac_bus_ops * ops ,
2018-06-01 22:53:58 -05:00
const struct hdac_ext_bus_ops * ext_ops )
2015-06-11 14:11:47 +05:30
{
int ret ;
2019-08-07 20:32:08 +02:00
ret = snd_hdac_bus_init ( bus , dev , ops ) ;
2015-06-11 14:11:47 +05:30
if ( ret < 0 )
return ret ;
2018-06-01 22:53:58 -05:00
bus - > ext_ops = ext_ops ;
2019-06-17 13:36:35 +02:00
/* FIXME:
* Currently only one bus is supported , if there is device with more
* buses , bus - > idx should be greater than 0 , but there needs to be a
* reliable way to always assign same number .
*/
bus - > idx = 0 ;
2018-06-01 22:53:50 -05:00
bus - > cmd_dma_state = true ;
2016-05-12 08:58:53 +05:30
2015-06-11 14:11:47 +05:30
return 0 ;
}
EXPORT_SYMBOL_GPL ( snd_hdac_ext_bus_init ) ;
/**
* snd_hdac_ext_bus_exit - clean up a HD - audio extended bus
2020-01-13 14:56:38 -06:00
* @ bus : the pointer to HDAC bus object
2015-06-11 14:11:47 +05:30
*/
2018-06-01 22:53:50 -05:00
void snd_hdac_ext_bus_exit ( struct hdac_bus * bus )
2015-06-11 14:11:47 +05:30
{
2018-06-01 22:53:50 -05:00
snd_hdac_bus_exit ( bus ) ;
WARN_ON ( ! list_empty ( & bus - > hlink_list ) ) ;
2015-06-11 14:11:47 +05:30
}
EXPORT_SYMBOL_GPL ( snd_hdac_ext_bus_exit ) ;
2015-08-21 15:47:40 +05:30
/**
* snd_hdac_ext_bus_device_remove - remove HD - audio extended codec base devices
*
2020-01-13 14:56:38 -06:00
* @ bus : the pointer to HDAC bus object
2015-08-21 15:47:40 +05:30
*/
2018-06-01 22:53:50 -05:00
void snd_hdac_ext_bus_device_remove ( struct hdac_bus * bus )
2015-08-21 15:47:40 +05:30
{
struct hdac_device * codec , * __codec ;
/*
* we need to remove all the codec devices objects created in the
* snd_hdac_ext_bus_device_init
*/
2018-06-01 22:53:50 -05:00
list_for_each_entry_safe ( codec , __codec , & bus - > codec_list , list ) {
2015-08-21 15:47:40 +05:30
snd_hdac_device_unregister ( codec ) ;
put_device ( & codec - > dev ) ;
}
}
EXPORT_SYMBOL_GPL ( snd_hdac_ext_bus_device_remove ) ;
2015-08-21 15:47:42 +05:30
# define dev_to_hdac(dev) (container_of((dev), \
struct hdac_device , dev ) )
2018-06-01 22:53:51 -05:00
static inline struct hdac_driver * get_hdrv ( struct device * dev )
2015-08-21 15:47:42 +05:30
{
struct hdac_driver * hdrv = drv_to_hdac_driver ( dev - > driver ) ;
2018-06-01 22:53:51 -05:00
return hdrv ;
2015-08-21 15:47:42 +05:30
}
2018-06-01 22:53:49 -05:00
static inline struct hdac_device * get_hdev ( struct device * dev )
2015-08-21 15:47:42 +05:30
{
struct hdac_device * hdev = dev_to_hdac_dev ( dev ) ;
2018-06-01 22:53:49 -05:00
return hdev ;
2015-08-21 15:47:42 +05:30
}
static int hda_ext_drv_probe ( struct device * dev )
{
2018-06-01 22:53:51 -05:00
return ( get_hdrv ( dev ) ) - > probe ( get_hdev ( dev ) ) ;
2015-08-21 15:47:42 +05:30
}
static int hdac_ext_drv_remove ( struct device * dev )
{
2018-06-01 22:53:51 -05:00
return ( get_hdrv ( dev ) ) - > remove ( get_hdev ( dev ) ) ;
2015-08-21 15:47:42 +05:30
}
static void hdac_ext_drv_shutdown ( struct device * dev )
{
2018-06-01 22:53:51 -05:00
return ( get_hdrv ( dev ) ) - > shutdown ( get_hdev ( dev ) ) ;
2015-08-21 15:47:42 +05:30
}
/**
* snd_hda_ext_driver_register - register a driver for ext hda devices
*
* @ drv : ext hda driver structure
*/
2018-06-01 22:53:51 -05:00
int snd_hda_ext_driver_register ( struct hdac_driver * drv )
2015-08-21 15:47:42 +05:30
{
2018-06-01 22:53:51 -05:00
drv - > type = HDA_DEV_ASOC ;
drv - > driver . bus = & snd_hda_bus_type ;
2015-08-21 15:47:42 +05:30
/* we use default match */
if ( drv - > probe )
2018-06-01 22:53:51 -05:00
drv - > driver . probe = hda_ext_drv_probe ;
2015-08-21 15:47:42 +05:30
if ( drv - > remove )
2018-06-01 22:53:51 -05:00
drv - > driver . remove = hdac_ext_drv_remove ;
2015-08-21 15:47:42 +05:30
if ( drv - > shutdown )
2018-06-01 22:53:51 -05:00
drv - > driver . shutdown = hdac_ext_drv_shutdown ;
2015-08-21 15:47:42 +05:30
2018-06-01 22:53:51 -05:00
return driver_register ( & drv - > driver ) ;
2015-08-21 15:47:42 +05:30
}
EXPORT_SYMBOL_GPL ( snd_hda_ext_driver_register ) ;
/**
* snd_hda_ext_driver_unregister - unregister a driver for ext hda devices
*
* @ drv : ext hda driver structure
*/
2018-06-01 22:53:51 -05:00
void snd_hda_ext_driver_unregister ( struct hdac_driver * drv )
2015-08-21 15:47:42 +05:30
{
2018-06-01 22:53:51 -05:00
driver_unregister ( & drv - > driver ) ;
2015-08-21 15:47:42 +05:30
}
EXPORT_SYMBOL_GPL ( snd_hda_ext_driver_unregister ) ;