1 // SPDX-License-Identifier: GPL-2.0+ 2 /* I2C support for Dialog DA9063 3 * 4 * Copyright 2012 Dialog Semiconductor Ltd. 5 * Copyright 2013 Philipp Zabel, Pengutronix 6 * 7 * Author: Krystian Garbaciak, Dialog Semiconductor 8 */ 9 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> 17 18 #include <linux/mfd/core.h> 19 #include <linux/mfd/da9063/core.h> 20 #include <linux/mfd/da9063/registers.h> 21 22 #include <linux/of.h> 23 #include <linux/regulator/of_regulator.h> 24 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), 31 }; 32 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), 41 }; 42 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), 53 }; 54 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), 58 }; 59 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), 63 }; 64 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), 68 }; 69 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), 76 }; 77 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), 86 }; 87 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), 98 }; 99 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), 103 }; 104 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), 108 }; 109 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), 113 }; 114 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), 121 }; 122 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), 130 }; 131 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), 142 }; 143 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), 147 }; 148 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), 152 }; 153 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), 157 }; 158 159 static const struct regmap_range_cfg da9063_range_cfg[] = { 160 { 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, 166 .window_start = 0, 167 .window_len = 256, 168 } 169 }; 170 171 static struct regmap_config da9063_regmap_config = { 172 .reg_bits = 8, 173 .val_bits = 8, 174 .ranges = da9063_range_cfg, 175 .num_ranges = ARRAY_SIZE(da9063_range_cfg), 176 .max_register = DA9063_REG_CHIP_VARIANT, 177 178 .cache_type = REGCACHE_RBTREE, 179 }; 180 181 static const struct of_device_id da9063_dt_ids[] = { 182 { .compatible = "dlg,da9063", }, 183 { .compatible = "dlg,da9063l", }, 184 { } 185 }; 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) 189 { 190 struct da9063 *da9063; 191 int ret; 192 193 da9063 = devm_kzalloc(&i2c->dev, sizeof(struct da9063), GFP_KERNEL); 194 if (da9063 == NULL) 195 return -ENOMEM; 196 197 i2c_set_clientdata(i2c, da9063); 198 da9063->dev = &i2c->dev; 199 da9063->chip_irq = i2c->irq; 200 da9063->type = id->driver_data; 201 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; 210 } else { 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; 214 } 215 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", 220 ret); 221 return ret; 222 } 223 224 return da9063_device_init(da9063, i2c->irq); 225 } 226 227 static const struct i2c_device_id da9063_i2c_id[] = { 228 { "da9063", PMIC_TYPE_DA9063 }, 229 { "da9063l", PMIC_TYPE_DA9063L }, 230 {}, 231 }; 232 MODULE_DEVICE_TABLE(i2c, da9063_i2c_id); 233 234 static struct i2c_driver da9063_i2c_driver = { 235 .driver = { 236 .name = "da9063", 237 .of_match_table = of_match_ptr(da9063_dt_ids), 238 }, 239 .probe = da9063_i2c_probe, 240 .id_table = da9063_i2c_id, 241 }; 242 243 module_i2c_driver(da9063_i2c_driver); 244