2018-07-02 09:26:27 +03:00
// SPDX-License-Identifier: GPL-2.0+
//
// soc-ac97.c -- ALSA SoC Audio Layer AC97 support
//
// Copyright 2005 Wolfson Microelectronics PLC.
// Copyright 2005 Openedhand Ltd.
// Copyright (C) 2010 Slimlogic Ltd.
// Copyright (C) 2010 Texas Instruments Inc.
//
// Author: Liam Girdwood <lrg@slimlogic.co.uk>
// with code, comments and ideas from :-
// Richard Purdie <richard@openedhand.com>
2014-11-11 00:41:46 +03:00
# include <linux/ctype.h>
# include <linux/delay.h>
# include <linux/export.h>
# include <linux/gpio.h>
2015-11-11 15:12:51 +03:00
# include <linux/gpio/driver.h>
2014-11-11 00:41:46 +03:00
# include <linux/init.h>
# include <linux/of_gpio.h>
# include <linux/of.h>
# include <linux/pinctrl/consumer.h>
# include <linux/slab.h>
# include <sound/ac97_codec.h>
# include <sound/soc.h>
struct snd_ac97_reset_cfg {
struct pinctrl * pctl ;
struct pinctrl_state * pstate_reset ;
struct pinctrl_state * pstate_warm_reset ;
struct pinctrl_state * pstate_run ;
int gpio_sdata ;
int gpio_sync ;
int gpio_reset ;
} ;
2014-11-11 00:41:47 +03:00
static struct snd_ac97_bus soc_ac97_bus = {
. ops = NULL , /* Gets initialized in snd_soc_set_ac97_ops() */
} ;
2014-11-11 00:41:46 +03:00
static void soc_ac97_device_release ( struct device * dev )
{
kfree ( to_ac97_t ( dev ) ) ;
}
2015-11-11 15:12:51 +03:00
# ifdef CONFIG_GPIOLIB
2021-08-16 07:56:23 +03:00
struct snd_ac97_gpio_priv {
struct gpio_chip gpio_chip ;
unsigned int gpios_set ;
struct snd_soc_component * component ;
} ;
2018-01-29 05:58:25 +03:00
static inline struct snd_soc_component * gpio_to_component ( struct gpio_chip * chip )
2015-11-11 15:12:51 +03:00
{
2015-12-09 01:48:29 +03:00
struct snd_ac97_gpio_priv * gpio_priv = gpiochip_get_data ( chip ) ;
2015-11-11 15:12:51 +03:00
2018-01-29 05:58:25 +03:00
return gpio_priv - > component ;
2015-11-11 15:12:51 +03:00
}
2022-08-16 20:51:05 +03:00
static int snd_soc_ac97_gpio_request ( struct gpio_chip * chip , unsigned int offset )
2015-11-11 15:12:51 +03:00
{
if ( offset > = AC97_NUM_GPIOS )
return - EINVAL ;
return 0 ;
}
static int snd_soc_ac97_gpio_direction_in ( struct gpio_chip * chip ,
2022-08-16 20:51:05 +03:00
unsigned int offset )
2015-11-11 15:12:51 +03:00
{
2018-01-29 05:58:25 +03:00
struct snd_soc_component * component = gpio_to_component ( chip ) ;
2015-11-11 15:12:51 +03:00
2018-01-29 05:58:25 +03:00
dev_dbg ( component - > dev , " set gpio %d to output \n " , offset ) ;
return snd_soc_component_update_bits ( component , AC97_GPIO_CFG ,
2015-11-11 15:12:51 +03:00
1 < < offset , 1 < < offset ) ;
}
2022-08-16 20:51:05 +03:00
static int snd_soc_ac97_gpio_get ( struct gpio_chip * chip , unsigned int offset )
2015-11-11 15:12:51 +03:00
{
2018-01-29 05:58:25 +03:00
struct snd_soc_component * component = gpio_to_component ( chip ) ;
2015-11-11 15:12:51 +03:00
int ret ;
ASoC: soc-component: merge snd_soc_component_read() and snd_soc_component_read32()
We had read/write function for Codec, Platform, etc,
but these has been merged into snd_soc_component_read/write().
Internally, it is using regmap or driver function.
In read case, each styles are like below
regmap
ret = regmap_read(..., reg, &val);
driver function
val = xxx->read(..., reg);
Because of this kind of different style, to keep same read style,
when we merged each read function into snd_soc_component_read(),
we created snd_soc_component_read32(), like below.
commit 738b49efe6c6 ("ASoC: add snd_soc_component_read32")
(1) val = snd_soc_component_read32(component, reg);
(2) ret = snd_soc_component_read(component, reg, &val);
Many drivers are using snd_soc_component_read32(), and
some drivers are using snd_soc_component_read() today.
In generally, we don't check read function successes,
because, we will have many other issues at initial timing
if read function didn't work.
Now we can use soc_component_err() when error case.
This means, it is easy to notice if error occurred.
This patch aggressively merge snd_soc_component_read() and _read32(),
and makes snd_soc_component_read/write() as generally style.
This patch do
1) merge snd_soc_component_read() and snd_soc_component_read32()
2) it uses soc_component_err() when error case (easy to notice)
3) keeps read32 for now by #define
4) update snd_soc_component_read() for all drivers
Because _read() user drivers are not too many, this patch changes
all user drivers.
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Reviewed-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
Link: https://lore.kernel.org/r/87sgev4mfl.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2020-06-16 08:19:41 +03:00
ret = snd_soc_component_read ( component , AC97_GPIO_STATUS ) ;
2018-01-29 05:58:25 +03:00
dev_dbg ( component - > dev , " get gpio %d : %d \n " , offset ,
ASoC: soc-component: merge snd_soc_component_read() and snd_soc_component_read32()
We had read/write function for Codec, Platform, etc,
but these has been merged into snd_soc_component_read/write().
Internally, it is using regmap or driver function.
In read case, each styles are like below
regmap
ret = regmap_read(..., reg, &val);
driver function
val = xxx->read(..., reg);
Because of this kind of different style, to keep same read style,
when we merged each read function into snd_soc_component_read(),
we created snd_soc_component_read32(), like below.
commit 738b49efe6c6 ("ASoC: add snd_soc_component_read32")
(1) val = snd_soc_component_read32(component, reg);
(2) ret = snd_soc_component_read(component, reg, &val);
Many drivers are using snd_soc_component_read32(), and
some drivers are using snd_soc_component_read() today.
In generally, we don't check read function successes,
because, we will have many other issues at initial timing
if read function didn't work.
Now we can use soc_component_err() when error case.
This means, it is easy to notice if error occurred.
This patch aggressively merge snd_soc_component_read() and _read32(),
and makes snd_soc_component_read/write() as generally style.
This patch do
1) merge snd_soc_component_read() and snd_soc_component_read32()
2) it uses soc_component_err() when error case (easy to notice)
3) keeps read32 for now by #define
4) update snd_soc_component_read() for all drivers
Because _read() user drivers are not too many, this patch changes
all user drivers.
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Reviewed-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
Link: https://lore.kernel.org/r/87sgev4mfl.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2020-06-16 08:19:41 +03:00
ret & ( 1 < < offset ) ) ;
2015-11-11 15:12:51 +03:00
ASoC: soc-component: merge snd_soc_component_read() and snd_soc_component_read32()
We had read/write function for Codec, Platform, etc,
but these has been merged into snd_soc_component_read/write().
Internally, it is using regmap or driver function.
In read case, each styles are like below
regmap
ret = regmap_read(..., reg, &val);
driver function
val = xxx->read(..., reg);
Because of this kind of different style, to keep same read style,
when we merged each read function into snd_soc_component_read(),
we created snd_soc_component_read32(), like below.
commit 738b49efe6c6 ("ASoC: add snd_soc_component_read32")
(1) val = snd_soc_component_read32(component, reg);
(2) ret = snd_soc_component_read(component, reg, &val);
Many drivers are using snd_soc_component_read32(), and
some drivers are using snd_soc_component_read() today.
In generally, we don't check read function successes,
because, we will have many other issues at initial timing
if read function didn't work.
Now we can use soc_component_err() when error case.
This means, it is easy to notice if error occurred.
This patch aggressively merge snd_soc_component_read() and _read32(),
and makes snd_soc_component_read/write() as generally style.
This patch do
1) merge snd_soc_component_read() and snd_soc_component_read32()
2) it uses soc_component_err() when error case (easy to notice)
3) keeps read32 for now by #define
4) update snd_soc_component_read() for all drivers
Because _read() user drivers are not too many, this patch changes
all user drivers.
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Reviewed-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
Link: https://lore.kernel.org/r/87sgev4mfl.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2020-06-16 08:19:41 +03:00
return ! ! ( ret & ( 1 < < offset ) ) ;
2015-11-11 15:12:51 +03:00
}
2022-08-16 20:51:05 +03:00
static void snd_soc_ac97_gpio_set ( struct gpio_chip * chip , unsigned int offset ,
2015-11-11 15:12:51 +03:00
int value )
{
2015-12-09 01:48:29 +03:00
struct snd_ac97_gpio_priv * gpio_priv = gpiochip_get_data ( chip ) ;
2018-01-29 05:58:25 +03:00
struct snd_soc_component * component = gpio_to_component ( chip ) ;
2015-11-11 15:12:51 +03:00
gpio_priv - > gpios_set & = ~ ( 1 < < offset ) ;
gpio_priv - > gpios_set | = ( ! ! value ) < < offset ;
2018-01-29 05:58:25 +03:00
snd_soc_component_write ( component , AC97_GPIO_STATUS ,
gpio_priv - > gpios_set ) ;
dev_dbg ( component - > dev , " set gpio %d to %d \n " , offset , ! ! value ) ;
2015-11-11 15:12:51 +03:00
}
static int snd_soc_ac97_gpio_direction_out ( struct gpio_chip * chip ,
unsigned offset , int value )
{
2018-01-29 05:58:25 +03:00
struct snd_soc_component * component = gpio_to_component ( chip ) ;
2015-11-11 15:12:51 +03:00
2018-01-29 05:58:25 +03:00
dev_dbg ( component - > dev , " set gpio %d to output \n " , offset ) ;
2015-11-11 15:12:51 +03:00
snd_soc_ac97_gpio_set ( chip , offset , value ) ;
2018-01-29 05:58:25 +03:00
return snd_soc_component_update_bits ( component , AC97_GPIO_CFG ,
1 < < offset , 0 ) ;
2015-11-11 15:12:51 +03:00
}
2016-09-11 15:14:41 +03:00
static const struct gpio_chip snd_soc_ac97_gpio_chip = {
2015-11-11 15:12:51 +03:00
. label = " snd_soc_ac97 " ,
. owner = THIS_MODULE ,
. request = snd_soc_ac97_gpio_request ,
. direction_input = snd_soc_ac97_gpio_direction_in ,
. get = snd_soc_ac97_gpio_get ,
. direction_output = snd_soc_ac97_gpio_direction_out ,
. set = snd_soc_ac97_gpio_set ,
. can_sleep = 1 ,
} ;
static int snd_soc_ac97_init_gpio ( struct snd_ac97 * ac97 ,
2018-01-29 05:58:25 +03:00
struct snd_soc_component * component )
2015-11-11 15:12:51 +03:00
{
struct snd_ac97_gpio_priv * gpio_priv ;
int ret ;
2018-01-29 05:58:25 +03:00
gpio_priv = devm_kzalloc ( component - > dev , sizeof ( * gpio_priv ) , GFP_KERNEL ) ;
2015-11-11 15:12:51 +03:00
if ( ! gpio_priv )
return - ENOMEM ;
ac97 - > gpio_priv = gpio_priv ;
2018-01-29 05:58:25 +03:00
gpio_priv - > component = component ;
2015-11-11 15:12:51 +03:00
gpio_priv - > gpio_chip = snd_soc_ac97_gpio_chip ;
gpio_priv - > gpio_chip . ngpio = AC97_NUM_GPIOS ;
2018-01-29 05:58:25 +03:00
gpio_priv - > gpio_chip . parent = component - > dev ;
2015-11-11 15:12:51 +03:00
gpio_priv - > gpio_chip . base = - 1 ;
2015-12-09 01:48:29 +03:00
ret = gpiochip_add_data ( & gpio_priv - > gpio_chip , gpio_priv ) ;
2015-11-11 15:12:51 +03:00
if ( ret ! = 0 )
2018-01-29 05:58:25 +03:00
dev_err ( component - > dev , " Failed to add GPIOs: %d \n " , ret ) ;
2015-11-11 15:12:51 +03:00
return ret ;
}
static void snd_soc_ac97_free_gpio ( struct snd_ac97 * ac97 )
{
gpiochip_remove ( & ac97 - > gpio_priv - > gpio_chip ) ;
}
# else
static int snd_soc_ac97_init_gpio ( struct snd_ac97 * ac97 ,
2018-01-29 05:58:25 +03:00
struct snd_soc_component * component )
2015-11-11 15:12:51 +03:00
{
return 0 ;
}
static void snd_soc_ac97_free_gpio ( struct snd_ac97 * ac97 )
{
}
# endif
2014-11-11 00:41:46 +03:00
/**
2018-01-29 05:58:25 +03:00
* snd_soc_alloc_ac97_component ( ) - Allocate new a AC ' 97 device
* @ component : The COMPONENT for which to create the AC ' 97 device
2014-11-11 00:41:46 +03:00
*
2015-01-23 18:21:36 +03:00
* Allocated a new snd_ac97 device and intializes it , but does not yet register
* it . The caller is responsible to either call device_add ( & ac97 - > dev ) to
* register the device , or to call put_device ( & ac97 - > dev ) to free the device .
*
* Returns : A snd_ac97 device or a PTR_ERR in case of an error .
2014-11-11 00:41:46 +03:00
*/
2018-01-29 05:58:25 +03:00
struct snd_ac97 * snd_soc_alloc_ac97_component ( struct snd_soc_component * component )
2014-11-11 00:41:46 +03:00
{
2014-11-11 00:41:53 +03:00
struct snd_ac97 * ac97 ;
2014-11-11 00:41:50 +03:00
2014-11-11 00:41:53 +03:00
ac97 = kzalloc ( sizeof ( struct snd_ac97 ) , GFP_KERNEL ) ;
if ( ac97 = = NULL )
return ERR_PTR ( - ENOMEM ) ;
2014-11-11 00:41:46 +03:00
2014-11-11 00:41:53 +03:00
ac97 - > bus = & soc_ac97_bus ;
ac97 - > num = 0 ;
2014-11-11 00:41:50 +03:00
2014-11-11 00:41:53 +03:00
ac97 - > dev . bus = & ac97_bus_type ;
2018-01-29 05:58:25 +03:00
ac97 - > dev . parent = component - > card - > dev ;
2014-11-11 00:41:53 +03:00
ac97 - > dev . release = soc_ac97_device_release ;
2014-11-11 00:41:46 +03:00
2014-11-11 00:41:53 +03:00
dev_set_name ( & ac97 - > dev , " %d-%d:%s " ,
2018-01-29 05:58:25 +03:00
component - > card - > snd_card - > number , 0 ,
component - > name ) ;
2014-11-11 00:41:50 +03:00
2015-01-23 18:21:36 +03:00
device_initialize ( & ac97 - > dev ) ;
return ac97 ;
}
2018-01-29 05:58:25 +03:00
EXPORT_SYMBOL ( snd_soc_alloc_ac97_component ) ;
2015-01-23 18:21:36 +03:00
/**
2018-01-29 05:58:25 +03:00
* snd_soc_new_ac97_component - initailise AC97 device
* @ component : audio component
2015-07-21 22:53:01 +03:00
* @ id : The expected device ID
* @ id_mask : Mask that is applied to the device ID before comparing with @ id
2015-01-23 18:21:36 +03:00
*
2018-01-29 05:58:25 +03:00
* Initialises AC97 component resources for use by ad - hoc devices only .
2015-07-21 22:53:01 +03:00
*
* If @ id is not 0 this function will reset the device , then read the ID from
* the device and check if it matches the expected ID . If it doesn ' t match an
* error will be returned and device will not be registered .
*
* Returns : A PTR_ERR ( ) on failure or a valid snd_ac97 struct on success .
2015-01-23 18:21:36 +03:00
*/
2018-01-29 05:58:25 +03:00
struct snd_ac97 * snd_soc_new_ac97_component ( struct snd_soc_component * component ,
2015-07-21 22:53:01 +03:00
unsigned int id , unsigned int id_mask )
2015-01-23 18:21:36 +03:00
{
struct snd_ac97 * ac97 ;
int ret ;
2018-01-29 05:58:25 +03:00
ac97 = snd_soc_alloc_ac97_component ( component ) ;
2015-01-23 18:21:36 +03:00
if ( IS_ERR ( ac97 ) )
return ac97 ;
2015-07-21 22:53:01 +03:00
if ( id ) {
ret = snd_ac97_reset ( ac97 , false , id , id_mask ) ;
if ( ret < 0 ) {
2018-01-29 05:58:25 +03:00
dev_err ( component - > dev , " Failed to reset AC97 device: %d \n " ,
2015-07-21 22:53:01 +03:00
ret ) ;
goto err_put_device ;
}
2014-11-11 00:41:53 +03:00
}
2014-11-11 00:41:46 +03:00
2015-07-21 22:53:01 +03:00
ret = device_add ( & ac97 - > dev ) ;
if ( ret )
goto err_put_device ;
2018-01-29 05:58:25 +03:00
ret = snd_soc_ac97_init_gpio ( ac97 , component ) ;
2015-11-11 15:12:51 +03:00
if ( ret )
goto err_put_device ;
2014-11-11 00:41:53 +03:00
return ac97 ;
2015-07-21 22:53:01 +03:00
err_put_device :
put_device ( & ac97 - > dev ) ;
return ERR_PTR ( ret ) ;
2014-11-11 00:41:46 +03:00
}
2018-01-29 05:58:25 +03:00
EXPORT_SYMBOL_GPL ( snd_soc_new_ac97_component ) ;
2014-11-11 00:41:46 +03:00
/**
2018-01-29 05:58:25 +03:00
* snd_soc_free_ac97_component - free AC97 component device
2017-01-12 14:38:15 +03:00
* @ ac97 : snd_ac97 device to be freed
2014-11-11 00:41:46 +03:00
*
2018-01-29 05:58:25 +03:00
* Frees AC97 component device resources .
2014-11-11 00:41:46 +03:00
*/
2018-01-29 05:58:25 +03:00
void snd_soc_free_ac97_component ( struct snd_ac97 * ac97 )
2014-11-11 00:41:46 +03:00
{
2015-11-11 15:12:51 +03:00
snd_soc_ac97_free_gpio ( ac97 ) ;
2014-11-11 00:41:53 +03:00
device_del ( & ac97 - > dev ) ;
ac97 - > bus = NULL ;
put_device ( & ac97 - > dev ) ;
2014-11-11 00:41:46 +03:00
}
2018-01-29 05:58:25 +03:00
EXPORT_SYMBOL_GPL ( snd_soc_free_ac97_component ) ;
2014-11-11 00:41:46 +03:00
static struct snd_ac97_reset_cfg snd_ac97_rst_cfg ;
static void snd_soc_ac97_warm_reset ( struct snd_ac97 * ac97 )
{
struct pinctrl * pctl = snd_ac97_rst_cfg . pctl ;
pinctrl_select_state ( pctl , snd_ac97_rst_cfg . pstate_warm_reset ) ;
gpio_direction_output ( snd_ac97_rst_cfg . gpio_sync , 1 ) ;
udelay ( 10 ) ;
gpio_direction_output ( snd_ac97_rst_cfg . gpio_sync , 0 ) ;
pinctrl_select_state ( pctl , snd_ac97_rst_cfg . pstate_run ) ;
msleep ( 2 ) ;
}
static void snd_soc_ac97_reset ( struct snd_ac97 * ac97 )
{
struct pinctrl * pctl = snd_ac97_rst_cfg . pctl ;
pinctrl_select_state ( pctl , snd_ac97_rst_cfg . pstate_reset ) ;
gpio_direction_output ( snd_ac97_rst_cfg . gpio_sync , 0 ) ;
gpio_direction_output ( snd_ac97_rst_cfg . gpio_sdata , 0 ) ;
gpio_direction_output ( snd_ac97_rst_cfg . gpio_reset , 0 ) ;
udelay ( 10 ) ;
gpio_direction_output ( snd_ac97_rst_cfg . gpio_reset , 1 ) ;
pinctrl_select_state ( pctl , snd_ac97_rst_cfg . pstate_run ) ;
msleep ( 2 ) ;
}
static int snd_soc_ac97_parse_pinctl ( struct device * dev ,
struct snd_ac97_reset_cfg * cfg )
{
struct pinctrl * p ;
struct pinctrl_state * state ;
int gpio ;
int ret ;
p = devm_pinctrl_get ( dev ) ;
if ( IS_ERR ( p ) ) {
dev_err ( dev , " Failed to get pinctrl \n " ) ;
return PTR_ERR ( p ) ;
}
cfg - > pctl = p ;
state = pinctrl_lookup_state ( p , " ac97-reset " ) ;
if ( IS_ERR ( state ) ) {
dev_err ( dev , " Can't find pinctrl state ac97-reset \n " ) ;
return PTR_ERR ( state ) ;
}
cfg - > pstate_reset = state ;
state = pinctrl_lookup_state ( p , " ac97-warm-reset " ) ;
if ( IS_ERR ( state ) ) {
dev_err ( dev , " Can't find pinctrl state ac97-warm-reset \n " ) ;
return PTR_ERR ( state ) ;
}
cfg - > pstate_warm_reset = state ;
state = pinctrl_lookup_state ( p , " ac97-running " ) ;
if ( IS_ERR ( state ) ) {
dev_err ( dev , " Can't find pinctrl state ac97-running \n " ) ;
return PTR_ERR ( state ) ;
}
cfg - > pstate_run = state ;
gpio = of_get_named_gpio ( dev - > of_node , " ac97-gpios " , 0 ) ;
if ( gpio < 0 ) {
dev_err ( dev , " Can't find ac97-sync gpio \n " ) ;
return gpio ;
}
ret = devm_gpio_request ( dev , gpio , " AC97 link sync " ) ;
if ( ret ) {
dev_err ( dev , " Failed requesting ac97-sync gpio \n " ) ;
return ret ;
}
cfg - > gpio_sync = gpio ;
gpio = of_get_named_gpio ( dev - > of_node , " ac97-gpios " , 1 ) ;
if ( gpio < 0 ) {
dev_err ( dev , " Can't find ac97-sdata gpio %d \n " , gpio ) ;
return gpio ;
}
ret = devm_gpio_request ( dev , gpio , " AC97 link sdata " ) ;
if ( ret ) {
dev_err ( dev , " Failed requesting ac97-sdata gpio \n " ) ;
return ret ;
}
cfg - > gpio_sdata = gpio ;
gpio = of_get_named_gpio ( dev - > of_node , " ac97-gpios " , 2 ) ;
if ( gpio < 0 ) {
dev_err ( dev , " Can't find ac97-reset gpio \n " ) ;
return gpio ;
}
ret = devm_gpio_request ( dev , gpio , " AC97 link reset " ) ;
if ( ret ) {
dev_err ( dev , " Failed requesting ac97-reset gpio \n " ) ;
return ret ;
}
cfg - > gpio_reset = gpio ;
return 0 ;
}
struct snd_ac97_bus_ops * soc_ac97_ops ;
EXPORT_SYMBOL_GPL ( soc_ac97_ops ) ;
int snd_soc_set_ac97_ops ( struct snd_ac97_bus_ops * ops )
{
if ( ops = = soc_ac97_ops )
return 0 ;
if ( soc_ac97_ops & & ops )
return - EBUSY ;
soc_ac97_ops = ops ;
2014-11-11 00:41:47 +03:00
soc_ac97_bus . ops = ops ;
2014-11-11 00:41:46 +03:00
return 0 ;
}
EXPORT_SYMBOL_GPL ( snd_soc_set_ac97_ops ) ;
/**
* snd_soc_set_ac97_ops_of_reset - Set ac97 ops with generic ac97 reset functions
2020-07-02 20:28:00 +03:00
* @ ops : bus ops
* @ pdev : platform device
2014-11-11 00:41:46 +03:00
*
* This function sets the reset and warm_reset properties of ops and parses
* the device node of pdev to get pinctrl states and gpio numbers to use .
*/
int snd_soc_set_ac97_ops_of_reset ( struct snd_ac97_bus_ops * ops ,
struct platform_device * pdev )
{
struct device * dev = & pdev - > dev ;
struct snd_ac97_reset_cfg cfg ;
int ret ;
ret = snd_soc_ac97_parse_pinctl ( dev , & cfg ) ;
if ( ret )
return ret ;
ret = snd_soc_set_ac97_ops ( ops ) ;
if ( ret )
return ret ;
ops - > warm_reset = snd_soc_ac97_warm_reset ;
ops - > reset = snd_soc_ac97_reset ;
snd_ac97_rst_cfg = cfg ;
return 0 ;
}
EXPORT_SYMBOL_GPL ( snd_soc_set_ac97_ops_of_reset ) ;