1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Core driver for ams AS3722 PMICs 4 * 5 * Copyright (C) 2013 AMS AG 6 * Copyright (c) 2013, NVIDIA Corporation. All rights reserved. 7 * 8 * Author: Florian Lobmaier <florian.lobmaier@ams.com> 9 * Author: Laxman Dewangan <ldewangan@nvidia.com> 10 */ 11 12 #include <linux/err.h> 13 #include <linux/i2c.h> 14 #include <linux/interrupt.h> 15 #include <linux/irq.h> 16 #include <linux/kernel.h> 17 #include <linux/module.h> 18 #include <linux/mfd/core.h> 19 #include <linux/mfd/as3722.h> 20 #include <linux/of.h> 21 #include <linux/regmap.h> 22 #include <linux/slab.h> 23 24 #define AS3722_DEVICE_ID 0x0C 25 26 static const struct resource as3722_rtc_resource[] = { 27 DEFINE_RES_IRQ_NAMED(AS3722_IRQ_RTC_ALARM, "as3722-rtc-alarm"), 28 }; 29 30 static const struct resource as3722_adc_resource[] = { 31 DEFINE_RES_IRQ_NAMED(AS3722_IRQ_ADC, "as3722-adc"), 32 }; 33 34 static const struct mfd_cell as3722_devs[] = { 35 { 36 .name = "as3722-pinctrl", 37 }, 38 { 39 .name = "as3722-regulator", 40 }, 41 { 42 .name = "as3722-rtc", 43 .num_resources = ARRAY_SIZE(as3722_rtc_resource), 44 .resources = as3722_rtc_resource, 45 }, 46 { 47 .name = "as3722-adc", 48 .num_resources = ARRAY_SIZE(as3722_adc_resource), 49 .resources = as3722_adc_resource, 50 }, 51 { 52 .name = "as3722-power-off", 53 }, 54 { 55 .name = "as3722-wdt", 56 }, 57 }; 58 59 static const struct regmap_irq as3722_irqs[] = { 60 /* INT1 IRQs */ 61 [AS3722_IRQ_LID] = { 62 .mask = AS3722_INTERRUPT_MASK1_LID, 63 }, 64 [AS3722_IRQ_ACOK] = { 65 .mask = AS3722_INTERRUPT_MASK1_ACOK, 66 }, 67 [AS3722_IRQ_ENABLE1] = { 68 .mask = AS3722_INTERRUPT_MASK1_ENABLE1, 69 }, 70 [AS3722_IRQ_OCCUR_ALARM_SD0] = { 71 .mask = AS3722_INTERRUPT_MASK1_OCURR_ALARM_SD0, 72 }, 73 [AS3722_IRQ_ONKEY_LONG_PRESS] = { 74 .mask = AS3722_INTERRUPT_MASK1_ONKEY_LONG, 75 }, 76 [AS3722_IRQ_ONKEY] = { 77 .mask = AS3722_INTERRUPT_MASK1_ONKEY, 78 }, 79 [AS3722_IRQ_OVTMP] = { 80 .mask = AS3722_INTERRUPT_MASK1_OVTMP, 81 }, 82 [AS3722_IRQ_LOWBAT] = { 83 .mask = AS3722_INTERRUPT_MASK1_LOWBAT, 84 }, 85 86 /* INT2 IRQs */ 87 [AS3722_IRQ_SD0_LV] = { 88 .mask = AS3722_INTERRUPT_MASK2_SD0_LV, 89 .reg_offset = 1, 90 }, 91 [AS3722_IRQ_SD1_LV] = { 92 .mask = AS3722_INTERRUPT_MASK2_SD1_LV, 93 .reg_offset = 1, 94 }, 95 [AS3722_IRQ_SD2_LV] = { 96 .mask = AS3722_INTERRUPT_MASK2_SD2345_LV, 97 .reg_offset = 1, 98 }, 99 [AS3722_IRQ_PWM1_OV_PROT] = { 100 .mask = AS3722_INTERRUPT_MASK2_PWM1_OV_PROT, 101 .reg_offset = 1, 102 }, 103 [AS3722_IRQ_PWM2_OV_PROT] = { 104 .mask = AS3722_INTERRUPT_MASK2_PWM2_OV_PROT, 105 .reg_offset = 1, 106 }, 107 [AS3722_IRQ_ENABLE2] = { 108 .mask = AS3722_INTERRUPT_MASK2_ENABLE2, 109 .reg_offset = 1, 110 }, 111 [AS3722_IRQ_SD6_LV] = { 112 .mask = AS3722_INTERRUPT_MASK2_SD6_LV, 113 .reg_offset = 1, 114 }, 115 [AS3722_IRQ_RTC_REP] = { 116 .mask = AS3722_INTERRUPT_MASK2_RTC_REP, 117 .reg_offset = 1, 118 }, 119 120 /* INT3 IRQs */ 121 [AS3722_IRQ_RTC_ALARM] = { 122 .mask = AS3722_INTERRUPT_MASK3_RTC_ALARM, 123 .reg_offset = 2, 124 }, 125 [AS3722_IRQ_GPIO1] = { 126 .mask = AS3722_INTERRUPT_MASK3_GPIO1, 127 .reg_offset = 2, 128 }, 129 [AS3722_IRQ_GPIO2] = { 130 .mask = AS3722_INTERRUPT_MASK3_GPIO2, 131 .reg_offset = 2, 132 }, 133 [AS3722_IRQ_GPIO3] = { 134 .mask = AS3722_INTERRUPT_MASK3_GPIO3, 135 .reg_offset = 2, 136 }, 137 [AS3722_IRQ_GPIO4] = { 138 .mask = AS3722_INTERRUPT_MASK3_GPIO4, 139 .reg_offset = 2, 140 }, 141 [AS3722_IRQ_GPIO5] = { 142 .mask = AS3722_INTERRUPT_MASK3_GPIO5, 143 .reg_offset = 2, 144 }, 145 [AS3722_IRQ_WATCHDOG] = { 146 .mask = AS3722_INTERRUPT_MASK3_WATCHDOG, 147 .reg_offset = 2, 148 }, 149 [AS3722_IRQ_ENABLE3] = { 150 .mask = AS3722_INTERRUPT_MASK3_ENABLE3, 151 .reg_offset = 2, 152 }, 153 154 /* INT4 IRQs */ 155 [AS3722_IRQ_TEMP_SD0_SHUTDOWN] = { 156 .mask = AS3722_INTERRUPT_MASK4_TEMP_SD0_SHUTDOWN, 157 .reg_offset = 3, 158 }, 159 [AS3722_IRQ_TEMP_SD1_SHUTDOWN] = { 160 .mask = AS3722_INTERRUPT_MASK4_TEMP_SD1_SHUTDOWN, 161 .reg_offset = 3, 162 }, 163 [AS3722_IRQ_TEMP_SD2_SHUTDOWN] = { 164 .mask = AS3722_INTERRUPT_MASK4_TEMP_SD6_SHUTDOWN, 165 .reg_offset = 3, 166 }, 167 [AS3722_IRQ_TEMP_SD0_ALARM] = { 168 .mask = AS3722_INTERRUPT_MASK4_TEMP_SD0_ALARM, 169 .reg_offset = 3, 170 }, 171 [AS3722_IRQ_TEMP_SD1_ALARM] = { 172 .mask = AS3722_INTERRUPT_MASK4_TEMP_SD1_ALARM, 173 .reg_offset = 3, 174 }, 175 [AS3722_IRQ_TEMP_SD6_ALARM] = { 176 .mask = AS3722_INTERRUPT_MASK4_TEMP_SD6_ALARM, 177 .reg_offset = 3, 178 }, 179 [AS3722_IRQ_OCCUR_ALARM_SD6] = { 180 .mask = AS3722_INTERRUPT_MASK4_OCCUR_ALARM_SD6, 181 .reg_offset = 3, 182 }, 183 [AS3722_IRQ_ADC] = { 184 .mask = AS3722_INTERRUPT_MASK4_ADC, 185 .reg_offset = 3, 186 }, 187 }; 188 189 static const struct regmap_irq_chip as3722_irq_chip = { 190 .name = "as3722", 191 .irqs = as3722_irqs, 192 .num_irqs = ARRAY_SIZE(as3722_irqs), 193 .num_regs = 4, 194 .status_base = AS3722_INTERRUPT_STATUS1_REG, 195 .mask_base = AS3722_INTERRUPT_MASK1_REG, 196 }; 197 198 static int as3722_check_device_id(struct as3722 *as3722) 199 { 200 u32 val; 201 int ret; 202 203 /* Check that this is actually a AS3722 */ 204 ret = as3722_read(as3722, AS3722_ASIC_ID1_REG, &val); 205 if (ret < 0) { 206 dev_err(as3722->dev, "ASIC_ID1 read failed: %d\n", ret); 207 return ret; 208 } 209 210 if (val != AS3722_DEVICE_ID) { 211 dev_err(as3722->dev, "Device is not AS3722, ID is 0x%x\n", val); 212 return -ENODEV; 213 } 214 215 ret = as3722_read(as3722, AS3722_ASIC_ID2_REG, &val); 216 if (ret < 0) { 217 dev_err(as3722->dev, "ASIC_ID2 read failed: %d\n", ret); 218 return ret; 219 } 220 221 dev_info(as3722->dev, "AS3722 with revision 0x%x found\n", val); 222 return 0; 223 } 224 225 static int as3722_configure_pullups(struct as3722 *as3722) 226 { 227 int ret; 228 u32 val = 0; 229 230 if (as3722->en_intern_int_pullup) 231 val |= AS3722_INT_PULL_UP; 232 if (as3722->en_intern_i2c_pullup) 233 val |= AS3722_I2C_PULL_UP; 234 235 ret = as3722_update_bits(as3722, AS3722_IOVOLTAGE_REG, 236 AS3722_INT_PULL_UP | AS3722_I2C_PULL_UP, val); 237 if (ret < 0) 238 dev_err(as3722->dev, "IOVOLTAGE_REG update failed: %d\n", ret); 239 return ret; 240 } 241 242 static const struct regmap_range as3722_readable_ranges[] = { 243 regmap_reg_range(AS3722_SD0_VOLTAGE_REG, AS3722_SD6_VOLTAGE_REG), 244 regmap_reg_range(AS3722_GPIO0_CONTROL_REG, AS3722_LDO7_VOLTAGE_REG), 245 regmap_reg_range(AS3722_LDO9_VOLTAGE_REG, AS3722_REG_SEQU_MOD3_REG), 246 regmap_reg_range(AS3722_SD_PHSW_CTRL_REG, AS3722_PWM_CONTROL_H_REG), 247 regmap_reg_range(AS3722_WATCHDOG_TIMER_REG, AS3722_WATCHDOG_TIMER_REG), 248 regmap_reg_range(AS3722_WATCHDOG_SOFTWARE_SIGNAL_REG, 249 AS3722_BATTERY_VOLTAGE_MONITOR2_REG), 250 regmap_reg_range(AS3722_SD_CONTROL_REG, AS3722_PWM_VCONTROL4_REG), 251 regmap_reg_range(AS3722_BB_CHARGER_REG, AS3722_SRAM_REG), 252 regmap_reg_range(AS3722_RTC_ACCESS_REG, AS3722_RTC_ACCESS_REG), 253 regmap_reg_range(AS3722_RTC_STATUS_REG, AS3722_TEMP_STATUS_REG), 254 regmap_reg_range(AS3722_ADC0_CONTROL_REG, AS3722_ADC_CONFIGURATION_REG), 255 regmap_reg_range(AS3722_ASIC_ID1_REG, AS3722_ASIC_ID2_REG), 256 regmap_reg_range(AS3722_LOCK_REG, AS3722_LOCK_REG), 257 regmap_reg_range(AS3722_FUSE7_REG, AS3722_FUSE7_REG), 258 }; 259 260 static const struct regmap_access_table as3722_readable_table = { 261 .yes_ranges = as3722_readable_ranges, 262 .n_yes_ranges = ARRAY_SIZE(as3722_readable_ranges), 263 }; 264 265 static const struct regmap_range as3722_writable_ranges[] = { 266 regmap_reg_range(AS3722_SD0_VOLTAGE_REG, AS3722_SD6_VOLTAGE_REG), 267 regmap_reg_range(AS3722_GPIO0_CONTROL_REG, AS3722_LDO7_VOLTAGE_REG), 268 regmap_reg_range(AS3722_LDO9_VOLTAGE_REG, AS3722_GPIO_SIGNAL_OUT_REG), 269 regmap_reg_range(AS3722_REG_SEQU_MOD1_REG, AS3722_REG_SEQU_MOD3_REG), 270 regmap_reg_range(AS3722_SD_PHSW_CTRL_REG, AS3722_PWM_CONTROL_H_REG), 271 regmap_reg_range(AS3722_WATCHDOG_TIMER_REG, AS3722_WATCHDOG_TIMER_REG), 272 regmap_reg_range(AS3722_WATCHDOG_SOFTWARE_SIGNAL_REG, 273 AS3722_BATTERY_VOLTAGE_MONITOR2_REG), 274 regmap_reg_range(AS3722_SD_CONTROL_REG, AS3722_PWM_VCONTROL4_REG), 275 regmap_reg_range(AS3722_BB_CHARGER_REG, AS3722_SRAM_REG), 276 regmap_reg_range(AS3722_INTERRUPT_MASK1_REG, AS3722_TEMP_STATUS_REG), 277 regmap_reg_range(AS3722_ADC0_CONTROL_REG, AS3722_ADC1_CONTROL_REG), 278 regmap_reg_range(AS3722_ADC1_THRESHOLD_HI_MSB_REG, 279 AS3722_ADC_CONFIGURATION_REG), 280 regmap_reg_range(AS3722_LOCK_REG, AS3722_LOCK_REG), 281 }; 282 283 static const struct regmap_access_table as3722_writable_table = { 284 .yes_ranges = as3722_writable_ranges, 285 .n_yes_ranges = ARRAY_SIZE(as3722_writable_ranges), 286 }; 287 288 static const struct regmap_range as3722_cacheable_ranges[] = { 289 regmap_reg_range(AS3722_SD0_VOLTAGE_REG, AS3722_LDO11_VOLTAGE_REG), 290 regmap_reg_range(AS3722_SD_CONTROL_REG, AS3722_LDOCONTROL1_REG), 291 }; 292 293 static const struct regmap_access_table as3722_volatile_table = { 294 .no_ranges = as3722_cacheable_ranges, 295 .n_no_ranges = ARRAY_SIZE(as3722_cacheable_ranges), 296 }; 297 298 static const struct regmap_config as3722_regmap_config = { 299 .reg_bits = 8, 300 .val_bits = 8, 301 .max_register = AS3722_MAX_REGISTER, 302 .cache_type = REGCACHE_MAPLE, 303 .rd_table = &as3722_readable_table, 304 .wr_table = &as3722_writable_table, 305 .volatile_table = &as3722_volatile_table, 306 }; 307 308 static int as3722_i2c_of_probe(struct i2c_client *i2c, 309 struct as3722 *as3722) 310 { 311 struct device_node *np = i2c->dev.of_node; 312 struct irq_data *irq_data; 313 314 if (!np) { 315 dev_err(&i2c->dev, "Device Tree not found\n"); 316 return -EINVAL; 317 } 318 319 irq_data = irq_get_irq_data(i2c->irq); 320 if (!irq_data) { 321 dev_err(&i2c->dev, "Invalid IRQ: %d\n", i2c->irq); 322 return -EINVAL; 323 } 324 325 as3722->en_intern_int_pullup = of_property_read_bool(np, 326 "ams,enable-internal-int-pullup"); 327 as3722->en_intern_i2c_pullup = of_property_read_bool(np, 328 "ams,enable-internal-i2c-pullup"); 329 as3722->en_ac_ok_pwr_on = of_property_read_bool(np, 330 "ams,enable-ac-ok-power-on"); 331 as3722->irq_flags = irqd_get_trigger_type(irq_data); 332 dev_dbg(&i2c->dev, "IRQ flags are 0x%08lx\n", as3722->irq_flags); 333 return 0; 334 } 335 336 static int as3722_i2c_probe(struct i2c_client *i2c) 337 { 338 struct as3722 *as3722; 339 unsigned long irq_flags; 340 int ret; 341 u8 val = 0; 342 343 as3722 = devm_kzalloc(&i2c->dev, sizeof(struct as3722), GFP_KERNEL); 344 if (!as3722) 345 return -ENOMEM; 346 347 as3722->dev = &i2c->dev; 348 as3722->chip_irq = i2c->irq; 349 i2c_set_clientdata(i2c, as3722); 350 351 ret = as3722_i2c_of_probe(i2c, as3722); 352 if (ret < 0) 353 return ret; 354 355 as3722->regmap = devm_regmap_init_i2c(i2c, &as3722_regmap_config); 356 if (IS_ERR(as3722->regmap)) { 357 ret = PTR_ERR(as3722->regmap); 358 dev_err(&i2c->dev, "regmap init failed: %d\n", ret); 359 return ret; 360 } 361 362 ret = as3722_check_device_id(as3722); 363 if (ret < 0) 364 return ret; 365 366 irq_flags = as3722->irq_flags | IRQF_ONESHOT; 367 ret = devm_regmap_add_irq_chip(as3722->dev, as3722->regmap, 368 as3722->chip_irq, 369 irq_flags, -1, &as3722_irq_chip, 370 &as3722->irq_data); 371 if (ret < 0) { 372 dev_err(as3722->dev, "Failed to add regmap irq: %d\n", ret); 373 return ret; 374 } 375 376 ret = as3722_configure_pullups(as3722); 377 if (ret < 0) 378 return ret; 379 380 if (as3722->en_ac_ok_pwr_on) 381 val = AS3722_CTRL_SEQU1_AC_OK_PWR_ON; 382 ret = as3722_update_bits(as3722, AS3722_CTRL_SEQU1_REG, 383 AS3722_CTRL_SEQU1_AC_OK_PWR_ON, val); 384 if (ret < 0) { 385 dev_err(as3722->dev, "CTRLsequ1 update failed: %d\n", ret); 386 return ret; 387 } 388 389 ret = devm_mfd_add_devices(&i2c->dev, -1, as3722_devs, 390 ARRAY_SIZE(as3722_devs), NULL, 0, 391 regmap_irq_get_domain(as3722->irq_data)); 392 if (ret) { 393 dev_err(as3722->dev, "Failed to add MFD devices: %d\n", ret); 394 return ret; 395 } 396 397 device_init_wakeup(as3722->dev, true); 398 399 dev_dbg(as3722->dev, "AS3722 core driver initialized successfully\n"); 400 return 0; 401 } 402 403 static int __maybe_unused as3722_i2c_suspend(struct device *dev) 404 { 405 struct as3722 *as3722 = dev_get_drvdata(dev); 406 407 if (device_may_wakeup(dev)) 408 enable_irq_wake(as3722->chip_irq); 409 disable_irq(as3722->chip_irq); 410 411 return 0; 412 } 413 414 static int __maybe_unused as3722_i2c_resume(struct device *dev) 415 { 416 struct as3722 *as3722 = dev_get_drvdata(dev); 417 418 enable_irq(as3722->chip_irq); 419 420 if (device_may_wakeup(dev)) 421 disable_irq_wake(as3722->chip_irq); 422 423 return 0; 424 } 425 426 static const struct of_device_id as3722_of_match[] = { 427 { .compatible = "ams,as3722", }, 428 {}, 429 }; 430 MODULE_DEVICE_TABLE(of, as3722_of_match); 431 432 static const struct i2c_device_id as3722_i2c_id[] = { 433 { "as3722", 0 }, 434 {}, 435 }; 436 MODULE_DEVICE_TABLE(i2c, as3722_i2c_id); 437 438 static const struct dev_pm_ops as3722_pm_ops = { 439 SET_SYSTEM_SLEEP_PM_OPS(as3722_i2c_suspend, as3722_i2c_resume) 440 }; 441 442 static struct i2c_driver as3722_i2c_driver = { 443 .driver = { 444 .name = "as3722", 445 .of_match_table = as3722_of_match, 446 .pm = &as3722_pm_ops, 447 }, 448 .probe = as3722_i2c_probe, 449 .id_table = as3722_i2c_id, 450 }; 451 452 module_i2c_driver(as3722_i2c_driver); 453 454 MODULE_DESCRIPTION("I2C support for AS3722 PMICs"); 455 MODULE_AUTHOR("Florian Lobmaier <florian.lobmaier@ams.com>"); 456 MODULE_AUTHOR("Laxman Dewangan <ldewangan@nvidia.com>"); 457 MODULE_LICENSE("GPL"); 458