2018-06-12 05:58:38 +00:00
// SPDX-License-Identifier: GPL-2.0
//
// Renesas R-Car Gen1 SRU/SSI support
//
// Copyright (C) 2013 Renesas Solutions Corp.
// Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
2014-10-21 18:13:46 -07:00
/*
* # define DEBUG
*
* you can also add below in
* $ { LINUX } / drivers / base / regmap / regmap . c
* for regmap debug
*
* # define LOG_DEVICE " xxxx.rcar_sound "
*/
2013-07-21 21:36:21 -07:00
# include "rsnd.h"
struct rsnd_gen {
struct rsnd_gen_ops * ops ;
2013-09-23 23:12:27 -07:00
2015-10-22 03:13:27 +00:00
/* RSND_BASE_MAX base */
void __iomem * base [ RSND_BASE_MAX ] ;
phys_addr_t res [ RSND_BASE_MAX ] ;
2014-07-29 00:37:31 -07:00
struct regmap * regmap [ RSND_BASE_MAX ] ;
2015-10-22 03:13:27 +00:00
/* RSND_REG_MAX base */
2018-12-12 16:03:58 +09:00
struct regmap_field * regs [ REG_MAX ] ;
const char * reg_name [ REG_MAX ] ;
2013-07-21 21:36:21 -07:00
} ;
# define rsnd_priv_to_gen(p) ((struct rsnd_gen *)(p)->gen)
2015-11-26 08:43:59 +00:00
# define rsnd_reg_name(gen, id) ((gen)->reg_name[id])
2013-07-21 21:36:21 -07:00
2014-07-29 00:37:31 -07:00
struct rsnd_regmap_field_conf {
int idx ;
unsigned int reg_offset ;
unsigned int id_offset ;
2015-11-26 08:43:59 +00:00
const char * reg_name ;
2014-07-29 00:37:31 -07:00
} ;
2013-09-23 23:12:27 -07:00
2015-11-26 08:43:59 +00:00
# define RSND_REG_SET(id, offset, _id_offset, n) \
2014-07-29 00:37:31 -07:00
{ \
. idx = id , \
. reg_offset = offset , \
. id_offset = _id_offset , \
2015-11-26 08:43:59 +00:00
. reg_name = n , \
2013-09-23 23:12:27 -07:00
}
2014-07-29 00:37:31 -07:00
/* single address mapping */
# define RSND_GEN_S_REG(id, offset) \
2018-12-12 16:03:58 +09:00
RSND_REG_SET ( id , offset , 0 , # id )
2013-09-23 23:12:27 -07:00
2014-07-29 00:37:31 -07:00
/* multi address mapping */
# define RSND_GEN_M_REG(id, offset, _id_offset) \
2018-12-12 16:03:58 +09:00
RSND_REG_SET ( id , offset , _id_offset , # id )
2013-09-23 23:12:27 -07:00
2014-07-29 00:37:31 -07:00
/*
* basic function
*/
2013-11-28 18:43:13 -08:00
static int rsnd_is_accessible_reg ( struct rsnd_priv * priv ,
struct rsnd_gen * gen , enum rsnd_reg reg )
{
if ( ! gen - > regs [ reg ] ) {
struct device * dev = rsnd_priv_to_dev ( priv ) ;
dev_err ( dev , " unsupported register access %x \n " , reg ) ;
return 0 ;
}
return 1 ;
}
2018-12-04 08:00:47 +00:00
static int rsnd_mod_id_cmd ( struct rsnd_mod * mod )
{
if ( mod - > ops - > id_cmd )
return mod - > ops - > id_cmd ( mod ) ;
return rsnd_mod_id ( mod ) ;
}
2018-12-12 16:03:58 +09:00
u32 rsnd_mod_read ( struct rsnd_mod * mod , enum rsnd_reg reg )
2013-09-23 23:12:27 -07:00
{
2018-12-12 16:03:58 +09:00
struct rsnd_priv * priv = rsnd_mod_to_priv ( mod ) ;
2014-07-29 00:37:31 -07:00
struct device * dev = rsnd_priv_to_dev ( priv ) ;
2013-09-23 23:12:27 -07:00
struct rsnd_gen * gen = rsnd_priv_to_gen ( priv ) ;
u32 val ;
2013-11-28 18:43:13 -08:00
if ( ! rsnd_is_accessible_reg ( priv , gen , reg ) )
return 0 ;
2018-12-04 08:00:47 +00:00
regmap_fields_read ( gen - > regs [ reg ] , rsnd_mod_id_cmd ( mod ) , & val ) ;
2015-10-22 03:13:06 +00:00
ASoC: rsnd: rsnd_mod_name() handles both name and ID
Current rsnd driver is using "%s[%d]" for mod name and ID,
but, this ID portion might confusable.
For example currently, CTU ID is 0 to 7, but using 00 to 13
(= 00, 01, 02, 03, 10, 11, 12, 13) is very best matching to datasheet.
In the future, we will support BUSIFn, but it will be more complicated
numbering. To avoid future confusable code, this patch modify
rsnd_mod_name() to return understandable name.
To avoid using pointless memory, it uses static char and snprintf,
thus, rsnd_mod_name() user should use it immediately, and shouldn't keep
its pointer.
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
2018-10-30 07:47:50 +00:00
dev_dbg ( dev , " r %s - %-18s (%4d) : %08x \n " ,
rsnd_mod_name ( mod ) ,
2015-11-26 08:43:59 +00:00
rsnd_reg_name ( gen , reg ) , reg , val ) ;
2013-09-23 23:12:27 -07:00
return val ;
}
2018-12-12 16:03:58 +09:00
void rsnd_mod_write ( struct rsnd_mod * mod ,
enum rsnd_reg reg , u32 data )
2013-09-23 23:12:27 -07:00
{
2018-12-12 16:03:58 +09:00
struct rsnd_priv * priv = rsnd_mod_to_priv ( mod ) ;
2014-07-29 00:37:31 -07:00
struct device * dev = rsnd_priv_to_dev ( priv ) ;
2013-09-23 23:12:27 -07:00
struct rsnd_gen * gen = rsnd_priv_to_gen ( priv ) ;
2015-06-16 08:53:11 +00:00
if ( ! rsnd_is_accessible_reg ( priv , gen , reg ) )
return ;
2018-12-04 08:00:47 +00:00
regmap_fields_force_write ( gen - > regs [ reg ] , rsnd_mod_id_cmd ( mod ) , data ) ;
2015-11-26 08:43:59 +00:00
ASoC: rsnd: rsnd_mod_name() handles both name and ID
Current rsnd driver is using "%s[%d]" for mod name and ID,
but, this ID portion might confusable.
For example currently, CTU ID is 0 to 7, but using 00 to 13
(= 00, 01, 02, 03, 10, 11, 12, 13) is very best matching to datasheet.
In the future, we will support BUSIFn, but it will be more complicated
numbering. To avoid future confusable code, this patch modify
rsnd_mod_name() to return understandable name.
To avoid using pointless memory, it uses static char and snprintf,
thus, rsnd_mod_name() user should use it immediately, and shouldn't keep
its pointer.
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
2018-10-30 07:47:50 +00:00
dev_dbg ( dev , " w %s - %-18s (%4d) : %08x \n " ,
rsnd_mod_name ( mod ) ,
2015-11-26 08:43:59 +00:00
rsnd_reg_name ( gen , reg ) , reg , data ) ;
2013-09-23 23:12:27 -07:00
}
2018-12-12 16:03:58 +09:00
void rsnd_mod_bset ( struct rsnd_mod * mod ,
enum rsnd_reg reg , u32 mask , u32 data )
2013-09-23 23:12:27 -07:00
{
2018-12-12 16:03:58 +09:00
struct rsnd_priv * priv = rsnd_mod_to_priv ( mod ) ;
2014-07-30 23:52:50 -07:00
struct device * dev = rsnd_priv_to_dev ( priv ) ;
2013-09-23 23:12:27 -07:00
struct rsnd_gen * gen = rsnd_priv_to_gen ( priv ) ;
2013-11-28 18:43:13 -08:00
if ( ! rsnd_is_accessible_reg ( priv , gen , reg ) )
return ;
2016-02-15 05:26:51 +00:00
regmap_fields_force_update_bits ( gen - > regs [ reg ] ,
2018-12-04 08:00:47 +00:00
rsnd_mod_id_cmd ( mod ) , mask , data ) ;
2015-11-26 08:43:59 +00:00
ASoC: rsnd: rsnd_mod_name() handles both name and ID
Current rsnd driver is using "%s[%d]" for mod name and ID,
but, this ID portion might confusable.
For example currently, CTU ID is 0 to 7, but using 00 to 13
(= 00, 01, 02, 03, 10, 11, 12, 13) is very best matching to datasheet.
In the future, we will support BUSIFn, but it will be more complicated
numbering. To avoid future confusable code, this patch modify
rsnd_mod_name() to return understandable name.
To avoid using pointless memory, it uses static char and snprintf,
thus, rsnd_mod_name() user should use it immediately, and shouldn't keep
its pointer.
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
2018-10-30 07:47:50 +00:00
dev_dbg ( dev , " b %s - %-18s (%4d) : %08x/%08x \n " ,
rsnd_mod_name ( mod ) ,
2015-11-26 08:43:59 +00:00
rsnd_reg_name ( gen , reg ) , reg , data , mask ) ;
2013-09-23 23:12:27 -07:00
}
2015-02-20 10:25:27 +00:00
phys_addr_t rsnd_gen_get_phy_addr ( struct rsnd_priv * priv , int reg_id )
{
struct rsnd_gen * gen = rsnd_priv_to_gen ( priv ) ;
return gen - > res [ reg_id ] ;
}
2015-02-20 10:24:52 +00:00
# define rsnd_gen_regmap_init(priv, id_size, reg_id, name, conf) \
_rsnd_gen_regmap_init ( priv , id_size , reg_id , name , conf , ARRAY_SIZE ( conf ) )
2014-07-29 00:37:31 -07:00
static int _rsnd_gen_regmap_init ( struct rsnd_priv * priv ,
int id_size ,
int reg_id ,
2015-02-20 10:24:52 +00:00
const char * name ,
2015-11-26 08:43:59 +00:00
const struct rsnd_regmap_field_conf * conf ,
2014-07-29 00:37:31 -07:00
int conf_size )
2013-11-28 18:43:01 -08:00
{
2014-07-29 00:37:31 -07:00
struct platform_device * pdev = rsnd_priv_to_pdev ( priv ) ;
struct rsnd_gen * gen = rsnd_priv_to_gen ( priv ) ;
2013-11-28 18:43:01 -08:00
struct device * dev = rsnd_priv_to_dev ( priv ) ;
2014-07-29 00:37:31 -07:00
struct resource * res ;
2013-11-28 18:43:01 -08:00
struct regmap_config regc ;
2014-07-29 00:37:31 -07:00
struct regmap_field * regs ;
struct regmap * regmap ;
struct reg_field regf ;
void __iomem * base ;
int i ;
2013-11-28 18:43:01 -08:00
memset ( & regc , 0 , sizeof ( regc ) ) ;
regc . reg_bits = 32 ;
regc . val_bits = 32 ;
2014-07-29 00:37:31 -07:00
regc . reg_stride = 4 ;
2015-03-10 01:25:36 +00:00
regc . name = name ;
2013-11-28 18:43:01 -08:00
2015-02-20 10:24:52 +00:00
res = platform_get_resource_byname ( pdev , IORESOURCE_MEM , name ) ;
if ( ! res )
res = platform_get_resource ( pdev , IORESOURCE_MEM , reg_id ) ;
2014-07-29 00:37:31 -07:00
if ( ! res )
return - ENODEV ;
base = devm_ioremap_resource ( dev , res ) ;
if ( IS_ERR ( base ) )
return PTR_ERR ( base ) ;
2013-11-28 18:43:01 -08:00
2014-07-29 00:37:31 -07:00
regmap = devm_regmap_init_mmio ( dev , base , & regc ) ;
if ( IS_ERR ( regmap ) )
return PTR_ERR ( regmap ) ;
2013-11-28 18:43:13 -08:00
2015-10-22 03:13:27 +00:00
/* RSND_BASE_MAX base */
2014-07-29 00:37:31 -07:00
gen - > base [ reg_id ] = base ;
gen - > regmap [ reg_id ] = regmap ;
2015-02-20 10:25:27 +00:00
gen - > res [ reg_id ] = res - > start ;
2013-11-28 18:43:01 -08:00
2014-07-29 00:37:31 -07:00
for ( i = 0 ; i < conf_size ; i + + ) {
regf . reg = conf [ i ] . reg_offset ;
regf . id_offset = conf [ i ] . id_offset ;
regf . lsb = 0 ;
regf . msb = 31 ;
regf . id_size = id_size ;
regs = devm_regmap_field_alloc ( dev , regmap , regf ) ;
if ( IS_ERR ( regs ) )
return PTR_ERR ( regs ) ;
2015-10-22 03:13:27 +00:00
/* RSND_REG_MAX base */
2014-07-29 00:37:31 -07:00
gen - > regs [ conf [ i ] . idx ] = regs ;
2015-11-26 08:43:59 +00:00
gen - > reg_name [ conf [ i ] . idx ] = conf [ i ] . reg_name ;
2013-11-28 18:43:01 -08:00
}
return 0 ;
}
2013-07-21 21:36:21 -07:00
2013-11-28 18:43:23 -08:00
/*
* Gen2
*/
2015-11-10 05:14:12 +00:00
static int rsnd_gen2_probe ( struct rsnd_priv * priv )
2013-11-28 18:43:45 -08:00
{
2016-06-13 17:39:46 +02:00
static const struct rsnd_regmap_field_conf conf_ssiu [ ] = {
2014-07-29 00:37:31 -07:00
RSND_GEN_S_REG ( SSI_MODE0 , 0x800 ) ,
RSND_GEN_S_REG ( SSI_MODE1 , 0x804 ) ,
2015-12-17 03:00:10 +00:00
RSND_GEN_S_REG ( SSI_MODE2 , 0x808 ) ,
RSND_GEN_S_REG ( SSI_CONTROL , 0x810 ) ,
2016-10-26 04:29:21 +00:00
RSND_GEN_S_REG ( SSI_SYS_STATUS0 , 0x840 ) ,
RSND_GEN_S_REG ( SSI_SYS_STATUS1 , 0x844 ) ,
RSND_GEN_S_REG ( SSI_SYS_STATUS2 , 0x848 ) ,
RSND_GEN_S_REG ( SSI_SYS_STATUS3 , 0x84c ) ,
RSND_GEN_S_REG ( SSI_SYS_STATUS4 , 0x880 ) ,
RSND_GEN_S_REG ( SSI_SYS_STATUS5 , 0x884 ) ,
RSND_GEN_S_REG ( SSI_SYS_STATUS6 , 0x888 ) ,
RSND_GEN_S_REG ( SSI_SYS_STATUS7 , 0x88c ) ,
2020-05-12 17:30:03 +08:00
RSND_GEN_S_REG ( SSI_SYS_INT_ENABLE0 , 0x850 ) ,
RSND_GEN_S_REG ( SSI_SYS_INT_ENABLE1 , 0x854 ) ,
RSND_GEN_S_REG ( SSI_SYS_INT_ENABLE2 , 0x858 ) ,
RSND_GEN_S_REG ( SSI_SYS_INT_ENABLE3 , 0x85c ) ,
RSND_GEN_S_REG ( SSI_SYS_INT_ENABLE4 , 0x890 ) ,
RSND_GEN_S_REG ( SSI_SYS_INT_ENABLE5 , 0x894 ) ,
RSND_GEN_S_REG ( SSI_SYS_INT_ENABLE6 , 0x898 ) ,
RSND_GEN_S_REG ( SSI_SYS_INT_ENABLE7 , 0x89c ) ,
2017-05-18 01:28:22 +00:00
RSND_GEN_S_REG ( HDMI0_SEL , 0x9e0 ) ,
RSND_GEN_S_REG ( HDMI1_SEL , 0x9e4 ) ,
2015-12-17 03:00:10 +00:00
2014-07-29 00:37:31 -07:00
/* FIXME: it needs SSI_MODE2/3 in the future */
2018-09-03 07:08:20 +00:00
RSND_GEN_M_REG ( SSI_BUSIF0_MODE , 0x0 , 0x80 ) ,
RSND_GEN_M_REG ( SSI_BUSIF0_ADINR , 0x4 , 0x80 ) ,
RSND_GEN_M_REG ( SSI_BUSIF0_DALIGN , 0x8 , 0x80 ) ,
2018-09-06 03:21:16 +00:00
RSND_GEN_M_REG ( SSI_BUSIF1_MODE , 0x20 , 0x80 ) ,
RSND_GEN_M_REG ( SSI_BUSIF1_ADINR , 0x24 , 0x80 ) ,
RSND_GEN_M_REG ( SSI_BUSIF1_DALIGN , 0x28 , 0x80 ) ,
RSND_GEN_M_REG ( SSI_BUSIF2_MODE , 0x40 , 0x80 ) ,
RSND_GEN_M_REG ( SSI_BUSIF2_ADINR , 0x44 , 0x80 ) ,
RSND_GEN_M_REG ( SSI_BUSIF2_DALIGN , 0x48 , 0x80 ) ,
RSND_GEN_M_REG ( SSI_BUSIF3_MODE , 0x60 , 0x80 ) ,
RSND_GEN_M_REG ( SSI_BUSIF3_ADINR , 0x64 , 0x80 ) ,
RSND_GEN_M_REG ( SSI_BUSIF3_DALIGN , 0x68 , 0x80 ) ,
RSND_GEN_M_REG ( SSI_BUSIF4_MODE , 0x500 , 0x80 ) ,
RSND_GEN_M_REG ( SSI_BUSIF4_ADINR , 0x504 , 0x80 ) ,
RSND_GEN_M_REG ( SSI_BUSIF4_DALIGN , 0x508 , 0x80 ) ,
RSND_GEN_M_REG ( SSI_BUSIF5_MODE , 0x520 , 0x80 ) ,
RSND_GEN_M_REG ( SSI_BUSIF5_ADINR , 0x524 , 0x80 ) ,
RSND_GEN_M_REG ( SSI_BUSIF5_DALIGN , 0x528 , 0x80 ) ,
RSND_GEN_M_REG ( SSI_BUSIF6_MODE , 0x540 , 0x80 ) ,
RSND_GEN_M_REG ( SSI_BUSIF6_ADINR , 0x544 , 0x80 ) ,
RSND_GEN_M_REG ( SSI_BUSIF6_DALIGN , 0x548 , 0x80 ) ,
RSND_GEN_M_REG ( SSI_BUSIF7_MODE , 0x560 , 0x80 ) ,
RSND_GEN_M_REG ( SSI_BUSIF7_ADINR , 0x564 , 0x80 ) ,
RSND_GEN_M_REG ( SSI_BUSIF7_DALIGN , 0x568 , 0x80 ) ,
RSND_GEN_M_REG ( SSI_MODE , 0xc , 0x80 ) ,
RSND_GEN_M_REG ( SSI_CTRL , 0x10 , 0x80 ) ,
RSND_GEN_M_REG ( SSI_INT_ENABLE , 0x18 , 0x80 ) ,
2019-02-25 12:14:20 +01:00
RSND_GEN_S_REG ( SSI9_BUSIF0_MODE , 0x48c ) ,
RSND_GEN_S_REG ( SSI9_BUSIF0_ADINR , 0x484 ) ,
RSND_GEN_S_REG ( SSI9_BUSIF0_DALIGN , 0x488 ) ,
RSND_GEN_S_REG ( SSI9_BUSIF1_MODE , 0x4a0 ) ,
RSND_GEN_S_REG ( SSI9_BUSIF1_ADINR , 0x4a4 ) ,
RSND_GEN_S_REG ( SSI9_BUSIF1_DALIGN , 0x4a8 ) ,
RSND_GEN_S_REG ( SSI9_BUSIF2_MODE , 0x4c0 ) ,
RSND_GEN_S_REG ( SSI9_BUSIF2_ADINR , 0x4c4 ) ,
RSND_GEN_S_REG ( SSI9_BUSIF2_DALIGN , 0x4c8 ) ,
RSND_GEN_S_REG ( SSI9_BUSIF3_MODE , 0x4e0 ) ,
RSND_GEN_S_REG ( SSI9_BUSIF3_ADINR , 0x4e4 ) ,
RSND_GEN_S_REG ( SSI9_BUSIF3_DALIGN , 0x4e8 ) ,
RSND_GEN_S_REG ( SSI9_BUSIF4_MODE , 0xd80 ) ,
RSND_GEN_S_REG ( SSI9_BUSIF4_ADINR , 0xd84 ) ,
RSND_GEN_S_REG ( SSI9_BUSIF4_DALIGN , 0xd88 ) ,
RSND_GEN_S_REG ( SSI9_BUSIF5_MODE , 0xda0 ) ,
RSND_GEN_S_REG ( SSI9_BUSIF5_ADINR , 0xda4 ) ,
RSND_GEN_S_REG ( SSI9_BUSIF5_DALIGN , 0xda8 ) ,
RSND_GEN_S_REG ( SSI9_BUSIF6_MODE , 0xdc0 ) ,
RSND_GEN_S_REG ( SSI9_BUSIF6_ADINR , 0xdc4 ) ,
RSND_GEN_S_REG ( SSI9_BUSIF6_DALIGN , 0xdc8 ) ,
RSND_GEN_S_REG ( SSI9_BUSIF7_MODE , 0xde0 ) ,
RSND_GEN_S_REG ( SSI9_BUSIF7_ADINR , 0xde4 ) ,
RSND_GEN_S_REG ( SSI9_BUSIF7_DALIGN , 0xde8 ) ,
2014-07-29 00:37:31 -07:00
} ;
2015-11-30 08:50:08 +00:00
2016-06-13 17:39:46 +02:00
static const struct rsnd_regmap_field_conf conf_scu [ ] = {
2015-11-30 08:50:08 +00:00
RSND_GEN_M_REG ( SRC_I_BUSIF_MODE , 0x0 , 0x20 ) ,
RSND_GEN_M_REG ( SRC_O_BUSIF_MODE , 0x4 , 0x20 ) ,
2015-07-15 07:14:47 +00:00
RSND_GEN_M_REG ( SRC_BUSIF_DALIGN , 0x8 , 0x20 ) ,
2014-07-29 00:37:31 -07:00
RSND_GEN_M_REG ( SRC_ROUTE_MODE0 , 0xc , 0x20 ) ,
RSND_GEN_M_REG ( SRC_CTRL , 0x10 , 0x20 ) ,
2015-01-08 01:52:36 +00:00
RSND_GEN_M_REG ( SRC_INT_ENABLE0 , 0x18 , 0x20 ) ,
2017-05-16 01:51:41 +00:00
RSND_GEN_M_REG ( CMD_BUSIF_MODE , 0x184 , 0x20 ) ,
2015-12-08 05:38:23 +00:00
RSND_GEN_M_REG ( CMD_BUSIF_DALIGN , 0x188 , 0x20 ) ,
2014-07-29 00:37:31 -07:00
RSND_GEN_M_REG ( CMD_ROUTE_SLCT , 0x18c , 0x20 ) ,
RSND_GEN_M_REG ( CMD_CTRL , 0x190 , 0x20 ) ,
2015-01-08 01:52:36 +00:00
RSND_GEN_S_REG ( SCU_SYS_STATUS0 , 0x1c8 ) ,
RSND_GEN_S_REG ( SCU_SYS_INT_EN0 , 0x1cc ) ,
RSND_GEN_S_REG ( SCU_SYS_STATUS1 , 0x1d0 ) ,
2015-11-05 23:53:03 +00:00
RSND_GEN_S_REG ( SCU_SYS_INT_EN1 , 0x1d4 ) ,
2014-07-29 00:37:31 -07:00
RSND_GEN_M_REG ( SRC_SWRSR , 0x200 , 0x40 ) ,
RSND_GEN_M_REG ( SRC_SRCIR , 0x204 , 0x40 ) ,
RSND_GEN_M_REG ( SRC_ADINR , 0x214 , 0x40 ) ,
RSND_GEN_M_REG ( SRC_IFSCR , 0x21c , 0x40 ) ,
RSND_GEN_M_REG ( SRC_IFSVR , 0x220 , 0x40 ) ,
RSND_GEN_M_REG ( SRC_SRCCR , 0x224 , 0x40 ) ,
RSND_GEN_M_REG ( SRC_BSDSR , 0x22c , 0x40 ) ,
RSND_GEN_M_REG ( SRC_BSISR , 0x238 , 0x40 ) ,
2016-01-21 01:58:53 +00:00
RSND_GEN_M_REG ( CTU_SWRSR , 0x500 , 0x100 ) ,
2015-07-15 07:17:17 +00:00
RSND_GEN_M_REG ( CTU_CTUIR , 0x504 , 0x100 ) ,
RSND_GEN_M_REG ( CTU_ADINR , 0x508 , 0x100 ) ,
2016-01-21 01:59:33 +00:00
RSND_GEN_M_REG ( CTU_CPMDR , 0x510 , 0x100 ) ,
RSND_GEN_M_REG ( CTU_SCMDR , 0x514 , 0x100 ) ,
RSND_GEN_M_REG ( CTU_SV00R , 0x518 , 0x100 ) ,
RSND_GEN_M_REG ( CTU_SV01R , 0x51c , 0x100 ) ,
RSND_GEN_M_REG ( CTU_SV02R , 0x520 , 0x100 ) ,
RSND_GEN_M_REG ( CTU_SV03R , 0x524 , 0x100 ) ,
RSND_GEN_M_REG ( CTU_SV04R , 0x528 , 0x100 ) ,
RSND_GEN_M_REG ( CTU_SV05R , 0x52c , 0x100 ) ,
RSND_GEN_M_REG ( CTU_SV06R , 0x530 , 0x100 ) ,
RSND_GEN_M_REG ( CTU_SV07R , 0x534 , 0x100 ) ,
RSND_GEN_M_REG ( CTU_SV10R , 0x538 , 0x100 ) ,
RSND_GEN_M_REG ( CTU_SV11R , 0x53c , 0x100 ) ,
RSND_GEN_M_REG ( CTU_SV12R , 0x540 , 0x100 ) ,
RSND_GEN_M_REG ( CTU_SV13R , 0x544 , 0x100 ) ,
RSND_GEN_M_REG ( CTU_SV14R , 0x548 , 0x100 ) ,
RSND_GEN_M_REG ( CTU_SV15R , 0x54c , 0x100 ) ,
RSND_GEN_M_REG ( CTU_SV16R , 0x550 , 0x100 ) ,
RSND_GEN_M_REG ( CTU_SV17R , 0x554 , 0x100 ) ,
RSND_GEN_M_REG ( CTU_SV20R , 0x558 , 0x100 ) ,
RSND_GEN_M_REG ( CTU_SV21R , 0x55c , 0x100 ) ,
RSND_GEN_M_REG ( CTU_SV22R , 0x560 , 0x100 ) ,
RSND_GEN_M_REG ( CTU_SV23R , 0x564 , 0x100 ) ,
RSND_GEN_M_REG ( CTU_SV24R , 0x568 , 0x100 ) ,
RSND_GEN_M_REG ( CTU_SV25R , 0x56c , 0x100 ) ,
RSND_GEN_M_REG ( CTU_SV26R , 0x570 , 0x100 ) ,
RSND_GEN_M_REG ( CTU_SV27R , 0x574 , 0x100 ) ,
RSND_GEN_M_REG ( CTU_SV30R , 0x578 , 0x100 ) ,
RSND_GEN_M_REG ( CTU_SV31R , 0x57c , 0x100 ) ,
RSND_GEN_M_REG ( CTU_SV32R , 0x580 , 0x100 ) ,
RSND_GEN_M_REG ( CTU_SV33R , 0x584 , 0x100 ) ,
RSND_GEN_M_REG ( CTU_SV34R , 0x588 , 0x100 ) ,
RSND_GEN_M_REG ( CTU_SV35R , 0x58c , 0x100 ) ,
RSND_GEN_M_REG ( CTU_SV36R , 0x590 , 0x100 ) ,
RSND_GEN_M_REG ( CTU_SV37R , 0x594 , 0x100 ) ,
2015-07-15 07:17:36 +00:00
RSND_GEN_M_REG ( MIX_SWRSR , 0xd00 , 0x40 ) ,
RSND_GEN_M_REG ( MIX_MIXIR , 0xd04 , 0x40 ) ,
RSND_GEN_M_REG ( MIX_ADINR , 0xd08 , 0x40 ) ,
RSND_GEN_M_REG ( MIX_MIXMR , 0xd10 , 0x40 ) ,
RSND_GEN_M_REG ( MIX_MVPDR , 0xd14 , 0x40 ) ,
RSND_GEN_M_REG ( MIX_MDBAR , 0xd18 , 0x40 ) ,
RSND_GEN_M_REG ( MIX_MDBBR , 0xd1c , 0x40 ) ,
RSND_GEN_M_REG ( MIX_MDBCR , 0xd20 , 0x40 ) ,
RSND_GEN_M_REG ( MIX_MDBDR , 0xd24 , 0x40 ) ,
RSND_GEN_M_REG ( MIX_MDBER , 0xd28 , 0x40 ) ,
2014-07-29 00:37:31 -07:00
RSND_GEN_M_REG ( DVC_SWRSR , 0xe00 , 0x100 ) ,
RSND_GEN_M_REG ( DVC_DVUIR , 0xe04 , 0x100 ) ,
RSND_GEN_M_REG ( DVC_ADINR , 0xe08 , 0x100 ) ,
RSND_GEN_M_REG ( DVC_DVUCR , 0xe10 , 0x100 ) ,
RSND_GEN_M_REG ( DVC_ZCMCR , 0xe14 , 0x100 ) ,
2014-11-09 19:52:06 -08:00
RSND_GEN_M_REG ( DVC_VRCTR , 0xe18 , 0x100 ) ,
RSND_GEN_M_REG ( DVC_VRPDR , 0xe1c , 0x100 ) ,
RSND_GEN_M_REG ( DVC_VRDBR , 0xe20 , 0x100 ) ,
2014-07-29 00:37:31 -07:00
RSND_GEN_M_REG ( DVC_VOL0R , 0xe28 , 0x100 ) ,
RSND_GEN_M_REG ( DVC_VOL1R , 0xe2c , 0x100 ) ,
2015-11-30 08:53:44 +00:00
RSND_GEN_M_REG ( DVC_VOL2R , 0xe30 , 0x100 ) ,
RSND_GEN_M_REG ( DVC_VOL3R , 0xe34 , 0x100 ) ,
RSND_GEN_M_REG ( DVC_VOL4R , 0xe38 , 0x100 ) ,
RSND_GEN_M_REG ( DVC_VOL5R , 0xe3c , 0x100 ) ,
RSND_GEN_M_REG ( DVC_VOL6R , 0xe40 , 0x100 ) ,
RSND_GEN_M_REG ( DVC_VOL7R , 0xe44 , 0x100 ) ,
2014-07-29 00:37:31 -07:00
RSND_GEN_M_REG ( DVC_DVUER , 0xe48 , 0x100 ) ,
} ;
2016-06-13 17:39:46 +02:00
static const struct rsnd_regmap_field_conf conf_adg [ ] = {
2014-07-29 00:37:31 -07:00
RSND_GEN_S_REG ( BRRA , 0x00 ) ,
RSND_GEN_S_REG ( BRRB , 0x04 ) ,
2016-10-28 04:12:40 +00:00
RSND_GEN_S_REG ( BRGCKR , 0x08 ) ,
2014-07-29 00:37:31 -07:00
RSND_GEN_S_REG ( AUDIO_CLK_SEL0 , 0x0c ) ,
RSND_GEN_S_REG ( AUDIO_CLK_SEL1 , 0x10 ) ,
RSND_GEN_S_REG ( AUDIO_CLK_SEL2 , 0x14 ) ,
RSND_GEN_S_REG ( DIV_EN , 0x30 ) ,
RSND_GEN_S_REG ( SRCIN_TIMSEL0 , 0x34 ) ,
RSND_GEN_S_REG ( SRCIN_TIMSEL1 , 0x38 ) ,
RSND_GEN_S_REG ( SRCIN_TIMSEL2 , 0x3c ) ,
RSND_GEN_S_REG ( SRCIN_TIMSEL3 , 0x40 ) ,
RSND_GEN_S_REG ( SRCIN_TIMSEL4 , 0x44 ) ,
RSND_GEN_S_REG ( SRCOUT_TIMSEL0 , 0x48 ) ,
RSND_GEN_S_REG ( SRCOUT_TIMSEL1 , 0x4c ) ,
RSND_GEN_S_REG ( SRCOUT_TIMSEL2 , 0x50 ) ,
RSND_GEN_S_REG ( SRCOUT_TIMSEL3 , 0x54 ) ,
RSND_GEN_S_REG ( SRCOUT_TIMSEL4 , 0x58 ) ,
RSND_GEN_S_REG ( CMDOUT_TIMSEL , 0x5c ) ,
} ;
2016-06-13 17:39:46 +02:00
static const struct rsnd_regmap_field_conf conf_ssi [ ] = {
2014-07-29 00:37:31 -07:00
RSND_GEN_M_REG ( SSICR , 0x00 , 0x40 ) ,
RSND_GEN_M_REG ( SSISR , 0x04 , 0x40 ) ,
RSND_GEN_M_REG ( SSITDR , 0x08 , 0x40 ) ,
RSND_GEN_M_REG ( SSIRDR , 0x0c , 0x40 ) ,
RSND_GEN_M_REG ( SSIWSR , 0x20 , 0x40 ) ,
} ;
int ret_ssiu ;
int ret_scu ;
int ret_adg ;
int ret_ssi ;
2015-02-20 10:24:52 +00:00
ret_ssiu = rsnd_gen_regmap_init ( priv , 10 , RSND_GEN2_SSIU , " ssiu " , conf_ssiu ) ;
ret_scu = rsnd_gen_regmap_init ( priv , 10 , RSND_GEN2_SCU , " scu " , conf_scu ) ;
ret_adg = rsnd_gen_regmap_init ( priv , 10 , RSND_GEN2_ADG , " adg " , conf_adg ) ;
ret_ssi = rsnd_gen_regmap_init ( priv , 10 , RSND_GEN2_SSI , " ssi " , conf_ssi ) ;
2014-07-29 00:37:31 -07:00
if ( ret_ssiu < 0 | |
ret_scu < 0 | |
ret_adg < 0 | |
ret_ssi < 0 )
return ret_ssiu | ret_scu | ret_adg | ret_ssi ;
2013-11-28 18:43:45 -08:00
return 0 ;
}
2013-11-28 18:43:23 -08:00
/*
* Gen1
*/
2015-11-10 05:14:12 +00:00
static int rsnd_gen1_probe ( struct rsnd_priv * priv )
2013-07-21 21:36:21 -07:00
{
2016-06-13 17:39:46 +02:00
static const struct rsnd_regmap_field_conf conf_adg [ ] = {
2014-07-29 00:37:31 -07:00
RSND_GEN_S_REG ( BRRA , 0x00 ) ,
RSND_GEN_S_REG ( BRRB , 0x04 ) ,
2016-10-28 04:12:40 +00:00
RSND_GEN_S_REG ( BRGCKR , 0x08 ) ,
2014-07-29 00:37:31 -07:00
RSND_GEN_S_REG ( AUDIO_CLK_SEL0 , 0x0c ) ,
RSND_GEN_S_REG ( AUDIO_CLK_SEL1 , 0x10 ) ,
} ;
2016-06-13 17:39:46 +02:00
static const struct rsnd_regmap_field_conf conf_ssi [ ] = {
2014-07-29 00:37:31 -07:00
RSND_GEN_M_REG ( SSICR , 0x00 , 0x40 ) ,
RSND_GEN_M_REG ( SSISR , 0x04 , 0x40 ) ,
RSND_GEN_M_REG ( SSITDR , 0x08 , 0x40 ) ,
RSND_GEN_M_REG ( SSIRDR , 0x0c , 0x40 ) ,
RSND_GEN_M_REG ( SSIWSR , 0x20 , 0x40 ) ,
} ;
int ret_adg ;
int ret_ssi ;
2013-07-21 21:36:35 -07:00
2015-02-20 10:24:52 +00:00
ret_adg = rsnd_gen_regmap_init ( priv , 9 , RSND_GEN1_ADG , " adg " , conf_adg ) ;
ret_ssi = rsnd_gen_regmap_init ( priv , 9 , RSND_GEN1_SSI , " ssi " , conf_ssi ) ;
2015-11-10 05:09:52 +00:00
if ( ret_adg < 0 | |
2014-07-29 00:37:31 -07:00
ret_ssi < 0 )
2015-11-10 05:09:52 +00:00
return ret_adg | ret_ssi ;
2013-07-21 21:36:35 -07:00
2013-07-21 21:36:21 -07:00
return 0 ;
}
/*
* Gen
*/
2015-11-10 05:14:12 +00:00
int rsnd_gen_probe ( struct rsnd_priv * priv )
2013-07-21 21:36:21 -07:00
{
struct device * dev = rsnd_priv_to_dev ( priv ) ;
struct rsnd_gen * gen ;
2013-11-28 18:43:34 -08:00
int ret ;
2013-07-21 21:36:21 -07:00
gen = devm_kzalloc ( dev , sizeof ( * gen ) , GFP_KERNEL ) ;
2017-08-10 17:13:19 +02:00
if ( ! gen )
2013-07-21 21:36:21 -07:00
return - ENOMEM ;
2013-11-28 18:43:34 -08:00
priv - > gen = gen ;
2013-09-01 20:31:16 -07:00
2013-11-28 18:43:45 -08:00
ret = - ENODEV ;
if ( rsnd_is_gen1 ( priv ) )
2015-11-10 05:14:12 +00:00
ret = rsnd_gen1_probe ( priv ) ;
2018-04-11 02:10:29 +00:00
else if ( rsnd_is_gen2 ( priv ) | |
rsnd_is_gen3 ( priv ) )
2015-11-10 05:14:12 +00:00
ret = rsnd_gen2_probe ( priv ) ;
2013-11-28 18:43:45 -08:00
if ( ret < 0 )
2013-09-01 20:31:16 -07:00
dev_err ( dev , " unknown generation R-Car sound device \n " ) ;
2013-11-28 18:43:34 -08:00
return ret ;
2013-07-21 21:36:21 -07:00
}