2019-03-18 18:57:24 +03:00
// SPDX-License-Identifier: GPL-2.0+
2013-07-29 21:00:43 +04:00
/*
2019-03-18 18:57:24 +03:00
* Device access for Dialog DA9063 modules
2013-07-29 21:00:43 +04:00
*
* Copyright 2012 Dialog Semiconductors Ltd .
* Copyright 2013 Philipp Zabel , Pengutronix
*
2016-08-08 16:16:11 +03:00
* Author : Krystian Garbaciak , Dialog Semiconductor
* Author : Michal Hajduk , Dialog Semiconductor
2013-07-29 21:00:43 +04:00
*
*/
# include <linux/kernel.h>
# include <linux/module.h>
# include <linux/init.h>
# include <linux/slab.h>
# include <linux/device.h>
# include <linux/delay.h>
# include <linux/interrupt.h>
# include <linux/mutex.h>
# include <linux/mfd/core.h>
# include <linux/regmap.h>
# include <linux/mfd/da9063/core.h>
# include <linux/mfd/da9063/registers.h>
# include <linux/proc_fs.h>
# include <linux/kthread.h>
# include <linux/uaccess.h>
2020-09-22 22:26:52 +03:00
static const struct resource da9063_regulators_resources [ ] = {
2013-07-29 21:00:44 +04:00
{
. name = " LDO_LIM " ,
. start = DA9063_IRQ_LDO_LIM ,
. end = DA9063_IRQ_LDO_LIM ,
. flags = IORESOURCE_IRQ ,
} ,
} ;
2020-09-22 22:26:52 +03:00
static const struct resource da9063_rtc_resources [ ] = {
2013-07-29 21:00:44 +04:00
{
. name = " ALARM " ,
. start = DA9063_IRQ_ALARM ,
. end = DA9063_IRQ_ALARM ,
. flags = IORESOURCE_IRQ ,
} ,
{
. name = " TICK " ,
. start = DA9063_IRQ_TICK ,
. end = DA9063_IRQ_TICK ,
. flags = IORESOURCE_IRQ ,
}
} ;
2020-09-22 22:26:52 +03:00
static const struct resource da9063_onkey_resources [ ] = {
2013-07-29 21:00:44 +04:00
{
2015-05-19 13:32:45 +03:00
. name = " ONKEY " ,
2013-07-29 21:00:44 +04:00
. start = DA9063_IRQ_ONKEY ,
. end = DA9063_IRQ_ONKEY ,
. flags = IORESOURCE_IRQ ,
} ,
} ;
2020-09-22 22:26:52 +03:00
static const struct resource da9063_hwmon_resources [ ] = {
2013-07-29 21:00:44 +04:00
{
. start = DA9063_IRQ_ADC_RDY ,
. end = DA9063_IRQ_ADC_RDY ,
. flags = IORESOURCE_IRQ ,
} ,
} ;
2018-06-11 14:58:49 +03:00
static const struct mfd_cell da9063_common_devs [ ] = {
2013-07-29 21:00:43 +04:00
{
. name = DA9063_DRVNAME_REGULATORS ,
2013-07-29 21:00:44 +04:00
. num_resources = ARRAY_SIZE ( da9063_regulators_resources ) ,
. resources = da9063_regulators_resources ,
2013-07-29 21:00:43 +04:00
} ,
{
. name = DA9063_DRVNAME_LEDS ,
} ,
{
. name = DA9063_DRVNAME_WATCHDOG ,
2015-01-20 16:54:25 +03:00
. of_compatible = " dlg,da9063-watchdog " ,
2013-07-29 21:00:43 +04:00
} ,
{
. name = DA9063_DRVNAME_HWMON ,
2013-07-29 21:00:44 +04:00
. num_resources = ARRAY_SIZE ( da9063_hwmon_resources ) ,
. resources = da9063_hwmon_resources ,
2013-07-29 21:00:43 +04:00
} ,
{
. name = DA9063_DRVNAME_ONKEY ,
2013-07-29 21:00:44 +04:00
. num_resources = ARRAY_SIZE ( da9063_onkey_resources ) ,
. resources = da9063_onkey_resources ,
2015-05-19 13:32:45 +03:00
. of_compatible = " dlg,da9063-onkey " ,
2013-07-29 21:00:43 +04:00
} ,
2018-06-11 14:58:49 +03:00
{
. name = DA9063_DRVNAME_VIBRATION ,
} ,
} ;
/* Only present on DA9063 , not on DA9063L */
static const struct mfd_cell da9063_devs [ ] = {
2013-07-29 21:00:43 +04:00
{
. name = DA9063_DRVNAME_RTC ,
2013-07-29 21:00:44 +04:00
. num_resources = ARRAY_SIZE ( da9063_rtc_resources ) ,
. resources = da9063_rtc_resources ,
2015-01-20 16:54:25 +03:00
. of_compatible = " dlg,da9063-rtc " ,
2013-07-29 21:00:43 +04:00
} ,
} ;
2015-05-19 13:32:45 +03:00
static int da9063_clear_fault_log ( struct da9063 * da9063 )
{
int ret = 0 ;
int fault_log = 0 ;
ret = regmap_read ( da9063 - > regmap , DA9063_REG_FAULT_LOG , & fault_log ) ;
if ( ret < 0 ) {
dev_err ( da9063 - > dev , " Cannot read FAULT_LOG. \n " ) ;
return - EIO ;
}
if ( fault_log ) {
if ( fault_log & DA9063_TWD_ERROR )
dev_dbg ( da9063 - > dev ,
" Fault log entry detected: DA9063_TWD_ERROR \n " ) ;
if ( fault_log & DA9063_POR )
dev_dbg ( da9063 - > dev ,
" Fault log entry detected: DA9063_POR \n " ) ;
if ( fault_log & DA9063_VDD_FAULT )
dev_dbg ( da9063 - > dev ,
" Fault log entry detected: DA9063_VDD_FAULT \n " ) ;
if ( fault_log & DA9063_VDD_START )
dev_dbg ( da9063 - > dev ,
" Fault log entry detected: DA9063_VDD_START \n " ) ;
if ( fault_log & DA9063_TEMP_CRIT )
dev_dbg ( da9063 - > dev ,
" Fault log entry detected: DA9063_TEMP_CRIT \n " ) ;
if ( fault_log & DA9063_KEY_RESET )
dev_dbg ( da9063 - > dev ,
" Fault log entry detected: DA9063_KEY_RESET \n " ) ;
if ( fault_log & DA9063_NSHUTDOWN )
dev_dbg ( da9063 - > dev ,
" Fault log entry detected: DA9063_NSHUTDOWN \n " ) ;
if ( fault_log & DA9063_WAIT_SHUT )
dev_dbg ( da9063 - > dev ,
" Fault log entry detected: DA9063_WAIT_SHUT \n " ) ;
}
ret = regmap_write ( da9063 - > regmap ,
DA9063_REG_FAULT_LOG ,
fault_log ) ;
if ( ret < 0 )
dev_err ( da9063 - > dev ,
" Cannot reset FAULT_LOG values %d \n " , ret ) ;
return ret ;
}
2013-07-29 21:00:43 +04:00
int da9063_device_init ( struct da9063 * da9063 , unsigned int irq )
{
int ret ;
2015-05-19 13:32:45 +03:00
ret = da9063_clear_fault_log ( da9063 ) ;
if ( ret < 0 )
dev_err ( da9063 - > dev , " Cannot clear fault log \n " ) ;
2019-03-18 18:47:55 +03:00
da9063 - > flags = 0 ;
da9063 - > irq_base = - 1 ;
2013-07-29 21:00:43 +04:00
da9063 - > chip_irq = irq ;
2013-07-29 21:00:44 +04:00
ret = da9063_irq_init ( da9063 ) ;
if ( ret ) {
dev_err ( da9063 - > dev , " Cannot initialize interrupts. \n " ) ;
return ret ;
}
2014-11-21 18:29:07 +03:00
da9063 - > irq_base = regmap_irq_chip_get_base ( da9063 - > regmap_irq ) ;
2018-06-11 14:58:42 +03:00
ret = devm_mfd_add_devices ( da9063 - > dev , PLATFORM_DEVID_NONE ,
2018-06-11 14:58:49 +03:00
da9063_common_devs ,
ARRAY_SIZE ( da9063_common_devs ) ,
2018-06-11 14:58:42 +03:00
NULL , da9063 - > irq_base , NULL ) ;
2018-06-11 14:58:49 +03:00
if ( ret ) {
dev_err ( da9063 - > dev , " Failed to add child devices \n " ) ;
return ret ;
}
if ( da9063 - > type = = PMIC_TYPE_DA9063 ) {
ret = devm_mfd_add_devices ( da9063 - > dev , PLATFORM_DEVID_NONE ,
da9063_devs , ARRAY_SIZE ( da9063_devs ) ,
NULL , da9063 - > irq_base , NULL ) ;
if ( ret ) {
dev_err ( da9063 - > dev , " Failed to add child devices \n " ) ;
return ret ;
}
}
2013-07-29 21:00:43 +04:00
return ret ;
}
MODULE_DESCRIPTION ( " PMIC driver for Dialog DA9063 " ) ;
2016-08-08 16:16:11 +03:00
MODULE_AUTHOR ( " Krystian Garbaciak " ) ;
MODULE_AUTHOR ( " Michal Hajduk " ) ;
2013-07-29 21:00:43 +04:00
MODULE_LICENSE ( " GPL " ) ;