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