2022-06-03 12:06:08 +05:30
// SPDX-License-Identifier: GPL-2.0-only
//
// tegra210_mbdrc.c - Tegra210 MBDRC driver
//
// Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved.
# include <linux/device.h>
# include <linux/io.h>
# include <linux/module.h>
# include <linux/of_address.h>
# include <linux/pm_runtime.h>
# include <linux/regmap.h>
# include <sound/core.h>
# include <sound/soc.h>
# include <sound/tlv.h>
# include "tegra210_mbdrc.h"
# include "tegra210_ope.h"
# define MBDRC_FILTER_REG(reg, id) \
( ( reg ) + ( ( id ) * TEGRA210_MBDRC_FILTER_PARAM_STRIDE ) )
# define MBDRC_FILTER_REG_DEFAULTS(id) \
{ MBDRC_FILTER_REG ( TEGRA210_MBDRC_IIR_CFG , id ) , 0x00000005 } , \
{ MBDRC_FILTER_REG ( TEGRA210_MBDRC_IN_ATTACK , id ) , 0x3e48590c } , \
{ MBDRC_FILTER_REG ( TEGRA210_MBDRC_IN_RELEASE , id ) , 0x08414e9f } , \
{ MBDRC_FILTER_REG ( TEGRA210_MBDRC_FAST_ATTACK , id ) , 0x7fffffff } , \
{ MBDRC_FILTER_REG ( TEGRA210_MBDRC_IN_THRESHOLD , id ) , 0x06145082 } , \
{ MBDRC_FILTER_REG ( TEGRA210_MBDRC_OUT_THRESHOLD , id ) , 0x060d379b } , \
{ MBDRC_FILTER_REG ( TEGRA210_MBDRC_RATIO_1ST , id ) , 0x0000a000 } , \
{ MBDRC_FILTER_REG ( TEGRA210_MBDRC_RATIO_2ND , id ) , 0x00002000 } , \
{ MBDRC_FILTER_REG ( TEGRA210_MBDRC_RATIO_3RD , id ) , 0x00000b33 } , \
{ MBDRC_FILTER_REG ( TEGRA210_MBDRC_RATIO_4TH , id ) , 0x00000800 } , \
{ MBDRC_FILTER_REG ( TEGRA210_MBDRC_RATIO_5TH , id ) , 0x0000019a } , \
{ MBDRC_FILTER_REG ( TEGRA210_MBDRC_MAKEUP_GAIN , id ) , 0x00000002 } , \
{ MBDRC_FILTER_REG ( TEGRA210_MBDRC_INIT_GAIN , id ) , 0x00066666 } , \
{ MBDRC_FILTER_REG ( TEGRA210_MBDRC_GAIN_ATTACK , id ) , 0x00d9ba0e } , \
{ MBDRC_FILTER_REG ( TEGRA210_MBDRC_GAIN_RELEASE , id ) , 0x3e48590c } , \
{ MBDRC_FILTER_REG ( TEGRA210_MBDRC_FAST_RELEASE , id ) , 0x7ffff26a } , \
{ MBDRC_FILTER_REG ( TEGRA210_MBDRC_CFG_RAM_CTRL , id ) , 0x4000 }
static const struct reg_default tegra210_mbdrc_reg_defaults [ ] = {
{ TEGRA210_MBDRC_CFG , 0x0030de51 } ,
{ TEGRA210_MBDRC_CHANNEL_MASK , 0x00000003 } ,
{ TEGRA210_MBDRC_FAST_FACTOR , 0x30000800 } ,
MBDRC_FILTER_REG_DEFAULTS ( 0 ) ,
MBDRC_FILTER_REG_DEFAULTS ( 1 ) ,
MBDRC_FILTER_REG_DEFAULTS ( 2 ) ,
} ;
/* Default MBDRC parameters */
static const struct tegra210_mbdrc_config mbdrc_init_config = {
. mode = 0 , /* Bypass */
. rms_off = 48 ,
. peak_rms_mode = 1 , /* PEAK */
2022-11-08 11:13:40 +00:00
. filter_structure = 0 , /* All-pass tree */
2022-06-03 12:06:08 +05:30
. shift_ctrl = 30 ,
. frame_size = 32 ,
. channel_mask = 0x3 ,
. fa_factor = 2048 ,
. fr_factor = 14747 ,
. band_params [ MBDRC_LOW_BAND ] = {
. band = MBDRC_LOW_BAND ,
. iir_stages = 5 ,
. in_attack_tc = 1044928780 ,
. in_release_tc = 138497695 ,
. fast_attack_tc = 2147483647 ,
. in_threshold = { 130 , 80 , 20 , 6 } ,
. out_threshold = { 155 , 55 , 13 , 6 } ,
. ratio = { 40960 , 8192 , 2867 , 2048 , 410 } ,
. makeup_gain = 4 ,
. gain_init = 419430 ,
. gain_attack_tc = 14268942 ,
. gain_release_tc = 1440547090 ,
. fast_release_tc = 2147480170 ,
. biquad_params = {
/*
* Gains :
*
* b0 , b1 , a0 ,
* a1 , a2 ,
*/
/* Band-0 */
961046798 , - 2030431983 , 1073741824 ,
2030431983 , - 961046798 ,
/* Band-1 */
1030244425 , - 2099481453 , 1073741824 ,
2099481453 , - 1030244425 ,
/* Band-2 */
1067169294 , - 2136327263 , 1073741824 ,
2136327263 , - 1067169294 ,
/* Band-3 */
434951949 , - 1306567134 , 1073741824 ,
1306567134 , - 434951949 ,
/* Band-4 */
780656019 , - 1605955641 , 1073741824 ,
1605955641 , - 780656019 ,
/* Band-5 */
1024497031 , - 1817128152 , 1073741824 ,
1817128152 , - 1024497031 ,
/* Band-6 */
1073741824 , 0 , 0 ,
0 , 0 ,
/* Band-7 */
1073741824 , 0 , 0 ,
0 , 0 ,
}
} ,
. band_params [ MBDRC_MID_BAND ] = {
. band = MBDRC_MID_BAND ,
. iir_stages = 5 ,
. in_attack_tc = 1581413104 ,
. in_release_tc = 35494783 ,
. fast_attack_tc = 2147483647 ,
. in_threshold = { 130 , 50 , 30 , 6 } ,
. out_threshold = { 106 , 50 , 30 , 13 } ,
. ratio = { 40960 , 2867 , 4096 , 2867 , 410 } ,
. makeup_gain = 6 ,
. gain_init = 419430 ,
. gain_attack_tc = 4766887 ,
. gain_release_tc = 1044928780 ,
. fast_release_tc = 2147480170 ,
. biquad_params = {
/*
* Gains :
*
* b0 , b1 , a0 ,
* a1 , a2 ,
*/
/* Band-0 */
- 1005668963 , 1073741824 , 0 ,
1005668963 , 0 ,
/* Band-1 */
998437058 , - 2067742187 , 1073741824 ,
2067742187 , - 998437058 ,
/* Band-2 */
1051963422 , - 2121153948 , 1073741824 ,
2121153948 , - 1051963422 ,
/* Band-3 */
434951949 , - 1306567134 , 1073741824 ,
1306567134 , - 434951949 ,
/* Band-4 */
780656019 , - 1605955641 , 1073741824 ,
1605955641 , - 780656019 ,
/* Band-5 */
1024497031 , - 1817128152 , 1073741824 ,
1817128152 , - 1024497031 ,
/* Band-6 */
1073741824 , 0 , 0 ,
0 , 0 ,
/* Band-7 */
1073741824 , 0 , 0 ,
0 , 0 ,
}
} ,
. band_params [ MBDRC_HIGH_BAND ] = {
. band = MBDRC_HIGH_BAND ,
. iir_stages = 5 ,
. in_attack_tc = 2144750688 ,
. in_release_tc = 70402888 ,
. fast_attack_tc = 2147483647 ,
. in_threshold = { 130 , 50 , 30 , 6 } ,
. out_threshold = { 106 , 50 , 30 , 13 } ,
. ratio = { 40960 , 2867 , 4096 , 2867 , 410 } ,
. makeup_gain = 6 ,
. gain_init = 419430 ,
. gain_attack_tc = 4766887 ,
. gain_release_tc = 1044928780 ,
. fast_release_tc = 2147480170 ,
. biquad_params = {
/*
* Gains :
*
* b0 , b1 , a0 ,
* a1 , a2 ,
*/
/* Band-0 */
1073741824 , 0 , 0 ,
0 , 0 ,
/* Band-1 */
1073741824 , 0 , 0 ,
0 , 0 ,
/* Band-2 */
1073741824 , 0 , 0 ,
0 , 0 ,
/* Band-3 */
- 619925131 , 1073741824 , 0 ,
619925131 , 0 ,
/* Band-4 */
606839335 , - 1455425976 , 1073741824 ,
1455425976 , - 606839335 ,
/* Band-5 */
917759617 , - 1724690840 , 1073741824 ,
1724690840 , - 917759617 ,
/* Band-6 */
1073741824 , 0 , 0 ,
0 , 0 ,
/* Band-7 */
1073741824 , 0 , 0 ,
0 , 0 ,
}
}
} ;
static void tegra210_mbdrc_write_ram ( struct regmap * regmap , unsigned int reg_ctrl ,
unsigned int reg_data , unsigned int ram_offset ,
unsigned int * data , size_t size )
{
unsigned int val ;
unsigned int i ;
val = ram_offset & TEGRA210_MBDRC_RAM_CTRL_RAM_ADDR_MASK ;
val | = TEGRA210_MBDRC_RAM_CTRL_ADDR_INIT_EN ;
val | = TEGRA210_MBDRC_RAM_CTRL_SEQ_ACCESS_EN ;
val | = TEGRA210_MBDRC_RAM_CTRL_RW_WRITE ;
regmap_write ( regmap , reg_ctrl , val ) ;
for ( i = 0 ; i < size ; i + + )
regmap_write ( regmap , reg_data , data [ i ] ) ;
}
static int tegra210_mbdrc_get ( struct snd_kcontrol * kcontrol ,
struct snd_ctl_elem_value * ucontrol )
{
struct soc_mixer_control * mc =
( struct soc_mixer_control * ) kcontrol - > private_value ;
struct snd_soc_component * cmpnt = snd_soc_kcontrol_component ( kcontrol ) ;
struct tegra210_ope * ope = snd_soc_component_get_drvdata ( cmpnt ) ;
unsigned int val ;
regmap_read ( ope - > mbdrc_regmap , mc - > reg , & val ) ;
ucontrol - > value . integer . value [ 0 ] = ( val > > mc - > shift ) & mc - > max ;
return 0 ;
}
static int tegra210_mbdrc_put ( struct snd_kcontrol * kcontrol ,
struct snd_ctl_elem_value * ucontrol )
{
struct soc_mixer_control * mc =
( struct soc_mixer_control * ) kcontrol - > private_value ;
struct snd_soc_component * cmpnt = snd_soc_kcontrol_component ( kcontrol ) ;
struct tegra210_ope * ope = snd_soc_component_get_drvdata ( cmpnt ) ;
unsigned int val = ucontrol - > value . integer . value [ 0 ] ;
bool change = false ;
val = val < < mc - > shift ;
regmap_update_bits_check ( ope - > mbdrc_regmap , mc - > reg ,
( mc - > max < < mc - > shift ) , val , & change ) ;
return change ? 1 : 0 ;
}
static int tegra210_mbdrc_get_enum ( struct snd_kcontrol * kcontrol ,
struct snd_ctl_elem_value * ucontrol )
{
struct snd_soc_component * cmpnt = snd_soc_kcontrol_component ( kcontrol ) ;
struct tegra210_ope * ope = snd_soc_component_get_drvdata ( cmpnt ) ;
struct soc_enum * e = ( struct soc_enum * ) kcontrol - > private_value ;
unsigned int val ;
regmap_read ( ope - > mbdrc_regmap , e - > reg , & val ) ;
ucontrol - > value . enumerated . item [ 0 ] = ( val > > e - > shift_l ) & e - > mask ;
return 0 ;
}
static int tegra210_mbdrc_put_enum ( struct snd_kcontrol * kcontrol ,
struct snd_ctl_elem_value * ucontrol )
{
struct snd_soc_component * cmpnt = snd_soc_kcontrol_component ( kcontrol ) ;
struct tegra210_ope * ope = snd_soc_component_get_drvdata ( cmpnt ) ;
struct soc_enum * e = ( struct soc_enum * ) kcontrol - > private_value ;
bool change = false ;
unsigned int val ;
unsigned int mask ;
if ( ucontrol - > value . enumerated . item [ 0 ] > e - > items - 1 )
return - EINVAL ;
val = ucontrol - > value . enumerated . item [ 0 ] < < e - > shift_l ;
mask = e - > mask < < e - > shift_l ;
regmap_update_bits_check ( ope - > mbdrc_regmap , e - > reg , mask , val ,
& change ) ;
return change ? 1 : 0 ;
}
static int tegra210_mbdrc_band_params_get ( struct snd_kcontrol * kcontrol ,
struct snd_ctl_elem_value * ucontrol )
{
struct tegra_soc_bytes * params = ( void * ) kcontrol - > private_value ;
struct snd_soc_component * cmpnt = snd_soc_kcontrol_component ( kcontrol ) ;
struct tegra210_ope * ope = snd_soc_component_get_drvdata ( cmpnt ) ;
u32 * data = ( u32 * ) ucontrol - > value . bytes . data ;
u32 regs = params - > soc . base ;
u32 mask = params - > soc . mask ;
u32 shift = params - > shift ;
unsigned int i ;
for ( i = 0 ; i < params - > soc . num_regs ; i + + , regs + = cmpnt - > val_bytes ) {
regmap_read ( ope - > mbdrc_regmap , regs , & data [ i ] ) ;
data [ i ] = ( ( data [ i ] & mask ) > > shift ) ;
}
return 0 ;
}
static int tegra210_mbdrc_band_params_put ( struct snd_kcontrol * kcontrol ,
struct snd_ctl_elem_value * ucontrol )
{
struct tegra_soc_bytes * params = ( void * ) kcontrol - > private_value ;
struct snd_soc_component * cmpnt = snd_soc_kcontrol_component ( kcontrol ) ;
struct tegra210_ope * ope = snd_soc_component_get_drvdata ( cmpnt ) ;
u32 * data = ( u32 * ) ucontrol - > value . bytes . data ;
u32 regs = params - > soc . base ;
u32 mask = params - > soc . mask ;
u32 shift = params - > shift ;
bool change = false ;
unsigned int i ;
for ( i = 0 ; i < params - > soc . num_regs ; i + + , regs + = cmpnt - > val_bytes ) {
bool update = false ;
regmap_update_bits_check ( ope - > mbdrc_regmap , regs , mask ,
data [ i ] < < shift , & update ) ;
change | = update ;
}
return change ? 1 : 0 ;
}
static int tegra210_mbdrc_threshold_get ( struct snd_kcontrol * kcontrol ,
struct snd_ctl_elem_value * ucontrol )
{
struct tegra_soc_bytes * params = ( void * ) kcontrol - > private_value ;
struct snd_soc_component * cmpnt = snd_soc_kcontrol_component ( kcontrol ) ;
struct tegra210_ope * ope = snd_soc_component_get_drvdata ( cmpnt ) ;
u32 * data = ( u32 * ) ucontrol - > value . bytes . data ;
u32 regs = params - > soc . base ;
u32 num_regs = params - > soc . num_regs ;
u32 val ;
unsigned int i ;
for ( i = 0 ; i < num_regs ; i + = 4 , regs + = cmpnt - > val_bytes ) {
regmap_read ( ope - > mbdrc_regmap , regs , & val ) ;
data [ i ] = ( val & TEGRA210_MBDRC_THRESH_1ST_MASK ) > >
TEGRA210_MBDRC_THRESH_1ST_SHIFT ;
data [ i + 1 ] = ( val & TEGRA210_MBDRC_THRESH_2ND_MASK ) > >
TEGRA210_MBDRC_THRESH_2ND_SHIFT ;
data [ i + 2 ] = ( val & TEGRA210_MBDRC_THRESH_3RD_MASK ) > >
TEGRA210_MBDRC_THRESH_3RD_SHIFT ;
data [ i + 3 ] = ( val & TEGRA210_MBDRC_THRESH_4TH_MASK ) > >
TEGRA210_MBDRC_THRESH_4TH_SHIFT ;
}
return 0 ;
}
static int tegra210_mbdrc_threshold_put ( struct snd_kcontrol * kcontrol ,
struct snd_ctl_elem_value * ucontrol )
{
struct tegra_soc_bytes * params = ( void * ) kcontrol - > private_value ;
struct snd_soc_component * cmpnt = snd_soc_kcontrol_component ( kcontrol ) ;
struct tegra210_ope * ope = snd_soc_component_get_drvdata ( cmpnt ) ;
u32 * data = ( u32 * ) ucontrol - > value . bytes . data ;
u32 regs = params - > soc . base ;
u32 num_regs = params - > soc . num_regs ;
bool change = false ;
unsigned int i ;
for ( i = 0 ; i < num_regs ; i + = 4 , regs + = cmpnt - > val_bytes ) {
bool update = false ;
data [ i ] = ( ( ( data [ i ] > > TEGRA210_MBDRC_THRESH_1ST_SHIFT ) &
TEGRA210_MBDRC_THRESH_1ST_MASK ) |
( ( data [ i + 1 ] > > TEGRA210_MBDRC_THRESH_2ND_SHIFT ) &
TEGRA210_MBDRC_THRESH_2ND_MASK ) |
( ( data [ i + 2 ] > > TEGRA210_MBDRC_THRESH_3RD_SHIFT ) &
TEGRA210_MBDRC_THRESH_3RD_MASK ) |
( ( data [ i + 3 ] > > TEGRA210_MBDRC_THRESH_4TH_SHIFT ) &
TEGRA210_MBDRC_THRESH_4TH_MASK ) ) ;
regmap_update_bits_check ( ope - > mbdrc_regmap , regs , 0xffffffff ,
data [ i ] , & update ) ;
change | = update ;
}
return change ? 1 : 0 ;
}
static int tegra210_mbdrc_biquad_coeffs_get ( struct snd_kcontrol * kcontrol ,
struct snd_ctl_elem_value * ucontrol )
{
struct tegra_soc_bytes * params = ( void * ) kcontrol - > private_value ;
struct snd_soc_component * cmpnt = snd_soc_kcontrol_component ( kcontrol ) ;
u32 * data = ( u32 * ) ucontrol - > value . bytes . data ;
memset ( data , 0 , params - > soc . num_regs * cmpnt - > val_bytes ) ;
return 0 ;
}
static int tegra210_mbdrc_biquad_coeffs_put ( struct snd_kcontrol * kcontrol ,
struct snd_ctl_elem_value * ucontrol )
{
struct tegra_soc_bytes * params = ( void * ) kcontrol - > private_value ;
struct snd_soc_component * cmpnt = snd_soc_kcontrol_component ( kcontrol ) ;
struct tegra210_ope * ope = snd_soc_component_get_drvdata ( cmpnt ) ;
u32 reg_ctrl = params - > soc . base ;
u32 reg_data = reg_ctrl + cmpnt - > val_bytes ;
u32 * data = ( u32 * ) ucontrol - > value . bytes . data ;
tegra210_mbdrc_write_ram ( ope - > mbdrc_regmap , reg_ctrl , reg_data ,
params - > shift , data , params - > soc . num_regs ) ;
return 1 ;
}
static int tegra210_mbdrc_param_info ( struct snd_kcontrol * kcontrol ,
struct snd_ctl_elem_info * uinfo )
{
struct soc_bytes * params = ( void * ) kcontrol - > private_value ;
uinfo - > type = SNDRV_CTL_ELEM_TYPE_BYTES ;
uinfo - > count = params - > num_regs * sizeof ( u32 ) ;
return 0 ;
}
static int tegra210_mbdrc_vol_get ( struct snd_kcontrol * kcontrol ,
struct snd_ctl_elem_value * ucontrol )
{
struct soc_mixer_control * mc =
( struct soc_mixer_control * ) kcontrol - > private_value ;
struct snd_soc_component * cmpnt = snd_soc_kcontrol_component ( kcontrol ) ;
struct tegra210_ope * ope = snd_soc_component_get_drvdata ( cmpnt ) ;
int val ;
regmap_read ( ope - > mbdrc_regmap , mc - > reg , & val ) ;
ucontrol - > value . integer . value [ 0 ] =
( ( val > > mc - > shift ) - TEGRA210_MBDRC_MASTER_VOL_MIN ) ;
return 0 ;
}
static int tegra210_mbdrc_vol_put ( struct snd_kcontrol * kcontrol ,
struct snd_ctl_elem_value * ucontrol )
{
struct soc_mixer_control * mc =
( struct soc_mixer_control * ) kcontrol - > private_value ;
struct snd_soc_component * cmpnt = snd_soc_kcontrol_component ( kcontrol ) ;
struct tegra210_ope * ope = snd_soc_component_get_drvdata ( cmpnt ) ;
int val = ucontrol - > value . integer . value [ 0 ] ;
bool change = false ;
val + = TEGRA210_MBDRC_MASTER_VOL_MIN ;
regmap_update_bits_check ( ope - > mbdrc_regmap , mc - > reg ,
mc - > max < < mc - > shift , val < < mc - > shift ,
& change ) ;
regmap_read ( ope - > mbdrc_regmap , mc - > reg , & val ) ;
return change ? 1 : 0 ;
}
static const char * const tegra210_mbdrc_mode_text [ ] = {
" Bypass " , " Fullband " , " Dualband " , " Multiband "
} ;
static const struct soc_enum tegra210_mbdrc_mode_enum =
SOC_ENUM_SINGLE ( TEGRA210_MBDRC_CFG , TEGRA210_MBDRC_CFG_MBDRC_MODE_SHIFT ,
4 , tegra210_mbdrc_mode_text ) ;
static const char * const tegra210_mbdrc_peak_rms_text [ ] = {
" Peak " , " RMS "
} ;
static const struct soc_enum tegra210_mbdrc_peak_rms_enum =
SOC_ENUM_SINGLE ( TEGRA210_MBDRC_CFG , TEGRA210_MBDRC_CFG_PEAK_RMS_SHIFT ,
2 , tegra210_mbdrc_peak_rms_text ) ;
static const char * const tegra210_mbdrc_filter_structure_text [ ] = {
" All-pass-tree " , " Flexible "
} ;
static const struct soc_enum tegra210_mbdrc_filter_structure_enum =
SOC_ENUM_SINGLE ( TEGRA210_MBDRC_CFG ,
TEGRA210_MBDRC_CFG_FILTER_STRUCTURE_SHIFT , 2 ,
tegra210_mbdrc_filter_structure_text ) ;
static const char * const tegra210_mbdrc_frame_size_text [ ] = {
" N1 " , " N2 " , " N4 " , " N8 " , " N16 " , " N32 " , " N64 "
} ;
static const struct soc_enum tegra210_mbdrc_frame_size_enum =
SOC_ENUM_SINGLE ( TEGRA210_MBDRC_CFG , TEGRA210_MBDRC_CFG_FRAME_SIZE_SHIFT ,
7 , tegra210_mbdrc_frame_size_text ) ;
# define TEGRA_MBDRC_BYTES_EXT(xname, xbase, xregs, xshift, xmask, xinfo) \
TEGRA_SOC_BYTES_EXT ( xname , xbase , xregs , xshift , xmask , \
tegra210_mbdrc_band_params_get , \
tegra210_mbdrc_band_params_put , \
tegra210_mbdrc_param_info )
# define TEGRA_MBDRC_BAND_BYTES_EXT(xname, xbase, xshift, xmask, xinfo) \
TEGRA_MBDRC_BYTES_EXT ( xname , xbase , TEGRA210_MBDRC_FILTER_COUNT , \
xshift , xmask , xinfo )
static const DECLARE_TLV_DB_MINMAX ( mdbrc_vol_tlv , - 25600 , 25500 ) ;
static const struct snd_kcontrol_new tegra210_mbdrc_controls [ ] = {
SOC_ENUM_EXT ( " MBDRC Peak RMS Mode " , tegra210_mbdrc_peak_rms_enum ,
tegra210_mbdrc_get_enum , tegra210_mbdrc_put_enum ) ,
SOC_ENUM_EXT ( " MBDRC Filter Structure " ,
tegra210_mbdrc_filter_structure_enum ,
tegra210_mbdrc_get_enum , tegra210_mbdrc_put_enum ) ,
SOC_ENUM_EXT ( " MBDRC Frame Size " , tegra210_mbdrc_frame_size_enum ,
tegra210_mbdrc_get_enum , tegra210_mbdrc_put_enum ) ,
SOC_ENUM_EXT ( " MBDRC Mode " , tegra210_mbdrc_mode_enum ,
tegra210_mbdrc_get_enum , tegra210_mbdrc_put_enum ) ,
SOC_SINGLE_EXT ( " MBDRC RMS Offset " , TEGRA210_MBDRC_CFG ,
TEGRA210_MBDRC_CFG_RMS_OFFSET_SHIFT , 0x1ff , 0 ,
tegra210_mbdrc_get , tegra210_mbdrc_put ) ,
SOC_SINGLE_EXT ( " MBDRC Shift Control " , TEGRA210_MBDRC_CFG ,
TEGRA210_MBDRC_CFG_SHIFT_CTRL_SHIFT , 0x1f , 0 ,
tegra210_mbdrc_get , tegra210_mbdrc_put ) ,
SOC_SINGLE_EXT ( " MBDRC Fast Attack Factor " , TEGRA210_MBDRC_FAST_FACTOR ,
TEGRA210_MBDRC_FAST_FACTOR_ATTACK_SHIFT , 0xffff , 0 ,
tegra210_mbdrc_get , tegra210_mbdrc_put ) ,
SOC_SINGLE_EXT ( " MBDRC Fast Release Factor " , TEGRA210_MBDRC_FAST_FACTOR ,
TEGRA210_MBDRC_FAST_FACTOR_RELEASE_SHIFT , 0xffff , 0 ,
tegra210_mbdrc_get , tegra210_mbdrc_put ) ,
SOC_SINGLE_RANGE_EXT_TLV ( " MBDRC Master Volume " ,
TEGRA210_MBDRC_MASTER_VOL ,
TEGRA210_MBDRC_MASTER_VOL_SHIFT ,
0 , 0x1ff , 0 ,
tegra210_mbdrc_vol_get , tegra210_mbdrc_vol_put ,
mdbrc_vol_tlv ) ,
TEGRA_SOC_BYTES_EXT ( " MBDRC IIR Stages " , TEGRA210_MBDRC_IIR_CFG ,
TEGRA210_MBDRC_FILTER_COUNT ,
TEGRA210_MBDRC_IIR_CFG_NUM_STAGES_SHIFT ,
TEGRA210_MBDRC_IIR_CFG_NUM_STAGES_MASK ,
tegra210_mbdrc_band_params_get ,
tegra210_mbdrc_band_params_put ,
tegra210_mbdrc_param_info ) ,
TEGRA_SOC_BYTES_EXT ( " MBDRC In Attack Time Const " , TEGRA210_MBDRC_IN_ATTACK ,
TEGRA210_MBDRC_FILTER_COUNT ,
TEGRA210_MBDRC_IN_ATTACK_TC_SHIFT ,
TEGRA210_MBDRC_IN_ATTACK_TC_MASK ,
tegra210_mbdrc_band_params_get ,
tegra210_mbdrc_band_params_put ,
tegra210_mbdrc_param_info ) ,
TEGRA_SOC_BYTES_EXT ( " MBDRC In Release Time Const " , TEGRA210_MBDRC_IN_RELEASE ,
TEGRA210_MBDRC_FILTER_COUNT ,
TEGRA210_MBDRC_IN_RELEASE_TC_SHIFT ,
TEGRA210_MBDRC_IN_RELEASE_TC_MASK ,
tegra210_mbdrc_band_params_get ,
tegra210_mbdrc_band_params_put ,
tegra210_mbdrc_param_info ) ,
TEGRA_SOC_BYTES_EXT ( " MBDRC Fast Attack Time Const " , TEGRA210_MBDRC_FAST_ATTACK ,
TEGRA210_MBDRC_FILTER_COUNT ,
TEGRA210_MBDRC_FAST_ATTACK_TC_SHIFT ,
TEGRA210_MBDRC_FAST_ATTACK_TC_MASK ,
tegra210_mbdrc_band_params_get ,
tegra210_mbdrc_band_params_put ,
tegra210_mbdrc_param_info ) ,
TEGRA_SOC_BYTES_EXT ( " MBDRC In Threshold " , TEGRA210_MBDRC_IN_THRESHOLD ,
TEGRA210_MBDRC_FILTER_COUNT * 4 , 0 , 0xffffffff ,
tegra210_mbdrc_threshold_get ,
tegra210_mbdrc_threshold_put ,
tegra210_mbdrc_param_info ) ,
TEGRA_SOC_BYTES_EXT ( " MBDRC Out Threshold " , TEGRA210_MBDRC_OUT_THRESHOLD ,
TEGRA210_MBDRC_FILTER_COUNT * 4 , 0 , 0xffffffff ,
tegra210_mbdrc_threshold_get ,
tegra210_mbdrc_threshold_put ,
tegra210_mbdrc_param_info ) ,
TEGRA_SOC_BYTES_EXT ( " MBDRC Ratio " , TEGRA210_MBDRC_RATIO_1ST ,
TEGRA210_MBDRC_FILTER_COUNT * 5 ,
TEGRA210_MBDRC_RATIO_1ST_SHIFT , TEGRA210_MBDRC_RATIO_1ST_MASK ,
tegra210_mbdrc_band_params_get ,
tegra210_mbdrc_band_params_put ,
tegra210_mbdrc_param_info ) ,
TEGRA_SOC_BYTES_EXT ( " MBDRC Makeup Gain " , TEGRA210_MBDRC_MAKEUP_GAIN ,
TEGRA210_MBDRC_FILTER_COUNT ,
TEGRA210_MBDRC_MAKEUP_GAIN_SHIFT ,
TEGRA210_MBDRC_MAKEUP_GAIN_MASK ,
tegra210_mbdrc_band_params_get ,
tegra210_mbdrc_band_params_put ,
tegra210_mbdrc_param_info ) ,
TEGRA_SOC_BYTES_EXT ( " MBDRC Init Gain " , TEGRA210_MBDRC_INIT_GAIN ,
TEGRA210_MBDRC_FILTER_COUNT ,
TEGRA210_MBDRC_INIT_GAIN_SHIFT ,
TEGRA210_MBDRC_INIT_GAIN_MASK ,
tegra210_mbdrc_band_params_get ,
tegra210_mbdrc_band_params_put ,
tegra210_mbdrc_param_info ) ,
TEGRA_SOC_BYTES_EXT ( " MBDRC Attack Gain " , TEGRA210_MBDRC_GAIN_ATTACK ,
TEGRA210_MBDRC_FILTER_COUNT ,
TEGRA210_MBDRC_GAIN_ATTACK_SHIFT ,
TEGRA210_MBDRC_GAIN_ATTACK_MASK ,
tegra210_mbdrc_band_params_get ,
tegra210_mbdrc_band_params_put ,
tegra210_mbdrc_param_info ) ,
TEGRA_SOC_BYTES_EXT ( " MBDRC Release Gain " , TEGRA210_MBDRC_GAIN_RELEASE ,
TEGRA210_MBDRC_FILTER_COUNT ,
TEGRA210_MBDRC_GAIN_RELEASE_SHIFT ,
TEGRA210_MBDRC_GAIN_RELEASE_MASK ,
tegra210_mbdrc_band_params_get ,
tegra210_mbdrc_band_params_put ,
tegra210_mbdrc_param_info ) ,
TEGRA_SOC_BYTES_EXT ( " MBDRC Fast Release Gain " ,
TEGRA210_MBDRC_FAST_RELEASE ,
TEGRA210_MBDRC_FILTER_COUNT ,
TEGRA210_MBDRC_FAST_RELEASE_SHIFT ,
TEGRA210_MBDRC_FAST_RELEASE_MASK ,
tegra210_mbdrc_band_params_get ,
tegra210_mbdrc_band_params_put ,
tegra210_mbdrc_param_info ) ,
TEGRA_SOC_BYTES_EXT ( " MBDRC Low Band Biquad Coeffs " ,
TEGRA210_MBDRC_CFG_RAM_CTRL ,
TEGRA210_MBDRC_MAX_BIQUAD_STAGES * 5 , 0 , 0xffffffff ,
tegra210_mbdrc_biquad_coeffs_get ,
tegra210_mbdrc_biquad_coeffs_put ,
tegra210_mbdrc_param_info ) ,
TEGRA_SOC_BYTES_EXT ( " MBDRC Mid Band Biquad Coeffs " ,
TEGRA210_MBDRC_CFG_RAM_CTRL +
TEGRA210_MBDRC_FILTER_PARAM_STRIDE ,
TEGRA210_MBDRC_MAX_BIQUAD_STAGES * 5 , 0 , 0xffffffff ,
tegra210_mbdrc_biquad_coeffs_get ,
tegra210_mbdrc_biquad_coeffs_put ,
tegra210_mbdrc_param_info ) ,
TEGRA_SOC_BYTES_EXT ( " MBDRC High Band Biquad Coeffs " ,
TEGRA210_MBDRC_CFG_RAM_CTRL +
( TEGRA210_MBDRC_FILTER_PARAM_STRIDE * 2 ) ,
TEGRA210_MBDRC_MAX_BIQUAD_STAGES * 5 , 0 , 0xffffffff ,
tegra210_mbdrc_biquad_coeffs_get ,
tegra210_mbdrc_biquad_coeffs_put ,
tegra210_mbdrc_param_info ) ,
} ;
static bool tegra210_mbdrc_wr_reg ( struct device * dev , unsigned int reg )
{
if ( reg > = TEGRA210_MBDRC_IIR_CFG )
reg - = ( ( reg - TEGRA210_MBDRC_IIR_CFG ) %
( TEGRA210_MBDRC_FILTER_PARAM_STRIDE *
TEGRA210_MBDRC_FILTER_COUNT ) ) ;
switch ( reg ) {
case TEGRA210_MBDRC_SOFT_RESET :
case TEGRA210_MBDRC_CG :
case TEGRA210_MBDRC_CFG . . . TEGRA210_MBDRC_CFG_RAM_DATA :
return true ;
default :
return false ;
}
}
static bool tegra210_mbdrc_rd_reg ( struct device * dev , unsigned int reg )
{
if ( tegra210_mbdrc_wr_reg ( dev , reg ) )
return true ;
if ( reg > = TEGRA210_MBDRC_IIR_CFG )
reg - = ( ( reg - TEGRA210_MBDRC_IIR_CFG ) %
( TEGRA210_MBDRC_FILTER_PARAM_STRIDE *
TEGRA210_MBDRC_FILTER_COUNT ) ) ;
switch ( reg ) {
case TEGRA210_MBDRC_STATUS :
return true ;
default :
return false ;
}
}
static bool tegra210_mbdrc_volatile_reg ( struct device * dev , unsigned int reg )
{
if ( reg > = TEGRA210_MBDRC_IIR_CFG )
reg - = ( ( reg - TEGRA210_MBDRC_IIR_CFG ) %
( TEGRA210_MBDRC_FILTER_PARAM_STRIDE *
TEGRA210_MBDRC_FILTER_COUNT ) ) ;
switch ( reg ) {
case TEGRA210_MBDRC_SOFT_RESET :
case TEGRA210_MBDRC_STATUS :
case TEGRA210_MBDRC_CFG_RAM_CTRL :
case TEGRA210_MBDRC_CFG_RAM_DATA :
return true ;
default :
return false ;
}
}
static bool tegra210_mbdrc_precious_reg ( struct device * dev , unsigned int reg )
{
if ( reg > = TEGRA210_MBDRC_IIR_CFG )
reg - = ( ( reg - TEGRA210_MBDRC_IIR_CFG ) %
( TEGRA210_MBDRC_FILTER_PARAM_STRIDE *
TEGRA210_MBDRC_FILTER_COUNT ) ) ;
switch ( reg ) {
case TEGRA210_MBDRC_CFG_RAM_DATA :
return true ;
default :
return false ;
}
}
static const struct regmap_config tegra210_mbdrc_regmap_cfg = {
. name = " mbdrc " ,
. reg_bits = 32 ,
. reg_stride = 4 ,
. val_bits = 32 ,
. max_register = TEGRA210_MBDRC_MAX_REG ,
. writeable_reg = tegra210_mbdrc_wr_reg ,
. readable_reg = tegra210_mbdrc_rd_reg ,
. volatile_reg = tegra210_mbdrc_volatile_reg ,
. precious_reg = tegra210_mbdrc_precious_reg ,
. reg_defaults = tegra210_mbdrc_reg_defaults ,
. num_reg_defaults = ARRAY_SIZE ( tegra210_mbdrc_reg_defaults ) ,
. cache_type = REGCACHE_FLAT ,
} ;
int tegra210_mbdrc_hw_params ( struct snd_soc_component * cmpnt )
{
struct tegra210_ope * ope = snd_soc_component_get_drvdata ( cmpnt ) ;
const struct tegra210_mbdrc_config * conf = & mbdrc_init_config ;
u32 val = 0 ;
unsigned int i ;
regmap_read ( ope - > mbdrc_regmap , TEGRA210_MBDRC_CFG , & val ) ;
2022-06-15 10:08:34 +05:30
val & = TEGRA210_MBDRC_CFG_MBDRC_MODE_MASK ;
if ( val = = TEGRA210_MBDRC_CFG_MBDRC_MODE_BYPASS )
2022-06-03 12:06:08 +05:30
return 0 ;
for ( i = 0 ; i < MBDRC_NUM_BAND ; i + + ) {
const struct tegra210_mbdrc_band_params * params =
& conf - > band_params [ i ] ;
u32 reg_off = i * TEGRA210_MBDRC_FILTER_PARAM_STRIDE ;
tegra210_mbdrc_write_ram ( ope - > mbdrc_regmap ,
reg_off + TEGRA210_MBDRC_CFG_RAM_CTRL ,
reg_off + TEGRA210_MBDRC_CFG_RAM_DATA ,
0 , ( u32 * ) & params - > biquad_params [ 0 ] ,
TEGRA210_MBDRC_MAX_BIQUAD_STAGES * 5 ) ;
}
return 0 ;
}
int tegra210_mbdrc_component_init ( struct snd_soc_component * cmpnt )
{
struct tegra210_ope * ope = snd_soc_component_get_drvdata ( cmpnt ) ;
const struct tegra210_mbdrc_config * conf = & mbdrc_init_config ;
unsigned int i ;
u32 val ;
pm_runtime_get_sync ( cmpnt - > dev ) ;
/* Initialize MBDRC registers and AHUB RAM with default params */
regmap_update_bits ( ope - > mbdrc_regmap , TEGRA210_MBDRC_CFG ,
TEGRA210_MBDRC_CFG_MBDRC_MODE_MASK ,
conf - > mode < < TEGRA210_MBDRC_CFG_MBDRC_MODE_SHIFT ) ;
regmap_update_bits ( ope - > mbdrc_regmap , TEGRA210_MBDRC_CFG ,
TEGRA210_MBDRC_CFG_RMS_OFFSET_MASK ,
conf - > rms_off < < TEGRA210_MBDRC_CFG_RMS_OFFSET_SHIFT ) ;
regmap_update_bits ( ope - > mbdrc_regmap , TEGRA210_MBDRC_CFG ,
TEGRA210_MBDRC_CFG_PEAK_RMS_MASK ,
conf - > peak_rms_mode < < TEGRA210_MBDRC_CFG_PEAK_RMS_SHIFT ) ;
regmap_update_bits ( ope - > mbdrc_regmap , TEGRA210_MBDRC_CFG ,
TEGRA210_MBDRC_CFG_FILTER_STRUCTURE_MASK ,
2022-11-08 11:13:40 +00:00
conf - > filter_structure < <
2022-06-03 12:06:08 +05:30
TEGRA210_MBDRC_CFG_FILTER_STRUCTURE_SHIFT ) ;
regmap_update_bits ( ope - > mbdrc_regmap , TEGRA210_MBDRC_CFG ,
TEGRA210_MBDRC_CFG_SHIFT_CTRL_MASK ,
conf - > shift_ctrl < < TEGRA210_MBDRC_CFG_SHIFT_CTRL_SHIFT ) ;
regmap_update_bits ( ope - > mbdrc_regmap , TEGRA210_MBDRC_CFG ,
TEGRA210_MBDRC_CFG_FRAME_SIZE_MASK ,
__ffs ( conf - > frame_size ) < <
TEGRA210_MBDRC_CFG_FRAME_SIZE_SHIFT ) ;
regmap_update_bits ( ope - > mbdrc_regmap , TEGRA210_MBDRC_CHANNEL_MASK ,
TEGRA210_MBDRC_CHANNEL_MASK_MASK ,
conf - > channel_mask < < TEGRA210_MBDRC_CHANNEL_MASK_SHIFT ) ;
regmap_update_bits ( ope - > mbdrc_regmap , TEGRA210_MBDRC_FAST_FACTOR ,
TEGRA210_MBDRC_FAST_FACTOR_ATTACK_MASK ,
conf - > fa_factor < < TEGRA210_MBDRC_FAST_FACTOR_ATTACK_SHIFT ) ;
regmap_update_bits ( ope - > mbdrc_regmap , TEGRA210_MBDRC_FAST_FACTOR ,
TEGRA210_MBDRC_FAST_FACTOR_ATTACK_MASK ,
conf - > fr_factor < < TEGRA210_MBDRC_FAST_FACTOR_ATTACK_SHIFT ) ;
for ( i = 0 ; i < MBDRC_NUM_BAND ; i + + ) {
const struct tegra210_mbdrc_band_params * params =
& conf - > band_params [ i ] ;
u32 reg_off = i * TEGRA210_MBDRC_FILTER_PARAM_STRIDE ;
regmap_update_bits ( ope - > mbdrc_regmap ,
reg_off + TEGRA210_MBDRC_IIR_CFG ,
TEGRA210_MBDRC_IIR_CFG_NUM_STAGES_MASK ,
params - > iir_stages < <
TEGRA210_MBDRC_IIR_CFG_NUM_STAGES_SHIFT ) ;
regmap_update_bits ( ope - > mbdrc_regmap ,
reg_off + TEGRA210_MBDRC_IN_ATTACK ,
TEGRA210_MBDRC_IN_ATTACK_TC_MASK ,
params - > in_attack_tc < <
TEGRA210_MBDRC_IN_ATTACK_TC_SHIFT ) ;
regmap_update_bits ( ope - > mbdrc_regmap ,
reg_off + TEGRA210_MBDRC_IN_RELEASE ,
TEGRA210_MBDRC_IN_RELEASE_TC_MASK ,
params - > in_release_tc < <
TEGRA210_MBDRC_IN_RELEASE_TC_SHIFT ) ;
regmap_update_bits ( ope - > mbdrc_regmap ,
reg_off + TEGRA210_MBDRC_FAST_ATTACK ,
TEGRA210_MBDRC_FAST_ATTACK_TC_MASK ,
params - > fast_attack_tc < <
TEGRA210_MBDRC_FAST_ATTACK_TC_SHIFT ) ;
val = ( ( ( params - > in_threshold [ 0 ] > >
TEGRA210_MBDRC_THRESH_1ST_SHIFT ) &
TEGRA210_MBDRC_THRESH_1ST_MASK ) |
( ( params - > in_threshold [ 1 ] > >
TEGRA210_MBDRC_THRESH_2ND_SHIFT ) &
TEGRA210_MBDRC_THRESH_2ND_MASK ) |
( ( params - > in_threshold [ 2 ] > >
TEGRA210_MBDRC_THRESH_3RD_SHIFT ) &
TEGRA210_MBDRC_THRESH_3RD_MASK ) |
( ( params - > in_threshold [ 3 ] > >
TEGRA210_MBDRC_THRESH_4TH_SHIFT ) &
TEGRA210_MBDRC_THRESH_4TH_MASK ) ) ;
regmap_update_bits ( ope - > mbdrc_regmap ,
reg_off + TEGRA210_MBDRC_IN_THRESHOLD ,
0xffffffff , val ) ;
val = ( ( ( params - > out_threshold [ 0 ] > >
TEGRA210_MBDRC_THRESH_1ST_SHIFT ) &
TEGRA210_MBDRC_THRESH_1ST_MASK ) |
( ( params - > out_threshold [ 1 ] > >
TEGRA210_MBDRC_THRESH_2ND_SHIFT ) &
TEGRA210_MBDRC_THRESH_2ND_MASK ) |
( ( params - > out_threshold [ 2 ] > >
TEGRA210_MBDRC_THRESH_3RD_SHIFT ) &
TEGRA210_MBDRC_THRESH_3RD_MASK ) |
( ( params - > out_threshold [ 3 ] > >
TEGRA210_MBDRC_THRESH_4TH_SHIFT ) &
TEGRA210_MBDRC_THRESH_4TH_MASK ) ) ;
regmap_update_bits ( ope - > mbdrc_regmap ,
reg_off + TEGRA210_MBDRC_OUT_THRESHOLD ,
0xffffffff , val ) ;
regmap_update_bits ( ope - > mbdrc_regmap ,
reg_off + TEGRA210_MBDRC_RATIO_1ST ,
TEGRA210_MBDRC_RATIO_1ST_MASK ,
params - > ratio [ 0 ] < < TEGRA210_MBDRC_RATIO_1ST_SHIFT ) ;
regmap_update_bits ( ope - > mbdrc_regmap ,
reg_off + TEGRA210_MBDRC_RATIO_2ND ,
TEGRA210_MBDRC_RATIO_2ND_MASK ,
params - > ratio [ 1 ] < < TEGRA210_MBDRC_RATIO_2ND_SHIFT ) ;
regmap_update_bits ( ope - > mbdrc_regmap ,
reg_off + TEGRA210_MBDRC_RATIO_3RD ,
TEGRA210_MBDRC_RATIO_3RD_MASK ,
params - > ratio [ 2 ] < < TEGRA210_MBDRC_RATIO_3RD_SHIFT ) ;
regmap_update_bits ( ope - > mbdrc_regmap ,
reg_off + TEGRA210_MBDRC_RATIO_4TH ,
TEGRA210_MBDRC_RATIO_4TH_MASK ,
params - > ratio [ 3 ] < < TEGRA210_MBDRC_RATIO_4TH_SHIFT ) ;
regmap_update_bits ( ope - > mbdrc_regmap ,
reg_off + TEGRA210_MBDRC_RATIO_5TH ,
TEGRA210_MBDRC_RATIO_5TH_MASK ,
params - > ratio [ 4 ] < < TEGRA210_MBDRC_RATIO_5TH_SHIFT ) ;
regmap_update_bits ( ope - > mbdrc_regmap ,
reg_off + TEGRA210_MBDRC_MAKEUP_GAIN ,
TEGRA210_MBDRC_MAKEUP_GAIN_MASK ,
params - > makeup_gain < <
TEGRA210_MBDRC_MAKEUP_GAIN_SHIFT ) ;
regmap_update_bits ( ope - > mbdrc_regmap ,
reg_off + TEGRA210_MBDRC_INIT_GAIN ,
TEGRA210_MBDRC_INIT_GAIN_MASK ,
params - > gain_init < <
TEGRA210_MBDRC_INIT_GAIN_SHIFT ) ;
regmap_update_bits ( ope - > mbdrc_regmap ,
reg_off + TEGRA210_MBDRC_GAIN_ATTACK ,
TEGRA210_MBDRC_GAIN_ATTACK_MASK ,
params - > gain_attack_tc < <
TEGRA210_MBDRC_GAIN_ATTACK_SHIFT ) ;
regmap_update_bits ( ope - > mbdrc_regmap ,
reg_off + TEGRA210_MBDRC_GAIN_RELEASE ,
TEGRA210_MBDRC_GAIN_RELEASE_MASK ,
params - > gain_release_tc < <
TEGRA210_MBDRC_GAIN_RELEASE_SHIFT ) ;
regmap_update_bits ( ope - > mbdrc_regmap ,
reg_off + TEGRA210_MBDRC_FAST_RELEASE ,
TEGRA210_MBDRC_FAST_RELEASE_MASK ,
params - > fast_release_tc < <
TEGRA210_MBDRC_FAST_RELEASE_SHIFT ) ;
tegra210_mbdrc_write_ram ( ope - > mbdrc_regmap ,
reg_off + TEGRA210_MBDRC_CFG_RAM_CTRL ,
reg_off + TEGRA210_MBDRC_CFG_RAM_DATA , 0 ,
( u32 * ) & params - > biquad_params [ 0 ] ,
TEGRA210_MBDRC_MAX_BIQUAD_STAGES * 5 ) ;
}
pm_runtime_put_sync ( cmpnt - > dev ) ;
snd_soc_add_component_controls ( cmpnt , tegra210_mbdrc_controls ,
ARRAY_SIZE ( tegra210_mbdrc_controls ) ) ;
return 0 ;
}
int tegra210_mbdrc_regmap_init ( struct platform_device * pdev )
{
struct device * dev = & pdev - > dev ;
struct tegra210_ope * ope = dev_get_drvdata ( dev ) ;
struct device_node * child ;
struct resource mem ;
void __iomem * regs ;
int err ;
child = of_get_child_by_name ( dev - > of_node , " dynamic-range-compressor " ) ;
if ( ! child )
return - ENODEV ;
err = of_address_to_resource ( child , 0 , & mem ) ;
of_node_put ( child ) ;
if ( err < 0 ) {
dev_err ( dev , " fail to get MBDRC resource \n " ) ;
return err ;
}
mem . flags = IORESOURCE_MEM ;
regs = devm_ioremap_resource ( dev , & mem ) ;
if ( IS_ERR ( regs ) )
return PTR_ERR ( regs ) ;
ope - > mbdrc_regmap = devm_regmap_init_mmio ( dev , regs ,
& tegra210_mbdrc_regmap_cfg ) ;
if ( IS_ERR ( ope - > mbdrc_regmap ) ) {
dev_err ( dev , " regmap init failed \n " ) ;
return PTR_ERR ( ope - > mbdrc_regmap ) ;
}
regcache_cache_only ( ope - > mbdrc_regmap , true ) ;
return 0 ;
}