mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-28 18:51:56 -04:00
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap: (36 commits) mfd: Clearing events requires event registers to be writable for da9052-core mfd: Fix annotations in da9052-core gpiolib: Mark da9052 driver broken mfd: Declare da9052_regmap_config for the bus drivers MFD: DA9052/53 MFD core module add SPI support v2 MFD: DA9052/53 MFD core module regmap: Add irq_base accessor to regmap_irq regmap: Allow drivers to reinitialise the register cache at runtime regmap: Add trace event for successful cache reads regmap: Allow regmap_update_bits() users to detect changes regmap: Report if we actually handled an interrupt in regmap-irq regmap: Fix rbtreee build when not using debugfs regmap: Provide debugfs dump of the rbtree cache data regmap: Do debugfs init before cache init regmap: Suppress noop writes in regmap_update_bits() regmap: Remove indexed cache type regmap: Drop check whether a register is readable in regcache_read regmap: Properly round cache_word_size regmap: Add support for 10/14 register formating regmap: Try cached read before checking if a hardware read is possible ...
This commit is contained in:
commit
b7d845f882
20 changed files with 2542 additions and 157 deletions
|
|
@ -328,6 +328,34 @@ config PMIC_DA903X
|
|||
individual components like LCD backlight, voltage regulators,
|
||||
LEDs and battery-charger under the corresponding menus.
|
||||
|
||||
config PMIC_DA9052
|
||||
bool
|
||||
select MFD_CORE
|
||||
|
||||
config MFD_DA9052_SPI
|
||||
bool "Support Dialog Semiconductor DA9052/53 PMIC variants with SPI"
|
||||
select REGMAP_SPI
|
||||
select REGMAP_IRQ
|
||||
select PMIC_DA9052
|
||||
depends on SPI_MASTER=y
|
||||
help
|
||||
Support for the Dialog Semiconductor DA9052 PMIC
|
||||
when controlled using SPI. This driver provides common support
|
||||
for accessing the device, additional drivers must be enabled in
|
||||
order to use the functionality of the device.
|
||||
|
||||
config MFD_DA9052_I2C
|
||||
bool "Support Dialog Semiconductor DA9052/53 PMIC variants with I2C"
|
||||
select REGMAP_I2C
|
||||
select REGMAP_IRQ
|
||||
select PMIC_DA9052
|
||||
depends on I2C=y
|
||||
help
|
||||
Support for the Dialog Semiconductor DA9052 PMIC
|
||||
when controlled using I2C. This driver provides common support
|
||||
for accessing the device, additional drivers must be enabled in
|
||||
order to use the functionality of the device.
|
||||
|
||||
config PMIC_ADP5520
|
||||
bool "Analog Devices ADP5520/01 MFD PMIC Core Support"
|
||||
depends on I2C=y
|
||||
|
|
|
|||
|
|
@ -67,6 +67,11 @@ endif
|
|||
obj-$(CONFIG_UCB1400_CORE) += ucb1400_core.o
|
||||
|
||||
obj-$(CONFIG_PMIC_DA903X) += da903x.o
|
||||
|
||||
obj-$(CONFIG_PMIC_DA9052) += da9052-core.o
|
||||
obj-$(CONFIG_MFD_DA9052_SPI) += da9052-spi.o
|
||||
obj-$(CONFIG_MFD_DA9052_I2C) += da9052-i2c.o
|
||||
|
||||
max8925-objs := max8925-core.o max8925-i2c.o
|
||||
obj-$(CONFIG_MFD_MAX8925) += max8925.o
|
||||
obj-$(CONFIG_MFD_MAX8997) += max8997.o max8997-irq.o
|
||||
|
|
|
|||
694
drivers/mfd/da9052-core.c
Normal file
694
drivers/mfd/da9052-core.c
Normal file
|
|
@ -0,0 +1,694 @@
|
|||
/*
|
||||
* Device access for Dialog DA9052 PMICs.
|
||||
*
|
||||
* Copyright(c) 2011 Dialog Semiconductor Ltd.
|
||||
*
|
||||
* Author: David Dajun Chen <dchen@diasemi.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*/
|
||||
|
||||
#include <linux/device.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/mfd/core.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#include <linux/mfd/da9052/da9052.h>
|
||||
#include <linux/mfd/da9052/pdata.h>
|
||||
#include <linux/mfd/da9052/reg.h>
|
||||
|
||||
#define DA9052_NUM_IRQ_REGS 4
|
||||
#define DA9052_IRQ_MASK_POS_1 0x01
|
||||
#define DA9052_IRQ_MASK_POS_2 0x02
|
||||
#define DA9052_IRQ_MASK_POS_3 0x04
|
||||
#define DA9052_IRQ_MASK_POS_4 0x08
|
||||
#define DA9052_IRQ_MASK_POS_5 0x10
|
||||
#define DA9052_IRQ_MASK_POS_6 0x20
|
||||
#define DA9052_IRQ_MASK_POS_7 0x40
|
||||
#define DA9052_IRQ_MASK_POS_8 0x80
|
||||
|
||||
static bool da9052_reg_readable(struct device *dev, unsigned int reg)
|
||||
{
|
||||
switch (reg) {
|
||||
case DA9052_PAGE0_CON_REG:
|
||||
case DA9052_STATUS_A_REG:
|
||||
case DA9052_STATUS_B_REG:
|
||||
case DA9052_STATUS_C_REG:
|
||||
case DA9052_STATUS_D_REG:
|
||||
case DA9052_EVENT_A_REG:
|
||||
case DA9052_EVENT_B_REG:
|
||||
case DA9052_EVENT_C_REG:
|
||||
case DA9052_EVENT_D_REG:
|
||||
case DA9052_FAULTLOG_REG:
|
||||
case DA9052_IRQ_MASK_A_REG:
|
||||
case DA9052_IRQ_MASK_B_REG:
|
||||
case DA9052_IRQ_MASK_C_REG:
|
||||
case DA9052_IRQ_MASK_D_REG:
|
||||
case DA9052_CONTROL_A_REG:
|
||||
case DA9052_CONTROL_B_REG:
|
||||
case DA9052_CONTROL_C_REG:
|
||||
case DA9052_CONTROL_D_REG:
|
||||
case DA9052_PDDIS_REG:
|
||||
case DA9052_INTERFACE_REG:
|
||||
case DA9052_RESET_REG:
|
||||
case DA9052_GPIO_0_1_REG:
|
||||
case DA9052_GPIO_2_3_REG:
|
||||
case DA9052_GPIO_4_5_REG:
|
||||
case DA9052_GPIO_6_7_REG:
|
||||
case DA9052_GPIO_14_15_REG:
|
||||
case DA9052_ID_0_1_REG:
|
||||
case DA9052_ID_2_3_REG:
|
||||
case DA9052_ID_4_5_REG:
|
||||
case DA9052_ID_6_7_REG:
|
||||
case DA9052_ID_8_9_REG:
|
||||
case DA9052_ID_10_11_REG:
|
||||
case DA9052_ID_12_13_REG:
|
||||
case DA9052_ID_14_15_REG:
|
||||
case DA9052_ID_16_17_REG:
|
||||
case DA9052_ID_18_19_REG:
|
||||
case DA9052_ID_20_21_REG:
|
||||
case DA9052_SEQ_STATUS_REG:
|
||||
case DA9052_SEQ_A_REG:
|
||||
case DA9052_SEQ_B_REG:
|
||||
case DA9052_SEQ_TIMER_REG:
|
||||
case DA9052_BUCKA_REG:
|
||||
case DA9052_BUCKB_REG:
|
||||
case DA9052_BUCKCORE_REG:
|
||||
case DA9052_BUCKPRO_REG:
|
||||
case DA9052_BUCKMEM_REG:
|
||||
case DA9052_BUCKPERI_REG:
|
||||
case DA9052_LDO1_REG:
|
||||
case DA9052_LDO2_REG:
|
||||
case DA9052_LDO3_REG:
|
||||
case DA9052_LDO4_REG:
|
||||
case DA9052_LDO5_REG:
|
||||
case DA9052_LDO6_REG:
|
||||
case DA9052_LDO7_REG:
|
||||
case DA9052_LDO8_REG:
|
||||
case DA9052_LDO9_REG:
|
||||
case DA9052_LDO10_REG:
|
||||
case DA9052_SUPPLY_REG:
|
||||
case DA9052_PULLDOWN_REG:
|
||||
case DA9052_CHGBUCK_REG:
|
||||
case DA9052_WAITCONT_REG:
|
||||
case DA9052_ISET_REG:
|
||||
case DA9052_BATCHG_REG:
|
||||
case DA9052_CHG_CONT_REG:
|
||||
case DA9052_INPUT_CONT_REG:
|
||||
case DA9052_CHG_TIME_REG:
|
||||
case DA9052_BBAT_CONT_REG:
|
||||
case DA9052_BOOST_REG:
|
||||
case DA9052_LED_CONT_REG:
|
||||
case DA9052_LEDMIN123_REG:
|
||||
case DA9052_LED1_CONF_REG:
|
||||
case DA9052_LED2_CONF_REG:
|
||||
case DA9052_LED3_CONF_REG:
|
||||
case DA9052_LED1CONT_REG:
|
||||
case DA9052_LED2CONT_REG:
|
||||
case DA9052_LED3CONT_REG:
|
||||
case DA9052_LED_CONT_4_REG:
|
||||
case DA9052_LED_CONT_5_REG:
|
||||
case DA9052_ADC_MAN_REG:
|
||||
case DA9052_ADC_CONT_REG:
|
||||
case DA9052_ADC_RES_L_REG:
|
||||
case DA9052_ADC_RES_H_REG:
|
||||
case DA9052_VDD_RES_REG:
|
||||
case DA9052_VDD_MON_REG:
|
||||
case DA9052_ICHG_AV_REG:
|
||||
case DA9052_ICHG_THD_REG:
|
||||
case DA9052_ICHG_END_REG:
|
||||
case DA9052_TBAT_RES_REG:
|
||||
case DA9052_TBAT_HIGHP_REG:
|
||||
case DA9052_TBAT_HIGHN_REG:
|
||||
case DA9052_TBAT_LOW_REG:
|
||||
case DA9052_T_OFFSET_REG:
|
||||
case DA9052_ADCIN4_RES_REG:
|
||||
case DA9052_AUTO4_HIGH_REG:
|
||||
case DA9052_AUTO4_LOW_REG:
|
||||
case DA9052_ADCIN5_RES_REG:
|
||||
case DA9052_AUTO5_HIGH_REG:
|
||||
case DA9052_AUTO5_LOW_REG:
|
||||
case DA9052_ADCIN6_RES_REG:
|
||||
case DA9052_AUTO6_HIGH_REG:
|
||||
case DA9052_AUTO6_LOW_REG:
|
||||
case DA9052_TJUNC_RES_REG:
|
||||
case DA9052_TSI_CONT_A_REG:
|
||||
case DA9052_TSI_CONT_B_REG:
|
||||
case DA9052_TSI_X_MSB_REG:
|
||||
case DA9052_TSI_Y_MSB_REG:
|
||||
case DA9052_TSI_LSB_REG:
|
||||
case DA9052_TSI_Z_MSB_REG:
|
||||
case DA9052_COUNT_S_REG:
|
||||
case DA9052_COUNT_MI_REG:
|
||||
case DA9052_COUNT_H_REG:
|
||||
case DA9052_COUNT_D_REG:
|
||||
case DA9052_COUNT_MO_REG:
|
||||
case DA9052_COUNT_Y_REG:
|
||||
case DA9052_ALARM_MI_REG:
|
||||
case DA9052_ALARM_H_REG:
|
||||
case DA9052_ALARM_D_REG:
|
||||
case DA9052_ALARM_MO_REG:
|
||||
case DA9052_ALARM_Y_REG:
|
||||
case DA9052_SECOND_A_REG:
|
||||
case DA9052_SECOND_B_REG:
|
||||
case DA9052_SECOND_C_REG:
|
||||
case DA9052_SECOND_D_REG:
|
||||
case DA9052_PAGE1_CON_REG:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static bool da9052_reg_writeable(struct device *dev, unsigned int reg)
|
||||
{
|
||||
switch (reg) {
|
||||
case DA9052_PAGE0_CON_REG:
|
||||
case DA9052_EVENT_A_REG:
|
||||
case DA9052_EVENT_B_REG:
|
||||
case DA9052_EVENT_C_REG:
|
||||
case DA9052_EVENT_D_REG:
|
||||
case DA9052_IRQ_MASK_A_REG:
|
||||
case DA9052_IRQ_MASK_B_REG:
|
||||
case DA9052_IRQ_MASK_C_REG:
|
||||
case DA9052_IRQ_MASK_D_REG:
|
||||
case DA9052_CONTROL_A_REG:
|
||||
case DA9052_CONTROL_B_REG:
|
||||
case DA9052_CONTROL_C_REG:
|
||||
case DA9052_CONTROL_D_REG:
|
||||
case DA9052_PDDIS_REG:
|
||||
case DA9052_RESET_REG:
|
||||
case DA9052_GPIO_0_1_REG:
|
||||
case DA9052_GPIO_2_3_REG:
|
||||
case DA9052_GPIO_4_5_REG:
|
||||
case DA9052_GPIO_6_7_REG:
|
||||
case DA9052_GPIO_14_15_REG:
|
||||
case DA9052_ID_0_1_REG:
|
||||
case DA9052_ID_2_3_REG:
|
||||
case DA9052_ID_4_5_REG:
|
||||
case DA9052_ID_6_7_REG:
|
||||
case DA9052_ID_8_9_REG:
|
||||
case DA9052_ID_10_11_REG:
|
||||
case DA9052_ID_12_13_REG:
|
||||
case DA9052_ID_14_15_REG:
|
||||
case DA9052_ID_16_17_REG:
|
||||
case DA9052_ID_18_19_REG:
|
||||
case DA9052_ID_20_21_REG:
|
||||
case DA9052_SEQ_STATUS_REG:
|
||||
case DA9052_SEQ_A_REG:
|
||||
case DA9052_SEQ_B_REG:
|
||||
case DA9052_SEQ_TIMER_REG:
|
||||
case DA9052_BUCKA_REG:
|
||||
case DA9052_BUCKB_REG:
|
||||
case DA9052_BUCKCORE_REG:
|
||||
case DA9052_BUCKPRO_REG:
|
||||
case DA9052_BUCKMEM_REG:
|
||||
case DA9052_BUCKPERI_REG:
|
||||
case DA9052_LDO1_REG:
|
||||
case DA9052_LDO2_REG:
|
||||
case DA9052_LDO3_REG:
|
||||
case DA9052_LDO4_REG:
|
||||
case DA9052_LDO5_REG:
|
||||
case DA9052_LDO6_REG:
|
||||
case DA9052_LDO7_REG:
|
||||
case DA9052_LDO8_REG:
|
||||
case DA9052_LDO9_REG:
|
||||
case DA9052_LDO10_REG:
|
||||
case DA9052_SUPPLY_REG:
|
||||
case DA9052_PULLDOWN_REG:
|
||||
case DA9052_CHGBUCK_REG:
|
||||
case DA9052_WAITCONT_REG:
|
||||
case DA9052_ISET_REG:
|
||||
case DA9052_BATCHG_REG:
|
||||
case DA9052_CHG_CONT_REG:
|
||||
case DA9052_INPUT_CONT_REG:
|
||||
case DA9052_BBAT_CONT_REG:
|
||||
case DA9052_BOOST_REG:
|
||||
case DA9052_LED_CONT_REG:
|
||||
case DA9052_LEDMIN123_REG:
|
||||
case DA9052_LED1_CONF_REG:
|
||||
case DA9052_LED2_CONF_REG:
|
||||
case DA9052_LED3_CONF_REG:
|
||||
case DA9052_LED1CONT_REG:
|
||||
case DA9052_LED2CONT_REG:
|
||||
case DA9052_LED3CONT_REG:
|
||||
case DA9052_LED_CONT_4_REG:
|
||||
case DA9052_LED_CONT_5_REG:
|
||||
case DA9052_ADC_MAN_REG:
|
||||
case DA9052_ADC_CONT_REG:
|
||||
case DA9052_ADC_RES_L_REG:
|
||||
case DA9052_ADC_RES_H_REG:
|
||||
case DA9052_VDD_RES_REG:
|
||||
case DA9052_VDD_MON_REG:
|
||||
case DA9052_ICHG_THD_REG:
|
||||
case DA9052_ICHG_END_REG:
|
||||
case DA9052_TBAT_HIGHP_REG:
|
||||
case DA9052_TBAT_HIGHN_REG:
|
||||
case DA9052_TBAT_LOW_REG:
|
||||
case DA9052_T_OFFSET_REG:
|
||||
case DA9052_AUTO4_HIGH_REG:
|
||||
case DA9052_AUTO4_LOW_REG:
|
||||
case DA9052_AUTO5_HIGH_REG:
|
||||
case DA9052_AUTO5_LOW_REG:
|
||||
case DA9052_AUTO6_HIGH_REG:
|
||||
case DA9052_AUTO6_LOW_REG:
|
||||
case DA9052_TSI_CONT_A_REG:
|
||||
case DA9052_TSI_CONT_B_REG:
|
||||
case DA9052_COUNT_S_REG:
|
||||
case DA9052_COUNT_MI_REG:
|
||||
case DA9052_COUNT_H_REG:
|
||||
case DA9052_COUNT_D_REG:
|
||||
case DA9052_COUNT_MO_REG:
|
||||
case DA9052_COUNT_Y_REG:
|
||||
case DA9052_ALARM_MI_REG:
|
||||
case DA9052_ALARM_H_REG:
|
||||
case DA9052_ALARM_D_REG:
|
||||
case DA9052_ALARM_MO_REG:
|
||||
case DA9052_ALARM_Y_REG:
|
||||
case DA9052_PAGE1_CON_REG:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static bool da9052_reg_volatile(struct device *dev, unsigned int reg)
|
||||
{
|
||||
switch (reg) {
|
||||
case DA9052_STATUS_A_REG:
|
||||
case DA9052_STATUS_B_REG:
|
||||
case DA9052_STATUS_C_REG:
|
||||
case DA9052_STATUS_D_REG:
|
||||
case DA9052_EVENT_A_REG:
|
||||
case DA9052_EVENT_B_REG:
|
||||
case DA9052_EVENT_C_REG:
|
||||
case DA9052_EVENT_D_REG:
|
||||
case DA9052_FAULTLOG_REG:
|
||||
case DA9052_CHG_TIME_REG:
|
||||
case DA9052_ADC_RES_L_REG:
|
||||
case DA9052_ADC_RES_H_REG:
|
||||
case DA9052_VDD_RES_REG:
|
||||
case DA9052_ICHG_AV_REG:
|
||||
case DA9052_TBAT_RES_REG:
|
||||
case DA9052_ADCIN4_RES_REG:
|
||||
case DA9052_ADCIN5_RES_REG:
|
||||
case DA9052_ADCIN6_RES_REG:
|
||||
case DA9052_TJUNC_RES_REG:
|
||||
case DA9052_TSI_X_MSB_REG:
|
||||
case DA9052_TSI_Y_MSB_REG:
|
||||
case DA9052_TSI_LSB_REG:
|
||||
case DA9052_TSI_Z_MSB_REG:
|
||||
case DA9052_COUNT_S_REG:
|
||||
case DA9052_COUNT_MI_REG:
|
||||
case DA9052_COUNT_H_REG:
|
||||
case DA9052_COUNT_D_REG:
|
||||
case DA9052_COUNT_MO_REG:
|
||||
case DA9052_COUNT_Y_REG:
|
||||
case DA9052_ALARM_MI_REG:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static struct resource da9052_rtc_resource = {
|
||||
.name = "ALM",
|
||||
.start = DA9052_IRQ_ALARM,
|
||||
.end = DA9052_IRQ_ALARM,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
};
|
||||
|
||||
static struct resource da9052_onkey_resource = {
|
||||
.name = "ONKEY",
|
||||
.start = DA9052_IRQ_NONKEY,
|
||||
.end = DA9052_IRQ_NONKEY,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
};
|
||||
|
||||
static struct resource da9052_bat_resources[] = {
|
||||
{
|
||||
.name = "BATT TEMP",
|
||||
.start = DA9052_IRQ_TBAT,
|
||||
.end = DA9052_IRQ_TBAT,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
{
|
||||
.name = "DCIN DET",
|
||||
.start = DA9052_IRQ_DCIN,
|
||||
.end = DA9052_IRQ_DCIN,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
{
|
||||
.name = "DCIN REM",
|
||||
.start = DA9052_IRQ_DCINREM,
|
||||
.end = DA9052_IRQ_DCINREM,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
{
|
||||
.name = "VBUS DET",
|
||||
.start = DA9052_IRQ_VBUS,
|
||||
.end = DA9052_IRQ_VBUS,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
{
|
||||
.name = "VBUS REM",
|
||||
.start = DA9052_IRQ_VBUSREM,
|
||||
.end = DA9052_IRQ_VBUSREM,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
{
|
||||
.name = "CHG END",
|
||||
.start = DA9052_IRQ_CHGEND,
|
||||
.end = DA9052_IRQ_CHGEND,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
static struct resource da9052_tsi_resources[] = {
|
||||
{
|
||||
.name = "PENDWN",
|
||||
.start = DA9052_IRQ_PENDOWN,
|
||||
.end = DA9052_IRQ_PENDOWN,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
{
|
||||
.name = "TSIRDY",
|
||||
.start = DA9052_IRQ_TSIREADY,
|
||||
.end = DA9052_IRQ_TSIREADY,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
static struct mfd_cell __devinitdata da9052_subdev_info[] = {
|
||||
{
|
||||
.name = "da9052-regulator",
|
||||
.id = 1,
|
||||
},
|
||||
{
|
||||
.name = "da9052-regulator",
|
||||
.id = 2,
|
||||
},
|
||||
{
|
||||
.name = "da9052-regulator",
|
||||
.id = 3,
|
||||
},
|
||||
{
|
||||
.name = "da9052-regulator",
|
||||
.id = 4,
|
||||
},
|
||||
{
|
||||
.name = "da9052-regulator",
|
||||
.id = 5,
|
||||
},
|
||||
{
|
||||
.name = "da9052-regulator",
|
||||
.id = 6,
|
||||
},
|
||||
{
|
||||
.name = "da9052-regulator",
|
||||
.id = 7,
|
||||
},
|
||||
{
|
||||
.name = "da9052-regulator",
|
||||
.id = 8,
|
||||
},
|
||||
{
|
||||
.name = "da9052-regulator",
|
||||
.id = 9,
|
||||
},
|
||||
{
|
||||
.name = "da9052-regulator",
|
||||
.id = 10,
|
||||
},
|
||||
{
|
||||
.name = "da9052-regulator",
|
||||
.id = 11,
|
||||
},
|
||||
{
|
||||
.name = "da9052-regulator",
|
||||
.id = 12,
|
||||
},
|
||||
{
|
||||
.name = "da9052-regulator",
|
||||
.id = 13,
|
||||
},
|
||||
{
|
||||
.name = "da9052-regulator",
|
||||
.id = 14,
|
||||
},
|
||||
{
|
||||
.name = "da9052-onkey",
|
||||
.resources = &da9052_onkey_resource,
|
||||
.num_resources = 1,
|
||||
},
|
||||
{
|
||||
.name = "da9052-rtc",
|
||||
.resources = &da9052_rtc_resource,
|
||||
.num_resources = 1,
|
||||
},
|
||||
{
|
||||
.name = "da9052-gpio",
|
||||
},
|
||||
{
|
||||
.name = "da9052-hwmon",
|
||||
},
|
||||
{
|
||||
.name = "da9052-leds",
|
||||
},
|
||||
{
|
||||
.name = "da9052-wled1",
|
||||
},
|
||||
{
|
||||
.name = "da9052-wled2",
|
||||
},
|
||||
{
|
||||
.name = "da9052-wled3",
|
||||
},
|
||||
{
|
||||
.name = "da9052-tsi",
|
||||
.resources = da9052_tsi_resources,
|
||||
.num_resources = ARRAY_SIZE(da9052_tsi_resources),
|
||||
},
|
||||
{
|
||||
.name = "da9052-bat",
|
||||
.resources = da9052_bat_resources,
|
||||
.num_resources = ARRAY_SIZE(da9052_bat_resources),
|
||||
},
|
||||
{
|
||||
.name = "da9052-watchdog",
|
||||
},
|
||||
};
|
||||
|
||||
static struct regmap_irq da9052_irqs[] = {
|
||||
[DA9052_IRQ_DCIN] = {
|
||||
.reg_offset = 0,
|
||||
.mask = DA9052_IRQ_MASK_POS_1,
|
||||
},
|
||||
[DA9052_IRQ_VBUS] = {
|
||||
.reg_offset = 0,
|
||||
.mask = DA9052_IRQ_MASK_POS_2,
|
||||
},
|
||||
[DA9052_IRQ_DCINREM] = {
|
||||
.reg_offset = 0,
|
||||
.mask = DA9052_IRQ_MASK_POS_3,
|
||||
},
|
||||
[DA9052_IRQ_VBUSREM] = {
|
||||
.reg_offset = 0,
|
||||
.mask = DA9052_IRQ_MASK_POS_4,
|
||||
},
|
||||
[DA9052_IRQ_VDDLOW] = {
|
||||
.reg_offset = 0,
|
||||
.mask = DA9052_IRQ_MASK_POS_5,
|
||||
},
|
||||
[DA9052_IRQ_ALARM] = {
|
||||
.reg_offset = 0,
|
||||
.mask = DA9052_IRQ_MASK_POS_6,
|
||||
},
|
||||
[DA9052_IRQ_SEQRDY] = {
|
||||
.reg_offset = 0,
|
||||
.mask = DA9052_IRQ_MASK_POS_7,
|
||||
},
|
||||
[DA9052_IRQ_COMP1V2] = {
|
||||
.reg_offset = 0,
|
||||
.mask = DA9052_IRQ_MASK_POS_8,
|
||||
},
|
||||
[DA9052_IRQ_NONKEY] = {
|
||||
.reg_offset = 1,
|
||||
.mask = DA9052_IRQ_MASK_POS_1,
|
||||
},
|
||||
[DA9052_IRQ_IDFLOAT] = {
|
||||
.reg_offset = 1,
|
||||
.mask = DA9052_IRQ_MASK_POS_2,
|
||||
},
|
||||
[DA9052_IRQ_IDGND] = {
|
||||
.reg_offset = 1,
|
||||
.mask = DA9052_IRQ_MASK_POS_3,
|
||||
},
|
||||
[DA9052_IRQ_CHGEND] = {
|
||||
.reg_offset = 1,
|
||||
.mask = DA9052_IRQ_MASK_POS_4,
|
||||
},
|
||||
[DA9052_IRQ_TBAT] = {
|
||||
.reg_offset = 1,
|
||||
.mask = DA9052_IRQ_MASK_POS_5,
|
||||
},
|
||||
[DA9052_IRQ_ADC_EOM] = {
|
||||
.reg_offset = 1,
|
||||
.mask = DA9052_IRQ_MASK_POS_6,
|
||||
},
|
||||
[DA9052_IRQ_PENDOWN] = {
|
||||
.reg_offset = 1,
|
||||
.mask = DA9052_IRQ_MASK_POS_7,
|
||||
},
|
||||
[DA9052_IRQ_TSIREADY] = {
|
||||
.reg_offset = 1,
|
||||
.mask = DA9052_IRQ_MASK_POS_8,
|
||||
},
|
||||
[DA9052_IRQ_GPI0] = {
|
||||
.reg_offset = 2,
|
||||
.mask = DA9052_IRQ_MASK_POS_1,
|
||||
},
|
||||
[DA9052_IRQ_GPI1] = {
|
||||
.reg_offset = 2,
|
||||
.mask = DA9052_IRQ_MASK_POS_2,
|
||||
},
|
||||
[DA9052_IRQ_GPI2] = {
|
||||
.reg_offset = 2,
|
||||
.mask = DA9052_IRQ_MASK_POS_3,
|
||||
},
|
||||
[DA9052_IRQ_GPI3] = {
|
||||
.reg_offset = 2,
|
||||
.mask = DA9052_IRQ_MASK_POS_4,
|
||||
},
|
||||
[DA9052_IRQ_GPI4] = {
|
||||
.reg_offset = 2,
|
||||
.mask = DA9052_IRQ_MASK_POS_5,
|
||||
},
|
||||
[DA9052_IRQ_GPI5] = {
|
||||
.reg_offset = 2,
|
||||
.mask = DA9052_IRQ_MASK_POS_6,
|
||||
},
|
||||
[DA9052_IRQ_GPI6] = {
|
||||
.reg_offset = 2,
|
||||
.mask = DA9052_IRQ_MASK_POS_7,
|
||||
},
|
||||
[DA9052_IRQ_GPI7] = {
|
||||
.reg_offset = 2,
|
||||
.mask = DA9052_IRQ_MASK_POS_8,
|
||||
},
|
||||
[DA9052_IRQ_GPI8] = {
|
||||
.reg_offset = 3,
|
||||
.mask = DA9052_IRQ_MASK_POS_1,
|
||||
},
|
||||
[DA9052_IRQ_GPI9] = {
|
||||
.reg_offset = 3,
|
||||
.mask = DA9052_IRQ_MASK_POS_2,
|
||||
},
|
||||
[DA9052_IRQ_GPI10] = {
|
||||
.reg_offset = 3,
|
||||
.mask = DA9052_IRQ_MASK_POS_3,
|
||||
},
|
||||
[DA9052_IRQ_GPI11] = {
|
||||
.reg_offset = 3,
|
||||
.mask = DA9052_IRQ_MASK_POS_4,
|
||||
},
|
||||
[DA9052_IRQ_GPI12] = {
|
||||
.reg_offset = 3,
|
||||
.mask = DA9052_IRQ_MASK_POS_5,
|
||||
},
|
||||
[DA9052_IRQ_GPI13] = {
|
||||
.reg_offset = 3,
|
||||
.mask = DA9052_IRQ_MASK_POS_6,
|
||||
},
|
||||
[DA9052_IRQ_GPI14] = {
|
||||
.reg_offset = 3,
|
||||
.mask = DA9052_IRQ_MASK_POS_7,
|
||||
},
|
||||
[DA9052_IRQ_GPI15] = {
|
||||
.reg_offset = 3,
|
||||
.mask = DA9052_IRQ_MASK_POS_8,
|
||||
},
|
||||
};
|
||||
|
||||
static struct regmap_irq_chip da9052_regmap_irq_chip = {
|
||||
.name = "da9052_irq",
|
||||
.status_base = DA9052_EVENT_A_REG,
|
||||
.mask_base = DA9052_IRQ_MASK_A_REG,
|
||||
.ack_base = DA9052_EVENT_A_REG,
|
||||
.num_regs = DA9052_NUM_IRQ_REGS,
|
||||
.irqs = da9052_irqs,
|
||||
.num_irqs = ARRAY_SIZE(da9052_irqs),
|
||||
};
|
||||
|
||||
struct regmap_config da9052_regmap_config = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
|
||||
.cache_type = REGCACHE_RBTREE,
|
||||
|
||||
.max_register = DA9052_PAGE1_CON_REG,
|
||||
.readable_reg = da9052_reg_readable,
|
||||
.writeable_reg = da9052_reg_writeable,
|
||||
.volatile_reg = da9052_reg_volatile,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(da9052_regmap_config);
|
||||
|
||||
int __devinit da9052_device_init(struct da9052 *da9052, u8 chip_id)
|
||||
{
|
||||
struct da9052_pdata *pdata = da9052->dev->platform_data;
|
||||
struct irq_desc *desc;
|
||||
int ret;
|
||||
|
||||
mutex_init(&da9052->io_lock);
|
||||
|
||||
if (pdata && pdata->init != NULL)
|
||||
pdata->init(da9052);
|
||||
|
||||
da9052->chip_id = chip_id;
|
||||
|
||||
if (!pdata || !pdata->irq_base)
|
||||
da9052->irq_base = -1;
|
||||
else
|
||||
da9052->irq_base = pdata->irq_base;
|
||||
|
||||
ret = regmap_add_irq_chip(da9052->regmap, da9052->chip_irq,
|
||||
IRQF_TRIGGER_LOW | IRQF_ONESHOT,
|
||||
da9052->irq_base, &da9052_regmap_irq_chip,
|
||||
NULL);
|
||||
if (ret < 0)
|
||||
goto regmap_err;
|
||||
|
||||
desc = irq_to_desc(da9052->chip_irq);
|
||||
da9052->irq_base = regmap_irq_chip_get_base(desc->action->dev_id);
|
||||
|
||||
ret = mfd_add_devices(da9052->dev, -1, da9052_subdev_info,
|
||||
ARRAY_SIZE(da9052_subdev_info), NULL, 0);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
mfd_remove_devices(da9052->dev);
|
||||
regmap_err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
void da9052_device_exit(struct da9052 *da9052)
|
||||
{
|
||||
regmap_del_irq_chip(da9052->chip_irq,
|
||||
irq_get_irq_data(da9052->irq_base)->chip_data);
|
||||
mfd_remove_devices(da9052->dev);
|
||||
}
|
||||
|
||||
MODULE_AUTHOR("David Dajun Chen <[email protected]>");
|
||||
MODULE_DESCRIPTION("DA9052 MFD Core");
|
||||
MODULE_LICENSE("GPL");
|
||||
140
drivers/mfd/da9052-i2c.c
Normal file
140
drivers/mfd/da9052-i2c.c
Normal file
|
|
@ -0,0 +1,140 @@
|
|||
/*
|
||||
* I2C access for DA9052 PMICs.
|
||||
*
|
||||
* Copyright(c) 2011 Dialog Semiconductor Ltd.
|
||||
*
|
||||
* Author: David Dajun Chen <dchen@diasemi.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/device.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/mfd/core.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/err.h>
|
||||
|
||||
#include <linux/mfd/da9052/da9052.h>
|
||||
#include <linux/mfd/da9052/reg.h>
|
||||
|
||||
static int da9052_i2c_enable_multiwrite(struct da9052 *da9052)
|
||||
{
|
||||
int reg_val, ret;
|
||||
|
||||
ret = regmap_read(da9052->regmap, DA9052_CONTROL_B_REG, ®_val);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (reg_val & DA9052_CONTROL_B_WRITEMODE) {
|
||||
reg_val &= ~DA9052_CONTROL_B_WRITEMODE;
|
||||
ret = regmap_write(da9052->regmap, DA9052_CONTROL_B_REG,
|
||||
reg_val);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __devinit da9052_i2c_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
struct da9052 *da9052;
|
||||
int ret;
|
||||
|
||||
da9052 = kzalloc(sizeof(struct da9052), GFP_KERNEL);
|
||||
if (!da9052)
|
||||
return -ENOMEM;
|
||||
|
||||
if (!i2c_check_functionality(client->adapter,
|
||||
I2C_FUNC_SMBUS_BYTE_DATA)) {
|
||||
dev_info(&client->dev, "Error in %s:i2c_check_functionality\n",
|
||||
__func__);
|
||||
ret = -ENODEV;
|
||||
goto err;
|
||||
}
|
||||
|
||||
da9052->dev = &client->dev;
|
||||
da9052->chip_irq = client->irq;
|
||||
|
||||
i2c_set_clientdata(client, da9052);
|
||||
|
||||
da9052->regmap = regmap_init_i2c(client, &da9052_regmap_config);
|
||||
if (IS_ERR(da9052->regmap)) {
|
||||
ret = PTR_ERR(da9052->regmap);
|
||||
dev_err(&client->dev, "Failed to allocate register map: %d\n",
|
||||
ret);
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = da9052_i2c_enable_multiwrite(da9052);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
ret = da9052_device_init(da9052, id->driver_data);
|
||||
if (ret != 0)
|
||||
goto err;
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
kfree(da9052);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int da9052_i2c_remove(struct i2c_client *client)
|
||||
{
|
||||
struct da9052 *da9052 = i2c_get_clientdata(client);
|
||||
|
||||
da9052_device_exit(da9052);
|
||||
kfree(da9052);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct i2c_device_id da9052_i2c_id[] = {
|
||||
{"da9052", DA9052},
|
||||
{"da9053-aa", DA9053_AA},
|
||||
{"da9053-ba", DA9053_BA},
|
||||
{"da9053-bb", DA9053_BB},
|
||||
{}
|
||||
};
|
||||
|
||||
static struct i2c_driver da9052_i2c_driver = {
|
||||
.probe = da9052_i2c_probe,
|
||||
.remove = da9052_i2c_remove,
|
||||
.id_table = da9052_i2c_id,
|
||||
.driver = {
|
||||
.name = "da9052",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init da9052_i2c_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = i2c_add_driver(&da9052_i2c_driver);
|
||||
if (ret != 0) {
|
||||
pr_err("DA9052 I2C registration failed %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
subsys_initcall(da9052_i2c_init);
|
||||
|
||||
static void __exit da9052_i2c_exit(void)
|
||||
{
|
||||
i2c_del_driver(&da9052_i2c_driver);
|
||||
}
|
||||
module_exit(da9052_i2c_exit);
|
||||
|
||||
MODULE_AUTHOR("David Dajun Chen <[email protected]>");
|
||||
MODULE_DESCRIPTION("I2C driver for Dialog DA9052 PMIC");
|
||||
MODULE_LICENSE("GPL");
|
||||
115
drivers/mfd/da9052-spi.c
Normal file
115
drivers/mfd/da9052-spi.c
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
/*
|
||||
* SPI access for Dialog DA9052 PMICs.
|
||||
*
|
||||
* Copyright(c) 2011 Dialog Semiconductor Ltd.
|
||||
*
|
||||
* Author: David Dajun Chen <dchen@diasemi.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/device.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/mfd/core.h>
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/err.h>
|
||||
|
||||
#include <linux/mfd/da9052/da9052.h>
|
||||
|
||||
static int da9052_spi_probe(struct spi_device *spi)
|
||||
{
|
||||
int ret;
|
||||
const struct spi_device_id *id = spi_get_device_id(spi);
|
||||
struct da9052 *da9052 = kzalloc(sizeof(struct da9052), GFP_KERNEL);
|
||||
|
||||
if (!da9052)
|
||||
return -ENOMEM;
|
||||
|
||||
spi->mode = SPI_MODE_0 | SPI_CPOL;
|
||||
spi->bits_per_word = 8;
|
||||
spi_setup(spi);
|
||||
|
||||
da9052->dev = &spi->dev;
|
||||
da9052->chip_irq = spi->irq;
|
||||
|
||||
dev_set_drvdata(&spi->dev, da9052);
|
||||
|
||||
da9052_regmap_config.read_flag_mask = 1;
|
||||
da9052_regmap_config.write_flag_mask = 0;
|
||||
|
||||
da9052->regmap = regmap_init_spi(spi, &da9052_regmap_config);
|
||||
if (IS_ERR(da9052->regmap)) {
|
||||
ret = PTR_ERR(da9052->regmap);
|
||||
dev_err(&spi->dev, "Failed to allocate register map: %d\n",
|
||||
ret);
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = da9052_device_init(da9052, id->driver_data);
|
||||
if (ret != 0)
|
||||
goto err;
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
kfree(da9052);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int da9052_spi_remove(struct spi_device *spi)
|
||||
{
|
||||
struct da9052 *da9052 = dev_get_drvdata(&spi->dev);
|
||||
|
||||
da9052_device_exit(da9052);
|
||||
kfree(da9052);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct spi_device_id da9052_spi_id[] = {
|
||||
{"da9052", DA9052},
|
||||
{"da9053-aa", DA9053_AA},
|
||||
{"da9053-ba", DA9053_BA},
|
||||
{"da9053-bb", DA9053_BB},
|
||||
{}
|
||||
};
|
||||
|
||||
static struct spi_driver da9052_spi_driver = {
|
||||
.probe = da9052_spi_probe,
|
||||
.remove = __devexit_p(da9052_spi_remove),
|
||||
.id_table = da9052_spi_id,
|
||||
.driver = {
|
||||
.name = "da9052",
|
||||
.bus = &spi_bus_type,
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init da9052_spi_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = spi_register_driver(&da9052_spi_driver);
|
||||
if (ret != 0) {
|
||||
pr_err("Failed to register DA9052 SPI driver, %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
subsys_initcall(da9052_spi_init);
|
||||
|
||||
static void __exit da9052_spi_exit(void)
|
||||
{
|
||||
spi_unregister_driver(&da9052_spi_driver);
|
||||
}
|
||||
module_exit(da9052_spi_exit);
|
||||
|
||||
MODULE_AUTHOR("David Dajun Chen <[email protected]>");
|
||||
MODULE_DESCRIPTION("SPI driver for Dialog DA9052 PMIC");
|
||||
MODULE_LICENSE("GPL");
|
||||
Loading…
Reference in a new issue