2019-06-04 11:11:33 +03:00
// SPDX-License-Identifier: GPL-2.0-only
2011-03-09 22:31:01 +03:00
/*
* wm8958 - dsp2 . c - - WM8958 DSP2 support
*
* Copyright 2011 Wolfson Microelectronics plc
*
* Author : Mark Brown < broonie @ opensource . wolfsonmicro . com >
*/
# include <linux/module.h>
# include <linux/moduleparam.h>
# include <linux/init.h>
# include <linux/delay.h>
# include <linux/pm.h>
# include <linux/i2c.h>
# include <linux/platform_device.h>
# include <linux/slab.h>
# include <sound/soc.h>
# include <sound/initval.h>
# include <sound/tlv.h>
# include <trace/events/asoc.h>
# include <linux/mfd/wm8994/core.h>
# include <linux/mfd/wm8994/registers.h>
# include <linux/mfd/wm8994/pdata.h>
# include <linux/mfd/wm8994/gpio.h>
2019-10-16 15:01:49 +03:00
# include <asm/unaligned.h>
2011-03-09 22:31:01 +03:00
# include "wm8994.h"
2011-03-11 21:09:04 +03:00
# define WM_FW_BLOCK_INFO 0xff
# define WM_FW_BLOCK_PM 0x00
# define WM_FW_BLOCK_X 0x01
# define WM_FW_BLOCK_Y 0x02
# define WM_FW_BLOCK_Z 0x03
# define WM_FW_BLOCK_I 0x06
# define WM_FW_BLOCK_A 0x08
# define WM_FW_BLOCK_C 0x0c
2018-01-29 06:12:21 +03:00
static int wm8958_dsp2_fw ( struct snd_soc_component * component , const char * name ,
2011-03-11 21:09:04 +03:00
const struct firmware * fw , bool check )
{
2018-01-29 06:12:21 +03:00
struct wm8994_priv * wm8994 = snd_soc_component_get_drvdata ( component ) ;
2011-03-11 21:09:04 +03:00
u64 data64 ;
u32 data32 ;
const u8 * data ;
char * str ;
size_t block_len , len ;
int ret = 0 ;
/* Suppress unneeded downloads */
if ( wm8994 - > cur_fw = = fw )
return 0 ;
if ( fw - > size < 32 ) {
2018-01-29 06:12:21 +03:00
dev_err ( component - > dev , " %s: firmware too short (%zd bytes) \n " ,
2011-11-16 17:38:28 +04:00
name , fw - > size ) ;
2011-03-11 21:09:04 +03:00
goto err ;
}
if ( memcmp ( fw - > data , " WMFW " , 4 ) ! = 0 ) {
2019-10-16 15:01:49 +03:00
data32 = get_unaligned_be32 ( fw - > data ) ;
2018-01-29 06:12:21 +03:00
dev_err ( component - > dev , " %s: firmware has bad file magic %08x \n " ,
2011-03-11 21:09:04 +03:00
name , data32 ) ;
goto err ;
}
2019-10-16 15:01:49 +03:00
len = get_unaligned_be32 ( fw - > data + 4 ) ;
data32 = get_unaligned_be32 ( fw - > data + 8 ) ;
2011-03-11 21:09:04 +03:00
if ( ( data32 > > 24 ) & 0xff ) {
2018-01-29 06:12:21 +03:00
dev_err ( component - > dev , " %s: unsupported firmware version %d \n " ,
2011-03-11 21:09:04 +03:00
name , ( data32 > > 24 ) & 0xff ) ;
goto err ;
}
if ( ( data32 & 0xffff ) ! = 8958 ) {
2018-01-29 06:12:21 +03:00
dev_err ( component - > dev , " %s: unsupported target device %d \n " ,
2011-03-11 21:09:04 +03:00
name , data32 & 0xffff ) ;
goto err ;
}
if ( ( ( data32 > > 16 ) & 0xff ) ! = 0xc ) {
2018-01-29 06:12:21 +03:00
dev_err ( component - > dev , " %s: unsupported target core %d \n " ,
2011-03-11 21:09:04 +03:00
name , ( data32 > > 16 ) & 0xff ) ;
goto err ;
}
if ( check ) {
2019-10-16 15:01:49 +03:00
data64 = get_unaligned_be64 ( fw - > data + 24 ) ;
dev_info ( component - > dev , " %s timestamp %llx \n " , name , data64 ) ;
2011-03-11 21:09:04 +03:00
} else {
2018-01-29 06:12:21 +03:00
snd_soc_component_write ( component , 0x102 , 0x2 ) ;
snd_soc_component_write ( component , 0x900 , 0x2 ) ;
2011-03-11 21:09:04 +03:00
}
data = fw - > data + len ;
len = fw - > size - len ;
while ( len ) {
if ( len < 12 ) {
2018-01-29 06:12:21 +03:00
dev_err ( component - > dev , " %s short data block of %zd \n " ,
2011-03-11 21:09:04 +03:00
name , len ) ;
goto err ;
}
2019-10-16 15:01:49 +03:00
block_len = get_unaligned_be32 ( data + 4 ) ;
2011-03-11 21:09:04 +03:00
if ( block_len + 8 > len ) {
2018-01-29 06:12:21 +03:00
dev_err ( component - > dev , " %zd byte block longer than file \n " ,
2011-03-11 21:09:04 +03:00
block_len ) ;
goto err ;
}
if ( block_len = = 0 ) {
2018-01-29 06:12:21 +03:00
dev_err ( component - > dev , " Zero length block \n " ) ;
2011-03-11 21:09:04 +03:00
goto err ;
}
2019-10-16 15:01:49 +03:00
data32 = get_unaligned_be32 ( data ) ;
2011-03-11 21:09:04 +03:00
switch ( ( data32 > > 24 ) & 0xff ) {
case WM_FW_BLOCK_INFO :
/* Informational text */
if ( ! check )
break ;
str = kzalloc ( block_len + 1 , GFP_KERNEL ) ;
if ( str ) {
memcpy ( str , data + 8 , block_len ) ;
2018-01-29 06:12:21 +03:00
dev_info ( component - > dev , " %s: %s \n " , name , str ) ;
2011-03-11 21:09:04 +03:00
kfree ( str ) ;
} else {
2018-01-29 06:12:21 +03:00
dev_err ( component - > dev , " Out of memory \n " ) ;
2011-03-11 21:09:04 +03:00
}
break ;
case WM_FW_BLOCK_PM :
case WM_FW_BLOCK_X :
case WM_FW_BLOCK_Y :
case WM_FW_BLOCK_Z :
case WM_FW_BLOCK_I :
case WM_FW_BLOCK_A :
case WM_FW_BLOCK_C :
2018-01-29 06:12:21 +03:00
dev_dbg ( component - > dev , " %s: %zd bytes of %x@%x \n " , name ,
2011-03-11 21:09:04 +03:00
block_len , ( data32 > > 24 ) & 0xff ,
data32 & 0xffffff ) ;
if ( check )
break ;
data32 & = 0xffffff ;
2014-02-22 21:30:13 +04:00
wm8994_bulk_write ( wm8994 - > wm8994 ,
2011-03-11 21:09:04 +03:00
data32 & 0xffffff ,
block_len / 2 ,
( void * ) ( data + 8 ) ) ;
break ;
default :
2018-01-29 06:12:21 +03:00
dev_warn ( component - > dev , " %s: unknown block type %d \n " ,
2011-03-11 21:09:04 +03:00
name , ( data32 > > 24 ) & 0xff ) ;
break ;
}
/* Round up to the next 32 bit word */
block_len + = block_len % 4 ;
data + = block_len + 8 ;
len - = block_len + 8 ;
}
if ( ! check ) {
2018-01-29 06:12:21 +03:00
dev_dbg ( component - > dev , " %s: download done \n " , name ) ;
2011-03-11 21:09:04 +03:00
wm8994 - > cur_fw = fw ;
} else {
2018-01-29 06:12:21 +03:00
dev_info ( component - > dev , " %s: got firmware \n " , name ) ;
2011-03-11 21:09:04 +03:00
}
goto ok ;
err :
ret = - EINVAL ;
ok :
if ( ! check ) {
2018-01-29 06:12:21 +03:00
snd_soc_component_write ( component , 0x900 , 0x0 ) ;
snd_soc_component_write ( component , 0x102 , 0x0 ) ;
2011-03-11 21:09:04 +03:00
}
return ret ;
}
2018-01-29 06:12:21 +03:00
static void wm8958_dsp_start_mbc ( struct snd_soc_component * component , int path )
2011-03-09 22:31:01 +03:00
{
2018-01-29 06:12:21 +03:00
struct wm8994_priv * wm8994 = snd_soc_component_get_drvdata ( component ) ;
2012-10-08 13:36:09 +04:00
struct wm8994 * control = wm8994 - > wm8994 ;
2011-03-11 21:09:04 +03:00
int i ;
/* If the DSP is already running then noop */
2020-06-16 08:21:29 +03:00
if ( snd_soc_component_read ( component , WM8958_DSP2_PROGRAM ) & WM8958_DSP2_ENA )
2011-03-11 21:09:04 +03:00
return ;
/* If we have MBC firmware download it */
if ( wm8994 - > mbc )
2018-01-29 06:12:21 +03:00
wm8958_dsp2_fw ( component , " MBC " , wm8994 - > mbc , false ) ;
2011-03-11 21:09:04 +03:00
2018-01-29 06:12:21 +03:00
snd_soc_component_update_bits ( component , WM8958_DSP2_PROGRAM ,
2011-03-11 21:09:04 +03:00
WM8958_DSP2_ENA , WM8958_DSP2_ENA ) ;
/* If we've got user supplied MBC settings use them */
2012-10-08 13:36:09 +04:00
if ( control - > pdata . num_mbc_cfgs ) {
2011-03-11 21:09:04 +03:00
struct wm8958_mbc_cfg * cfg
2012-10-08 13:36:09 +04:00
= & control - > pdata . mbc_cfgs [ wm8994 - > mbc_cfg ] ;
2011-03-11 21:09:04 +03:00
for ( i = 0 ; i < ARRAY_SIZE ( cfg - > coeff_regs ) ; i + + )
2018-01-29 06:12:21 +03:00
snd_soc_component_write ( component , i + WM8958_MBC_BAND_1_K_1 ,
2011-03-11 21:09:04 +03:00
cfg - > coeff_regs [ i ] ) ;
for ( i = 0 ; i < ARRAY_SIZE ( cfg - > cutoff_regs ) ; i + + )
2018-01-29 06:12:21 +03:00
snd_soc_component_write ( component ,
2011-03-11 21:09:04 +03:00
i + WM8958_MBC_BAND_2_LOWER_CUTOFF_C1_1 ,
cfg - > cutoff_regs [ i ] ) ;
}
/* Run the DSP */
2018-01-29 06:12:21 +03:00
snd_soc_component_write ( component , WM8958_DSP2_EXECCONTROL ,
2011-03-11 21:09:04 +03:00
WM8958_DSP2_RUNR ) ;
/* And we're off! */
2018-01-29 06:12:21 +03:00
snd_soc_component_update_bits ( component , WM8958_DSP2_CONFIG ,
2011-03-11 21:09:04 +03:00
WM8958_MBC_ENA |
WM8958_MBC_SEL_MASK ,
path < < WM8958_MBC_SEL_SHIFT |
WM8958_MBC_ENA ) ;
}
2018-01-29 06:12:21 +03:00
static void wm8958_dsp_start_vss ( struct snd_soc_component * component , int path )
2011-03-17 01:57:47 +03:00
{
2018-01-29 06:12:21 +03:00
struct wm8994_priv * wm8994 = snd_soc_component_get_drvdata ( component ) ;
2012-10-08 13:36:09 +04:00
struct wm8994 * control = wm8994 - > wm8994 ;
2011-03-17 01:57:47 +03:00
int i , ena ;
if ( wm8994 - > mbc_vss )
2018-01-29 06:12:21 +03:00
wm8958_dsp2_fw ( component , " MBC+VSS " , wm8994 - > mbc_vss , false ) ;
2011-03-17 01:57:47 +03:00
2018-01-29 06:12:21 +03:00
snd_soc_component_update_bits ( component , WM8958_DSP2_PROGRAM ,
2011-03-17 01:57:47 +03:00
WM8958_DSP2_ENA , WM8958_DSP2_ENA ) ;
/* If we've got user supplied settings use them */
2012-10-08 13:36:09 +04:00
if ( control - > pdata . num_mbc_cfgs ) {
2011-03-17 01:57:47 +03:00
struct wm8958_mbc_cfg * cfg
2012-10-08 13:36:09 +04:00
= & control - > pdata . mbc_cfgs [ wm8994 - > mbc_cfg ] ;
2011-03-17 01:57:47 +03:00
for ( i = 0 ; i < ARRAY_SIZE ( cfg - > combined_regs ) ; i + + )
2018-01-29 06:12:21 +03:00
snd_soc_component_write ( component , i + 0x2800 ,
2011-03-17 01:57:47 +03:00
cfg - > combined_regs [ i ] ) ;
}
2012-10-08 13:36:09 +04:00
if ( control - > pdata . num_vss_cfgs ) {
2011-03-17 01:57:47 +03:00
struct wm8958_vss_cfg * cfg
2012-10-08 13:36:09 +04:00
= & control - > pdata . vss_cfgs [ wm8994 - > vss_cfg ] ;
2011-03-17 01:57:47 +03:00
for ( i = 0 ; i < ARRAY_SIZE ( cfg - > regs ) ; i + + )
2018-01-29 06:12:21 +03:00
snd_soc_component_write ( component , i + 0x2600 , cfg - > regs [ i ] ) ;
2011-03-17 01:57:47 +03:00
}
2012-10-08 13:36:09 +04:00
if ( control - > pdata . num_vss_hpf_cfgs ) {
2011-03-17 01:57:47 +03:00
struct wm8958_vss_hpf_cfg * cfg
2012-10-08 13:36:09 +04:00
= & control - > pdata . vss_hpf_cfgs [ wm8994 - > vss_hpf_cfg ] ;
2011-03-17 01:57:47 +03:00
for ( i = 0 ; i < ARRAY_SIZE ( cfg - > regs ) ; i + + )
2018-01-29 06:12:21 +03:00
snd_soc_component_write ( component , i + 0x2400 , cfg - > regs [ i ] ) ;
2011-03-17 01:57:47 +03:00
}
/* Run the DSP */
2018-01-29 06:12:21 +03:00
snd_soc_component_write ( component , WM8958_DSP2_EXECCONTROL ,
2011-03-17 01:57:47 +03:00
WM8958_DSP2_RUNR ) ;
/* Enable the algorithms we've selected */
ena = 0 ;
if ( wm8994 - > mbc_ena [ path ] )
ena | = 0x8 ;
if ( wm8994 - > hpf2_ena [ path ] )
ena | = 0x4 ;
if ( wm8994 - > hpf1_ena [ path ] )
ena | = 0x2 ;
if ( wm8994 - > vss_ena [ path ] )
ena | = 0x1 ;
2018-01-29 06:12:21 +03:00
snd_soc_component_write ( component , 0x2201 , ena ) ;
2011-03-17 01:57:47 +03:00
/* Switch the DSP into the data path */
2018-01-29 06:12:21 +03:00
snd_soc_component_update_bits ( component , WM8958_DSP2_CONFIG ,
2011-03-17 01:57:47 +03:00
WM8958_MBC_SEL_MASK | WM8958_MBC_ENA ,
path < < WM8958_MBC_SEL_SHIFT | WM8958_MBC_ENA ) ;
}
2018-01-29 06:12:21 +03:00
static void wm8958_dsp_start_enh_eq ( struct snd_soc_component * component , int path )
2011-03-17 23:23:43 +03:00
{
2018-01-29 06:12:21 +03:00
struct wm8994_priv * wm8994 = snd_soc_component_get_drvdata ( component ) ;
2012-10-08 13:36:09 +04:00
struct wm8994 * control = wm8994 - > wm8994 ;
2011-03-17 23:23:43 +03:00
int i ;
2018-01-29 06:12:21 +03:00
wm8958_dsp2_fw ( component , " ENH_EQ " , wm8994 - > enh_eq , false ) ;
2011-03-17 23:23:43 +03:00
2018-01-29 06:12:21 +03:00
snd_soc_component_update_bits ( component , WM8958_DSP2_PROGRAM ,
2011-03-17 23:23:43 +03:00
WM8958_DSP2_ENA , WM8958_DSP2_ENA ) ;
/* If we've got user supplied settings use them */
2012-10-08 13:36:09 +04:00
if ( control - > pdata . num_enh_eq_cfgs ) {
2011-03-17 23:23:43 +03:00
struct wm8958_enh_eq_cfg * cfg
2012-10-08 13:36:09 +04:00
= & control - > pdata . enh_eq_cfgs [ wm8994 - > enh_eq_cfg ] ;
2011-03-17 23:23:43 +03:00
for ( i = 0 ; i < ARRAY_SIZE ( cfg - > regs ) ; i + + )
2018-01-29 06:12:21 +03:00
snd_soc_component_write ( component , i + 0x2200 ,
2011-03-17 23:23:43 +03:00
cfg - > regs [ i ] ) ;
}
/* Run the DSP */
2018-01-29 06:12:21 +03:00
snd_soc_component_write ( component , WM8958_DSP2_EXECCONTROL ,
2011-03-17 23:23:43 +03:00
WM8958_DSP2_RUNR ) ;
/* Switch the DSP into the data path */
2018-01-29 06:12:21 +03:00
snd_soc_component_update_bits ( component , WM8958_DSP2_CONFIG ,
2011-03-17 23:23:43 +03:00
WM8958_MBC_SEL_MASK | WM8958_MBC_ENA ,
path < < WM8958_MBC_SEL_SHIFT | WM8958_MBC_ENA ) ;
}
2011-03-17 01:57:47 +03:00
2018-01-29 06:12:21 +03:00
static void wm8958_dsp_apply ( struct snd_soc_component * component , int path , int start )
2011-03-11 21:09:04 +03:00
{
2018-01-29 06:12:21 +03:00
struct wm8994_priv * wm8994 = snd_soc_component_get_drvdata ( component ) ;
2020-06-16 08:21:29 +03:00
int pwr_reg = snd_soc_component_read ( component , WM8994_POWER_MANAGEMENT_5 ) ;
2011-03-16 23:55:37 +03:00
int ena , reg , aif ;
2011-03-09 22:31:01 +03:00
2011-03-16 23:55:37 +03:00
switch ( path ) {
2011-03-09 22:31:01 +03:00
case 0 :
pwr_reg & = ( WM8994_AIF1DAC1L_ENA | WM8994_AIF1DAC1R_ENA ) ;
aif = 0 ;
break ;
case 1 :
pwr_reg & = ( WM8994_AIF1DAC2L_ENA | WM8994_AIF1DAC2R_ENA ) ;
aif = 0 ;
break ;
case 2 :
pwr_reg & = ( WM8994_AIF2DACL_ENA | WM8994_AIF2DACR_ENA ) ;
aif = 1 ;
break ;
default :
2013-11-06 14:07:15 +04:00
WARN ( 1 , " Invalid path %d \n " , path ) ;
2011-03-09 22:31:01 +03:00
return ;
}
2011-03-16 23:55:37 +03:00
/* Do we have both an active AIF and an active algorithm? */
2011-03-17 01:57:47 +03:00
ena = wm8994 - > mbc_ena [ path ] | | wm8994 - > vss_ena [ path ] | |
2011-03-17 23:23:43 +03:00
wm8994 - > hpf1_ena [ path ] | | wm8994 - > hpf2_ena [ path ] | |
wm8994 - > enh_eq_ena [ path ] ;
2011-03-16 23:55:37 +03:00
if ( ! pwr_reg )
ena = 0 ;
2011-03-09 22:31:01 +03:00
2020-06-16 08:21:29 +03:00
reg = snd_soc_component_read ( component , WM8958_DSP2_PROGRAM ) ;
2011-03-09 22:31:01 +03:00
2018-01-29 06:12:21 +03:00
dev_dbg ( component - > dev , " DSP path %d %d startup: %d, power: %x, DSP: %x \n " ,
2011-03-16 23:55:37 +03:00
path , wm8994 - > dsp_active , start , pwr_reg , reg ) ;
2011-03-09 22:31:01 +03:00
if ( start & & ena ) {
2011-05-16 05:18:56 +04:00
/* If the DSP is already running then noop */
if ( reg & WM8958_DSP2_ENA )
return ;
2011-03-16 23:55:37 +03:00
/* If either AIFnCLK is not yet enabled postpone */
2020-06-16 08:21:29 +03:00
if ( ! ( snd_soc_component_read ( component , WM8994_AIF1_CLOCKING_1 )
2011-03-11 21:13:12 +03:00
& WM8994_AIF1CLK_ENA_MASK ) & &
2020-06-16 08:21:29 +03:00
! ( snd_soc_component_read ( component , WM8994_AIF2_CLOCKING_1 )
2011-03-11 21:13:12 +03:00
& WM8994_AIF2CLK_ENA_MASK ) )
return ;
2011-03-09 22:31:01 +03:00
/* Switch the clock over to the appropriate AIF */
2018-01-29 06:12:21 +03:00
snd_soc_component_update_bits ( component , WM8994_CLOCKING_1 ,
2011-03-09 22:31:01 +03:00
WM8958_DSP2CLK_SRC | WM8958_DSP2CLK_ENA ,
aif < < WM8958_DSP2CLK_SRC_SHIFT |
WM8958_DSP2CLK_ENA ) ;
2011-03-17 23:23:43 +03:00
if ( wm8994 - > enh_eq_ena [ path ] )
2018-01-29 06:12:21 +03:00
wm8958_dsp_start_enh_eq ( component , path ) ;
2011-03-17 23:23:43 +03:00
else if ( wm8994 - > vss_ena [ path ] | | wm8994 - > hpf1_ena [ path ] | |
2011-03-17 01:57:47 +03:00
wm8994 - > hpf2_ena [ path ] )
2018-01-29 06:12:21 +03:00
wm8958_dsp_start_vss ( component , path ) ;
2011-03-17 01:57:47 +03:00
else if ( wm8994 - > mbc_ena [ path ] )
2018-01-29 06:12:21 +03:00
wm8958_dsp_start_mbc ( component , path ) ;
2011-03-09 22:31:01 +03:00
2011-03-17 01:57:47 +03:00
wm8994 - > dsp_active = path ;
2018-01-29 06:12:21 +03:00
dev_dbg ( component - > dev , " DSP running in path %d \n " , path ) ;
2011-03-17 01:57:47 +03:00
}
if ( ! start & & wm8994 - > dsp_active = = path ) {
2011-03-09 22:31:01 +03:00
/* If the DSP is already stopped then noop */
if ( ! ( reg & WM8958_DSP2_ENA ) )
return ;
2018-01-29 06:12:21 +03:00
snd_soc_component_update_bits ( component , WM8958_DSP2_CONFIG ,
2011-03-09 22:31:01 +03:00
WM8958_MBC_ENA , 0 ) ;
2018-01-29 06:12:21 +03:00
snd_soc_component_write ( component , WM8958_DSP2_EXECCONTROL ,
2011-03-16 23:55:37 +03:00
WM8958_DSP2_STOP ) ;
2018-01-29 06:12:21 +03:00
snd_soc_component_update_bits ( component , WM8958_DSP2_PROGRAM ,
2011-03-09 22:31:01 +03:00
WM8958_DSP2_ENA , 0 ) ;
2018-01-29 06:12:21 +03:00
snd_soc_component_update_bits ( component , WM8994_CLOCKING_1 ,
2011-03-09 22:31:01 +03:00
WM8958_DSP2CLK_ENA , 0 ) ;
2011-03-16 23:55:37 +03:00
wm8994 - > dsp_active = - 1 ;
2018-01-29 06:12:21 +03:00
dev_dbg ( component - > dev , " DSP stopped \n " ) ;
2011-03-09 22:31:01 +03:00
}
}
int wm8958_aif_ev ( struct snd_soc_dapm_widget * w ,
struct snd_kcontrol * kcontrol , int event )
{
2018-01-29 06:12:21 +03:00
struct snd_soc_component * component = snd_soc_dapm_to_component ( w - > dapm ) ;
2020-07-31 20:38:34 +03:00
struct wm8994 * control = dev_get_drvdata ( component - > dev - > parent ) ;
2011-03-11 21:13:12 +03:00
int i ;
2011-03-09 22:31:01 +03:00
2020-07-31 20:38:34 +03:00
if ( control - > type ! = WM8958 )
return 0 ;
2011-03-09 22:31:01 +03:00
switch ( event ) {
case SND_SOC_DAPM_POST_PMU :
2011-03-11 21:13:12 +03:00
case SND_SOC_DAPM_PRE_PMU :
for ( i = 0 ; i < 3 ; i + + )
2018-01-29 06:12:21 +03:00
wm8958_dsp_apply ( component , i , 1 ) ;
2011-03-09 22:31:01 +03:00
break ;
case SND_SOC_DAPM_POST_PMD :
2011-03-11 21:13:12 +03:00
case SND_SOC_DAPM_PRE_PMD :
for ( i = 0 ; i < 3 ; i + + )
2018-01-29 06:12:21 +03:00
wm8958_dsp_apply ( component , i , 0 ) ;
2011-03-09 22:31:01 +03:00
break ;
}
return 0 ;
}
2011-03-16 23:55:37 +03:00
/* Check if DSP2 is in use on another AIF */
static int wm8958_dsp2_busy ( struct wm8994_priv * wm8994 , int aif )
{
int i ;
for ( i = 0 ; i < ARRAY_SIZE ( wm8994 - > mbc_ena ) ; i + + ) {
if ( i = = aif )
continue ;
2011-03-17 01:57:47 +03:00
if ( wm8994 - > mbc_ena [ i ] | | wm8994 - > vss_ena [ i ] | |
wm8994 - > hpf1_ena [ i ] | | wm8994 - > hpf2_ena [ i ] )
2011-03-16 23:55:37 +03:00
return 1 ;
}
return 0 ;
}
2011-03-09 22:31:01 +03:00
static int wm8958_put_mbc_enum ( struct snd_kcontrol * kcontrol ,
struct snd_ctl_elem_value * ucontrol )
{
2018-01-29 06:12:21 +03:00
struct snd_soc_component * component = snd_soc_kcontrol_component ( kcontrol ) ;
struct wm8994_priv * wm8994 = snd_soc_component_get_drvdata ( component ) ;
2012-10-08 13:36:09 +04:00
struct wm8994 * control = wm8994 - > wm8994 ;
2016-02-29 20:01:12 +03:00
int value = ucontrol - > value . enumerated . item [ 0 ] ;
2011-03-09 22:31:01 +03:00
int reg ;
/* Don't allow on the fly reconfiguration */
2020-06-16 08:21:29 +03:00
reg = snd_soc_component_read ( component , WM8994_CLOCKING_1 ) ;
2011-03-09 22:31:01 +03:00
if ( reg < 0 | | reg & WM8958_DSP2CLK_ENA )
return - EBUSY ;
2012-10-08 13:36:09 +04:00
if ( value > = control - > pdata . num_mbc_cfgs )
2011-03-09 22:31:01 +03:00
return - EINVAL ;
wm8994 - > mbc_cfg = value ;
return 0 ;
}
static int wm8958_get_mbc_enum ( struct snd_kcontrol * kcontrol ,
struct snd_ctl_elem_value * ucontrol )
{
2018-01-29 06:12:21 +03:00
struct snd_soc_component * component = snd_soc_kcontrol_component ( kcontrol ) ;
struct wm8994_priv * wm8994 = snd_soc_component_get_drvdata ( component ) ;
2011-03-09 22:31:01 +03:00
ucontrol - > value . enumerated . item [ 0 ] = wm8994 - > mbc_cfg ;
return 0 ;
}
static int wm8958_mbc_info ( struct snd_kcontrol * kcontrol ,
struct snd_ctl_elem_info * uinfo )
{
uinfo - > type = SNDRV_CTL_ELEM_TYPE_BOOLEAN ;
uinfo - > count = 1 ;
uinfo - > value . integer . min = 0 ;
uinfo - > value . integer . max = 1 ;
return 0 ;
}
static int wm8958_mbc_get ( struct snd_kcontrol * kcontrol ,
struct snd_ctl_elem_value * ucontrol )
{
int mbc = kcontrol - > private_value ;
2018-01-29 06:12:21 +03:00
struct snd_soc_component * component = snd_soc_kcontrol_component ( kcontrol ) ;
struct wm8994_priv * wm8994 = snd_soc_component_get_drvdata ( component ) ;
2011-03-09 22:31:01 +03:00
ucontrol - > value . integer . value [ 0 ] = wm8994 - > mbc_ena [ mbc ] ;
return 0 ;
}
static int wm8958_mbc_put ( struct snd_kcontrol * kcontrol ,
struct snd_ctl_elem_value * ucontrol )
{
int mbc = kcontrol - > private_value ;
2018-01-29 06:12:21 +03:00
struct snd_soc_component * component = snd_soc_kcontrol_component ( kcontrol ) ;
struct wm8994_priv * wm8994 = snd_soc_component_get_drvdata ( component ) ;
2011-03-09 22:31:01 +03:00
2011-05-16 05:02:53 +04:00
if ( wm8994 - > mbc_ena [ mbc ] = = ucontrol - > value . integer . value [ 0 ] )
return 0 ;
2011-03-09 22:31:01 +03:00
if ( ucontrol - > value . integer . value [ 0 ] > 1 )
return - EINVAL ;
2011-03-16 23:55:37 +03:00
if ( wm8958_dsp2_busy ( wm8994 , mbc ) ) {
2018-01-29 06:12:21 +03:00
dev_dbg ( component - > dev , " DSP2 active on %d already \n " , mbc ) ;
2011-03-16 23:55:37 +03:00
return - EBUSY ;
2011-03-09 22:31:01 +03:00
}
2011-03-17 23:23:43 +03:00
if ( wm8994 - > enh_eq_ena [ mbc ] )
return - EBUSY ;
2011-03-09 22:31:01 +03:00
wm8994 - > mbc_ena [ mbc ] = ucontrol - > value . integer . value [ 0 ] ;
2018-01-29 06:12:21 +03:00
wm8958_dsp_apply ( component , mbc , wm8994 - > mbc_ena [ mbc ] ) ;
2011-03-09 22:31:01 +03:00
return 0 ;
}
# define WM8958_MBC_SWITCH(xname, xval) {\
. iface = SNDRV_CTL_ELEM_IFACE_MIXER , . name = ( xname ) , \
. access = SNDRV_CTL_ELEM_ACCESS_READWRITE , \
. info = wm8958_mbc_info , \
. get = wm8958_mbc_get , . put = wm8958_mbc_put , \
. private_value = xval }
2011-03-17 01:57:47 +03:00
static int wm8958_put_vss_enum ( struct snd_kcontrol * kcontrol ,
struct snd_ctl_elem_value * ucontrol )
{
2018-01-29 06:12:21 +03:00
struct snd_soc_component * component = snd_soc_kcontrol_component ( kcontrol ) ;
struct wm8994_priv * wm8994 = snd_soc_component_get_drvdata ( component ) ;
2012-10-08 13:36:09 +04:00
struct wm8994 * control = wm8994 - > wm8994 ;
2016-02-29 20:01:12 +03:00
int value = ucontrol - > value . enumerated . item [ 0 ] ;
2011-03-17 01:57:47 +03:00
int reg ;
/* Don't allow on the fly reconfiguration */
2020-06-16 08:21:29 +03:00
reg = snd_soc_component_read ( component , WM8994_CLOCKING_1 ) ;
2011-03-17 01:57:47 +03:00
if ( reg < 0 | | reg & WM8958_DSP2CLK_ENA )
return - EBUSY ;
2012-10-08 13:36:09 +04:00
if ( value > = control - > pdata . num_vss_cfgs )
2011-03-17 01:57:47 +03:00
return - EINVAL ;
wm8994 - > vss_cfg = value ;
return 0 ;
}
static int wm8958_get_vss_enum ( struct snd_kcontrol * kcontrol ,
struct snd_ctl_elem_value * ucontrol )
{
2018-01-29 06:12:21 +03:00
struct snd_soc_component * component = snd_soc_kcontrol_component ( kcontrol ) ;
struct wm8994_priv * wm8994 = snd_soc_component_get_drvdata ( component ) ;
2011-03-17 01:57:47 +03:00
ucontrol - > value . enumerated . item [ 0 ] = wm8994 - > vss_cfg ;
return 0 ;
}
static int wm8958_put_vss_hpf_enum ( struct snd_kcontrol * kcontrol ,
struct snd_ctl_elem_value * ucontrol )
{
2018-01-29 06:12:21 +03:00
struct snd_soc_component * component = snd_soc_kcontrol_component ( kcontrol ) ;
struct wm8994_priv * wm8994 = snd_soc_component_get_drvdata ( component ) ;
2012-10-08 13:36:09 +04:00
struct wm8994 * control = wm8994 - > wm8994 ;
2016-02-29 20:01:12 +03:00
int value = ucontrol - > value . enumerated . item [ 0 ] ;
2011-03-17 01:57:47 +03:00
int reg ;
/* Don't allow on the fly reconfiguration */
2020-06-16 08:21:29 +03:00
reg = snd_soc_component_read ( component , WM8994_CLOCKING_1 ) ;
2011-03-17 01:57:47 +03:00
if ( reg < 0 | | reg & WM8958_DSP2CLK_ENA )
return - EBUSY ;
2012-10-08 13:36:09 +04:00
if ( value > = control - > pdata . num_vss_hpf_cfgs )
2011-03-17 01:57:47 +03:00
return - EINVAL ;
wm8994 - > vss_hpf_cfg = value ;
return 0 ;
}
static int wm8958_get_vss_hpf_enum ( struct snd_kcontrol * kcontrol ,
struct snd_ctl_elem_value * ucontrol )
{
2018-01-29 06:12:21 +03:00
struct snd_soc_component * component = snd_soc_kcontrol_component ( kcontrol ) ;
struct wm8994_priv * wm8994 = snd_soc_component_get_drvdata ( component ) ;
2011-03-17 01:57:47 +03:00
ucontrol - > value . enumerated . item [ 0 ] = wm8994 - > vss_hpf_cfg ;
return 0 ;
}
static int wm8958_vss_info ( struct snd_kcontrol * kcontrol ,
struct snd_ctl_elem_info * uinfo )
{
uinfo - > type = SNDRV_CTL_ELEM_TYPE_BOOLEAN ;
uinfo - > count = 1 ;
uinfo - > value . integer . min = 0 ;
uinfo - > value . integer . max = 1 ;
return 0 ;
}
static int wm8958_vss_get ( struct snd_kcontrol * kcontrol ,
struct snd_ctl_elem_value * ucontrol )
{
int vss = kcontrol - > private_value ;
2018-01-29 06:12:21 +03:00
struct snd_soc_component * component = snd_soc_kcontrol_component ( kcontrol ) ;
struct wm8994_priv * wm8994 = snd_soc_component_get_drvdata ( component ) ;
2011-03-17 01:57:47 +03:00
ucontrol - > value . integer . value [ 0 ] = wm8994 - > vss_ena [ vss ] ;
return 0 ;
}
static int wm8958_vss_put ( struct snd_kcontrol * kcontrol ,
struct snd_ctl_elem_value * ucontrol )
{
int vss = kcontrol - > private_value ;
2018-01-29 06:12:21 +03:00
struct snd_soc_component * component = snd_soc_kcontrol_component ( kcontrol ) ;
struct wm8994_priv * wm8994 = snd_soc_component_get_drvdata ( component ) ;
2011-03-17 01:57:47 +03:00
2011-05-16 05:02:53 +04:00
if ( wm8994 - > vss_ena [ vss ] = = ucontrol - > value . integer . value [ 0 ] )
return 0 ;
2011-03-17 01:57:47 +03:00
if ( ucontrol - > value . integer . value [ 0 ] > 1 )
return - EINVAL ;
if ( ! wm8994 - > mbc_vss )
return - ENODEV ;
if ( wm8958_dsp2_busy ( wm8994 , vss ) ) {
2018-01-29 06:12:21 +03:00
dev_dbg ( component - > dev , " DSP2 active on %d already \n " , vss ) ;
2011-03-17 01:57:47 +03:00
return - EBUSY ;
}
2011-03-17 23:23:43 +03:00
if ( wm8994 - > enh_eq_ena [ vss ] )
return - EBUSY ;
2011-03-17 01:57:47 +03:00
wm8994 - > vss_ena [ vss ] = ucontrol - > value . integer . value [ 0 ] ;
2018-01-29 06:12:21 +03:00
wm8958_dsp_apply ( component , vss , wm8994 - > vss_ena [ vss ] ) ;
2011-03-17 01:57:47 +03:00
return 0 ;
}
# define WM8958_VSS_SWITCH(xname, xval) {\
. iface = SNDRV_CTL_ELEM_IFACE_MIXER , . name = ( xname ) , \
. access = SNDRV_CTL_ELEM_ACCESS_READWRITE , \
. info = wm8958_vss_info , \
. get = wm8958_vss_get , . put = wm8958_vss_put , \
. private_value = xval }
static int wm8958_hpf_info ( struct snd_kcontrol * kcontrol ,
struct snd_ctl_elem_info * uinfo )
{
uinfo - > type = SNDRV_CTL_ELEM_TYPE_BOOLEAN ;
uinfo - > count = 1 ;
uinfo - > value . integer . min = 0 ;
uinfo - > value . integer . max = 1 ;
return 0 ;
}
static int wm8958_hpf_get ( struct snd_kcontrol * kcontrol ,
struct snd_ctl_elem_value * ucontrol )
{
int hpf = kcontrol - > private_value ;
2018-01-29 06:12:21 +03:00
struct snd_soc_component * component = snd_soc_kcontrol_component ( kcontrol ) ;
struct wm8994_priv * wm8994 = snd_soc_component_get_drvdata ( component ) ;
2011-03-17 01:57:47 +03:00
if ( hpf < 3 )
ucontrol - > value . integer . value [ 0 ] = wm8994 - > hpf1_ena [ hpf % 3 ] ;
else
ucontrol - > value . integer . value [ 0 ] = wm8994 - > hpf2_ena [ hpf % 3 ] ;
return 0 ;
}
static int wm8958_hpf_put ( struct snd_kcontrol * kcontrol ,
struct snd_ctl_elem_value * ucontrol )
{
int hpf = kcontrol - > private_value ;
2018-01-29 06:12:21 +03:00
struct snd_soc_component * component = snd_soc_kcontrol_component ( kcontrol ) ;
struct wm8994_priv * wm8994 = snd_soc_component_get_drvdata ( component ) ;
2011-03-17 01:57:47 +03:00
2011-05-16 05:02:53 +04:00
if ( hpf < 3 ) {
if ( wm8994 - > hpf1_ena [ hpf % 3 ] = =
ucontrol - > value . integer . value [ 0 ] )
return 0 ;
} else {
if ( wm8994 - > hpf2_ena [ hpf % 3 ] = =
ucontrol - > value . integer . value [ 0 ] )
return 0 ;
}
2011-03-17 01:57:47 +03:00
if ( ucontrol - > value . integer . value [ 0 ] > 1 )
return - EINVAL ;
if ( ! wm8994 - > mbc_vss )
return - ENODEV ;
if ( wm8958_dsp2_busy ( wm8994 , hpf % 3 ) ) {
2018-01-29 06:12:21 +03:00
dev_dbg ( component - > dev , " DSP2 active on %d already \n " , hpf ) ;
2011-03-17 01:57:47 +03:00
return - EBUSY ;
}
2011-03-17 23:23:43 +03:00
if ( wm8994 - > enh_eq_ena [ hpf % 3 ] )
2011-03-17 01:57:47 +03:00
return - EBUSY ;
if ( hpf < 3 )
wm8994 - > hpf1_ena [ hpf % 3 ] = ucontrol - > value . integer . value [ 0 ] ;
else
wm8994 - > hpf2_ena [ hpf % 3 ] = ucontrol - > value . integer . value [ 0 ] ;
2018-01-29 06:12:21 +03:00
wm8958_dsp_apply ( component , hpf % 3 , ucontrol - > value . integer . value [ 0 ] ) ;
2011-03-17 01:57:47 +03:00
return 0 ;
}
# define WM8958_HPF_SWITCH(xname, xval) {\
. iface = SNDRV_CTL_ELEM_IFACE_MIXER , . name = ( xname ) , \
. access = SNDRV_CTL_ELEM_ACCESS_READWRITE , \
. info = wm8958_hpf_info , \
. get = wm8958_hpf_get , . put = wm8958_hpf_put , \
. private_value = xval }
2011-03-17 23:23:43 +03:00
static int wm8958_put_enh_eq_enum ( struct snd_kcontrol * kcontrol ,
struct snd_ctl_elem_value * ucontrol )
{
2018-01-29 06:12:21 +03:00
struct snd_soc_component * component = snd_soc_kcontrol_component ( kcontrol ) ;
struct wm8994_priv * wm8994 = snd_soc_component_get_drvdata ( component ) ;
2012-10-08 13:36:09 +04:00
struct wm8994 * control = wm8994 - > wm8994 ;
2016-02-29 20:01:12 +03:00
int value = ucontrol - > value . enumerated . item [ 0 ] ;
2011-03-17 23:23:43 +03:00
int reg ;
/* Don't allow on the fly reconfiguration */
2020-06-16 08:21:29 +03:00
reg = snd_soc_component_read ( component , WM8994_CLOCKING_1 ) ;
2011-03-17 23:23:43 +03:00
if ( reg < 0 | | reg & WM8958_DSP2CLK_ENA )
return - EBUSY ;
2012-10-08 13:36:09 +04:00
if ( value > = control - > pdata . num_enh_eq_cfgs )
2011-03-17 23:23:43 +03:00
return - EINVAL ;
wm8994 - > enh_eq_cfg = value ;
return 0 ;
}
static int wm8958_get_enh_eq_enum ( struct snd_kcontrol * kcontrol ,
struct snd_ctl_elem_value * ucontrol )
{
2018-01-29 06:12:21 +03:00
struct snd_soc_component * component = snd_soc_kcontrol_component ( kcontrol ) ;
struct wm8994_priv * wm8994 = snd_soc_component_get_drvdata ( component ) ;
2011-03-17 23:23:43 +03:00
ucontrol - > value . enumerated . item [ 0 ] = wm8994 - > enh_eq_cfg ;
return 0 ;
}
static int wm8958_enh_eq_info ( struct snd_kcontrol * kcontrol ,
struct snd_ctl_elem_info * uinfo )
{
uinfo - > type = SNDRV_CTL_ELEM_TYPE_BOOLEAN ;
uinfo - > count = 1 ;
uinfo - > value . integer . min = 0 ;
uinfo - > value . integer . max = 1 ;
return 0 ;
}
static int wm8958_enh_eq_get ( struct snd_kcontrol * kcontrol ,
struct snd_ctl_elem_value * ucontrol )
{
int eq = kcontrol - > private_value ;
2018-01-29 06:12:21 +03:00
struct snd_soc_component * component = snd_soc_kcontrol_component ( kcontrol ) ;
struct wm8994_priv * wm8994 = snd_soc_component_get_drvdata ( component ) ;
2011-03-17 23:23:43 +03:00
ucontrol - > value . integer . value [ 0 ] = wm8994 - > enh_eq_ena [ eq ] ;
return 0 ;
}
static int wm8958_enh_eq_put ( struct snd_kcontrol * kcontrol ,
struct snd_ctl_elem_value * ucontrol )
{
int eq = kcontrol - > private_value ;
2018-01-29 06:12:21 +03:00
struct snd_soc_component * component = snd_soc_kcontrol_component ( kcontrol ) ;
struct wm8994_priv * wm8994 = snd_soc_component_get_drvdata ( component ) ;
2011-03-17 23:23:43 +03:00
2011-05-16 05:02:53 +04:00
if ( wm8994 - > enh_eq_ena [ eq ] = = ucontrol - > value . integer . value [ 0 ] )
return 0 ;
2011-03-17 23:23:43 +03:00
if ( ucontrol - > value . integer . value [ 0 ] > 1 )
return - EINVAL ;
if ( ! wm8994 - > enh_eq )
return - ENODEV ;
if ( wm8958_dsp2_busy ( wm8994 , eq ) ) {
2018-01-29 06:12:21 +03:00
dev_dbg ( component - > dev , " DSP2 active on %d already \n " , eq ) ;
2011-03-17 23:23:43 +03:00
return - EBUSY ;
}
if ( wm8994 - > mbc_ena [ eq ] | | wm8994 - > vss_ena [ eq ] | |
wm8994 - > hpf1_ena [ eq ] | | wm8994 - > hpf2_ena [ eq ] )
return - EBUSY ;
wm8994 - > enh_eq_ena [ eq ] = ucontrol - > value . integer . value [ 0 ] ;
2018-01-29 06:12:21 +03:00
wm8958_dsp_apply ( component , eq , ucontrol - > value . integer . value [ 0 ] ) ;
2011-03-17 23:23:43 +03:00
return 0 ;
}
# define WM8958_ENH_EQ_SWITCH(xname, xval) {\
. iface = SNDRV_CTL_ELEM_IFACE_MIXER , . name = ( xname ) , \
. access = SNDRV_CTL_ELEM_ACCESS_READWRITE , \
. info = wm8958_enh_eq_info , \
. get = wm8958_enh_eq_get , . put = wm8958_enh_eq_put , \
. private_value = xval }
2011-03-09 22:31:01 +03:00
static const struct snd_kcontrol_new wm8958_mbc_snd_controls [ ] = {
WM8958_MBC_SWITCH ( " AIF1DAC1 MBC Switch " , 0 ) ,
WM8958_MBC_SWITCH ( " AIF1DAC2 MBC Switch " , 1 ) ,
WM8958_MBC_SWITCH ( " AIF2DAC MBC Switch " , 2 ) ,
} ;
2011-03-17 01:57:47 +03:00
static const struct snd_kcontrol_new wm8958_vss_snd_controls [ ] = {
WM8958_VSS_SWITCH ( " AIF1DAC1 VSS Switch " , 0 ) ,
WM8958_VSS_SWITCH ( " AIF1DAC2 VSS Switch " , 1 ) ,
WM8958_VSS_SWITCH ( " AIF2DAC VSS Switch " , 2 ) ,
WM8958_HPF_SWITCH ( " AIF1DAC1 HPF1 Switch " , 0 ) ,
WM8958_HPF_SWITCH ( " AIF1DAC2 HPF1 Switch " , 1 ) ,
WM8958_HPF_SWITCH ( " AIF2DAC HPF1 Switch " , 2 ) ,
WM8958_HPF_SWITCH ( " AIF1DAC1 HPF2 Switch " , 3 ) ,
WM8958_HPF_SWITCH ( " AIF1DAC2 HPF2 Switch " , 4 ) ,
WM8958_HPF_SWITCH ( " AIF2DAC HPF2 Switch " , 5 ) ,
} ;
2011-03-17 23:23:43 +03:00
static const struct snd_kcontrol_new wm8958_enh_eq_snd_controls [ ] = {
WM8958_ENH_EQ_SWITCH ( " AIF1DAC1 Enhanced EQ Switch " , 0 ) ,
WM8958_ENH_EQ_SWITCH ( " AIF1DAC2 Enhanced EQ Switch " , 1 ) ,
WM8958_ENH_EQ_SWITCH ( " AIF2DAC Enhanced EQ Switch " , 2 ) ,
} ;
static void wm8958_enh_eq_loaded ( const struct firmware * fw , void * context )
{
2018-01-29 06:12:21 +03:00
struct snd_soc_component * component = context ;
struct wm8994_priv * wm8994 = snd_soc_component_get_drvdata ( component ) ;
2011-03-17 23:23:43 +03:00
2018-01-29 06:12:21 +03:00
if ( fw & & ( wm8958_dsp2_fw ( component , " ENH_EQ " , fw , true ) = = 0 ) ) {
2014-11-09 19:01:02 +03:00
mutex_lock ( & wm8994 - > fw_lock ) ;
2011-03-17 23:23:43 +03:00
wm8994 - > enh_eq = fw ;
2014-11-09 19:01:02 +03:00
mutex_unlock ( & wm8994 - > fw_lock ) ;
2011-03-17 23:23:43 +03:00
}
}
2011-03-17 01:57:47 +03:00
static void wm8958_mbc_vss_loaded ( const struct firmware * fw , void * context )
2011-03-11 21:09:04 +03:00
{
2018-01-29 06:12:21 +03:00
struct snd_soc_component * component = context ;
struct wm8994_priv * wm8994 = snd_soc_component_get_drvdata ( component ) ;
2011-03-11 21:09:04 +03:00
2018-01-29 06:12:21 +03:00
if ( fw & & ( wm8958_dsp2_fw ( component , " MBC+VSS " , fw , true ) = = 0 ) ) {
2014-11-09 19:01:02 +03:00
mutex_lock ( & wm8994 - > fw_lock ) ;
2011-03-17 01:57:47 +03:00
wm8994 - > mbc_vss = fw ;
2014-11-09 19:01:02 +03:00
mutex_unlock ( & wm8994 - > fw_lock ) ;
2011-03-11 21:09:04 +03:00
}
2011-03-17 01:57:47 +03:00
}
static void wm8958_mbc_loaded ( const struct firmware * fw , void * context )
{
2018-01-29 06:12:21 +03:00
struct snd_soc_component * component = context ;
struct wm8994_priv * wm8994 = snd_soc_component_get_drvdata ( component ) ;
2011-03-17 01:57:47 +03:00
2018-01-29 06:12:21 +03:00
if ( fw & & ( wm8958_dsp2_fw ( component , " MBC " , fw , true ) = = 0 ) ) {
2014-11-09 19:01:02 +03:00
mutex_lock ( & wm8994 - > fw_lock ) ;
2012-10-10 05:59:24 +04:00
wm8994 - > mbc = fw ;
2014-11-09 19:01:02 +03:00
mutex_unlock ( & wm8994 - > fw_lock ) ;
2012-10-10 05:59:24 +04:00
}
2011-03-11 21:09:04 +03:00
}
2018-01-29 06:12:21 +03:00
void wm8958_dsp2_init ( struct snd_soc_component * component )
2011-03-09 22:31:01 +03:00
{
2018-01-29 06:12:21 +03:00
struct wm8994_priv * wm8994 = snd_soc_component_get_drvdata ( component ) ;
2012-10-08 13:36:09 +04:00
struct wm8994 * control = wm8994 - > wm8994 ;
struct wm8994_pdata * pdata = & control - > pdata ;
2011-03-09 22:31:01 +03:00
int ret , i ;
2011-03-16 23:55:37 +03:00
wm8994 - > dsp_active = - 1 ;
2018-01-29 06:12:21 +03:00
snd_soc_add_component_controls ( component , wm8958_mbc_snd_controls ,
2011-03-09 22:31:01 +03:00
ARRAY_SIZE ( wm8958_mbc_snd_controls ) ) ;
2018-01-29 06:12:21 +03:00
snd_soc_add_component_controls ( component , wm8958_vss_snd_controls ,
2011-03-17 01:57:47 +03:00
ARRAY_SIZE ( wm8958_vss_snd_controls ) ) ;
2018-01-29 06:12:21 +03:00
snd_soc_add_component_controls ( component , wm8958_enh_eq_snd_controls ,
2011-03-17 23:23:43 +03:00
ARRAY_SIZE ( wm8958_enh_eq_snd_controls ) ) ;
2011-03-17 01:57:47 +03:00
2011-03-09 22:31:01 +03:00
2011-03-16 23:55:37 +03:00
/* We don't *require* firmware and don't want to delay boot */
2011-03-11 21:09:04 +03:00
request_firmware_nowait ( THIS_MODULE , FW_ACTION_HOTPLUG ,
2018-01-29 06:12:21 +03:00
" wm8958_mbc.wfw " , component - > dev , GFP_KERNEL ,
component , wm8958_mbc_loaded ) ;
2012-10-10 05:59:24 +04:00
request_firmware_nowait ( THIS_MODULE , FW_ACTION_HOTPLUG ,
2018-01-29 06:12:21 +03:00
" wm8958_mbc_vss.wfw " , component - > dev , GFP_KERNEL ,
component , wm8958_mbc_vss_loaded ) ;
2012-10-10 05:59:24 +04:00
request_firmware_nowait ( THIS_MODULE , FW_ACTION_HOTPLUG ,
2018-01-29 06:12:21 +03:00
" wm8958_enh_eq.wfw " , component - > dev , GFP_KERNEL ,
component , wm8958_enh_eq_loaded ) ;
2011-03-11 21:09:04 +03:00
2011-03-09 22:31:01 +03:00
if ( pdata - > num_mbc_cfgs ) {
struct snd_kcontrol_new control [ ] = {
SOC_ENUM_EXT ( " MBC Mode " , wm8994 - > mbc_enum ,
wm8958_get_mbc_enum , wm8958_put_mbc_enum ) ,
} ;
/* We need an array of texts for the enum API */
treewide: kmalloc() -> kmalloc_array()
The kmalloc() function has a 2-factor argument form, kmalloc_array(). This
patch replaces cases of:
kmalloc(a * b, gfp)
with:
kmalloc_array(a * b, gfp)
as well as handling cases of:
kmalloc(a * b * c, gfp)
with:
kmalloc(array3_size(a, b, c), gfp)
as it's slightly less ugly than:
kmalloc_array(array_size(a, b), c, gfp)
This does, however, attempt to ignore constant size factors like:
kmalloc(4 * 1024, gfp)
though any constants defined via macros get caught up in the conversion.
Any factors with a sizeof() of "unsigned char", "char", and "u8" were
dropped, since they're redundant.
The tools/ directory was manually excluded, since it has its own
implementation of kmalloc().
The Coccinelle script used for this was:
// Fix redundant parens around sizeof().
@@
type TYPE;
expression THING, E;
@@
(
kmalloc(
- (sizeof(TYPE)) * E
+ sizeof(TYPE) * E
, ...)
|
kmalloc(
- (sizeof(THING)) * E
+ sizeof(THING) * E
, ...)
)
// Drop single-byte sizes and redundant parens.
@@
expression COUNT;
typedef u8;
typedef __u8;
@@
(
kmalloc(
- sizeof(u8) * (COUNT)
+ COUNT
, ...)
|
kmalloc(
- sizeof(__u8) * (COUNT)
+ COUNT
, ...)
|
kmalloc(
- sizeof(char) * (COUNT)
+ COUNT
, ...)
|
kmalloc(
- sizeof(unsigned char) * (COUNT)
+ COUNT
, ...)
|
kmalloc(
- sizeof(u8) * COUNT
+ COUNT
, ...)
|
kmalloc(
- sizeof(__u8) * COUNT
+ COUNT
, ...)
|
kmalloc(
- sizeof(char) * COUNT
+ COUNT
, ...)
|
kmalloc(
- sizeof(unsigned char) * COUNT
+ COUNT
, ...)
)
// 2-factor product with sizeof(type/expression) and identifier or constant.
@@
type TYPE;
expression THING;
identifier COUNT_ID;
constant COUNT_CONST;
@@
(
- kmalloc
+ kmalloc_array
(
- sizeof(TYPE) * (COUNT_ID)
+ COUNT_ID, sizeof(TYPE)
, ...)
|
- kmalloc
+ kmalloc_array
(
- sizeof(TYPE) * COUNT_ID
+ COUNT_ID, sizeof(TYPE)
, ...)
|
- kmalloc
+ kmalloc_array
(
- sizeof(TYPE) * (COUNT_CONST)
+ COUNT_CONST, sizeof(TYPE)
, ...)
|
- kmalloc
+ kmalloc_array
(
- sizeof(TYPE) * COUNT_CONST
+ COUNT_CONST, sizeof(TYPE)
, ...)
|
- kmalloc
+ kmalloc_array
(
- sizeof(THING) * (COUNT_ID)
+ COUNT_ID, sizeof(THING)
, ...)
|
- kmalloc
+ kmalloc_array
(
- sizeof(THING) * COUNT_ID
+ COUNT_ID, sizeof(THING)
, ...)
|
- kmalloc
+ kmalloc_array
(
- sizeof(THING) * (COUNT_CONST)
+ COUNT_CONST, sizeof(THING)
, ...)
|
- kmalloc
+ kmalloc_array
(
- sizeof(THING) * COUNT_CONST
+ COUNT_CONST, sizeof(THING)
, ...)
)
// 2-factor product, only identifiers.
@@
identifier SIZE, COUNT;
@@
- kmalloc
+ kmalloc_array
(
- SIZE * COUNT
+ COUNT, SIZE
, ...)
// 3-factor product with 1 sizeof(type) or sizeof(expression), with
// redundant parens removed.
@@
expression THING;
identifier STRIDE, COUNT;
type TYPE;
@@
(
kmalloc(
- sizeof(TYPE) * (COUNT) * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kmalloc(
- sizeof(TYPE) * (COUNT) * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kmalloc(
- sizeof(TYPE) * COUNT * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kmalloc(
- sizeof(TYPE) * COUNT * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kmalloc(
- sizeof(THING) * (COUNT) * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
kmalloc(
- sizeof(THING) * (COUNT) * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
kmalloc(
- sizeof(THING) * COUNT * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
kmalloc(
- sizeof(THING) * COUNT * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
)
// 3-factor product with 2 sizeof(variable), with redundant parens removed.
@@
expression THING1, THING2;
identifier COUNT;
type TYPE1, TYPE2;
@@
(
kmalloc(
- sizeof(TYPE1) * sizeof(TYPE2) * COUNT
+ array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
, ...)
|
kmalloc(
- sizeof(TYPE1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
, ...)
|
kmalloc(
- sizeof(THING1) * sizeof(THING2) * COUNT
+ array3_size(COUNT, sizeof(THING1), sizeof(THING2))
, ...)
|
kmalloc(
- sizeof(THING1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(THING1), sizeof(THING2))
, ...)
|
kmalloc(
- sizeof(TYPE1) * sizeof(THING2) * COUNT
+ array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
, ...)
|
kmalloc(
- sizeof(TYPE1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
, ...)
)
// 3-factor product, only identifiers, with redundant parens removed.
@@
identifier STRIDE, SIZE, COUNT;
@@
(
kmalloc(
- (COUNT) * STRIDE * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kmalloc(
- COUNT * (STRIDE) * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kmalloc(
- COUNT * STRIDE * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kmalloc(
- (COUNT) * (STRIDE) * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kmalloc(
- COUNT * (STRIDE) * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kmalloc(
- (COUNT) * STRIDE * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kmalloc(
- (COUNT) * (STRIDE) * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kmalloc(
- COUNT * STRIDE * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
)
// Any remaining multi-factor products, first at least 3-factor products,
// when they're not all constants...
@@
expression E1, E2, E3;
constant C1, C2, C3;
@@
(
kmalloc(C1 * C2 * C3, ...)
|
kmalloc(
- (E1) * E2 * E3
+ array3_size(E1, E2, E3)
, ...)
|
kmalloc(
- (E1) * (E2) * E3
+ array3_size(E1, E2, E3)
, ...)
|
kmalloc(
- (E1) * (E2) * (E3)
+ array3_size(E1, E2, E3)
, ...)
|
kmalloc(
- E1 * E2 * E3
+ array3_size(E1, E2, E3)
, ...)
)
// And then all remaining 2 factors products when they're not all constants,
// keeping sizeof() as the second factor argument.
@@
expression THING, E1, E2;
type TYPE;
constant C1, C2, C3;
@@
(
kmalloc(sizeof(THING) * C2, ...)
|
kmalloc(sizeof(TYPE) * C2, ...)
|
kmalloc(C1 * C2 * C3, ...)
|
kmalloc(C1 * C2, ...)
|
- kmalloc
+ kmalloc_array
(
- sizeof(TYPE) * (E2)
+ E2, sizeof(TYPE)
, ...)
|
- kmalloc
+ kmalloc_array
(
- sizeof(TYPE) * E2
+ E2, sizeof(TYPE)
, ...)
|
- kmalloc
+ kmalloc_array
(
- sizeof(THING) * (E2)
+ E2, sizeof(THING)
, ...)
|
- kmalloc
+ kmalloc_array
(
- sizeof(THING) * E2
+ E2, sizeof(THING)
, ...)
|
- kmalloc
+ kmalloc_array
(
- (E1) * E2
+ E1, E2
, ...)
|
- kmalloc
+ kmalloc_array
(
- (E1) * (E2)
+ E1, E2
, ...)
|
- kmalloc
+ kmalloc_array
(
- E1 * E2
+ E1, E2
, ...)
)
Signed-off-by: Kees Cook <keescook@chromium.org>
2018-06-12 23:55:00 +03:00
wm8994 - > mbc_texts = kmalloc_array ( pdata - > num_mbc_cfgs ,
sizeof ( char * ) ,
GFP_KERNEL ) ;
2014-06-20 13:59:09 +04:00
if ( ! wm8994 - > mbc_texts )
2011-03-09 22:31:01 +03:00
return ;
for ( i = 0 ; i < pdata - > num_mbc_cfgs ; i + + )
wm8994 - > mbc_texts [ i ] = pdata - > mbc_cfgs [ i ] . name ;
2014-02-18 11:11:42 +04:00
wm8994 - > mbc_enum . items = pdata - > num_mbc_cfgs ;
2011-03-09 22:31:01 +03:00
wm8994 - > mbc_enum . texts = wm8994 - > mbc_texts ;
2018-01-29 06:12:21 +03:00
ret = snd_soc_add_component_controls ( wm8994 - > hubs . component ,
2012-07-25 21:10:03 +04:00
control , 1 ) ;
2011-03-09 22:31:01 +03:00
if ( ret ! = 0 )
2018-01-29 06:12:21 +03:00
dev_err ( wm8994 - > hubs . component - > dev ,
2011-03-09 22:31:01 +03:00
" Failed to add MBC mode controls: %d \n " , ret ) ;
}
2011-03-17 01:57:47 +03:00
if ( pdata - > num_vss_cfgs ) {
struct snd_kcontrol_new control [ ] = {
SOC_ENUM_EXT ( " VSS Mode " , wm8994 - > vss_enum ,
wm8958_get_vss_enum , wm8958_put_vss_enum ) ,
} ;
2011-03-09 22:31:01 +03:00
2011-03-17 01:57:47 +03:00
/* We need an array of texts for the enum API */
treewide: kmalloc() -> kmalloc_array()
The kmalloc() function has a 2-factor argument form, kmalloc_array(). This
patch replaces cases of:
kmalloc(a * b, gfp)
with:
kmalloc_array(a * b, gfp)
as well as handling cases of:
kmalloc(a * b * c, gfp)
with:
kmalloc(array3_size(a, b, c), gfp)
as it's slightly less ugly than:
kmalloc_array(array_size(a, b), c, gfp)
This does, however, attempt to ignore constant size factors like:
kmalloc(4 * 1024, gfp)
though any constants defined via macros get caught up in the conversion.
Any factors with a sizeof() of "unsigned char", "char", and "u8" were
dropped, since they're redundant.
The tools/ directory was manually excluded, since it has its own
implementation of kmalloc().
The Coccinelle script used for this was:
// Fix redundant parens around sizeof().
@@
type TYPE;
expression THING, E;
@@
(
kmalloc(
- (sizeof(TYPE)) * E
+ sizeof(TYPE) * E
, ...)
|
kmalloc(
- (sizeof(THING)) * E
+ sizeof(THING) * E
, ...)
)
// Drop single-byte sizes and redundant parens.
@@
expression COUNT;
typedef u8;
typedef __u8;
@@
(
kmalloc(
- sizeof(u8) * (COUNT)
+ COUNT
, ...)
|
kmalloc(
- sizeof(__u8) * (COUNT)
+ COUNT
, ...)
|
kmalloc(
- sizeof(char) * (COUNT)
+ COUNT
, ...)
|
kmalloc(
- sizeof(unsigned char) * (COUNT)
+ COUNT
, ...)
|
kmalloc(
- sizeof(u8) * COUNT
+ COUNT
, ...)
|
kmalloc(
- sizeof(__u8) * COUNT
+ COUNT
, ...)
|
kmalloc(
- sizeof(char) * COUNT
+ COUNT
, ...)
|
kmalloc(
- sizeof(unsigned char) * COUNT
+ COUNT
, ...)
)
// 2-factor product with sizeof(type/expression) and identifier or constant.
@@
type TYPE;
expression THING;
identifier COUNT_ID;
constant COUNT_CONST;
@@
(
- kmalloc
+ kmalloc_array
(
- sizeof(TYPE) * (COUNT_ID)
+ COUNT_ID, sizeof(TYPE)
, ...)
|
- kmalloc
+ kmalloc_array
(
- sizeof(TYPE) * COUNT_ID
+ COUNT_ID, sizeof(TYPE)
, ...)
|
- kmalloc
+ kmalloc_array
(
- sizeof(TYPE) * (COUNT_CONST)
+ COUNT_CONST, sizeof(TYPE)
, ...)
|
- kmalloc
+ kmalloc_array
(
- sizeof(TYPE) * COUNT_CONST
+ COUNT_CONST, sizeof(TYPE)
, ...)
|
- kmalloc
+ kmalloc_array
(
- sizeof(THING) * (COUNT_ID)
+ COUNT_ID, sizeof(THING)
, ...)
|
- kmalloc
+ kmalloc_array
(
- sizeof(THING) * COUNT_ID
+ COUNT_ID, sizeof(THING)
, ...)
|
- kmalloc
+ kmalloc_array
(
- sizeof(THING) * (COUNT_CONST)
+ COUNT_CONST, sizeof(THING)
, ...)
|
- kmalloc
+ kmalloc_array
(
- sizeof(THING) * COUNT_CONST
+ COUNT_CONST, sizeof(THING)
, ...)
)
// 2-factor product, only identifiers.
@@
identifier SIZE, COUNT;
@@
- kmalloc
+ kmalloc_array
(
- SIZE * COUNT
+ COUNT, SIZE
, ...)
// 3-factor product with 1 sizeof(type) or sizeof(expression), with
// redundant parens removed.
@@
expression THING;
identifier STRIDE, COUNT;
type TYPE;
@@
(
kmalloc(
- sizeof(TYPE) * (COUNT) * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kmalloc(
- sizeof(TYPE) * (COUNT) * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kmalloc(
- sizeof(TYPE) * COUNT * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kmalloc(
- sizeof(TYPE) * COUNT * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kmalloc(
- sizeof(THING) * (COUNT) * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
kmalloc(
- sizeof(THING) * (COUNT) * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
kmalloc(
- sizeof(THING) * COUNT * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
kmalloc(
- sizeof(THING) * COUNT * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
)
// 3-factor product with 2 sizeof(variable), with redundant parens removed.
@@
expression THING1, THING2;
identifier COUNT;
type TYPE1, TYPE2;
@@
(
kmalloc(
- sizeof(TYPE1) * sizeof(TYPE2) * COUNT
+ array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
, ...)
|
kmalloc(
- sizeof(TYPE1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
, ...)
|
kmalloc(
- sizeof(THING1) * sizeof(THING2) * COUNT
+ array3_size(COUNT, sizeof(THING1), sizeof(THING2))
, ...)
|
kmalloc(
- sizeof(THING1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(THING1), sizeof(THING2))
, ...)
|
kmalloc(
- sizeof(TYPE1) * sizeof(THING2) * COUNT
+ array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
, ...)
|
kmalloc(
- sizeof(TYPE1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
, ...)
)
// 3-factor product, only identifiers, with redundant parens removed.
@@
identifier STRIDE, SIZE, COUNT;
@@
(
kmalloc(
- (COUNT) * STRIDE * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kmalloc(
- COUNT * (STRIDE) * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kmalloc(
- COUNT * STRIDE * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kmalloc(
- (COUNT) * (STRIDE) * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kmalloc(
- COUNT * (STRIDE) * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kmalloc(
- (COUNT) * STRIDE * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kmalloc(
- (COUNT) * (STRIDE) * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kmalloc(
- COUNT * STRIDE * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
)
// Any remaining multi-factor products, first at least 3-factor products,
// when they're not all constants...
@@
expression E1, E2, E3;
constant C1, C2, C3;
@@
(
kmalloc(C1 * C2 * C3, ...)
|
kmalloc(
- (E1) * E2 * E3
+ array3_size(E1, E2, E3)
, ...)
|
kmalloc(
- (E1) * (E2) * E3
+ array3_size(E1, E2, E3)
, ...)
|
kmalloc(
- (E1) * (E2) * (E3)
+ array3_size(E1, E2, E3)
, ...)
|
kmalloc(
- E1 * E2 * E3
+ array3_size(E1, E2, E3)
, ...)
)
// And then all remaining 2 factors products when they're not all constants,
// keeping sizeof() as the second factor argument.
@@
expression THING, E1, E2;
type TYPE;
constant C1, C2, C3;
@@
(
kmalloc(sizeof(THING) * C2, ...)
|
kmalloc(sizeof(TYPE) * C2, ...)
|
kmalloc(C1 * C2 * C3, ...)
|
kmalloc(C1 * C2, ...)
|
- kmalloc
+ kmalloc_array
(
- sizeof(TYPE) * (E2)
+ E2, sizeof(TYPE)
, ...)
|
- kmalloc
+ kmalloc_array
(
- sizeof(TYPE) * E2
+ E2, sizeof(TYPE)
, ...)
|
- kmalloc
+ kmalloc_array
(
- sizeof(THING) * (E2)
+ E2, sizeof(THING)
, ...)
|
- kmalloc
+ kmalloc_array
(
- sizeof(THING) * E2
+ E2, sizeof(THING)
, ...)
|
- kmalloc
+ kmalloc_array
(
- (E1) * E2
+ E1, E2
, ...)
|
- kmalloc
+ kmalloc_array
(
- (E1) * (E2)
+ E1, E2
, ...)
|
- kmalloc
+ kmalloc_array
(
- E1 * E2
+ E1, E2
, ...)
)
Signed-off-by: Kees Cook <keescook@chromium.org>
2018-06-12 23:55:00 +03:00
wm8994 - > vss_texts = kmalloc_array ( pdata - > num_vss_cfgs ,
sizeof ( char * ) ,
GFP_KERNEL ) ;
2014-06-20 13:59:09 +04:00
if ( ! wm8994 - > vss_texts )
2011-03-17 01:57:47 +03:00
return ;
for ( i = 0 ; i < pdata - > num_vss_cfgs ; i + + )
wm8994 - > vss_texts [ i ] = pdata - > vss_cfgs [ i ] . name ;
2014-02-18 11:11:42 +04:00
wm8994 - > vss_enum . items = pdata - > num_vss_cfgs ;
2011-03-17 01:57:47 +03:00
wm8994 - > vss_enum . texts = wm8994 - > vss_texts ;
2018-01-29 06:12:21 +03:00
ret = snd_soc_add_component_controls ( wm8994 - > hubs . component ,
2012-07-25 21:10:03 +04:00
control , 1 ) ;
2011-03-17 01:57:47 +03:00
if ( ret ! = 0 )
2018-01-29 06:12:21 +03:00
dev_err ( wm8994 - > hubs . component - > dev ,
2011-03-17 01:57:47 +03:00
" Failed to add VSS mode controls: %d \n " , ret ) ;
}
if ( pdata - > num_vss_hpf_cfgs ) {
struct snd_kcontrol_new control [ ] = {
SOC_ENUM_EXT ( " VSS HPF Mode " , wm8994 - > vss_hpf_enum ,
wm8958_get_vss_hpf_enum ,
wm8958_put_vss_hpf_enum ) ,
} ;
/* We need an array of texts for the enum API */
treewide: kmalloc() -> kmalloc_array()
The kmalloc() function has a 2-factor argument form, kmalloc_array(). This
patch replaces cases of:
kmalloc(a * b, gfp)
with:
kmalloc_array(a * b, gfp)
as well as handling cases of:
kmalloc(a * b * c, gfp)
with:
kmalloc(array3_size(a, b, c), gfp)
as it's slightly less ugly than:
kmalloc_array(array_size(a, b), c, gfp)
This does, however, attempt to ignore constant size factors like:
kmalloc(4 * 1024, gfp)
though any constants defined via macros get caught up in the conversion.
Any factors with a sizeof() of "unsigned char", "char", and "u8" were
dropped, since they're redundant.
The tools/ directory was manually excluded, since it has its own
implementation of kmalloc().
The Coccinelle script used for this was:
// Fix redundant parens around sizeof().
@@
type TYPE;
expression THING, E;
@@
(
kmalloc(
- (sizeof(TYPE)) * E
+ sizeof(TYPE) * E
, ...)
|
kmalloc(
- (sizeof(THING)) * E
+ sizeof(THING) * E
, ...)
)
// Drop single-byte sizes and redundant parens.
@@
expression COUNT;
typedef u8;
typedef __u8;
@@
(
kmalloc(
- sizeof(u8) * (COUNT)
+ COUNT
, ...)
|
kmalloc(
- sizeof(__u8) * (COUNT)
+ COUNT
, ...)
|
kmalloc(
- sizeof(char) * (COUNT)
+ COUNT
, ...)
|
kmalloc(
- sizeof(unsigned char) * (COUNT)
+ COUNT
, ...)
|
kmalloc(
- sizeof(u8) * COUNT
+ COUNT
, ...)
|
kmalloc(
- sizeof(__u8) * COUNT
+ COUNT
, ...)
|
kmalloc(
- sizeof(char) * COUNT
+ COUNT
, ...)
|
kmalloc(
- sizeof(unsigned char) * COUNT
+ COUNT
, ...)
)
// 2-factor product with sizeof(type/expression) and identifier or constant.
@@
type TYPE;
expression THING;
identifier COUNT_ID;
constant COUNT_CONST;
@@
(
- kmalloc
+ kmalloc_array
(
- sizeof(TYPE) * (COUNT_ID)
+ COUNT_ID, sizeof(TYPE)
, ...)
|
- kmalloc
+ kmalloc_array
(
- sizeof(TYPE) * COUNT_ID
+ COUNT_ID, sizeof(TYPE)
, ...)
|
- kmalloc
+ kmalloc_array
(
- sizeof(TYPE) * (COUNT_CONST)
+ COUNT_CONST, sizeof(TYPE)
, ...)
|
- kmalloc
+ kmalloc_array
(
- sizeof(TYPE) * COUNT_CONST
+ COUNT_CONST, sizeof(TYPE)
, ...)
|
- kmalloc
+ kmalloc_array
(
- sizeof(THING) * (COUNT_ID)
+ COUNT_ID, sizeof(THING)
, ...)
|
- kmalloc
+ kmalloc_array
(
- sizeof(THING) * COUNT_ID
+ COUNT_ID, sizeof(THING)
, ...)
|
- kmalloc
+ kmalloc_array
(
- sizeof(THING) * (COUNT_CONST)
+ COUNT_CONST, sizeof(THING)
, ...)
|
- kmalloc
+ kmalloc_array
(
- sizeof(THING) * COUNT_CONST
+ COUNT_CONST, sizeof(THING)
, ...)
)
// 2-factor product, only identifiers.
@@
identifier SIZE, COUNT;
@@
- kmalloc
+ kmalloc_array
(
- SIZE * COUNT
+ COUNT, SIZE
, ...)
// 3-factor product with 1 sizeof(type) or sizeof(expression), with
// redundant parens removed.
@@
expression THING;
identifier STRIDE, COUNT;
type TYPE;
@@
(
kmalloc(
- sizeof(TYPE) * (COUNT) * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kmalloc(
- sizeof(TYPE) * (COUNT) * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kmalloc(
- sizeof(TYPE) * COUNT * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kmalloc(
- sizeof(TYPE) * COUNT * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kmalloc(
- sizeof(THING) * (COUNT) * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
kmalloc(
- sizeof(THING) * (COUNT) * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
kmalloc(
- sizeof(THING) * COUNT * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
kmalloc(
- sizeof(THING) * COUNT * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
)
// 3-factor product with 2 sizeof(variable), with redundant parens removed.
@@
expression THING1, THING2;
identifier COUNT;
type TYPE1, TYPE2;
@@
(
kmalloc(
- sizeof(TYPE1) * sizeof(TYPE2) * COUNT
+ array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
, ...)
|
kmalloc(
- sizeof(TYPE1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
, ...)
|
kmalloc(
- sizeof(THING1) * sizeof(THING2) * COUNT
+ array3_size(COUNT, sizeof(THING1), sizeof(THING2))
, ...)
|
kmalloc(
- sizeof(THING1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(THING1), sizeof(THING2))
, ...)
|
kmalloc(
- sizeof(TYPE1) * sizeof(THING2) * COUNT
+ array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
, ...)
|
kmalloc(
- sizeof(TYPE1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
, ...)
)
// 3-factor product, only identifiers, with redundant parens removed.
@@
identifier STRIDE, SIZE, COUNT;
@@
(
kmalloc(
- (COUNT) * STRIDE * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kmalloc(
- COUNT * (STRIDE) * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kmalloc(
- COUNT * STRIDE * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kmalloc(
- (COUNT) * (STRIDE) * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kmalloc(
- COUNT * (STRIDE) * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kmalloc(
- (COUNT) * STRIDE * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kmalloc(
- (COUNT) * (STRIDE) * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kmalloc(
- COUNT * STRIDE * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
)
// Any remaining multi-factor products, first at least 3-factor products,
// when they're not all constants...
@@
expression E1, E2, E3;
constant C1, C2, C3;
@@
(
kmalloc(C1 * C2 * C3, ...)
|
kmalloc(
- (E1) * E2 * E3
+ array3_size(E1, E2, E3)
, ...)
|
kmalloc(
- (E1) * (E2) * E3
+ array3_size(E1, E2, E3)
, ...)
|
kmalloc(
- (E1) * (E2) * (E3)
+ array3_size(E1, E2, E3)
, ...)
|
kmalloc(
- E1 * E2 * E3
+ array3_size(E1, E2, E3)
, ...)
)
// And then all remaining 2 factors products when they're not all constants,
// keeping sizeof() as the second factor argument.
@@
expression THING, E1, E2;
type TYPE;
constant C1, C2, C3;
@@
(
kmalloc(sizeof(THING) * C2, ...)
|
kmalloc(sizeof(TYPE) * C2, ...)
|
kmalloc(C1 * C2 * C3, ...)
|
kmalloc(C1 * C2, ...)
|
- kmalloc
+ kmalloc_array
(
- sizeof(TYPE) * (E2)
+ E2, sizeof(TYPE)
, ...)
|
- kmalloc
+ kmalloc_array
(
- sizeof(TYPE) * E2
+ E2, sizeof(TYPE)
, ...)
|
- kmalloc
+ kmalloc_array
(
- sizeof(THING) * (E2)
+ E2, sizeof(THING)
, ...)
|
- kmalloc
+ kmalloc_array
(
- sizeof(THING) * E2
+ E2, sizeof(THING)
, ...)
|
- kmalloc
+ kmalloc_array
(
- (E1) * E2
+ E1, E2
, ...)
|
- kmalloc
+ kmalloc_array
(
- (E1) * (E2)
+ E1, E2
, ...)
|
- kmalloc
+ kmalloc_array
(
- E1 * E2
+ E1, E2
, ...)
)
Signed-off-by: Kees Cook <keescook@chromium.org>
2018-06-12 23:55:00 +03:00
wm8994 - > vss_hpf_texts = kmalloc_array ( pdata - > num_vss_hpf_cfgs ,
sizeof ( char * ) ,
GFP_KERNEL ) ;
2014-06-20 13:59:09 +04:00
if ( ! wm8994 - > vss_hpf_texts )
2011-03-17 01:57:47 +03:00
return ;
for ( i = 0 ; i < pdata - > num_vss_hpf_cfgs ; i + + )
wm8994 - > vss_hpf_texts [ i ] = pdata - > vss_hpf_cfgs [ i ] . name ;
2014-02-18 11:11:42 +04:00
wm8994 - > vss_hpf_enum . items = pdata - > num_vss_hpf_cfgs ;
2011-03-17 01:57:47 +03:00
wm8994 - > vss_hpf_enum . texts = wm8994 - > vss_hpf_texts ;
2018-01-29 06:12:21 +03:00
ret = snd_soc_add_component_controls ( wm8994 - > hubs . component ,
2012-07-25 21:10:03 +04:00
control , 1 ) ;
2011-03-17 01:57:47 +03:00
if ( ret ! = 0 )
2018-01-29 06:12:21 +03:00
dev_err ( wm8994 - > hubs . component - > dev ,
2011-03-17 01:57:47 +03:00
" Failed to add VSS HPFmode controls: %d \n " ,
ret ) ;
}
2011-03-17 23:23:43 +03:00
if ( pdata - > num_enh_eq_cfgs ) {
struct snd_kcontrol_new control [ ] = {
SOC_ENUM_EXT ( " Enhanced EQ Mode " , wm8994 - > enh_eq_enum ,
wm8958_get_enh_eq_enum ,
wm8958_put_enh_eq_enum ) ,
} ;
/* We need an array of texts for the enum API */
treewide: kmalloc() -> kmalloc_array()
The kmalloc() function has a 2-factor argument form, kmalloc_array(). This
patch replaces cases of:
kmalloc(a * b, gfp)
with:
kmalloc_array(a * b, gfp)
as well as handling cases of:
kmalloc(a * b * c, gfp)
with:
kmalloc(array3_size(a, b, c), gfp)
as it's slightly less ugly than:
kmalloc_array(array_size(a, b), c, gfp)
This does, however, attempt to ignore constant size factors like:
kmalloc(4 * 1024, gfp)
though any constants defined via macros get caught up in the conversion.
Any factors with a sizeof() of "unsigned char", "char", and "u8" were
dropped, since they're redundant.
The tools/ directory was manually excluded, since it has its own
implementation of kmalloc().
The Coccinelle script used for this was:
// Fix redundant parens around sizeof().
@@
type TYPE;
expression THING, E;
@@
(
kmalloc(
- (sizeof(TYPE)) * E
+ sizeof(TYPE) * E
, ...)
|
kmalloc(
- (sizeof(THING)) * E
+ sizeof(THING) * E
, ...)
)
// Drop single-byte sizes and redundant parens.
@@
expression COUNT;
typedef u8;
typedef __u8;
@@
(
kmalloc(
- sizeof(u8) * (COUNT)
+ COUNT
, ...)
|
kmalloc(
- sizeof(__u8) * (COUNT)
+ COUNT
, ...)
|
kmalloc(
- sizeof(char) * (COUNT)
+ COUNT
, ...)
|
kmalloc(
- sizeof(unsigned char) * (COUNT)
+ COUNT
, ...)
|
kmalloc(
- sizeof(u8) * COUNT
+ COUNT
, ...)
|
kmalloc(
- sizeof(__u8) * COUNT
+ COUNT
, ...)
|
kmalloc(
- sizeof(char) * COUNT
+ COUNT
, ...)
|
kmalloc(
- sizeof(unsigned char) * COUNT
+ COUNT
, ...)
)
// 2-factor product with sizeof(type/expression) and identifier or constant.
@@
type TYPE;
expression THING;
identifier COUNT_ID;
constant COUNT_CONST;
@@
(
- kmalloc
+ kmalloc_array
(
- sizeof(TYPE) * (COUNT_ID)
+ COUNT_ID, sizeof(TYPE)
, ...)
|
- kmalloc
+ kmalloc_array
(
- sizeof(TYPE) * COUNT_ID
+ COUNT_ID, sizeof(TYPE)
, ...)
|
- kmalloc
+ kmalloc_array
(
- sizeof(TYPE) * (COUNT_CONST)
+ COUNT_CONST, sizeof(TYPE)
, ...)
|
- kmalloc
+ kmalloc_array
(
- sizeof(TYPE) * COUNT_CONST
+ COUNT_CONST, sizeof(TYPE)
, ...)
|
- kmalloc
+ kmalloc_array
(
- sizeof(THING) * (COUNT_ID)
+ COUNT_ID, sizeof(THING)
, ...)
|
- kmalloc
+ kmalloc_array
(
- sizeof(THING) * COUNT_ID
+ COUNT_ID, sizeof(THING)
, ...)
|
- kmalloc
+ kmalloc_array
(
- sizeof(THING) * (COUNT_CONST)
+ COUNT_CONST, sizeof(THING)
, ...)
|
- kmalloc
+ kmalloc_array
(
- sizeof(THING) * COUNT_CONST
+ COUNT_CONST, sizeof(THING)
, ...)
)
// 2-factor product, only identifiers.
@@
identifier SIZE, COUNT;
@@
- kmalloc
+ kmalloc_array
(
- SIZE * COUNT
+ COUNT, SIZE
, ...)
// 3-factor product with 1 sizeof(type) or sizeof(expression), with
// redundant parens removed.
@@
expression THING;
identifier STRIDE, COUNT;
type TYPE;
@@
(
kmalloc(
- sizeof(TYPE) * (COUNT) * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kmalloc(
- sizeof(TYPE) * (COUNT) * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kmalloc(
- sizeof(TYPE) * COUNT * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kmalloc(
- sizeof(TYPE) * COUNT * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kmalloc(
- sizeof(THING) * (COUNT) * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
kmalloc(
- sizeof(THING) * (COUNT) * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
kmalloc(
- sizeof(THING) * COUNT * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
kmalloc(
- sizeof(THING) * COUNT * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
)
// 3-factor product with 2 sizeof(variable), with redundant parens removed.
@@
expression THING1, THING2;
identifier COUNT;
type TYPE1, TYPE2;
@@
(
kmalloc(
- sizeof(TYPE1) * sizeof(TYPE2) * COUNT
+ array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
, ...)
|
kmalloc(
- sizeof(TYPE1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
, ...)
|
kmalloc(
- sizeof(THING1) * sizeof(THING2) * COUNT
+ array3_size(COUNT, sizeof(THING1), sizeof(THING2))
, ...)
|
kmalloc(
- sizeof(THING1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(THING1), sizeof(THING2))
, ...)
|
kmalloc(
- sizeof(TYPE1) * sizeof(THING2) * COUNT
+ array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
, ...)
|
kmalloc(
- sizeof(TYPE1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
, ...)
)
// 3-factor product, only identifiers, with redundant parens removed.
@@
identifier STRIDE, SIZE, COUNT;
@@
(
kmalloc(
- (COUNT) * STRIDE * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kmalloc(
- COUNT * (STRIDE) * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kmalloc(
- COUNT * STRIDE * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kmalloc(
- (COUNT) * (STRIDE) * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kmalloc(
- COUNT * (STRIDE) * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kmalloc(
- (COUNT) * STRIDE * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kmalloc(
- (COUNT) * (STRIDE) * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kmalloc(
- COUNT * STRIDE * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
)
// Any remaining multi-factor products, first at least 3-factor products,
// when they're not all constants...
@@
expression E1, E2, E3;
constant C1, C2, C3;
@@
(
kmalloc(C1 * C2 * C3, ...)
|
kmalloc(
- (E1) * E2 * E3
+ array3_size(E1, E2, E3)
, ...)
|
kmalloc(
- (E1) * (E2) * E3
+ array3_size(E1, E2, E3)
, ...)
|
kmalloc(
- (E1) * (E2) * (E3)
+ array3_size(E1, E2, E3)
, ...)
|
kmalloc(
- E1 * E2 * E3
+ array3_size(E1, E2, E3)
, ...)
)
// And then all remaining 2 factors products when they're not all constants,
// keeping sizeof() as the second factor argument.
@@
expression THING, E1, E2;
type TYPE;
constant C1, C2, C3;
@@
(
kmalloc(sizeof(THING) * C2, ...)
|
kmalloc(sizeof(TYPE) * C2, ...)
|
kmalloc(C1 * C2 * C3, ...)
|
kmalloc(C1 * C2, ...)
|
- kmalloc
+ kmalloc_array
(
- sizeof(TYPE) * (E2)
+ E2, sizeof(TYPE)
, ...)
|
- kmalloc
+ kmalloc_array
(
- sizeof(TYPE) * E2
+ E2, sizeof(TYPE)
, ...)
|
- kmalloc
+ kmalloc_array
(
- sizeof(THING) * (E2)
+ E2, sizeof(THING)
, ...)
|
- kmalloc
+ kmalloc_array
(
- sizeof(THING) * E2
+ E2, sizeof(THING)
, ...)
|
- kmalloc
+ kmalloc_array
(
- (E1) * E2
+ E1, E2
, ...)
|
- kmalloc
+ kmalloc_array
(
- (E1) * (E2)
+ E1, E2
, ...)
|
- kmalloc
+ kmalloc_array
(
- E1 * E2
+ E1, E2
, ...)
)
Signed-off-by: Kees Cook <keescook@chromium.org>
2018-06-12 23:55:00 +03:00
wm8994 - > enh_eq_texts = kmalloc_array ( pdata - > num_enh_eq_cfgs ,
sizeof ( char * ) ,
GFP_KERNEL ) ;
2014-06-20 13:59:09 +04:00
if ( ! wm8994 - > enh_eq_texts )
2011-03-17 23:23:43 +03:00
return ;
for ( i = 0 ; i < pdata - > num_enh_eq_cfgs ; i + + )
wm8994 - > enh_eq_texts [ i ] = pdata - > enh_eq_cfgs [ i ] . name ;
2014-02-18 11:11:42 +04:00
wm8994 - > enh_eq_enum . items = pdata - > num_enh_eq_cfgs ;
2011-03-17 23:23:43 +03:00
wm8994 - > enh_eq_enum . texts = wm8994 - > enh_eq_texts ;
2018-01-29 06:12:21 +03:00
ret = snd_soc_add_component_controls ( wm8994 - > hubs . component ,
2012-07-25 21:10:03 +04:00
control , 1 ) ;
2011-03-17 23:23:43 +03:00
if ( ret ! = 0 )
2018-01-29 06:12:21 +03:00
dev_err ( wm8994 - > hubs . component - > dev ,
2011-03-17 23:23:43 +03:00
" Failed to add enhanced EQ controls: %d \n " ,
ret ) ;
}
2011-03-09 22:31:01 +03:00
}