.. | .. |
---|
1 | | -/* da9063-i2c.c: Interrupt support for Dialog DA9063 |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0+ |
---|
| 2 | +/* I2C support for Dialog DA9063 |
---|
2 | 3 | * |
---|
3 | 4 | * Copyright 2012 Dialog Semiconductor Ltd. |
---|
4 | 5 | * Copyright 2013 Philipp Zabel, Pengutronix |
---|
5 | 6 | * |
---|
6 | 7 | * Author: Krystian Garbaciak, Dialog Semiconductor |
---|
7 | | - * |
---|
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. |
---|
12 | | - * |
---|
13 | 8 | */ |
---|
14 | 9 | |
---|
15 | 10 | #include <linux/kernel.h> |
---|
.. | .. |
---|
22 | 17 | |
---|
23 | 18 | #include <linux/mfd/core.h> |
---|
24 | 19 | #include <linux/mfd/da9063/core.h> |
---|
25 | | -#include <linux/mfd/da9063/pdata.h> |
---|
26 | 20 | #include <linux/mfd/da9063/registers.h> |
---|
27 | 21 | |
---|
28 | 22 | #include <linux/of.h> |
---|
29 | 23 | #include <linux/regulator/of_regulator.h> |
---|
| 24 | + |
---|
| 25 | +/* |
---|
| 26 | + * Raw I2C access required for just accessing chip and variant info before we |
---|
| 27 | + * know which device is present. The info read from the device using this |
---|
| 28 | + * approach is then used to select the correct regmap tables. |
---|
| 29 | + */ |
---|
| 30 | + |
---|
| 31 | +#define DA9063_REG_PAGE_SIZE 0x100 |
---|
| 32 | +#define DA9063_REG_PAGED_ADDR_MASK 0xFF |
---|
| 33 | + |
---|
| 34 | +enum da9063_page_sel_buf_fmt { |
---|
| 35 | + DA9063_PAGE_SEL_BUF_PAGE_REG = 0, |
---|
| 36 | + DA9063_PAGE_SEL_BUF_PAGE_VAL, |
---|
| 37 | + DA9063_PAGE_SEL_BUF_SIZE, |
---|
| 38 | +}; |
---|
| 39 | + |
---|
| 40 | +enum da9063_paged_read_msgs { |
---|
| 41 | + DA9063_PAGED_READ_MSG_PAGE_SEL = 0, |
---|
| 42 | + DA9063_PAGED_READ_MSG_REG_SEL, |
---|
| 43 | + DA9063_PAGED_READ_MSG_DATA, |
---|
| 44 | + DA9063_PAGED_READ_MSG_CNT, |
---|
| 45 | +}; |
---|
| 46 | + |
---|
| 47 | +static int da9063_i2c_blockreg_read(struct i2c_client *client, u16 addr, |
---|
| 48 | + u8 *buf, int count) |
---|
| 49 | +{ |
---|
| 50 | + struct i2c_msg xfer[DA9063_PAGED_READ_MSG_CNT]; |
---|
| 51 | + u8 page_sel_buf[DA9063_PAGE_SEL_BUF_SIZE]; |
---|
| 52 | + u8 page_num, paged_addr; |
---|
| 53 | + int ret; |
---|
| 54 | + |
---|
| 55 | + /* Determine page info based on register address */ |
---|
| 56 | + page_num = (addr / DA9063_REG_PAGE_SIZE); |
---|
| 57 | + if (page_num > 1) { |
---|
| 58 | + dev_err(&client->dev, "Invalid register address provided\n"); |
---|
| 59 | + return -EINVAL; |
---|
| 60 | + } |
---|
| 61 | + |
---|
| 62 | + paged_addr = (addr % DA9063_REG_PAGE_SIZE) & DA9063_REG_PAGED_ADDR_MASK; |
---|
| 63 | + page_sel_buf[DA9063_PAGE_SEL_BUF_PAGE_REG] = DA9063_REG_PAGE_CON; |
---|
| 64 | + page_sel_buf[DA9063_PAGE_SEL_BUF_PAGE_VAL] = |
---|
| 65 | + (page_num << DA9063_I2C_PAGE_SEL_SHIFT) & DA9063_REG_PAGE_MASK; |
---|
| 66 | + |
---|
| 67 | + /* Write reg address, page selection */ |
---|
| 68 | + xfer[DA9063_PAGED_READ_MSG_PAGE_SEL].addr = client->addr; |
---|
| 69 | + xfer[DA9063_PAGED_READ_MSG_PAGE_SEL].flags = 0; |
---|
| 70 | + xfer[DA9063_PAGED_READ_MSG_PAGE_SEL].len = DA9063_PAGE_SEL_BUF_SIZE; |
---|
| 71 | + xfer[DA9063_PAGED_READ_MSG_PAGE_SEL].buf = page_sel_buf; |
---|
| 72 | + |
---|
| 73 | + /* Select register address */ |
---|
| 74 | + xfer[DA9063_PAGED_READ_MSG_REG_SEL].addr = client->addr; |
---|
| 75 | + xfer[DA9063_PAGED_READ_MSG_REG_SEL].flags = 0; |
---|
| 76 | + xfer[DA9063_PAGED_READ_MSG_REG_SEL].len = sizeof(paged_addr); |
---|
| 77 | + xfer[DA9063_PAGED_READ_MSG_REG_SEL].buf = &paged_addr; |
---|
| 78 | + |
---|
| 79 | + /* Read data */ |
---|
| 80 | + xfer[DA9063_PAGED_READ_MSG_DATA].addr = client->addr; |
---|
| 81 | + xfer[DA9063_PAGED_READ_MSG_DATA].flags = I2C_M_RD; |
---|
| 82 | + xfer[DA9063_PAGED_READ_MSG_DATA].len = count; |
---|
| 83 | + xfer[DA9063_PAGED_READ_MSG_DATA].buf = buf; |
---|
| 84 | + |
---|
| 85 | + ret = i2c_transfer(client->adapter, xfer, DA9063_PAGED_READ_MSG_CNT); |
---|
| 86 | + if (ret < 0) { |
---|
| 87 | + dev_err(&client->dev, "Paged block read failed: %d\n", ret); |
---|
| 88 | + return ret; |
---|
| 89 | + } |
---|
| 90 | + |
---|
| 91 | + if (ret != DA9063_PAGED_READ_MSG_CNT) { |
---|
| 92 | + dev_err(&client->dev, "Paged block read failed to complete\n"); |
---|
| 93 | + return -EIO; |
---|
| 94 | + } |
---|
| 95 | + |
---|
| 96 | + return 0; |
---|
| 97 | +} |
---|
| 98 | + |
---|
| 99 | +enum { |
---|
| 100 | + DA9063_DEV_ID_REG = 0, |
---|
| 101 | + DA9063_VAR_ID_REG, |
---|
| 102 | + DA9063_CHIP_ID_REGS, |
---|
| 103 | +}; |
---|
| 104 | + |
---|
| 105 | +static int da9063_get_device_type(struct i2c_client *i2c, struct da9063 *da9063) |
---|
| 106 | +{ |
---|
| 107 | + u8 buf[DA9063_CHIP_ID_REGS]; |
---|
| 108 | + int ret; |
---|
| 109 | + |
---|
| 110 | + ret = da9063_i2c_blockreg_read(i2c, DA9063_REG_DEVICE_ID, buf, |
---|
| 111 | + DA9063_CHIP_ID_REGS); |
---|
| 112 | + if (ret) |
---|
| 113 | + return ret; |
---|
| 114 | + |
---|
| 115 | + if (buf[DA9063_DEV_ID_REG] != PMIC_CHIP_ID_DA9063) { |
---|
| 116 | + dev_err(da9063->dev, |
---|
| 117 | + "Invalid chip device ID: 0x%02x\n", |
---|
| 118 | + buf[DA9063_DEV_ID_REG]); |
---|
| 119 | + return -ENODEV; |
---|
| 120 | + } |
---|
| 121 | + |
---|
| 122 | + dev_info(da9063->dev, |
---|
| 123 | + "Device detected (chip-ID: 0x%02X, var-ID: 0x%02X)\n", |
---|
| 124 | + buf[DA9063_DEV_ID_REG], buf[DA9063_VAR_ID_REG]); |
---|
| 125 | + |
---|
| 126 | + da9063->variant_code = |
---|
| 127 | + (buf[DA9063_VAR_ID_REG] & DA9063_VARIANT_ID_MRC_MASK) |
---|
| 128 | + >> DA9063_VARIANT_ID_MRC_SHIFT; |
---|
| 129 | + |
---|
| 130 | + return 0; |
---|
| 131 | +} |
---|
| 132 | + |
---|
| 133 | +/* |
---|
| 134 | + * Variant specific regmap configs |
---|
| 135 | + */ |
---|
30 | 136 | |
---|
31 | 137 | static const struct regmap_range da9063_ad_readable_ranges[] = { |
---|
32 | 138 | regmap_reg_range(DA9063_REG_PAGE_CON, DA9063_AD_REG_SECOND_D), |
---|
33 | 139 | regmap_reg_range(DA9063_REG_SEQ, DA9063_REG_ID_32_31), |
---|
34 | 140 | regmap_reg_range(DA9063_REG_SEQ_A, DA9063_REG_AUTO3_LOW), |
---|
35 | 141 | 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), |
---|
| 142 | + regmap_reg_range(DA9063_REG_DEVICE_ID, DA9063_REG_VARIANT_ID), |
---|
37 | 143 | }; |
---|
38 | 144 | |
---|
39 | 145 | static const struct regmap_range da9063_ad_writeable_ranges[] = { |
---|
.. | .. |
---|
78 | 184 | regmap_reg_range(DA9063_REG_SEQ, DA9063_REG_ID_32_31), |
---|
79 | 185 | regmap_reg_range(DA9063_REG_SEQ_A, DA9063_REG_AUTO3_LOW), |
---|
80 | 186 | 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), |
---|
| 187 | + regmap_reg_range(DA9063_REG_DEVICE_ID, DA9063_REG_VARIANT_ID), |
---|
82 | 188 | }; |
---|
83 | 189 | |
---|
84 | 190 | static const struct regmap_range da9063_bb_writeable_ranges[] = { |
---|
.. | .. |
---|
91 | 197 | regmap_reg_range(DA9063_BB_REG_GP_ID_0, DA9063_BB_REG_GP_ID_19), |
---|
92 | 198 | }; |
---|
93 | 199 | |
---|
94 | | -static const struct regmap_range da9063_bb_volatile_ranges[] = { |
---|
| 200 | +static const struct regmap_range da9063_bb_da_volatile_ranges[] = { |
---|
95 | 201 | regmap_reg_range(DA9063_REG_PAGE_CON, DA9063_REG_EVENT_D), |
---|
96 | 202 | regmap_reg_range(DA9063_REG_CONTROL_A, DA9063_REG_CONTROL_B), |
---|
97 | 203 | regmap_reg_range(DA9063_REG_CONTROL_E, DA9063_REG_CONTROL_F), |
---|
.. | .. |
---|
113 | 219 | .n_yes_ranges = ARRAY_SIZE(da9063_bb_writeable_ranges), |
---|
114 | 220 | }; |
---|
115 | 221 | |
---|
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), |
---|
| 222 | +static const struct regmap_access_table da9063_bb_da_volatile_table = { |
---|
| 223 | + .yes_ranges = da9063_bb_da_volatile_ranges, |
---|
| 224 | + .n_yes_ranges = ARRAY_SIZE(da9063_bb_da_volatile_ranges), |
---|
119 | 225 | }; |
---|
120 | 226 | |
---|
121 | 227 | static const struct regmap_range da9063l_bb_readable_ranges[] = { |
---|
.. | .. |
---|
123 | 229 | regmap_reg_range(DA9063_REG_SEQ, DA9063_REG_ID_32_31), |
---|
124 | 230 | regmap_reg_range(DA9063_REG_SEQ_A, DA9063_REG_AUTO3_LOW), |
---|
125 | 231 | 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), |
---|
| 232 | + regmap_reg_range(DA9063_REG_DEVICE_ID, DA9063_REG_VARIANT_ID), |
---|
127 | 233 | }; |
---|
128 | 234 | |
---|
129 | 235 | static const struct regmap_range da9063l_bb_writeable_ranges[] = { |
---|
.. | .. |
---|
135 | 241 | regmap_reg_range(DA9063_BB_REG_GP_ID_0, DA9063_BB_REG_GP_ID_19), |
---|
136 | 242 | }; |
---|
137 | 243 | |
---|
138 | | -static const struct regmap_range da9063l_bb_volatile_ranges[] = { |
---|
| 244 | +static const struct regmap_range da9063l_bb_da_volatile_ranges[] = { |
---|
139 | 245 | regmap_reg_range(DA9063_REG_PAGE_CON, DA9063_REG_EVENT_D), |
---|
140 | 246 | regmap_reg_range(DA9063_REG_CONTROL_A, DA9063_REG_CONTROL_B), |
---|
141 | 247 | regmap_reg_range(DA9063_REG_CONTROL_E, DA9063_REG_CONTROL_F), |
---|
.. | .. |
---|
157 | 263 | .n_yes_ranges = ARRAY_SIZE(da9063l_bb_writeable_ranges), |
---|
158 | 264 | }; |
---|
159 | 265 | |
---|
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), |
---|
| 266 | +static const struct regmap_access_table da9063l_bb_da_volatile_table = { |
---|
| 267 | + .yes_ranges = da9063l_bb_da_volatile_ranges, |
---|
| 268 | + .n_yes_ranges = ARRAY_SIZE(da9063l_bb_da_volatile_ranges), |
---|
| 269 | +}; |
---|
| 270 | + |
---|
| 271 | +static const struct regmap_range da9063_da_readable_ranges[] = { |
---|
| 272 | + regmap_reg_range(DA9063_REG_PAGE_CON, DA9063_BB_REG_SECOND_D), |
---|
| 273 | + regmap_reg_range(DA9063_REG_SEQ, DA9063_REG_ID_32_31), |
---|
| 274 | + regmap_reg_range(DA9063_REG_SEQ_A, DA9063_REG_AUTO3_LOW), |
---|
| 275 | + regmap_reg_range(DA9063_REG_T_OFFSET, DA9063_BB_REG_GP_ID_11), |
---|
| 276 | + regmap_reg_range(DA9063_REG_DEVICE_ID, DA9063_REG_VARIANT_ID), |
---|
| 277 | +}; |
---|
| 278 | + |
---|
| 279 | +static const struct regmap_range da9063_da_writeable_ranges[] = { |
---|
| 280 | + regmap_reg_range(DA9063_REG_PAGE_CON, DA9063_REG_PAGE_CON), |
---|
| 281 | + regmap_reg_range(DA9063_REG_FAULT_LOG, DA9063_REG_VSYS_MON), |
---|
| 282 | + regmap_reg_range(DA9063_REG_COUNT_S, DA9063_BB_REG_ALARM_Y), |
---|
| 283 | + regmap_reg_range(DA9063_REG_SEQ, DA9063_REG_ID_32_31), |
---|
| 284 | + regmap_reg_range(DA9063_REG_SEQ_A, DA9063_REG_AUTO3_LOW), |
---|
| 285 | + regmap_reg_range(DA9063_REG_CONFIG_I, DA9063_BB_REG_MON_REG_4), |
---|
| 286 | + regmap_reg_range(DA9063_BB_REG_GP_ID_0, DA9063_BB_REG_GP_ID_11), |
---|
| 287 | +}; |
---|
| 288 | + |
---|
| 289 | +static const struct regmap_access_table da9063_da_readable_table = { |
---|
| 290 | + .yes_ranges = da9063_da_readable_ranges, |
---|
| 291 | + .n_yes_ranges = ARRAY_SIZE(da9063_da_readable_ranges), |
---|
| 292 | +}; |
---|
| 293 | + |
---|
| 294 | +static const struct regmap_access_table da9063_da_writeable_table = { |
---|
| 295 | + .yes_ranges = da9063_da_writeable_ranges, |
---|
| 296 | + .n_yes_ranges = ARRAY_SIZE(da9063_da_writeable_ranges), |
---|
| 297 | +}; |
---|
| 298 | + |
---|
| 299 | +static const struct regmap_range da9063l_da_readable_ranges[] = { |
---|
| 300 | + regmap_reg_range(DA9063_REG_PAGE_CON, DA9063_REG_MON_A10_RES), |
---|
| 301 | + regmap_reg_range(DA9063_REG_SEQ, DA9063_REG_ID_32_31), |
---|
| 302 | + regmap_reg_range(DA9063_REG_SEQ_A, DA9063_REG_AUTO3_LOW), |
---|
| 303 | + regmap_reg_range(DA9063_REG_T_OFFSET, DA9063_BB_REG_GP_ID_11), |
---|
| 304 | + regmap_reg_range(DA9063_REG_DEVICE_ID, DA9063_REG_VARIANT_ID), |
---|
| 305 | +}; |
---|
| 306 | + |
---|
| 307 | +static const struct regmap_range da9063l_da_writeable_ranges[] = { |
---|
| 308 | + regmap_reg_range(DA9063_REG_PAGE_CON, DA9063_REG_PAGE_CON), |
---|
| 309 | + regmap_reg_range(DA9063_REG_FAULT_LOG, DA9063_REG_VSYS_MON), |
---|
| 310 | + regmap_reg_range(DA9063_REG_SEQ, DA9063_REG_ID_32_31), |
---|
| 311 | + regmap_reg_range(DA9063_REG_SEQ_A, DA9063_REG_AUTO3_LOW), |
---|
| 312 | + regmap_reg_range(DA9063_REG_CONFIG_I, DA9063_BB_REG_MON_REG_4), |
---|
| 313 | + regmap_reg_range(DA9063_BB_REG_GP_ID_0, DA9063_BB_REG_GP_ID_11), |
---|
| 314 | +}; |
---|
| 315 | + |
---|
| 316 | +static const struct regmap_access_table da9063l_da_readable_table = { |
---|
| 317 | + .yes_ranges = da9063l_da_readable_ranges, |
---|
| 318 | + .n_yes_ranges = ARRAY_SIZE(da9063l_da_readable_ranges), |
---|
| 319 | +}; |
---|
| 320 | + |
---|
| 321 | +static const struct regmap_access_table da9063l_da_writeable_table = { |
---|
| 322 | + .yes_ranges = da9063l_da_writeable_ranges, |
---|
| 323 | + .n_yes_ranges = ARRAY_SIZE(da9063l_da_writeable_ranges), |
---|
163 | 324 | }; |
---|
164 | 325 | |
---|
165 | 326 | static const struct regmap_range_cfg da9063_range_cfg[] = { |
---|
166 | 327 | { |
---|
167 | 328 | .range_min = DA9063_REG_PAGE_CON, |
---|
168 | | - .range_max = DA9063_REG_CHIP_VARIANT, |
---|
| 329 | + .range_max = DA9063_REG_CONFIG_ID, |
---|
169 | 330 | .selector_reg = DA9063_REG_PAGE_CON, |
---|
170 | 331 | .selector_mask = 1 << DA9063_I2C_PAGE_SEL_SHIFT, |
---|
171 | 332 | .selector_shift = DA9063_I2C_PAGE_SEL_SHIFT, |
---|
.. | .. |
---|
179 | 340 | .val_bits = 8, |
---|
180 | 341 | .ranges = da9063_range_cfg, |
---|
181 | 342 | .num_ranges = ARRAY_SIZE(da9063_range_cfg), |
---|
182 | | - .max_register = DA9063_REG_CHIP_VARIANT, |
---|
| 343 | + .max_register = DA9063_REG_CONFIG_ID, |
---|
183 | 344 | |
---|
184 | 345 | .cache_type = REGCACHE_RBTREE, |
---|
185 | 346 | }; |
---|
.. | .. |
---|
205 | 366 | da9063->chip_irq = i2c->irq; |
---|
206 | 367 | da9063->type = id->driver_data; |
---|
207 | 368 | |
---|
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; |
---|
216 | | - } else { |
---|
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; |
---|
| 369 | + ret = da9063_get_device_type(i2c, da9063); |
---|
| 370 | + if (ret) |
---|
| 371 | + return ret; |
---|
| 372 | + |
---|
| 373 | + switch (da9063->type) { |
---|
| 374 | + case PMIC_TYPE_DA9063: |
---|
| 375 | + switch (da9063->variant_code) { |
---|
| 376 | + case PMIC_DA9063_AD: |
---|
| 377 | + da9063_regmap_config.rd_table = |
---|
| 378 | + &da9063_ad_readable_table; |
---|
| 379 | + da9063_regmap_config.wr_table = |
---|
| 380 | + &da9063_ad_writeable_table; |
---|
| 381 | + da9063_regmap_config.volatile_table = |
---|
| 382 | + &da9063_ad_volatile_table; |
---|
| 383 | + break; |
---|
| 384 | + case PMIC_DA9063_BB: |
---|
| 385 | + case PMIC_DA9063_CA: |
---|
| 386 | + da9063_regmap_config.rd_table = |
---|
| 387 | + &da9063_bb_readable_table; |
---|
| 388 | + da9063_regmap_config.wr_table = |
---|
| 389 | + &da9063_bb_writeable_table; |
---|
| 390 | + da9063_regmap_config.volatile_table = |
---|
| 391 | + &da9063_bb_da_volatile_table; |
---|
| 392 | + break; |
---|
| 393 | + case PMIC_DA9063_DA: |
---|
| 394 | + da9063_regmap_config.rd_table = |
---|
| 395 | + &da9063_da_readable_table; |
---|
| 396 | + da9063_regmap_config.wr_table = |
---|
| 397 | + &da9063_da_writeable_table; |
---|
| 398 | + da9063_regmap_config.volatile_table = |
---|
| 399 | + &da9063_bb_da_volatile_table; |
---|
| 400 | + break; |
---|
| 401 | + default: |
---|
| 402 | + dev_err(da9063->dev, |
---|
| 403 | + "Chip variant not supported for DA9063\n"); |
---|
| 404 | + return -ENODEV; |
---|
| 405 | + } |
---|
| 406 | + break; |
---|
| 407 | + case PMIC_TYPE_DA9063L: |
---|
| 408 | + switch (da9063->variant_code) { |
---|
| 409 | + case PMIC_DA9063_BB: |
---|
| 410 | + case PMIC_DA9063_CA: |
---|
| 411 | + da9063_regmap_config.rd_table = |
---|
| 412 | + &da9063l_bb_readable_table; |
---|
| 413 | + da9063_regmap_config.wr_table = |
---|
| 414 | + &da9063l_bb_writeable_table; |
---|
| 415 | + da9063_regmap_config.volatile_table = |
---|
| 416 | + &da9063l_bb_da_volatile_table; |
---|
| 417 | + break; |
---|
| 418 | + case PMIC_DA9063_DA: |
---|
| 419 | + da9063_regmap_config.rd_table = |
---|
| 420 | + &da9063l_da_readable_table; |
---|
| 421 | + da9063_regmap_config.wr_table = |
---|
| 422 | + &da9063l_da_writeable_table; |
---|
| 423 | + da9063_regmap_config.volatile_table = |
---|
| 424 | + &da9063l_bb_da_volatile_table; |
---|
| 425 | + break; |
---|
| 426 | + default: |
---|
| 427 | + dev_err(da9063->dev, |
---|
| 428 | + "Chip variant not supported for DA9063L\n"); |
---|
| 429 | + return -ENODEV; |
---|
| 430 | + } |
---|
| 431 | + break; |
---|
| 432 | + default: |
---|
| 433 | + dev_err(da9063->dev, "Chip type not supported\n"); |
---|
| 434 | + return -ENODEV; |
---|
220 | 435 | } |
---|
221 | 436 | |
---|
222 | 437 | da9063->regmap = devm_regmap_init_i2c(i2c, &da9063_regmap_config); |
---|
.. | .. |
---|
227 | 442 | return ret; |
---|
228 | 443 | } |
---|
229 | 444 | |
---|
| 445 | + /* If SMBus is not available and only I2C is possible, enter I2C mode */ |
---|
| 446 | + if (i2c_check_functionality(i2c->adapter, I2C_FUNC_I2C)) { |
---|
| 447 | + ret = regmap_clear_bits(da9063->regmap, DA9063_REG_CONFIG_J, |
---|
| 448 | + DA9063_TWOWIRE_TO); |
---|
| 449 | + if (ret < 0) { |
---|
| 450 | + dev_err(da9063->dev, "Failed to set Two-Wire Bus Mode.\n"); |
---|
| 451 | + return -EIO; |
---|
| 452 | + } |
---|
| 453 | + } |
---|
| 454 | + |
---|
230 | 455 | return da9063_device_init(da9063, i2c->irq); |
---|
231 | 456 | } |
---|
232 | 457 | |
---|