2019-03-18 18:57:24 +03:00
// SPDX-License-Identifier: GPL-2.0+
/* Interrupt support for Dialog DA9063
2013-07-29 21:00:44 +04:00
*
* Copyright 2012 Dialog Semiconductor Ltd .
* Copyright 2013 Philipp Zabel , Pengutronix
*
2016-08-08 16:16:11 +03:00
* Author : Michal Hajduk , Dialog Semiconductor
2013-07-29 21:00:44 +04:00
*/
# include <linux/kernel.h>
# include <linux/module.h>
# include <linux/irq.h>
# include <linux/mfd/core.h>
# include <linux/interrupt.h>
# include <linux/regmap.h>
# include <linux/mfd/da9063/core.h>
# define DA9063_REG_EVENT_A_OFFSET 0
# define DA9063_REG_EVENT_B_OFFSET 1
# define DA9063_REG_EVENT_C_OFFSET 2
# define DA9063_REG_EVENT_D_OFFSET 3
2015-04-27 15:54:13 +03:00
static const struct regmap_irq da9063_irqs [ ] = {
2013-07-29 21:00:44 +04:00
/* DA9063 event A register */
2018-06-11 14:58:41 +03:00
REGMAP_IRQ_REG ( DA9063_IRQ_ONKEY ,
DA9063_REG_EVENT_A_OFFSET , DA9063_M_ONKEY ) ,
REGMAP_IRQ_REG ( DA9063_IRQ_ALARM ,
DA9063_REG_EVENT_A_OFFSET , DA9063_M_ALARM ) ,
REGMAP_IRQ_REG ( DA9063_IRQ_TICK ,
DA9063_REG_EVENT_A_OFFSET , DA9063_M_TICK ) ,
REGMAP_IRQ_REG ( DA9063_IRQ_ADC_RDY ,
DA9063_REG_EVENT_A_OFFSET , DA9063_M_ADC_RDY ) ,
REGMAP_IRQ_REG ( DA9063_IRQ_SEQ_RDY ,
DA9063_REG_EVENT_A_OFFSET , DA9063_M_SEQ_RDY ) ,
2013-07-29 21:00:44 +04:00
/* DA9063 event B register */
2018-06-11 14:58:41 +03:00
REGMAP_IRQ_REG ( DA9063_IRQ_WAKE ,
DA9063_REG_EVENT_B_OFFSET , DA9063_M_WAKE ) ,
REGMAP_IRQ_REG ( DA9063_IRQ_TEMP ,
DA9063_REG_EVENT_B_OFFSET , DA9063_M_TEMP ) ,
REGMAP_IRQ_REG ( DA9063_IRQ_COMP_1V2 ,
DA9063_REG_EVENT_B_OFFSET , DA9063_M_COMP_1V2 ) ,
REGMAP_IRQ_REG ( DA9063_IRQ_LDO_LIM ,
DA9063_REG_EVENT_B_OFFSET , DA9063_M_LDO_LIM ) ,
REGMAP_IRQ_REG ( DA9063_IRQ_REG_UVOV ,
DA9063_REG_EVENT_B_OFFSET , DA9063_M_UVOV ) ,
REGMAP_IRQ_REG ( DA9063_IRQ_DVC_RDY ,
DA9063_REG_EVENT_B_OFFSET , DA9063_M_DVC_RDY ) ,
REGMAP_IRQ_REG ( DA9063_IRQ_VDD_MON ,
DA9063_REG_EVENT_B_OFFSET , DA9063_M_VDD_MON ) ,
REGMAP_IRQ_REG ( DA9063_IRQ_WARN ,
DA9063_REG_EVENT_B_OFFSET , DA9063_M_VDD_WARN ) ,
2013-07-29 21:00:44 +04:00
/* DA9063 event C register */
2018-06-11 14:58:41 +03:00
REGMAP_IRQ_REG ( DA9063_IRQ_GPI0 ,
DA9063_REG_EVENT_C_OFFSET , DA9063_M_GPI0 ) ,
REGMAP_IRQ_REG ( DA9063_IRQ_GPI1 ,
DA9063_REG_EVENT_C_OFFSET , DA9063_M_GPI1 ) ,
REGMAP_IRQ_REG ( DA9063_IRQ_GPI2 ,
DA9063_REG_EVENT_C_OFFSET , DA9063_M_GPI2 ) ,
REGMAP_IRQ_REG ( DA9063_IRQ_GPI3 ,
DA9063_REG_EVENT_C_OFFSET , DA9063_M_GPI3 ) ,
REGMAP_IRQ_REG ( DA9063_IRQ_GPI4 ,
DA9063_REG_EVENT_C_OFFSET , DA9063_M_GPI4 ) ,
REGMAP_IRQ_REG ( DA9063_IRQ_GPI5 ,
DA9063_REG_EVENT_C_OFFSET , DA9063_M_GPI5 ) ,
REGMAP_IRQ_REG ( DA9063_IRQ_GPI6 ,
DA9063_REG_EVENT_C_OFFSET , DA9063_M_GPI6 ) ,
REGMAP_IRQ_REG ( DA9063_IRQ_GPI7 ,
DA9063_REG_EVENT_C_OFFSET , DA9063_M_GPI7 ) ,
2013-07-29 21:00:44 +04:00
/* DA9063 event D register */
2018-06-11 14:58:41 +03:00
REGMAP_IRQ_REG ( DA9063_IRQ_GPI8 ,
DA9063_REG_EVENT_D_OFFSET , DA9063_M_GPI8 ) ,
REGMAP_IRQ_REG ( DA9063_IRQ_GPI9 ,
DA9063_REG_EVENT_D_OFFSET , DA9063_M_GPI9 ) ,
REGMAP_IRQ_REG ( DA9063_IRQ_GPI10 ,
DA9063_REG_EVENT_D_OFFSET , DA9063_M_GPI10 ) ,
REGMAP_IRQ_REG ( DA9063_IRQ_GPI11 ,
DA9063_REG_EVENT_D_OFFSET , DA9063_M_GPI11 ) ,
REGMAP_IRQ_REG ( DA9063_IRQ_GPI12 ,
DA9063_REG_EVENT_D_OFFSET , DA9063_M_GPI12 ) ,
REGMAP_IRQ_REG ( DA9063_IRQ_GPI13 ,
DA9063_REG_EVENT_D_OFFSET , DA9063_M_GPI13 ) ,
REGMAP_IRQ_REG ( DA9063_IRQ_GPI14 ,
DA9063_REG_EVENT_D_OFFSET , DA9063_M_GPI14 ) ,
REGMAP_IRQ_REG ( DA9063_IRQ_GPI15 ,
DA9063_REG_EVENT_D_OFFSET , DA9063_M_GPI15 ) ,
2013-07-29 21:00:44 +04:00
} ;
2015-04-27 15:54:13 +03:00
static const struct regmap_irq_chip da9063_irq_chip = {
2013-07-29 21:00:44 +04:00
. name = " da9063-irq " ,
. irqs = da9063_irqs ,
2018-06-11 14:58:43 +03:00
. num_irqs = ARRAY_SIZE ( da9063_irqs ) ,
2013-07-29 21:00:44 +04:00
. num_regs = 4 ,
. status_base = DA9063_REG_EVENT_A ,
. mask_base = DA9063_REG_IRQ_MASK_A ,
. ack_base = DA9063_REG_EVENT_A ,
. init_ack_masked = true ,
} ;
2018-06-11 14:58:48 +03:00
static const struct regmap_irq da9063l_irqs [ ] = {
/* DA9063 event A register */
REGMAP_IRQ_REG ( DA9063_IRQ_ONKEY ,
DA9063_REG_EVENT_A_OFFSET , DA9063_M_ONKEY ) ,
REGMAP_IRQ_REG ( DA9063_IRQ_ADC_RDY ,
DA9063_REG_EVENT_A_OFFSET , DA9063_M_ADC_RDY ) ,
REGMAP_IRQ_REG ( DA9063_IRQ_SEQ_RDY ,
DA9063_REG_EVENT_A_OFFSET , DA9063_M_SEQ_RDY ) ,
/* DA9063 event B register */
REGMAP_IRQ_REG ( DA9063_IRQ_WAKE ,
DA9063_REG_EVENT_B_OFFSET , DA9063_M_WAKE ) ,
REGMAP_IRQ_REG ( DA9063_IRQ_TEMP ,
DA9063_REG_EVENT_B_OFFSET , DA9063_M_TEMP ) ,
REGMAP_IRQ_REG ( DA9063_IRQ_COMP_1V2 ,
DA9063_REG_EVENT_B_OFFSET , DA9063_M_COMP_1V2 ) ,
REGMAP_IRQ_REG ( DA9063_IRQ_LDO_LIM ,
DA9063_REG_EVENT_B_OFFSET , DA9063_M_LDO_LIM ) ,
REGMAP_IRQ_REG ( DA9063_IRQ_REG_UVOV ,
DA9063_REG_EVENT_B_OFFSET , DA9063_M_UVOV ) ,
REGMAP_IRQ_REG ( DA9063_IRQ_DVC_RDY ,
DA9063_REG_EVENT_B_OFFSET , DA9063_M_DVC_RDY ) ,
REGMAP_IRQ_REG ( DA9063_IRQ_VDD_MON ,
DA9063_REG_EVENT_B_OFFSET , DA9063_M_VDD_MON ) ,
REGMAP_IRQ_REG ( DA9063_IRQ_WARN ,
DA9063_REG_EVENT_B_OFFSET , DA9063_M_VDD_WARN ) ,
/* DA9063 event C register */
REGMAP_IRQ_REG ( DA9063_IRQ_GPI0 ,
DA9063_REG_EVENT_C_OFFSET , DA9063_M_GPI0 ) ,
REGMAP_IRQ_REG ( DA9063_IRQ_GPI1 ,
DA9063_REG_EVENT_C_OFFSET , DA9063_M_GPI1 ) ,
REGMAP_IRQ_REG ( DA9063_IRQ_GPI2 ,
DA9063_REG_EVENT_C_OFFSET , DA9063_M_GPI2 ) ,
REGMAP_IRQ_REG ( DA9063_IRQ_GPI3 ,
DA9063_REG_EVENT_C_OFFSET , DA9063_M_GPI3 ) ,
REGMAP_IRQ_REG ( DA9063_IRQ_GPI4 ,
DA9063_REG_EVENT_C_OFFSET , DA9063_M_GPI4 ) ,
REGMAP_IRQ_REG ( DA9063_IRQ_GPI5 ,
DA9063_REG_EVENT_C_OFFSET , DA9063_M_GPI5 ) ,
REGMAP_IRQ_REG ( DA9063_IRQ_GPI6 ,
DA9063_REG_EVENT_C_OFFSET , DA9063_M_GPI6 ) ,
REGMAP_IRQ_REG ( DA9063_IRQ_GPI7 ,
DA9063_REG_EVENT_C_OFFSET , DA9063_M_GPI7 ) ,
/* DA9063 event D register */
REGMAP_IRQ_REG ( DA9063_IRQ_GPI8 ,
DA9063_REG_EVENT_D_OFFSET , DA9063_M_GPI8 ) ,
REGMAP_IRQ_REG ( DA9063_IRQ_GPI9 ,
DA9063_REG_EVENT_D_OFFSET , DA9063_M_GPI9 ) ,
REGMAP_IRQ_REG ( DA9063_IRQ_GPI10 ,
DA9063_REG_EVENT_D_OFFSET , DA9063_M_GPI10 ) ,
REGMAP_IRQ_REG ( DA9063_IRQ_GPI11 ,
DA9063_REG_EVENT_D_OFFSET , DA9063_M_GPI11 ) ,
REGMAP_IRQ_REG ( DA9063_IRQ_GPI12 ,
DA9063_REG_EVENT_D_OFFSET , DA9063_M_GPI12 ) ,
REGMAP_IRQ_REG ( DA9063_IRQ_GPI13 ,
DA9063_REG_EVENT_D_OFFSET , DA9063_M_GPI13 ) ,
REGMAP_IRQ_REG ( DA9063_IRQ_GPI14 ,
DA9063_REG_EVENT_D_OFFSET , DA9063_M_GPI14 ) ,
REGMAP_IRQ_REG ( DA9063_IRQ_GPI15 ,
DA9063_REG_EVENT_D_OFFSET , DA9063_M_GPI15 ) ,
} ;
static const struct regmap_irq_chip da9063l_irq_chip = {
. name = " da9063l-irq " ,
. irqs = da9063l_irqs ,
. num_irqs = ARRAY_SIZE ( da9063l_irqs ) ,
. num_regs = 4 ,
. status_base = DA9063_REG_EVENT_A ,
. mask_base = DA9063_REG_IRQ_MASK_A ,
. ack_base = DA9063_REG_EVENT_A ,
. init_ack_masked = true ,
} ;
2013-07-29 21:00:44 +04:00
int da9063_irq_init ( struct da9063 * da9063 )
{
2018-06-11 14:58:48 +03:00
const struct regmap_irq_chip * irq_chip ;
2013-07-29 21:00:44 +04:00
int ret ;
if ( ! da9063 - > chip_irq ) {
dev_err ( da9063 - > dev , " No IRQ configured \n " ) ;
return - EINVAL ;
}
2018-06-11 14:58:48 +03:00
if ( da9063 - > type = = PMIC_TYPE_DA9063 )
irq_chip = & da9063_irq_chip ;
else
irq_chip = & da9063l_irq_chip ;
2018-06-11 14:58:38 +03:00
ret = devm_regmap_add_irq_chip ( da9063 - > dev , da9063 - > regmap ,
da9063 - > chip_irq ,
2013-07-29 21:00:44 +04:00
IRQF_TRIGGER_LOW | IRQF_ONESHOT | IRQF_SHARED ,
2018-06-11 14:58:48 +03:00
da9063 - > irq_base , irq_chip , & da9063 - > regmap_irq ) ;
2013-07-29 21:00:44 +04:00
if ( ret ) {
dev_err ( da9063 - > dev , " Failed to reguest IRQ %d: %d \n " ,
da9063 - > chip_irq , ret ) ;
return ret ;
}
return 0 ;
}