1 // SPDX-License-Identifier: GPL-2.0+
2 /* I2C support for Dialog DA9063
4 * Copyright 2012 Dialog Semiconductor Ltd.
5 * Copyright 2013 Philipp Zabel, Pengutronix
7 * Author: Krystian Garbaciak, Dialog Semiconductor
10 #include <linux/kernel.h>
11 #include <linux/module.h>
12 #include <linux/i2c.h>
13 #include <linux/regmap.h>
14 #include <linux/delay.h>
15 #include <linux/slab.h>
16 #include <linux/err.h>
18 #include <linux/mfd/core.h>
19 #include <linux/mfd/da9063/core.h>
20 #include <linux/mfd/da9063/registers.h>
23 #include <linux/regulator/of_regulator.h>
25 static const struct regmap_range da9063_ad_readable_ranges
[] = {
26 regmap_reg_range(DA9063_REG_PAGE_CON
, DA9063_AD_REG_SECOND_D
),
27 regmap_reg_range(DA9063_REG_SEQ
, DA9063_REG_ID_32_31
),
28 regmap_reg_range(DA9063_REG_SEQ_A
, DA9063_REG_AUTO3_LOW
),
29 regmap_reg_range(DA9063_REG_T_OFFSET
, DA9063_AD_REG_GP_ID_19
),
30 regmap_reg_range(DA9063_REG_CHIP_ID
, DA9063_REG_CHIP_VARIANT
),
33 static const struct regmap_range da9063_ad_writeable_ranges
[] = {
34 regmap_reg_range(DA9063_REG_PAGE_CON
, DA9063_REG_PAGE_CON
),
35 regmap_reg_range(DA9063_REG_FAULT_LOG
, DA9063_REG_VSYS_MON
),
36 regmap_reg_range(DA9063_REG_COUNT_S
, DA9063_AD_REG_ALARM_Y
),
37 regmap_reg_range(DA9063_REG_SEQ
, DA9063_REG_ID_32_31
),
38 regmap_reg_range(DA9063_REG_SEQ_A
, DA9063_REG_AUTO3_LOW
),
39 regmap_reg_range(DA9063_REG_CONFIG_I
, DA9063_AD_REG_MON_REG_4
),
40 regmap_reg_range(DA9063_AD_REG_GP_ID_0
, DA9063_AD_REG_GP_ID_19
),
43 static const struct regmap_range da9063_ad_volatile_ranges
[] = {
44 regmap_reg_range(DA9063_REG_PAGE_CON
, DA9063_REG_EVENT_D
),
45 regmap_reg_range(DA9063_REG_CONTROL_A
, DA9063_REG_CONTROL_B
),
46 regmap_reg_range(DA9063_REG_CONTROL_E
, DA9063_REG_CONTROL_F
),
47 regmap_reg_range(DA9063_REG_BCORE2_CONT
, DA9063_REG_LDO11_CONT
),
48 regmap_reg_range(DA9063_REG_DVC_1
, DA9063_REG_ADC_MAN
),
49 regmap_reg_range(DA9063_REG_ADC_RES_L
, DA9063_AD_REG_SECOND_D
),
50 regmap_reg_range(DA9063_REG_SEQ
, DA9063_REG_SEQ
),
51 regmap_reg_range(DA9063_REG_EN_32K
, DA9063_REG_EN_32K
),
52 regmap_reg_range(DA9063_AD_REG_MON_REG_5
, DA9063_AD_REG_MON_REG_6
),
55 static const struct regmap_access_table da9063_ad_readable_table
= {
56 .yes_ranges
= da9063_ad_readable_ranges
,
57 .n_yes_ranges
= ARRAY_SIZE(da9063_ad_readable_ranges
),
60 static const struct regmap_access_table da9063_ad_writeable_table
= {
61 .yes_ranges
= da9063_ad_writeable_ranges
,
62 .n_yes_ranges
= ARRAY_SIZE(da9063_ad_writeable_ranges
),
65 static const struct regmap_access_table da9063_ad_volatile_table
= {
66 .yes_ranges
= da9063_ad_volatile_ranges
,
67 .n_yes_ranges
= ARRAY_SIZE(da9063_ad_volatile_ranges
),
70 static const struct regmap_range da9063_bb_readable_ranges
[] = {
71 regmap_reg_range(DA9063_REG_PAGE_CON
, DA9063_BB_REG_SECOND_D
),
72 regmap_reg_range(DA9063_REG_SEQ
, DA9063_REG_ID_32_31
),
73 regmap_reg_range(DA9063_REG_SEQ_A
, DA9063_REG_AUTO3_LOW
),
74 regmap_reg_range(DA9063_REG_T_OFFSET
, DA9063_BB_REG_GP_ID_19
),
75 regmap_reg_range(DA9063_REG_CHIP_ID
, DA9063_REG_CHIP_VARIANT
),
78 static const struct regmap_range da9063_bb_writeable_ranges
[] = {
79 regmap_reg_range(DA9063_REG_PAGE_CON
, DA9063_REG_PAGE_CON
),
80 regmap_reg_range(DA9063_REG_FAULT_LOG
, DA9063_REG_VSYS_MON
),
81 regmap_reg_range(DA9063_REG_COUNT_S
, DA9063_BB_REG_ALARM_Y
),
82 regmap_reg_range(DA9063_REG_SEQ
, DA9063_REG_ID_32_31
),
83 regmap_reg_range(DA9063_REG_SEQ_A
, DA9063_REG_AUTO3_LOW
),
84 regmap_reg_range(DA9063_REG_CONFIG_I
, DA9063_BB_REG_MON_REG_4
),
85 regmap_reg_range(DA9063_BB_REG_GP_ID_0
, DA9063_BB_REG_GP_ID_19
),
88 static const struct regmap_range da9063_bb_volatile_ranges
[] = {
89 regmap_reg_range(DA9063_REG_PAGE_CON
, DA9063_REG_EVENT_D
),
90 regmap_reg_range(DA9063_REG_CONTROL_A
, DA9063_REG_CONTROL_B
),
91 regmap_reg_range(DA9063_REG_CONTROL_E
, DA9063_REG_CONTROL_F
),
92 regmap_reg_range(DA9063_REG_BCORE2_CONT
, DA9063_REG_LDO11_CONT
),
93 regmap_reg_range(DA9063_REG_DVC_1
, DA9063_REG_ADC_MAN
),
94 regmap_reg_range(DA9063_REG_ADC_RES_L
, DA9063_BB_REG_SECOND_D
),
95 regmap_reg_range(DA9063_REG_SEQ
, DA9063_REG_SEQ
),
96 regmap_reg_range(DA9063_REG_EN_32K
, DA9063_REG_EN_32K
),
97 regmap_reg_range(DA9063_BB_REG_MON_REG_5
, DA9063_BB_REG_MON_REG_6
),
100 static const struct regmap_access_table da9063_bb_readable_table
= {
101 .yes_ranges
= da9063_bb_readable_ranges
,
102 .n_yes_ranges
= ARRAY_SIZE(da9063_bb_readable_ranges
),
105 static const struct regmap_access_table da9063_bb_writeable_table
= {
106 .yes_ranges
= da9063_bb_writeable_ranges
,
107 .n_yes_ranges
= ARRAY_SIZE(da9063_bb_writeable_ranges
),
110 static const struct regmap_access_table da9063_bb_volatile_table
= {
111 .yes_ranges
= da9063_bb_volatile_ranges
,
112 .n_yes_ranges
= ARRAY_SIZE(da9063_bb_volatile_ranges
),
115 static const struct regmap_range da9063l_bb_readable_ranges
[] = {
116 regmap_reg_range(DA9063_REG_PAGE_CON
, DA9063_REG_MON_A10_RES
),
117 regmap_reg_range(DA9063_REG_SEQ
, DA9063_REG_ID_32_31
),
118 regmap_reg_range(DA9063_REG_SEQ_A
, DA9063_REG_AUTO3_LOW
),
119 regmap_reg_range(DA9063_REG_T_OFFSET
, DA9063_BB_REG_GP_ID_19
),
120 regmap_reg_range(DA9063_REG_CHIP_ID
, DA9063_REG_CHIP_VARIANT
),
123 static const struct regmap_range da9063l_bb_writeable_ranges
[] = {
124 regmap_reg_range(DA9063_REG_PAGE_CON
, DA9063_REG_PAGE_CON
),
125 regmap_reg_range(DA9063_REG_FAULT_LOG
, DA9063_REG_VSYS_MON
),
126 regmap_reg_range(DA9063_REG_SEQ
, DA9063_REG_ID_32_31
),
127 regmap_reg_range(DA9063_REG_SEQ_A
, DA9063_REG_AUTO3_LOW
),
128 regmap_reg_range(DA9063_REG_CONFIG_I
, DA9063_BB_REG_MON_REG_4
),
129 regmap_reg_range(DA9063_BB_REG_GP_ID_0
, DA9063_BB_REG_GP_ID_19
),
132 static const struct regmap_range da9063l_bb_volatile_ranges
[] = {
133 regmap_reg_range(DA9063_REG_PAGE_CON
, DA9063_REG_EVENT_D
),
134 regmap_reg_range(DA9063_REG_CONTROL_A
, DA9063_REG_CONTROL_B
),
135 regmap_reg_range(DA9063_REG_CONTROL_E
, DA9063_REG_CONTROL_F
),
136 regmap_reg_range(DA9063_REG_BCORE2_CONT
, DA9063_REG_LDO11_CONT
),
137 regmap_reg_range(DA9063_REG_DVC_1
, DA9063_REG_ADC_MAN
),
138 regmap_reg_range(DA9063_REG_ADC_RES_L
, DA9063_REG_MON_A10_RES
),
139 regmap_reg_range(DA9063_REG_SEQ
, DA9063_REG_SEQ
),
140 regmap_reg_range(DA9063_REG_EN_32K
, DA9063_REG_EN_32K
),
141 regmap_reg_range(DA9063_BB_REG_MON_REG_5
, DA9063_BB_REG_MON_REG_6
),
144 static const struct regmap_access_table da9063l_bb_readable_table
= {
145 .yes_ranges
= da9063l_bb_readable_ranges
,
146 .n_yes_ranges
= ARRAY_SIZE(da9063l_bb_readable_ranges
),
149 static const struct regmap_access_table da9063l_bb_writeable_table
= {
150 .yes_ranges
= da9063l_bb_writeable_ranges
,
151 .n_yes_ranges
= ARRAY_SIZE(da9063l_bb_writeable_ranges
),
154 static const struct regmap_access_table da9063l_bb_volatile_table
= {
155 .yes_ranges
= da9063l_bb_volatile_ranges
,
156 .n_yes_ranges
= ARRAY_SIZE(da9063l_bb_volatile_ranges
),
159 static const struct regmap_range_cfg da9063_range_cfg
[] = {
161 .range_min
= DA9063_REG_PAGE_CON
,
162 .range_max
= DA9063_REG_CHIP_VARIANT
,
163 .selector_reg
= DA9063_REG_PAGE_CON
,
164 .selector_mask
= 1 << DA9063_I2C_PAGE_SEL_SHIFT
,
165 .selector_shift
= DA9063_I2C_PAGE_SEL_SHIFT
,
171 static struct regmap_config da9063_regmap_config
= {
174 .ranges
= da9063_range_cfg
,
175 .num_ranges
= ARRAY_SIZE(da9063_range_cfg
),
176 .max_register
= DA9063_REG_CHIP_VARIANT
,
178 .cache_type
= REGCACHE_RBTREE
,
181 static const struct of_device_id da9063_dt_ids
[] = {
182 { .compatible
= "dlg,da9063", },
183 { .compatible
= "dlg,da9063l", },
186 MODULE_DEVICE_TABLE(of
, da9063_dt_ids
);
187 static int da9063_i2c_probe(struct i2c_client
*i2c
,
188 const struct i2c_device_id
*id
)
190 struct da9063
*da9063
;
193 da9063
= devm_kzalloc(&i2c
->dev
, sizeof(struct da9063
), GFP_KERNEL
);
197 i2c_set_clientdata(i2c
, da9063
);
198 da9063
->dev
= &i2c
->dev
;
199 da9063
->chip_irq
= i2c
->irq
;
200 da9063
->type
= id
->driver_data
;
202 if (da9063
->variant_code
== PMIC_DA9063_AD
) {
203 da9063_regmap_config
.rd_table
= &da9063_ad_readable_table
;
204 da9063_regmap_config
.wr_table
= &da9063_ad_writeable_table
;
205 da9063_regmap_config
.volatile_table
= &da9063_ad_volatile_table
;
206 } else if (da9063
->type
== PMIC_TYPE_DA9063L
) {
207 da9063_regmap_config
.rd_table
= &da9063l_bb_readable_table
;
208 da9063_regmap_config
.wr_table
= &da9063l_bb_writeable_table
;
209 da9063_regmap_config
.volatile_table
= &da9063l_bb_volatile_table
;
211 da9063_regmap_config
.rd_table
= &da9063_bb_readable_table
;
212 da9063_regmap_config
.wr_table
= &da9063_bb_writeable_table
;
213 da9063_regmap_config
.volatile_table
= &da9063_bb_volatile_table
;
216 da9063
->regmap
= devm_regmap_init_i2c(i2c
, &da9063_regmap_config
);
217 if (IS_ERR(da9063
->regmap
)) {
218 ret
= PTR_ERR(da9063
->regmap
);
219 dev_err(da9063
->dev
, "Failed to allocate register map: %d\n",
224 return da9063_device_init(da9063
, i2c
->irq
);
227 static const struct i2c_device_id da9063_i2c_id
[] = {
228 { "da9063", PMIC_TYPE_DA9063
},
229 { "da9063l", PMIC_TYPE_DA9063L
},
232 MODULE_DEVICE_TABLE(i2c
, da9063_i2c_id
);
234 static struct i2c_driver da9063_i2c_driver
= {
237 .of_match_table
= of_match_ptr(da9063_dt_ids
),
239 .probe
= da9063_i2c_probe
,
240 .id_table
= da9063_i2c_id
,
243 module_i2c_driver(da9063_i2c_driver
);