Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

power: supply: bd71828-power: Support ROHM BD72720

The ROHM BD72720 is a power management IC with a charger and coulomb
counter block which is closely related to the charger / coulomb counter
found from the BD71815, BD71828, BD71879 which are all supported by the
bd71828-power driver. Due to the similarities it makes sense to support
also the BD72720 with the same driver.

Add basic support for the charger logic on ROHM BD72720.

Signed-off-by: Matti Vaittinen <mazziesaccount@gmail.com>
Link: https://patch.msgid.link/fb74c0cab3dfe534135d26dbbb9c66699678c2de.1765804226.git.mazziesaccount@gmail.com
Signed-off-by: Lee Jones <lee@kernel.org>

authored by

Matti Vaittinen and committed by
Lee Jones
bcb5bb59 de8f20af

+116 -18
+116 -18
drivers/power/supply/bd71828-power.c
··· 5 5 #include <linux/kernel.h> 6 6 #include <linux/mfd/rohm-bd71815.h> 7 7 #include <linux/mfd/rohm-bd71828.h> 8 + #include <linux/mfd/rohm-bd72720.h> 8 9 #include <linux/module.h> 9 10 #include <linux/mod_devicetable.h> 10 11 #include <linux/platform_device.h> ··· 52 51 unsigned int chg_state; 53 52 unsigned int bat_temp; 54 53 unsigned int dcin_stat; 54 + unsigned int dcin_online_mask; 55 55 unsigned int dcin_collapse_limit; 56 56 unsigned int chg_set1; 57 57 unsigned int chg_en; 58 58 unsigned int vbat_alm_limit_u; 59 59 unsigned int conf; 60 60 unsigned int vdcin; 61 + unsigned int vdcin_himask; 61 62 }; 62 63 63 64 static const struct pwr_regs pwr_regs_bd71828 = { ··· 70 67 .chg_state = BD71828_REG_CHG_STATE, 71 68 .bat_temp = BD71828_REG_BAT_TEMP, 72 69 .dcin_stat = BD71828_REG_DCIN_STAT, 70 + .dcin_online_mask = BD7182x_MASK_DCIN_DET, 73 71 .dcin_collapse_limit = BD71828_REG_DCIN_CLPS, 74 72 .chg_set1 = BD71828_REG_CHG_SET1, 75 73 .chg_en = BD71828_REG_CHG_EN, 76 74 .vbat_alm_limit_u = BD71828_REG_ALM_VBAT_LIMIT_U, 77 75 .conf = BD71828_REG_CONF, 78 76 .vdcin = BD71828_REG_VDCIN_U, 77 + .vdcin_himask = BD7182x_MASK_VDCIN_U, 79 78 }; 80 79 81 80 static const struct pwr_regs pwr_regs_bd71815 = { ··· 90 85 .chg_state = BD71815_REG_CHG_STATE, 91 86 .bat_temp = BD71815_REG_BAT_TEMP, 92 87 .dcin_stat = BD71815_REG_DCIN_STAT, 88 + .dcin_online_mask = BD7182x_MASK_DCIN_DET, 93 89 .dcin_collapse_limit = BD71815_REG_DCIN_CLPS, 94 90 .chg_set1 = BD71815_REG_CHG_SET1, 95 91 .chg_en = BD71815_REG_CHG_SET1, ··· 98 92 .conf = BD71815_REG_CONF, 99 93 100 94 .vdcin = BD71815_REG_VM_DCIN_U, 95 + .vdcin_himask = BD7182x_MASK_VDCIN_U, 96 + }; 97 + 98 + static struct pwr_regs pwr_regs_bd72720 = { 99 + .vbat_avg = BD72720_REG_VM_SA_VBAT_U, 100 + .ibat = BD72720_REG_CC_CURCD_U, 101 + .ibat_avg = BD72720_REG_CC_SA_CURCD_U, 102 + .btemp_vth = BD72720_REG_VM_BTMP_U, 103 + /* 104 + * Note, state 0x40 IMP_CHK. not documented 105 + * on other variants but was still handled in 106 + * existing code. No memory traces as to why. 107 + */ 108 + .chg_state = BD72720_REG_CHG_STATE, 109 + .bat_temp = BD72720_REG_CHG_BAT_TEMP_STAT, 110 + .dcin_stat = BD72720_REG_INT_VBUS_SRC, 111 + .dcin_online_mask = BD72720_MASK_DCIN_DET, 112 + .dcin_collapse_limit = -1, /* Automatic. Setting not supported */ 113 + .chg_set1 = BD72720_REG_CHG_SET_1, 114 + .chg_en = BD72720_REG_CHG_EN, 115 + /* 15mV note in data-sheet */ 116 + .vbat_alm_limit_u = BD72720_REG_ALM_VBAT_TH_U, 117 + .conf = BD72720_REG_CONF, /* o XSTB, only PON. Seprate slave addr */ 118 + .vdcin = BD72720_REG_VM_VBUS_U, /* 10 bits not 11 as with other ICs */ 119 + .vdcin_himask = BD72720_MASK_VDCIN_U, 101 120 }; 102 121 103 122 struct bd71828_power { ··· 329 298 dev_err(pwr->dev, "Failed to read DCIN status\n"); 330 299 return ret; 331 300 } 332 - *chg_online = ((r & BD7182x_MASK_DCIN_DET) != 0); 301 + *chg_online = ((r & pwr->regs->dcin_online_mask) != 0); 333 302 334 303 return 0; 335 304 } ··· 360 329 ret = val & BD7182x_MASK_CONF_PON; 361 330 362 331 if (ret) 363 - regmap_update_bits(pwr->regmap, pwr->regs->conf, 364 - BD7182x_MASK_CONF_PON, 0); 332 + if (regmap_update_bits(pwr->regmap, pwr->regs->conf, BD7182x_MASK_CONF_PON, 0)) 333 + dev_err(pwr->dev, "Failed to write CONF register\n"); 365 334 366 335 return ret; 367 336 } ··· 389 358 int ret; 390 359 391 360 /* TODO: Collapse limit should come from device-tree ? */ 392 - ret = regmap_write(pwr->regmap, pwr->regs->dcin_collapse_limit, 393 - BD7182x_DCIN_COLLAPSE_DEFAULT); 394 - if (ret) { 395 - dev_err(pwr->dev, "Failed to write DCIN collapse limit\n"); 396 - return ret; 361 + if (pwr->regs->dcin_collapse_limit != (unsigned int)-1) { 362 + ret = regmap_write(pwr->regmap, pwr->regs->dcin_collapse_limit, 363 + BD7182x_DCIN_COLLAPSE_DEFAULT); 364 + if (ret) { 365 + dev_err(pwr->dev, "Failed to write DCIN collapse limit\n"); 366 + return ret; 367 + } 397 368 } 398 369 399 370 ret = pwr->bat_inserted(pwr); ··· 452 419 break; 453 420 case POWER_SUPPLY_PROP_VOLTAGE_NOW: 454 421 ret = bd7182x_read16_himask(pwr, pwr->regs->vdcin, 455 - BD7182x_MASK_VDCIN_U, &tmp); 422 + pwr->regs->vdcin_himask, &tmp); 456 423 if (ret) 457 424 return ret; 458 425 ··· 663 630 BD_ISR_DUMMY(dcin_mon_det, "DCIN voltage below threshold") 664 631 BD_ISR_DUMMY(dcin_mon_res, "DCIN voltage above threshold") 665 632 633 + BD_ISR_DUMMY(vbus_curr_limit, "VBUS current limited") 634 + BD_ISR_DUMMY(vsys_ov_res, "VSYS over-voltage cleared") 635 + BD_ISR_DUMMY(vsys_ov_det, "VSYS over-voltage") 666 636 BD_ISR_DUMMY(vsys_uv_res, "VSYS under-voltage cleared") 667 637 BD_ISR_DUMMY(vsys_uv_det, "VSYS under-voltage") 668 638 BD_ISR_DUMMY(vsys_low_res, "'VSYS low' cleared") ··· 914 878 BDIRQ("bd71828-temp-125-over", bd71828_temp_vf125_det), 915 879 BDIRQ("bd71828-temp-125-under", bd71828_temp_vf125_res), 916 880 }; 881 + static const struct bd7182x_irq_res bd72720_irqs[] = { 882 + BDIRQ("bd72720_int_vbus_rmv", BD_ISR_NAME(dcin_removed)), 883 + BDIRQ("bd72720_int_vbus_det", bd7182x_dcin_detected), 884 + BDIRQ("bd72720_int_vbus_mon_res", BD_ISR_NAME(dcin_mon_res)), 885 + BDIRQ("bd72720_int_vbus_mon_det", BD_ISR_NAME(dcin_mon_det)), 886 + BDIRQ("bd72720_int_vsys_mon_res", BD_ISR_NAME(vsys_mon_res)), 887 + BDIRQ("bd72720_int_vsys_mon_det", BD_ISR_NAME(vsys_mon_det)), 888 + BDIRQ("bd72720_int_vsys_uv_res", BD_ISR_NAME(vsys_uv_res)), 889 + BDIRQ("bd72720_int_vsys_uv_det", BD_ISR_NAME(vsys_uv_det)), 890 + BDIRQ("bd72720_int_vsys_lo_res", BD_ISR_NAME(vsys_low_res)), 891 + BDIRQ("bd72720_int_vsys_lo_det", BD_ISR_NAME(vsys_low_det)), 892 + BDIRQ("bd72720_int_vsys_ov_res", BD_ISR_NAME(vsys_ov_res)), 893 + BDIRQ("bd72720_int_vsys_ov_det", BD_ISR_NAME(vsys_ov_det)), 894 + BDIRQ("bd72720_int_bat_ilim", BD_ISR_NAME(vbus_curr_limit)), 895 + BDIRQ("bd72720_int_chg_done", bd718x7_chg_done), 896 + BDIRQ("bd72720_int_extemp_tout", BD_ISR_NAME(chg_wdg_temp)), 897 + BDIRQ("bd72720_int_chg_wdt_exp", BD_ISR_NAME(chg_wdg)), 898 + BDIRQ("bd72720_int_bat_mnt_out", BD_ISR_NAME(rechg_res)), 899 + BDIRQ("bd72720_int_bat_mnt_in", BD_ISR_NAME(rechg_det)), 900 + BDIRQ("bd72720_int_chg_trns", BD_ISR_NAME(chg_state_changed)), 901 + 902 + BDIRQ("bd72720_int_vbat_mon_res", BD_ISR_NAME(bat_mon_res)), 903 + BDIRQ("bd72720_int_vbat_mon_det", BD_ISR_NAME(bat_mon)), 904 + BDIRQ("bd72720_int_vbat_sht_res", BD_ISR_NAME(bat_short_res)), 905 + BDIRQ("bd72720_int_vbat_sht_det", BD_ISR_NAME(bat_short)), 906 + BDIRQ("bd72720_int_vbat_lo_res", BD_ISR_NAME(bat_low_res)), 907 + BDIRQ("bd72720_int_vbat_lo_det", BD_ISR_NAME(bat_low)), 908 + BDIRQ("bd72720_int_vbat_ov_res", BD_ISR_NAME(bat_ov_res)), 909 + BDIRQ("bd72720_int_vbat_ov_det", BD_ISR_NAME(bat_ov)), 910 + BDIRQ("bd72720_int_bat_rmv", BD_ISR_NAME(bat_removed)), 911 + BDIRQ("bd72720_int_bat_det", BD_ISR_NAME(bat_det)), 912 + BDIRQ("bd72720_int_dbat_det", BD_ISR_NAME(bat_dead)), 913 + BDIRQ("bd72720_int_bat_temp_trns", BD_ISR_NAME(temp_transit)), 914 + BDIRQ("bd72720_int_lobtmp_res", BD_ISR_NAME(temp_bat_low_res)), 915 + BDIRQ("bd72720_int_lobtmp_det", BD_ISR_NAME(temp_bat_low)), 916 + BDIRQ("bd72720_int_ovbtmp_res", BD_ISR_NAME(temp_bat_hi_res)), 917 + BDIRQ("bd72720_int_ovbtmp_det", BD_ISR_NAME(temp_bat_hi)), 918 + BDIRQ("bd72720_int_ocur1_res", BD_ISR_NAME(bat_oc1_res)), 919 + BDIRQ("bd72720_int_ocur1_det", BD_ISR_NAME(bat_oc1)), 920 + BDIRQ("bd72720_int_ocur2_res", BD_ISR_NAME(bat_oc2_res)), 921 + BDIRQ("bd72720_int_ocur2_det", BD_ISR_NAME(bat_oc2)), 922 + BDIRQ("bd72720_int_ocur3_res", BD_ISR_NAME(bat_oc3_res)), 923 + BDIRQ("bd72720_int_ocur3_det", BD_ISR_NAME(bat_oc3)), 924 + BDIRQ("bd72720_int_cc_mon2_det", BD_ISR_NAME(bat_cc_mon)), 925 + }; 917 926 int num_irqs; 918 927 const struct bd7182x_irq_res *irqs; 919 928 ··· 970 889 case ROHM_CHIP_TYPE_BD71815: 971 890 irqs = &bd71815_irqs[0]; 972 891 num_irqs = ARRAY_SIZE(bd71815_irqs); 892 + break; 893 + case ROHM_CHIP_TYPE_BD72720: 894 + irqs = &bd72720_irqs[0]; 895 + num_irqs = ARRAY_SIZE(bd72720_irqs); 973 896 break; 974 897 default: 975 898 return -EINVAL; ··· 1043 958 struct power_supply_config ac_cfg = {}; 1044 959 struct power_supply_config bat_cfg = {}; 1045 960 int ret; 1046 - struct regmap *regmap; 1047 - 1048 - regmap = dev_get_regmap(pdev->dev.parent, NULL); 1049 - if (!regmap) { 1050 - dev_err(&pdev->dev, "No parent regmap\n"); 1051 - return -EINVAL; 1052 - } 1053 961 1054 962 pwr = devm_kzalloc(&pdev->dev, sizeof(*pwr), GFP_KERNEL); 1055 963 if (!pwr) 1056 964 return -ENOMEM; 1057 965 1058 - pwr->regmap = regmap; 1059 - pwr->dev = &pdev->dev; 966 + /* 967 + * The BD72720 MFD device registers two regmaps. Power-supply driver 968 + * uses the "wrap-map", which provides access to both of the I2C slave 969 + * addresses used by the BD72720 970 + */ 1060 971 pwr->chip_type = platform_get_device_id(pdev)->driver_data; 972 + if (pwr->chip_type != ROHM_CHIP_TYPE_BD72720) 973 + pwr->regmap = dev_get_regmap(pdev->dev.parent, NULL); 974 + else 975 + pwr->regmap = dev_get_regmap(pdev->dev.parent, "wrap-map"); 976 + if (!pwr->regmap) { 977 + dev_err(&pdev->dev, "No parent regmap\n"); 978 + return -EINVAL; 979 + } 980 + 981 + pwr->dev = &pdev->dev; 1061 982 1062 983 switch (pwr->chip_type) { 1063 984 case ROHM_CHIP_TYPE_BD71828: ··· 1075 984 pwr->bat_inserted = bd71815_bat_inserted; 1076 985 pwr->get_temp = bd71815_get_temp; 1077 986 pwr->regs = &pwr_regs_bd71815; 987 + break; 988 + case ROHM_CHIP_TYPE_BD72720: 989 + pwr->bat_inserted = bd71828_bat_inserted; 990 + pwr->regs = &pwr_regs_bd72720; 991 + pwr->get_temp = bd71828_get_temp; 992 + dev_dbg(pwr->dev, "Found ROHM BD72720\n"); 1078 993 break; 1079 994 default: 1080 995 dev_err(pwr->dev, "Unknown PMIC\n"); ··· 1127 1030 static const struct platform_device_id bd71828_charger_id[] = { 1128 1031 { "bd71815-power", ROHM_CHIP_TYPE_BD71815 }, 1129 1032 { "bd71828-power", ROHM_CHIP_TYPE_BD71828 }, 1033 + { "bd72720-power", ROHM_CHIP_TYPE_BD72720 }, 1130 1034 { }, 1131 1035 }; 1132 1036 MODULE_DEVICE_TABLE(platform, bd71828_charger_id);