2019-08-01 22:03:35 +03:00
// SPDX-License-Identifier: GPL-2.0
/*
* Device access for Basin Cove PMIC
*
* Copyright ( c ) 2019 , Intel Corporation .
* Author : Andy Shevchenko < andriy . shevchenko @ linux . intel . com >
*/
# include <linux/acpi.h>
# include <linux/interrupt.h>
# include <linux/mfd/core.h>
# include <linux/mfd/intel_soc_pmic.h>
# include <linux/mfd/intel_soc_pmic_mrfld.h>
# include <linux/module.h>
# include <linux/platform_device.h>
# include <linux/regmap.h>
# include <asm/intel_scu_ipc.h>
/*
* Level 2 IRQs
*
* Firmware on the systems with Basin Cove PMIC services Level 1 IRQs
* without an assistance . Thus , each of the Level 1 IRQ is represented
* as a separate RTE in IOAPIC .
*/
static struct resource irq_level2_resources [ ] = {
DEFINE_RES_IRQ ( 0 ) , /* power button */
DEFINE_RES_IRQ ( 0 ) , /* TMU */
DEFINE_RES_IRQ ( 0 ) , /* thermal */
DEFINE_RES_IRQ ( 0 ) , /* BCU */
DEFINE_RES_IRQ ( 0 ) , /* ADC */
DEFINE_RES_IRQ ( 0 ) , /* charger */
DEFINE_RES_IRQ ( 0 ) , /* GPIO */
} ;
static const struct mfd_cell bcove_dev [ ] = {
{
. name = " mrfld_bcove_pwrbtn " ,
. num_resources = 1 ,
. resources = & irq_level2_resources [ 0 ] ,
} , {
. name = " mrfld_bcove_tmu " ,
. num_resources = 1 ,
. resources = & irq_level2_resources [ 1 ] ,
} , {
. name = " mrfld_bcove_thermal " ,
. num_resources = 1 ,
. resources = & irq_level2_resources [ 2 ] ,
} , {
. name = " mrfld_bcove_bcu " ,
. num_resources = 1 ,
. resources = & irq_level2_resources [ 3 ] ,
} , {
. name = " mrfld_bcove_adc " ,
. num_resources = 1 ,
. resources = & irq_level2_resources [ 4 ] ,
} , {
. name = " mrfld_bcove_charger " ,
. num_resources = 1 ,
. resources = & irq_level2_resources [ 5 ] ,
} , {
. name = " mrfld_bcove_pwrsrc " ,
. num_resources = 1 ,
. resources = & irq_level2_resources [ 5 ] ,
} , {
. name = " mrfld_bcove_gpio " ,
. num_resources = 1 ,
. resources = & irq_level2_resources [ 6 ] ,
} ,
{ . name = " mrfld_bcove_region " , } ,
} ;
static int bcove_ipc_byte_reg_read ( void * context , unsigned int reg ,
unsigned int * val )
{
2020-04-16 11:15:44 +03:00
struct intel_soc_pmic * pmic = context ;
2019-08-01 22:03:35 +03:00
u8 ipc_out ;
int ret ;
2020-04-16 11:15:44 +03:00
ret = intel_scu_ipc_dev_ioread8 ( pmic - > scu , reg , & ipc_out ) ;
2019-08-01 22:03:35 +03:00
if ( ret )
return ret ;
* val = ipc_out ;
return 0 ;
}
static int bcove_ipc_byte_reg_write ( void * context , unsigned int reg ,
unsigned int val )
{
2020-04-16 11:15:44 +03:00
struct intel_soc_pmic * pmic = context ;
2019-08-01 22:03:35 +03:00
u8 ipc_in = val ;
2020-07-27 06:04:07 +03:00
return intel_scu_ipc_dev_iowrite8 ( pmic - > scu , reg , ipc_in ) ;
2019-08-01 22:03:35 +03:00
}
static const struct regmap_config bcove_regmap_config = {
. reg_bits = 16 ,
. val_bits = 8 ,
. max_register = 0xff ,
. reg_write = bcove_ipc_byte_reg_write ,
. reg_read = bcove_ipc_byte_reg_read ,
} ;
static int bcove_probe ( struct platform_device * pdev )
{
struct device * dev = & pdev - > dev ;
struct intel_soc_pmic * pmic ;
unsigned int i ;
int ret ;
pmic = devm_kzalloc ( dev , sizeof ( * pmic ) , GFP_KERNEL ) ;
if ( ! pmic )
return - ENOMEM ;
2020-04-16 11:15:44 +03:00
pmic - > scu = devm_intel_scu_ipc_dev_get ( dev ) ;
if ( ! pmic - > scu )
return - ENOMEM ;
2019-08-01 22:03:35 +03:00
platform_set_drvdata ( pdev , pmic ) ;
pmic - > dev = & pdev - > dev ;
pmic - > regmap = devm_regmap_init ( dev , NULL , pmic , & bcove_regmap_config ) ;
if ( IS_ERR ( pmic - > regmap ) )
return PTR_ERR ( pmic - > regmap ) ;
for ( i = 0 ; i < ARRAY_SIZE ( irq_level2_resources ) ; i + + ) {
ret = platform_get_irq ( pdev , i ) ;
if ( ret < 0 )
return ret ;
irq_level2_resources [ i ] . start = ret ;
irq_level2_resources [ i ] . end = ret ;
}
return devm_mfd_add_devices ( dev , PLATFORM_DEVID_NONE ,
bcove_dev , ARRAY_SIZE ( bcove_dev ) ,
NULL , 0 , NULL ) ;
}
static const struct acpi_device_id bcove_acpi_ids [ ] = {
{ " INTC100E " } ,
{ }
} ;
MODULE_DEVICE_TABLE ( acpi , bcove_acpi_ids ) ;
static struct platform_driver bcove_driver = {
. driver = {
. name = " intel_soc_pmic_mrfld " ,
. acpi_match_table = bcove_acpi_ids ,
} ,
. probe = bcove_probe ,
} ;
module_platform_driver ( bcove_driver ) ;
MODULE_DESCRIPTION ( " IPC driver for Intel SoC Basin Cove PMIC " ) ;
MODULE_LICENSE ( " GPL v2 " ) ;