1 /* da9063-i2c.c: Interrupt support for Dialog DA9063
3 * Copyright 2012 Dialog Semiconductor Ltd.
4 * Copyright 2013 Philipp Zabel, Pengutronix
6 * Author: Krystian Garbaciak, Dialog Semiconductor
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
15 #include <linux/kernel.h>
16 #include <linux/module.h>
17 #include <linux/i2c.h>
18 #include <linux/regmap.h>
19 #include <linux/delay.h>
20 #include <linux/slab.h>
21 #include <linux/err.h>
23 #include <linux/mfd/core.h>
24 #include <linux/mfd/da9063/core.h>
25 #include <linux/mfd/da9063/pdata.h>
26 #include <linux/mfd/da9063/registers.h>
29 #include <linux/regulator/of_regulator.h>
31 static const struct regmap_range da9063_ad_readable_ranges
[] = {
32 regmap_reg_range(DA9063_REG_PAGE_CON
, DA9063_AD_REG_SECOND_D
),
33 regmap_reg_range(DA9063_REG_SEQ
, DA9063_REG_ID_32_31
),
34 regmap_reg_range(DA9063_REG_SEQ_A
, DA9063_REG_AUTO3_LOW
),
35 regmap_reg_range(DA9063_REG_T_OFFSET
, DA9063_AD_REG_GP_ID_19
),
36 regmap_reg_range(DA9063_REG_CHIP_ID
, DA9063_REG_CHIP_VARIANT
),
39 static const struct regmap_range da9063_ad_writeable_ranges
[] = {
40 regmap_reg_range(DA9063_REG_PAGE_CON
, DA9063_REG_PAGE_CON
),
41 regmap_reg_range(DA9063_REG_FAULT_LOG
, DA9063_REG_VSYS_MON
),
42 regmap_reg_range(DA9063_REG_COUNT_S
, DA9063_AD_REG_ALARM_Y
),
43 regmap_reg_range(DA9063_REG_SEQ
, DA9063_REG_ID_32_31
),
44 regmap_reg_range(DA9063_REG_SEQ_A
, DA9063_REG_AUTO3_LOW
),
45 regmap_reg_range(DA9063_REG_CONFIG_I
, DA9063_AD_REG_MON_REG_4
),
46 regmap_reg_range(DA9063_AD_REG_GP_ID_0
, DA9063_AD_REG_GP_ID_19
),
49 static const struct regmap_range da9063_ad_volatile_ranges
[] = {
50 regmap_reg_range(DA9063_REG_PAGE_CON
, DA9063_REG_EVENT_D
),
51 regmap_reg_range(DA9063_REG_CONTROL_A
, DA9063_REG_CONTROL_B
),
52 regmap_reg_range(DA9063_REG_CONTROL_E
, DA9063_REG_CONTROL_F
),
53 regmap_reg_range(DA9063_REG_BCORE2_CONT
, DA9063_REG_LDO11_CONT
),
54 regmap_reg_range(DA9063_REG_DVC_1
, DA9063_REG_ADC_MAN
),
55 regmap_reg_range(DA9063_REG_ADC_RES_L
, DA9063_AD_REG_SECOND_D
),
56 regmap_reg_range(DA9063_REG_SEQ
, DA9063_REG_SEQ
),
57 regmap_reg_range(DA9063_REG_EN_32K
, DA9063_REG_EN_32K
),
58 regmap_reg_range(DA9063_AD_REG_MON_REG_5
, DA9063_AD_REG_MON_REG_6
),
61 static const struct regmap_access_table da9063_ad_readable_table
= {
62 .yes_ranges
= da9063_ad_readable_ranges
,
63 .n_yes_ranges
= ARRAY_SIZE(da9063_ad_readable_ranges
),
66 static const struct regmap_access_table da9063_ad_writeable_table
= {
67 .yes_ranges
= da9063_ad_writeable_ranges
,
68 .n_yes_ranges
= ARRAY_SIZE(da9063_ad_writeable_ranges
),
71 static const struct regmap_access_table da9063_ad_volatile_table
= {
72 .yes_ranges
= da9063_ad_volatile_ranges
,
73 .n_yes_ranges
= ARRAY_SIZE(da9063_ad_volatile_ranges
),
76 static const struct regmap_range da9063_bb_readable_ranges
[] = {
77 regmap_reg_range(DA9063_REG_PAGE_CON
, DA9063_BB_REG_SECOND_D
),
78 regmap_reg_range(DA9063_REG_SEQ
, DA9063_REG_ID_32_31
),
79 regmap_reg_range(DA9063_REG_SEQ_A
, DA9063_REG_AUTO3_LOW
),
80 regmap_reg_range(DA9063_REG_T_OFFSET
, DA9063_BB_REG_GP_ID_19
),
81 regmap_reg_range(DA9063_REG_CHIP_ID
, DA9063_REG_CHIP_VARIANT
),
84 static const struct regmap_range da9063_bb_writeable_ranges
[] = {
85 regmap_reg_range(DA9063_REG_PAGE_CON
, DA9063_REG_PAGE_CON
),
86 regmap_reg_range(DA9063_REG_FAULT_LOG
, DA9063_REG_VSYS_MON
),
87 regmap_reg_range(DA9063_REG_COUNT_S
, DA9063_BB_REG_ALARM_Y
),
88 regmap_reg_range(DA9063_REG_SEQ
, DA9063_REG_ID_32_31
),
89 regmap_reg_range(DA9063_REG_SEQ_A
, DA9063_REG_AUTO3_LOW
),
90 regmap_reg_range(DA9063_REG_CONFIG_I
, DA9063_BB_REG_MON_REG_4
),
91 regmap_reg_range(DA9063_BB_REG_GP_ID_0
, DA9063_BB_REG_GP_ID_19
),
94 static const struct regmap_range da9063_bb_volatile_ranges
[] = {
95 regmap_reg_range(DA9063_REG_PAGE_CON
, DA9063_REG_EVENT_D
),
96 regmap_reg_range(DA9063_REG_CONTROL_A
, DA9063_REG_CONTROL_B
),
97 regmap_reg_range(DA9063_REG_CONTROL_E
, DA9063_REG_CONTROL_F
),
98 regmap_reg_range(DA9063_REG_BCORE2_CONT
, DA9063_REG_LDO11_CONT
),
99 regmap_reg_range(DA9063_REG_DVC_1
, DA9063_REG_ADC_MAN
),
100 regmap_reg_range(DA9063_REG_ADC_RES_L
, DA9063_BB_REG_SECOND_D
),
101 regmap_reg_range(DA9063_REG_SEQ
, DA9063_REG_SEQ
),
102 regmap_reg_range(DA9063_REG_EN_32K
, DA9063_REG_EN_32K
),
103 regmap_reg_range(DA9063_BB_REG_MON_REG_5
, DA9063_BB_REG_MON_REG_6
),
106 static const struct regmap_access_table da9063_bb_readable_table
= {
107 .yes_ranges
= da9063_bb_readable_ranges
,
108 .n_yes_ranges
= ARRAY_SIZE(da9063_bb_readable_ranges
),
111 static const struct regmap_access_table da9063_bb_writeable_table
= {
112 .yes_ranges
= da9063_bb_writeable_ranges
,
113 .n_yes_ranges
= ARRAY_SIZE(da9063_bb_writeable_ranges
),
116 static const struct regmap_access_table da9063_bb_volatile_table
= {
117 .yes_ranges
= da9063_bb_volatile_ranges
,
118 .n_yes_ranges
= ARRAY_SIZE(da9063_bb_volatile_ranges
),
121 static const struct regmap_range da9063l_bb_readable_ranges
[] = {
122 regmap_reg_range(DA9063_REG_PAGE_CON
, DA9063_REG_MON_A10_RES
),
123 regmap_reg_range(DA9063_REG_SEQ
, DA9063_REG_ID_32_31
),
124 regmap_reg_range(DA9063_REG_SEQ_A
, DA9063_REG_AUTO3_LOW
),
125 regmap_reg_range(DA9063_REG_T_OFFSET
, DA9063_BB_REG_GP_ID_19
),
126 regmap_reg_range(DA9063_REG_CHIP_ID
, DA9063_REG_CHIP_VARIANT
),
129 static const struct regmap_range da9063l_bb_writeable_ranges
[] = {
130 regmap_reg_range(DA9063_REG_PAGE_CON
, DA9063_REG_PAGE_CON
),
131 regmap_reg_range(DA9063_REG_FAULT_LOG
, DA9063_REG_VSYS_MON
),
132 regmap_reg_range(DA9063_REG_SEQ
, DA9063_REG_ID_32_31
),
133 regmap_reg_range(DA9063_REG_SEQ_A
, DA9063_REG_AUTO3_LOW
),
134 regmap_reg_range(DA9063_REG_CONFIG_I
, DA9063_BB_REG_MON_REG_4
),
135 regmap_reg_range(DA9063_BB_REG_GP_ID_0
, DA9063_BB_REG_GP_ID_19
),
138 static const struct regmap_range da9063l_bb_volatile_ranges
[] = {
139 regmap_reg_range(DA9063_REG_PAGE_CON
, DA9063_REG_EVENT_D
),
140 regmap_reg_range(DA9063_REG_CONTROL_A
, DA9063_REG_CONTROL_B
),
141 regmap_reg_range(DA9063_REG_CONTROL_E
, DA9063_REG_CONTROL_F
),
142 regmap_reg_range(DA9063_REG_BCORE2_CONT
, DA9063_REG_LDO11_CONT
),
143 regmap_reg_range(DA9063_REG_DVC_1
, DA9063_REG_ADC_MAN
),
144 regmap_reg_range(DA9063_REG_ADC_RES_L
, DA9063_REG_MON_A10_RES
),
145 regmap_reg_range(DA9063_REG_SEQ
, DA9063_REG_SEQ
),
146 regmap_reg_range(DA9063_REG_EN_32K
, DA9063_REG_EN_32K
),
147 regmap_reg_range(DA9063_BB_REG_MON_REG_5
, DA9063_BB_REG_MON_REG_6
),
150 static const struct regmap_access_table da9063l_bb_readable_table
= {
151 .yes_ranges
= da9063l_bb_readable_ranges
,
152 .n_yes_ranges
= ARRAY_SIZE(da9063l_bb_readable_ranges
),
155 static const struct regmap_access_table da9063l_bb_writeable_table
= {
156 .yes_ranges
= da9063l_bb_writeable_ranges
,
157 .n_yes_ranges
= ARRAY_SIZE(da9063l_bb_writeable_ranges
),
160 static const struct regmap_access_table da9063l_bb_volatile_table
= {
161 .yes_ranges
= da9063l_bb_volatile_ranges
,
162 .n_yes_ranges
= ARRAY_SIZE(da9063l_bb_volatile_ranges
),
165 static const struct regmap_range_cfg da9063_range_cfg
[] = {
167 .range_min
= DA9063_REG_PAGE_CON
,
168 .range_max
= DA9063_REG_CHIP_VARIANT
,
169 .selector_reg
= DA9063_REG_PAGE_CON
,
170 .selector_mask
= 1 << DA9063_I2C_PAGE_SEL_SHIFT
,
171 .selector_shift
= DA9063_I2C_PAGE_SEL_SHIFT
,
177 static struct regmap_config da9063_regmap_config
= {
180 .ranges
= da9063_range_cfg
,
181 .num_ranges
= ARRAY_SIZE(da9063_range_cfg
),
182 .max_register
= DA9063_REG_CHIP_VARIANT
,
184 .cache_type
= REGCACHE_RBTREE
,
187 static const struct of_device_id da9063_dt_ids
[] = {
188 { .compatible
= "dlg,da9063", },
189 { .compatible
= "dlg,da9063l", },
192 MODULE_DEVICE_TABLE(of
, da9063_dt_ids
);
193 static int da9063_i2c_probe(struct i2c_client
*i2c
,
194 const struct i2c_device_id
*id
)
196 struct da9063
*da9063
;
199 da9063
= devm_kzalloc(&i2c
->dev
, sizeof(struct da9063
), GFP_KERNEL
);
203 i2c_set_clientdata(i2c
, da9063
);
204 da9063
->dev
= &i2c
->dev
;
205 da9063
->chip_irq
= i2c
->irq
;
206 da9063
->type
= id
->driver_data
;
208 if (da9063
->variant_code
== PMIC_DA9063_AD
) {
209 da9063_regmap_config
.rd_table
= &da9063_ad_readable_table
;
210 da9063_regmap_config
.wr_table
= &da9063_ad_writeable_table
;
211 da9063_regmap_config
.volatile_table
= &da9063_ad_volatile_table
;
212 } else if (da9063
->type
== PMIC_TYPE_DA9063L
) {
213 da9063_regmap_config
.rd_table
= &da9063l_bb_readable_table
;
214 da9063_regmap_config
.wr_table
= &da9063l_bb_writeable_table
;
215 da9063_regmap_config
.volatile_table
= &da9063l_bb_volatile_table
;
217 da9063_regmap_config
.rd_table
= &da9063_bb_readable_table
;
218 da9063_regmap_config
.wr_table
= &da9063_bb_writeable_table
;
219 da9063_regmap_config
.volatile_table
= &da9063_bb_volatile_table
;
222 da9063
->regmap
= devm_regmap_init_i2c(i2c
, &da9063_regmap_config
);
223 if (IS_ERR(da9063
->regmap
)) {
224 ret
= PTR_ERR(da9063
->regmap
);
225 dev_err(da9063
->dev
, "Failed to allocate register map: %d\n",
230 return da9063_device_init(da9063
, i2c
->irq
);
233 static const struct i2c_device_id da9063_i2c_id
[] = {
234 { "da9063", PMIC_TYPE_DA9063
},
235 { "da9063l", PMIC_TYPE_DA9063L
},
238 MODULE_DEVICE_TABLE(i2c
, da9063_i2c_id
);
240 static struct i2c_driver da9063_i2c_driver
= {
243 .of_match_table
= of_match_ptr(da9063_dt_ids
),
245 .probe
= da9063_i2c_probe
,
246 .id_table
= da9063_i2c_id
,
249 module_i2c_driver(da9063_i2c_driver
);