From patchwork Mon Nov 11 07:47:14 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?Q3PDs2vDoXMsIEJlbmNl?= X-Patchwork-Id: 13870334 Received: from fw2.prolan.hu (fw2.prolan.hu [193.68.50.107]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C096214AD2B; Mon, 11 Nov 2024 07:47:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.68.50.107 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731311280; cv=none; b=aH+gEiqo1NEbR4h3ExhPmKF9wm7R4bs5l8vblYKdj8AHorHvk0cjBsbnJifplstYiV7cRsTAKJmd7WcWgrgjcqhEfH87dDiheSAXcjBjz8qgwdI9H3WEHp/1q4SQn1mEIprcW3jTrUtXyYcdWmkboSvAE7RClYB5pAAwSwAvZyM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731311280; c=relaxed/simple; bh=GLcL7OysIZmmBy11h4SwtPB5W7rzbVje81ou9z8rvkc=; h=From:To:CC:Subject:Date:Message-ID:MIME-Version:Content-Type; b=d0oGlzTfWHL4KCKeg79ZiBB4P3lnzm3l85kXNfCxJgWROIEZ1ng6fllqMeMcgCP0QhJKs2xBsdTFHZt0oAtzSZcWkWVAgjLMLZfdaBJINdl1lOOc+h7ZMBjWfepnDcdM2O+0gzmSIfVW4Ie/KI1nHe/LY56CaWRdsP8M6WjRoEg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=prolan.hu; spf=pass smtp.mailfrom=prolan.hu; dkim=pass (4096-bit key) header.d=prolan.hu header.i=@prolan.hu header.b=uThgbu/F; arc=none smtp.client-ip=193.68.50.107 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=prolan.hu Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=prolan.hu Authentication-Results: smtp.subspace.kernel.org; dkim=pass (4096-bit key) header.d=prolan.hu header.i=@prolan.hu header.b="uThgbu/F" Received: from proxmox-mailgw.intranet.prolan.hu (localhost.localdomain [127.0.0.1]) by proxmox-mailgw.intranet.prolan.hu (Proxmox) with ESMTP id D1DDCA02FA; Mon, 11 Nov 2024 08:47:48 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=prolan.hu; h=cc :cc:content-transfer-encoding:content-type:content-type:date :from:from:message-id:mime-version:reply-to:subject:subject:to :to; s=mail; bh=+1kpk6bopCA6lvlfhNgkvWPJianLjo7nXDzO1z3iMoU=; b= uThgbu/F4KS27MIdDLPVnFwfEKItZa+GegtvQ6QO2v8xFYQWv1lqF1bfB+WMMS2C O6U4+CBmV3/CNgM574/BUOd0g0A9tQnUT5yT8JVORMLsxijaUfZvh1CQHWwHwH3x 2pYp8fnVVr9yDNSIbrOGmrIXprR3M5G9GkvTx8Tu8b95zQ8MQUvXaZki0LsGXGFW ERR/lg01JHt1Edhb5CzWENpn+lTV5+MIOkhQ/c4p2nZWK7JrBw4NdR3+lcdjcg4r /sZQutB8qU7D1GnTLBUFnGJCpGmVCJFlbB4LoAr254eYuSMdCw8Bpx6AElJ+1Onj t0tC+MWG7UR+yw7SXXUwbacfO1xHIxrqqbkK/JbfXqnATO+c1WpjlO4EGA7TQrKi 6yXEs9n5tEYcAD9nxbvZqp+VWzhGISVIvgolC4vgfxR7+fmtcq2YDm5ObCmftz6V Q7ba5nJd16zXVwOkbJW4GbpK9+m6XWmx97EmPpVjgCphSs7XRPmbyuGrcBOETl2j Kan+ep+m4j5XEdnRyZ+dfmlkFFmt9PVcxU76zgLd9V3wGAK6AGGWJdoOKhfyh5bg LjyAfB7qGsnD4o28wViM6/Gztab+X2Pc++wWhK6ZnbmwZEa7DcN1puv+XTxd32w4 apeyvxUyLer/dwX+UBdHjkBefpqfzwj2Dg9zeZam1h0= From: =?utf-8?b?Q3PDs2vDoXMsIEJlbmNl?= To: , CC: =?utf-8?b?Q3PDs2vDoXMsIEJlbmNl?= , "Samuel Holland" , Sebastian Reichel Subject: [PATCH v4 1/7] power: ip5xxx_power: Use regmap_field API Date: Mon, 11 Nov 2024 08:47:14 +0100 Message-ID: <20241111074720.1727163-1-csokas.bence@prolan.hu> X-Mailer: git-send-email 2.34.1 Precedence: bulk X-Mailing-List: linux-pm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ESET-AS: R=OK;S=0;OP=CALC;TIME=1731311266;VERSION=7980;MC=1792284896;ID=287555;TRN=0;CRV=0;IPC=;SP=0;SIPS=0;PI=3;F=0 X-ESET-Antispam: OK X-EsetResult: clean, is OK X-EsetId: 37303A2980D9485561716B The IP53xx series [1] has a much different register layout than the 51xx/52xx [2] currently supported by this driver. To accommodate supporting the former, refactor the code to use the flexible regmap_field API. [1] https://sharvielectronics.com/wp-content/uploads/2021/07/IP5306-I2C-registers.pdf [2] https://www.windworkshop.cn/wp-content/uploads/2022/04/IP5209-IP5109-IP5207-IP5108-I2C-registers.pdf Signed-off-by: Csókás, Bence --- Notes: Changes in v2: * s/&ip5xxx->regs/ip5xxx->regs/g * and then undo it for the ADC regs... * s/;/,/ on `ip51xx_fields` * and some other typos... Changes in v3: * keep `ip5xxx_read()` name * check `field` for non-NULL Changes in v4: * fix bit order * whitespace drivers/power/supply/ip5xxx_power.c | 451 ++++++++++++++++++---------- 1 file changed, 293 insertions(+), 158 deletions(-) diff --git a/drivers/power/supply/ip5xxx_power.c b/drivers/power/supply/ip5xxx_power.c index 82263646ddc6..2d4435881a9e 100644 --- a/drivers/power/supply/ip5xxx_power.c +++ b/drivers/power/supply/ip5xxx_power.c @@ -7,76 +7,132 @@ #include #include -#define IP5XXX_SYS_CTL0 0x01 -#define IP5XXX_SYS_CTL0_WLED_DET_EN BIT(4) -#define IP5XXX_SYS_CTL0_WLED_EN BIT(3) -#define IP5XXX_SYS_CTL0_BOOST_EN BIT(2) -#define IP5XXX_SYS_CTL0_CHARGER_EN BIT(1) -#define IP5XXX_SYS_CTL1 0x02 -#define IP5XXX_SYS_CTL1_LIGHT_SHDN_EN BIT(1) -#define IP5XXX_SYS_CTL1_LOAD_PWRUP_EN BIT(0) -#define IP5XXX_SYS_CTL2 0x0c -#define IP5XXX_SYS_CTL2_LIGHT_SHDN_TH GENMASK(7, 3) -#define IP5XXX_SYS_CTL3 0x03 -#define IP5XXX_SYS_CTL3_LONG_PRESS_TIME_SEL GENMASK(7, 6) -#define IP5XXX_SYS_CTL3_BTN_SHDN_EN BIT(5) -#define IP5XXX_SYS_CTL4 0x04 -#define IP5XXX_SYS_CTL4_SHDN_TIME_SEL GENMASK(7, 6) -#define IP5XXX_SYS_CTL4_VIN_PULLOUT_BOOST_EN BIT(5) -#define IP5XXX_SYS_CTL5 0x07 -#define IP5XXX_SYS_CTL5_NTC_DIS BIT(6) -#define IP5XXX_SYS_CTL5_WLED_MODE_SEL BIT(1) -#define IP5XXX_SYS_CTL5_BTN_SHDN_SEL BIT(0) -#define IP5XXX_CHG_CTL1 0x22 -#define IP5XXX_CHG_CTL1_BOOST_UVP_SEL GENMASK(3, 2) -#define IP5XXX_CHG_CTL2 0x24 -#define IP5XXX_CHG_CTL2_BAT_TYPE_SEL GENMASK(6, 5) -#define IP5XXX_CHG_CTL2_BAT_TYPE_SEL_4_2V (0x0 << 5) -#define IP5XXX_CHG_CTL2_BAT_TYPE_SEL_4_3V (0x1 << 5) -#define IP5XXX_CHG_CTL2_BAT_TYPE_SEL_4_35V (0x2 << 5) -#define IP5XXX_CHG_CTL2_CONST_VOLT_SEL GENMASK(2, 1) -#define IP5XXX_CHG_CTL4 0x26 -#define IP5XXX_CHG_CTL4_BAT_TYPE_SEL_EN BIT(6) -#define IP5XXX_CHG_CTL4A 0x25 -#define IP5XXX_CHG_CTL4A_CONST_CUR_SEL GENMASK(4, 0) -#define IP5XXX_MFP_CTL0 0x51 -#define IP5XXX_MFP_CTL1 0x52 -#define IP5XXX_GPIO_CTL2 0x53 -#define IP5XXX_GPIO_CTL2A 0x54 -#define IP5XXX_GPIO_CTL3 0x55 -#define IP5XXX_READ0 0x71 -#define IP5XXX_READ0_CHG_STAT GENMASK(7, 5) -#define IP5XXX_READ0_CHG_STAT_IDLE (0x0 << 5) -#define IP5XXX_READ0_CHG_STAT_TRICKLE (0x1 << 5) -#define IP5XXX_READ0_CHG_STAT_CONST_VOLT (0x2 << 5) -#define IP5XXX_READ0_CHG_STAT_CONST_CUR (0x3 << 5) -#define IP5XXX_READ0_CHG_STAT_CONST_VOLT_STOP (0x4 << 5) -#define IP5XXX_READ0_CHG_STAT_FULL (0x5 << 5) -#define IP5XXX_READ0_CHG_STAT_TIMEOUT (0x6 << 5) -#define IP5XXX_READ0_CHG_OP BIT(4) -#define IP5XXX_READ0_CHG_END BIT(3) -#define IP5XXX_READ0_CONST_VOLT_TIMEOUT BIT(2) -#define IP5XXX_READ0_CHG_TIMEOUT BIT(1) -#define IP5XXX_READ0_TRICKLE_TIMEOUT BIT(0) -#define IP5XXX_READ0_TIMEOUT GENMASK(2, 0) -#define IP5XXX_READ1 0x72 -#define IP5XXX_READ1_WLED_PRESENT BIT(7) -#define IP5XXX_READ1_LIGHT_LOAD BIT(6) -#define IP5XXX_READ1_VIN_OVERVOLT BIT(5) -#define IP5XXX_READ2 0x77 -#define IP5XXX_READ2_BTN_PRESS BIT(3) -#define IP5XXX_READ2_BTN_LONG_PRESS BIT(1) -#define IP5XXX_READ2_BTN_SHORT_PRESS BIT(0) -#define IP5XXX_BATVADC_DAT0 0xa2 -#define IP5XXX_BATVADC_DAT1 0xa3 -#define IP5XXX_BATIADC_DAT0 0xa4 -#define IP5XXX_BATIADC_DAT1 0xa5 -#define IP5XXX_BATOCV_DAT0 0xa8 -#define IP5XXX_BATOCV_DAT1 0xa9 +#define IP5XXX_BAT_TYPE_4_2V 0x0 +#define IP5XXX_BAT_TYPE_4_3V 0x1 +#define IP5XXX_BAT_TYPE_4_35V 0x2 +#define IP5XXX_CHG_STAT_IDLE 0x0 +#define IP5XXX_CHG_STAT_TRICKLE 0x1 +#define IP5XXX_CHG_STAT_CONST_VOLT 0x2 +#define IP5XXX_CHG_STAT_CONST_CUR 0x3 +#define IP5XXX_CHG_STAT_CONST_VOLT_STOP 0x4 +#define IP5XXX_CHG_STAT_FULL 0x5 +#define IP5XXX_CHG_STAT_TIMEOUT 0x6 struct ip5xxx { struct regmap *regmap; bool initialized; + struct { + struct { + /* Charger enable */ + struct regmap_field *enable; + /* Constant voltage value */ + struct regmap_field *const_volt_sel; + /* Constant current value */ + struct regmap_field *const_curr_sel; + /* Charger status */ + struct regmap_field *status; + /* Charging ended flag */ + struct regmap_field *chg_end; + /* Timeout flags (CV, charge, trickle) */ + struct regmap_field *timeout; + /* Overvoltage limit */ + struct regmap_field *vin_overvolt; + } charger; + struct { + /* Boost converter enable */ + struct regmap_field *enable; + struct { + /* Light load shutdown enable */ + struct regmap_field *enable; + /* Light load shutdown current limit */ + struct regmap_field *i_limit; + } light_load_shutdown; + /* Automatic powerup on increased load */ + struct regmap_field *load_powerup_en; + /* Automatic powerup on VIN pull-out */ + struct regmap_field *vin_pullout_en; + /* Undervoltage limit */ + struct regmap_field *undervolt_limit; + /* Light load status flag */ + struct regmap_field *light_load_status; + } boost; + struct { + /* NTC disable */ + struct regmap_field *ntc_dis; + /* Battery voltage type */ + struct regmap_field *type; + /* Battery voltage autoset from Vset pin */ + struct regmap_field *vset_en; + struct { + /* Battery measurement registers */ + struct ip5xxx_battery_adc_regs { + struct regmap_field *low; + struct regmap_field *high; + } volt, curr, open_volt; + } adc; + } battery; + struct { + /* Double/long press shutdown enable */ + struct regmap_field *shdn_enable; + /* WLED activation: double press or long press */ + struct regmap_field *wled_mode; + /* Shutdown activation: double press or long press */ + struct regmap_field *shdn_mode; + /* Long press time */ + struct regmap_field *long_press_time; + /* Button pressed */ + struct regmap_field *pressed; + /* Button long-pressed */ + struct regmap_field *long_pressed; + /* Button short-pressed */ + struct regmap_field *short_pressed; + } btn; + struct { + /* WLED enable */ + struct regmap_field *enable; + /* WLED detect */ + struct regmap_field *detect_en; + /* WLED present */ + struct regmap_field *present; + } wled; + } regs; +}; + +/* Register fields layout. Unsupported registers marked as { .lsb = 1 } */ +struct ip5xxx_regfield_config { + const struct reg_field charger_enable; + const struct reg_field charger_const_volt_sel; + const struct reg_field charger_const_curr_sel; + const struct reg_field charger_status; + const struct reg_field charger_chg_end; + const struct reg_field charger_timeout; + const struct reg_field charger_vin_overvolt; + const struct reg_field boost_enable; + const struct reg_field boost_llshdn_enable; + const struct reg_field boost_llshdn_i_limit; + const struct reg_field boost_load_powerup_en; + const struct reg_field boost_vin_pullout_en; + const struct reg_field boost_undervolt_limit; + const struct reg_field boost_light_load_status; + const struct reg_field battery_ntc_dis; + const struct reg_field battery_type; + const struct reg_field battery_vset_en; + const struct reg_field battery_adc_volt_low; + const struct reg_field battery_adc_volt_high; + const struct reg_field battery_adc_curr_low; + const struct reg_field battery_adc_curr_high; + const struct reg_field battery_adc_ovolt_low; + const struct reg_field battery_adc_ovolt_high; + const struct reg_field btn_shdn_enable; + const struct reg_field btn_wled_mode; + const struct reg_field btn_shdn_mode; + const struct reg_field btn_long_press_time; + const struct reg_field btn_pressed; + const struct reg_field btn_long_pressed; + const struct reg_field btn_short_pressed; + const struct reg_field wled_enable; + const struct reg_field wled_detect_en; + const struct reg_field wled_present; }; /* @@ -87,24 +143,30 @@ struct ip5xxx { * 2) Attempt the initialization sequence on each subsequent register access * until it succeeds. */ -static int ip5xxx_read(struct ip5xxx *ip5xxx, unsigned int reg, +static int ip5xxx_read(struct ip5xxx *ip5xxx, struct regmap_field *field, unsigned int *val) { int ret; - ret = regmap_read(ip5xxx->regmap, reg, val); + if (!field) + return -EOPNOTSUPP; + + ret = regmap_field_read(field, val); if (ret) ip5xxx->initialized = false; return ret; } -static int ip5xxx_update_bits(struct ip5xxx *ip5xxx, unsigned int reg, - unsigned int mask, unsigned int val) +static int ip5xxx_write(struct ip5xxx *ip5xxx, struct regmap_field *field, + unsigned int val) { int ret; - ret = regmap_update_bits(ip5xxx->regmap, reg, mask, val); + if (!field) + return -EOPNOTSUPP; + + ret = regmap_field_write(field, val); if (ret) ip5xxx->initialized = false; @@ -123,28 +185,24 @@ static int ip5xxx_initialize(struct power_supply *psy) * Disable shutdown under light load. * Enable power on when under load. */ - ret = ip5xxx_update_bits(ip5xxx, IP5XXX_SYS_CTL1, - IP5XXX_SYS_CTL1_LIGHT_SHDN_EN | - IP5XXX_SYS_CTL1_LOAD_PWRUP_EN, - IP5XXX_SYS_CTL1_LOAD_PWRUP_EN); + ret = ip5xxx_write(ip5xxx, ip5xxx->regs.boost.light_load_shutdown.enable, 0); + if (ret) + return ret; + ret = ip5xxx_write(ip5xxx, ip5xxx->regs.boost.load_powerup_en, 1); if (ret) return ret; /* * Enable shutdown after a long button press (as configured below). */ - ret = ip5xxx_update_bits(ip5xxx, IP5XXX_SYS_CTL3, - IP5XXX_SYS_CTL3_BTN_SHDN_EN, - IP5XXX_SYS_CTL3_BTN_SHDN_EN); + ret = ip5xxx_write(ip5xxx, ip5xxx->regs.btn.shdn_enable, 1); if (ret) return ret; /* * Power on automatically when VIN is removed. */ - ret = ip5xxx_update_bits(ip5xxx, IP5XXX_SYS_CTL4, - IP5XXX_SYS_CTL4_VIN_PULLOUT_BOOST_EN, - IP5XXX_SYS_CTL4_VIN_PULLOUT_BOOST_EN); + ret = ip5xxx_write(ip5xxx, ip5xxx->regs.boost.vin_pullout_en, 1); if (ret) return ret; @@ -152,12 +210,13 @@ static int ip5xxx_initialize(struct power_supply *psy) * Enable the NTC. * Configure the button for two presses => LED, long press => shutdown. */ - ret = ip5xxx_update_bits(ip5xxx, IP5XXX_SYS_CTL5, - IP5XXX_SYS_CTL5_NTC_DIS | - IP5XXX_SYS_CTL5_WLED_MODE_SEL | - IP5XXX_SYS_CTL5_BTN_SHDN_SEL, - IP5XXX_SYS_CTL5_WLED_MODE_SEL | - IP5XXX_SYS_CTL5_BTN_SHDN_SEL); + ret = ip5xxx_write(ip5xxx, ip5xxx->regs.battery.ntc_dis, 0); + if (ret) + return ret; + ret = ip5xxx_write(ip5xxx, ip5xxx->regs.btn.wled_mode, 1); + if (ret) + return ret; + ret = ip5xxx_write(ip5xxx, ip5xxx->regs.btn.shdn_mode, 1); if (ret) return ret; @@ -186,24 +245,24 @@ static int ip5xxx_battery_get_status(struct ip5xxx *ip5xxx, int *val) unsigned int rval; int ret; - ret = ip5xxx_read(ip5xxx, IP5XXX_READ0, &rval); + ret = ip5xxx_read(ip5xxx, ip5xxx->regs.charger.status, &rval); if (ret) return ret; - switch (rval & IP5XXX_READ0_CHG_STAT) { - case IP5XXX_READ0_CHG_STAT_IDLE: + switch (rval) { + case IP5XXX_CHG_STAT_IDLE: *val = POWER_SUPPLY_STATUS_DISCHARGING; break; - case IP5XXX_READ0_CHG_STAT_TRICKLE: - case IP5XXX_READ0_CHG_STAT_CONST_CUR: - case IP5XXX_READ0_CHG_STAT_CONST_VOLT: + case IP5XXX_CHG_STAT_TRICKLE: + case IP5XXX_CHG_STAT_CONST_CUR: + case IP5XXX_CHG_STAT_CONST_VOLT: *val = POWER_SUPPLY_STATUS_CHARGING; break; - case IP5XXX_READ0_CHG_STAT_CONST_VOLT_STOP: - case IP5XXX_READ0_CHG_STAT_FULL: + case IP5XXX_CHG_STAT_CONST_VOLT_STOP: + case IP5XXX_CHG_STAT_FULL: *val = POWER_SUPPLY_STATUS_FULL; break; - case IP5XXX_READ0_CHG_STAT_TIMEOUT: + case IP5XXX_CHG_STAT_TIMEOUT: *val = POWER_SUPPLY_STATUS_NOT_CHARGING; break; default: @@ -218,22 +277,22 @@ static int ip5xxx_battery_get_charge_type(struct ip5xxx *ip5xxx, int *val) unsigned int rval; int ret; - ret = ip5xxx_read(ip5xxx, IP5XXX_READ0, &rval); + ret = ip5xxx_read(ip5xxx, ip5xxx->regs.charger.status, &rval); if (ret) return ret; - switch (rval & IP5XXX_READ0_CHG_STAT) { - case IP5XXX_READ0_CHG_STAT_IDLE: - case IP5XXX_READ0_CHG_STAT_CONST_VOLT_STOP: - case IP5XXX_READ0_CHG_STAT_FULL: - case IP5XXX_READ0_CHG_STAT_TIMEOUT: + switch (rval) { + case IP5XXX_CHG_STAT_IDLE: + case IP5XXX_CHG_STAT_CONST_VOLT_STOP: + case IP5XXX_CHG_STAT_FULL: + case IP5XXX_CHG_STAT_TIMEOUT: *val = POWER_SUPPLY_CHARGE_TYPE_NONE; break; - case IP5XXX_READ0_CHG_STAT_TRICKLE: + case IP5XXX_CHG_STAT_TRICKLE: *val = POWER_SUPPLY_CHARGE_TYPE_TRICKLE; break; - case IP5XXX_READ0_CHG_STAT_CONST_CUR: - case IP5XXX_READ0_CHG_STAT_CONST_VOLT: + case IP5XXX_CHG_STAT_CONST_CUR: + case IP5XXX_CHG_STAT_CONST_VOLT: *val = POWER_SUPPLY_CHARGE_TYPE_STANDARD; break; default: @@ -248,11 +307,11 @@ static int ip5xxx_battery_get_health(struct ip5xxx *ip5xxx, int *val) unsigned int rval; int ret; - ret = ip5xxx_read(ip5xxx, IP5XXX_READ0, &rval); + ret = ip5xxx_read(ip5xxx, ip5xxx->regs.charger.timeout, &rval); if (ret) return ret; - if (rval & IP5XXX_READ0_TIMEOUT) + if (rval) *val = POWER_SUPPLY_HEALTH_SAFETY_TIMER_EXPIRE; else *val = POWER_SUPPLY_HEALTH_GOOD; @@ -265,7 +324,7 @@ static int ip5xxx_battery_get_voltage_max(struct ip5xxx *ip5xxx, int *val) unsigned int rval; int ret; - ret = ip5xxx_read(ip5xxx, IP5XXX_CHG_CTL2, &rval); + ret = ip5xxx_read(ip5xxx, ip5xxx->regs.battery.type, &rval); if (ret) return ret; @@ -273,14 +332,14 @@ static int ip5xxx_battery_get_voltage_max(struct ip5xxx *ip5xxx, int *val) * It is not clear what this will return if * IP5XXX_CHG_CTL4_BAT_TYPE_SEL_EN is not set... */ - switch (rval & IP5XXX_CHG_CTL2_BAT_TYPE_SEL) { - case IP5XXX_CHG_CTL2_BAT_TYPE_SEL_4_2V: + switch (rval) { + case IP5XXX_BAT_TYPE_4_2V: *val = 4200000; break; - case IP5XXX_CHG_CTL2_BAT_TYPE_SEL_4_3V: + case IP5XXX_BAT_TYPE_4_3V: *val = 4300000; break; - case IP5XXX_CHG_CTL2_BAT_TYPE_SEL_4_35V: + case IP5XXX_BAT_TYPE_4_35V: *val = 4350000; break; default: @@ -291,16 +350,16 @@ static int ip5xxx_battery_get_voltage_max(struct ip5xxx *ip5xxx, int *val) } static int ip5xxx_battery_read_adc(struct ip5xxx *ip5xxx, - u8 lo_reg, u8 hi_reg, int *val) + struct ip5xxx_battery_adc_regs *regs, int *val) { unsigned int hi, lo; int ret; - ret = ip5xxx_read(ip5xxx, lo_reg, &lo); + ret = ip5xxx_read(ip5xxx, regs->low, &lo); if (ret) return ret; - ret = ip5xxx_read(ip5xxx, hi_reg, &hi); + ret = ip5xxx_read(ip5xxx, regs->high, &hi); if (ret) return ret; @@ -335,32 +394,28 @@ static int ip5xxx_battery_get_property(struct power_supply *psy, return ip5xxx_battery_get_voltage_max(ip5xxx, &val->intval); case POWER_SUPPLY_PROP_VOLTAGE_NOW: - ret = ip5xxx_battery_read_adc(ip5xxx, IP5XXX_BATVADC_DAT0, - IP5XXX_BATVADC_DAT1, &raw); + ret = ip5xxx_battery_read_adc(ip5xxx, &ip5xxx->regs.battery.adc.volt, &raw); val->intval = 2600000 + DIV_ROUND_CLOSEST(raw * 26855, 100); return 0; case POWER_SUPPLY_PROP_VOLTAGE_OCV: - ret = ip5xxx_battery_read_adc(ip5xxx, IP5XXX_BATOCV_DAT0, - IP5XXX_BATOCV_DAT1, &raw); + ret = ip5xxx_battery_read_adc(ip5xxx, &ip5xxx->regs.battery.adc.open_volt, &raw); val->intval = 2600000 + DIV_ROUND_CLOSEST(raw * 26855, 100); return 0; case POWER_SUPPLY_PROP_CURRENT_NOW: - ret = ip5xxx_battery_read_adc(ip5xxx, IP5XXX_BATIADC_DAT0, - IP5XXX_BATIADC_DAT1, &raw); + ret = ip5xxx_battery_read_adc(ip5xxx, &ip5xxx->regs.battery.adc.curr, &raw); val->intval = DIV_ROUND_CLOSEST(raw * 149197, 200); return 0; case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT: - ret = ip5xxx_read(ip5xxx, IP5XXX_CHG_CTL4A, &rval); + ret = ip5xxx_read(ip5xxx, ip5xxx->regs.charger.const_curr_sel, &rval); if (ret) return ret; - rval &= IP5XXX_CHG_CTL4A_CONST_CUR_SEL; val->intval = 100000 * rval; return 0; @@ -373,12 +428,11 @@ static int ip5xxx_battery_get_property(struct power_supply *psy, if (ret) return ret; - ret = ip5xxx_read(ip5xxx, IP5XXX_CHG_CTL2, &rval); + ret = ip5xxx_read(ip5xxx, ip5xxx->regs.charger.const_volt_sel, &rval); if (ret) return ret; - rval &= IP5XXX_CHG_CTL2_CONST_VOLT_SEL; - val->intval = vmax + 14000 * (rval >> 1); + val->intval = vmax + 14000 * rval; return 0; case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX: @@ -401,26 +455,23 @@ static int ip5xxx_battery_set_voltage_max(struct ip5xxx *ip5xxx, int val) switch (val) { case 4200000: - rval = IP5XXX_CHG_CTL2_BAT_TYPE_SEL_4_2V; + rval = IP5XXX_BAT_TYPE_4_2V; break; case 4300000: - rval = IP5XXX_CHG_CTL2_BAT_TYPE_SEL_4_3V; + rval = IP5XXX_BAT_TYPE_4_3V; break; case 4350000: - rval = IP5XXX_CHG_CTL2_BAT_TYPE_SEL_4_35V; + rval = IP5XXX_BAT_TYPE_4_35V; break; default: return -EINVAL; } - ret = ip5xxx_update_bits(ip5xxx, IP5XXX_CHG_CTL2, - IP5XXX_CHG_CTL2_BAT_TYPE_SEL, rval); + ret = ip5xxx_write(ip5xxx, ip5xxx->regs.battery.type, rval); if (ret) return ret; - ret = ip5xxx_update_bits(ip5xxx, IP5XXX_CHG_CTL4, - IP5XXX_CHG_CTL4_BAT_TYPE_SEL_EN, - IP5XXX_CHG_CTL4_BAT_TYPE_SEL_EN); + ret = ip5xxx_write(ip5xxx, ip5xxx->regs.battery.vset_en, 1); if (ret) return ret; @@ -443,7 +494,7 @@ static int ip5xxx_battery_set_property(struct power_supply *psy, case POWER_SUPPLY_PROP_STATUS: switch (val->intval) { case POWER_SUPPLY_STATUS_CHARGING: - rval = IP5XXX_SYS_CTL0_CHARGER_EN; + rval = 1; break; case POWER_SUPPLY_STATUS_DISCHARGING: case POWER_SUPPLY_STATUS_NOT_CHARGING: @@ -452,25 +503,22 @@ static int ip5xxx_battery_set_property(struct power_supply *psy, default: return -EINVAL; } - return ip5xxx_update_bits(ip5xxx, IP5XXX_SYS_CTL0, - IP5XXX_SYS_CTL0_CHARGER_EN, rval); + return ip5xxx_write(ip5xxx, ip5xxx->regs.charger.enable, rval); case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN: return ip5xxx_battery_set_voltage_max(ip5xxx, val->intval); case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT: rval = val->intval / 100000; - return ip5xxx_update_bits(ip5xxx, IP5XXX_CHG_CTL4A, - IP5XXX_CHG_CTL4A_CONST_CUR_SEL, rval); + return ip5xxx_write(ip5xxx, ip5xxx->regs.charger.const_curr_sel, rval); case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE: ret = ip5xxx_battery_get_voltage_max(ip5xxx, &vmax); if (ret) return ret; - rval = ((val->intval - vmax) / 14000) << 1; - return ip5xxx_update_bits(ip5xxx, IP5XXX_CHG_CTL2, - IP5XXX_CHG_CTL2_CONST_VOLT_SEL, rval); + rval = (val->intval - vmax) / 14000; + return ip5xxx_write(ip5xxx, ip5xxx->regs.charger.const_volt_sel, rval); default: return -EINVAL; @@ -515,20 +563,19 @@ static int ip5xxx_boost_get_property(struct power_supply *psy, switch (psp) { case POWER_SUPPLY_PROP_ONLINE: - ret = ip5xxx_read(ip5xxx, IP5XXX_SYS_CTL0, &rval); + ret = ip5xxx_read(ip5xxx, ip5xxx->regs.boost.enable, &rval); if (ret) return ret; - val->intval = !!(rval & IP5XXX_SYS_CTL0_BOOST_EN); + val->intval = !!rval; return 0; case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN: - ret = ip5xxx_read(ip5xxx, IP5XXX_CHG_CTL1, &rval); + ret = ip5xxx_read(ip5xxx, ip5xxx->regs.boost.undervolt_limit, &rval); if (ret) return ret; - rval &= IP5XXX_CHG_CTL1_BOOST_UVP_SEL; - val->intval = 4530000 + 100000 * (rval >> 2); + val->intval = 4530000 + 100000 * rval; return 0; default: @@ -550,14 +597,11 @@ static int ip5xxx_boost_set_property(struct power_supply *psy, switch (psp) { case POWER_SUPPLY_PROP_ONLINE: - rval = val->intval ? IP5XXX_SYS_CTL0_BOOST_EN : 0; - return ip5xxx_update_bits(ip5xxx, IP5XXX_SYS_CTL0, - IP5XXX_SYS_CTL0_BOOST_EN, rval); + return ip5xxx_write(ip5xxx, ip5xxx->regs.boost.enable, !!val->intval); case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN: - rval = ((val->intval - 4530000) / 100000) << 2; - return ip5xxx_update_bits(ip5xxx, IP5XXX_CHG_CTL1, - IP5XXX_CHG_CTL1_BOOST_UVP_SEL, rval); + rval = (val->intval - 4530000) / 100000; + return ip5xxx_write(ip5xxx, ip5xxx->regs.boost.undervolt_limit, rval); default: return -EINVAL; @@ -583,13 +627,99 @@ static const struct power_supply_desc ip5xxx_boost_desc = { static const struct regmap_config ip5xxx_regmap_config = { .reg_bits = 8, .val_bits = 8, - .max_register = IP5XXX_BATOCV_DAT1, + .max_register = 0xa9, +}; + +static struct ip5xxx_regfield_config ip51xx_fields = { + .charger_enable = REG_FIELD(0x01, 1, 1), + .charger_const_volt_sel = REG_FIELD(0x24, 1, 2), + .charger_const_curr_sel = REG_FIELD(0x25, 0, 4), + .charger_status = REG_FIELD(0x71, 5, 7), + .charger_chg_end = REG_FIELD(0x71, 3, 3), + .charger_timeout = REG_FIELD(0x71, 0, 2), + .charger_vin_overvolt = REG_FIELD(0x72, 5, 5), + .boost_enable = REG_FIELD(0x01, 2, 2), + .boost_llshdn_enable = REG_FIELD(0x02, 1, 1), + .boost_llshdn_i_limit = REG_FIELD(0x0c, 3, 7), + .boost_load_powerup_en = REG_FIELD(0x02, 0, 0), + .boost_vin_pullout_en = REG_FIELD(0x04, 5, 5), + .boost_undervolt_limit = REG_FIELD(0x22, 2, 3), + .boost_light_load_status = REG_FIELD(0x72, 6, 6), + .battery_ntc_dis = REG_FIELD(0x07, 6, 6), + .battery_type = REG_FIELD(0x24, 5, 6), + .battery_vset_en = REG_FIELD(0x26, 6, 6), + .battery_adc_volt_low = REG_FIELD(0xa2, 0, 7), + .battery_adc_volt_high = REG_FIELD(0xa3, 0, 5), + .battery_adc_curr_low = REG_FIELD(0xa4, 0, 7), + .battery_adc_curr_high = REG_FIELD(0xa5, 0, 5), + .battery_adc_ovolt_low = REG_FIELD(0xa8, 0, 7), + .battery_adc_ovolt_high = REG_FIELD(0xa9, 0, 5), + .btn_shdn_enable = REG_FIELD(0x03, 5, 5), + .btn_wled_mode = REG_FIELD(0x07, 1, 1), + .btn_shdn_mode = REG_FIELD(0x07, 0, 0), + .btn_long_press_time = REG_FIELD(0x03, 6, 7), + .btn_pressed = REG_FIELD(0x77, 3, 3), + .btn_long_pressed = REG_FIELD(0x77, 1, 1), + .btn_short_pressed = REG_FIELD(0x77, 0, 0), + .wled_enable = REG_FIELD(0x01, 3, 3), + .wled_detect_en = REG_FIELD(0x01, 4, 4), + .wled_present = REG_FIELD(0x72, 7, 7), }; +#define ip5xxx_setup_reg(_field, _reg) \ + do { \ + if (likely(cfg->_field.lsb <= cfg->_field.msb)) { \ + struct regmap_field *_tmp = devm_regmap_field_alloc(dev, \ + ip5xxx->regmap, cfg->_field); \ + if (!IS_ERR(_tmp)) \ + ip5xxx->regs._reg = _tmp; \ + } \ + } while (0) + +static void ip5xxx_setup_regs(struct device *dev, struct ip5xxx *ip5xxx, + const struct ip5xxx_regfield_config *cfg) +{ + ip5xxx_setup_reg(charger_enable, charger.enable); + ip5xxx_setup_reg(charger_const_volt_sel, charger.const_volt_sel); + ip5xxx_setup_reg(charger_const_curr_sel, charger.const_curr_sel); + ip5xxx_setup_reg(charger_status, charger.status); + ip5xxx_setup_reg(charger_chg_end, charger.chg_end); + ip5xxx_setup_reg(charger_timeout, charger.timeout); + ip5xxx_setup_reg(charger_vin_overvolt, charger.vin_overvolt); + ip5xxx_setup_reg(boost_enable, boost.enable); + ip5xxx_setup_reg(boost_llshdn_enable, boost.light_load_shutdown.enable); + ip5xxx_setup_reg(boost_llshdn_i_limit, boost.light_load_shutdown.i_limit); + ip5xxx_setup_reg(boost_load_powerup_en, boost.load_powerup_en); + ip5xxx_setup_reg(boost_vin_pullout_en, boost.vin_pullout_en); + ip5xxx_setup_reg(boost_undervolt_limit, boost.undervolt_limit); + ip5xxx_setup_reg(boost_light_load_status, boost.light_load_status); + ip5xxx_setup_reg(battery_ntc_dis, battery.ntc_dis); + ip5xxx_setup_reg(battery_type, battery.type); + ip5xxx_setup_reg(battery_vset_en, battery.vset_en); + ip5xxx_setup_reg(battery_adc_volt_low, battery.adc.volt.low); + ip5xxx_setup_reg(battery_adc_volt_high, battery.adc.volt.high); + ip5xxx_setup_reg(battery_adc_curr_low, battery.adc.curr.low); + ip5xxx_setup_reg(battery_adc_curr_high, battery.adc.curr.high); + ip5xxx_setup_reg(battery_adc_ovolt_low, battery.adc.open_volt.low); + ip5xxx_setup_reg(battery_adc_ovolt_high, battery.adc.open_volt.high); + ip5xxx_setup_reg(btn_shdn_enable, btn.shdn_enable); + ip5xxx_setup_reg(btn_wled_mode, btn.wled_mode); + ip5xxx_setup_reg(btn_shdn_mode, btn.shdn_mode); + ip5xxx_setup_reg(btn_long_press_time, btn.long_press_time); + ip5xxx_setup_reg(btn_pressed, btn.pressed); + ip5xxx_setup_reg(btn_long_pressed, btn.long_pressed); + ip5xxx_setup_reg(btn_short_pressed, btn.short_pressed); + ip5xxx_setup_reg(wled_enable, wled.enable); + ip5xxx_setup_reg(wled_detect_en, wled.detect_en); + ip5xxx_setup_reg(wled_present, wled.present); +} + static int ip5xxx_power_probe(struct i2c_client *client) { + const struct ip5xxx_regfield_config *fields = &ip51xx_fields; struct power_supply_config psy_cfg = {}; struct device *dev = &client->dev; + const struct of_device_id *of_id; struct power_supply *psy; struct ip5xxx *ip5xxx; @@ -601,6 +731,11 @@ static int ip5xxx_power_probe(struct i2c_client *client) if (IS_ERR(ip5xxx->regmap)) return PTR_ERR(ip5xxx->regmap); + of_id = i2c_of_match_device(dev->driver->of_match_table, client); + if (of_id) + fields = (const struct ip5xxx_regfield_config *)of_id->data; + ip5xxx_setup_regs(dev, ip5xxx, fields); + psy_cfg.of_node = dev->of_node; psy_cfg.drv_data = ip5xxx; @@ -616,10 +751,10 @@ static int ip5xxx_power_probe(struct i2c_client *client) } static const struct of_device_id ip5xxx_power_of_match[] = { - { .compatible = "injoinic,ip5108" }, - { .compatible = "injoinic,ip5109" }, - { .compatible = "injoinic,ip5207" }, - { .compatible = "injoinic,ip5209" }, + { .compatible = "injoinic,ip5108", .data = &ip51xx_fields }, + { .compatible = "injoinic,ip5109", .data = &ip51xx_fields }, + { .compatible = "injoinic,ip5207", .data = &ip51xx_fields }, + { .compatible = "injoinic,ip5209", .data = &ip51xx_fields }, { } }; MODULE_DEVICE_TABLE(of, ip5xxx_power_of_match); From patchwork Mon Nov 11 07:47:15 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?Q3PDs2vDoXMsIEJlbmNl?= X-Patchwork-Id: 13870330 Received: from fw2.prolan.hu (fw2.prolan.hu [193.68.50.107]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C09F01552E7; Mon, 11 Nov 2024 07:47:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.68.50.107 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731311279; cv=none; b=jVJft9hUmC72ybk8044GcGI/ucmp0YDETSby6NxZ0F4bgihJEELT3jqpcsrNCowi1eE15iVSamlOioZM89QzP7Td6/CR3aTg8o30+ZnUH6Rryre0gtSLuJtXO579mftDDGclUrTZfhN9urfx8TsOBvLQRmMvAGYG9CZo6lZy+uA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731311279; c=relaxed/simple; bh=sK0kWk+8VYxo38aU63eiYOmeLS96q4K2u2uUzpGH55g=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=Pyu/QvZ0lKhJlKFjKyVNoJqz4F0e73uGXECO1ASABRyMmX+ZCeuWSVgfXKFVk+zC05Rkml36YvWWwcXcW2RPF00iaErka9xtcsUviylbxDh4UY7O8r37VOraifef9cfktXzF1c30QFHzidXdUDUaCo1kU7Oaht5ACSpDZ/JEs2I= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=prolan.hu; spf=pass smtp.mailfrom=prolan.hu; dkim=pass (4096-bit key) header.d=prolan.hu header.i=@prolan.hu header.b=hTmxkere; arc=none smtp.client-ip=193.68.50.107 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=prolan.hu Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=prolan.hu Authentication-Results: smtp.subspace.kernel.org; dkim=pass (4096-bit key) header.d=prolan.hu header.i=@prolan.hu header.b="hTmxkere" Received: from proxmox-mailgw.intranet.prolan.hu (localhost.localdomain [127.0.0.1]) by proxmox-mailgw.intranet.prolan.hu (Proxmox) with ESMTP id BA192A0331; Mon, 11 Nov 2024 08:47:47 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=prolan.hu; h=cc :cc:content-transfer-encoding:content-type:content-type:date :from:from:in-reply-to:message-id:mime-version:references :reply-to:subject:subject:to:to; s=mail; bh=270OS3AUGIEnFR7GA4rh i6oZuXf4WByJ/XiZ6z+upJg=; b=hTmxkerenaYvai+eNShRpNfr9sLGUF/Rhxyw SeJj8GiuK0I8IGosy9PrtF2Jwjkh5yf59cfFyjeRGQzipmRMmw5KEnuYOZ0gk+cx Tyr6ifJnIAxh8FAxuQs6fM2h/plo4hbA2ZeLJbHiak5bG96O3QUS1n6/SoaS9ew9 fBHKozMt+ge9JlhvoBhO8FbNAie8IY7avfIosVF2URm7V48e+BdUgnTYReVTz5ik nGw/s7lXXC9i5C0TunydNUTPFjwhfKbuxRjtmNBjESfxicMDmRql8ogGwP5xhsBR WqbHes8GEYKb0zuWZI1thd5LglRQl/ozF5XmbKzvjDctEsCzzdnqd5nhBM/2W48Y orTxJZvnZER6Ej+avlOA7Bkr7Jv8ZVeXoVwEN4KWzinGGmUBgU2UM7UHJIwqxB9N bXifjkReTzLapXVSudMPcs8H8k5H4Hwg3c+V4zKZL4I2mlHSM6BizNygvJHSzYGi bl3/WF1zVnLaLR8wWHWaH9ZgNbN9RjkyWsabbcLfuDxo9+d7K77VLMaw30cQPgBN KEfRTvAefAETbymgIAKrAYf+sFLUbM7REQWhs28ZvE92t7B759TarlMHV5a/AktA hBH05J1XLumIluavQU7GeHTLDvxXYhNdjwqoHkUv9HNiuWK/5ySb8KbV+wL59pAc +5i/Y7Q= From: =?utf-8?b?Q3PDs2vDoXMsIEJlbmNl?= To: Samuel Holland , Sebastian Reichel , , CC: =?utf-8?b?Q3PDs2vDoXMsIEJlbmNl?= , Sebastian Reichel Subject: [PATCH v4 2/7] power: ip5xxx_power: Fix return value on ADC read errors Date: Mon, 11 Nov 2024 08:47:15 +0100 Message-ID: <20241111074720.1727163-2-csokas.bence@prolan.hu> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20241111074720.1727163-1-csokas.bence@prolan.hu> References: <20241111074720.1727163-1-csokas.bence@prolan.hu> Precedence: bulk X-Mailing-List: linux-pm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ESET-AS: R=OK;S=0;OP=CALC;TIME=1731311267;VERSION=7980;MC=57183446;ID=287556;TRN=0;CRV=0;IPC=;SP=0;SIPS=0;PI=3;F=0 X-ESET-Antispam: OK X-EsetResult: clean, is OK X-EsetId: 37303A2980D9485561716B If ADC read returns an error, the return value was silently ignored, execution continued and an uninitialized value and a return code of 0 was passed back to userspace. The only exception was POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT, which bailed out correctly. Fix returns for the other cases as well. Fixes: 75853406fa27 ("power: supply: Add a driver for Injoinic power bank ICs") Signed-off-by: Csókás, Bence --- drivers/power/supply/ip5xxx_power.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/power/supply/ip5xxx_power.c b/drivers/power/supply/ip5xxx_power.c index 2d4435881a9e..41d91504eb32 100644 --- a/drivers/power/supply/ip5xxx_power.c +++ b/drivers/power/supply/ip5xxx_power.c @@ -395,18 +395,24 @@ static int ip5xxx_battery_get_property(struct power_supply *psy, case POWER_SUPPLY_PROP_VOLTAGE_NOW: ret = ip5xxx_battery_read_adc(ip5xxx, &ip5xxx->regs.battery.adc.volt, &raw); + if (ret) + return ret; val->intval = 2600000 + DIV_ROUND_CLOSEST(raw * 26855, 100); return 0; case POWER_SUPPLY_PROP_VOLTAGE_OCV: ret = ip5xxx_battery_read_adc(ip5xxx, &ip5xxx->regs.battery.adc.open_volt, &raw); + if (ret) + return ret; val->intval = 2600000 + DIV_ROUND_CLOSEST(raw * 26855, 100); return 0; case POWER_SUPPLY_PROP_CURRENT_NOW: ret = ip5xxx_battery_read_adc(ip5xxx, &ip5xxx->regs.battery.adc.curr, &raw); + if (ret) + return ret; val->intval = DIV_ROUND_CLOSEST(raw * 149197, 200); return 0; From patchwork Mon Nov 11 07:47:16 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?Q3PDs2vDoXMsIEJlbmNl?= X-Patchwork-Id: 13870332 Received: from fw2.prolan.hu (fw2.prolan.hu [193.68.50.107]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C08E5B67F; Mon, 11 Nov 2024 07:47:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.68.50.107 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731311279; cv=none; b=kwruPiZFx4skHd0LmRyBoggm+dwfD9cz5PjAnH5NvXUg+qzen0gHZ3yYfukWMNdILyy47UMCwZrdGI6tG+To67M3L0uZW9QpDLv1i6JPRjbmi474FVsLErzhVet9jXl2bNAgqOkFKPU1PxfBzavaUBKjBCGH9I7qg19qJP1UHTQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731311279; c=relaxed/simple; bh=7O6l3W8jdtTHFsZPhIqdpPWwmQl3mjScIw0wphIRdpQ=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=TvenMbiKrUmUkG6TU9B7JgjcMj6MyVgKK4hAfmTvN+OLJSyJG+oy7OTC49jTaAEQunJZpXhKZmHpTuO+Vd7YcAwCCT2fW9y5D8jtOkdJQ9Lz/zTozhp4rlg5pwGfP/v3P92Rw/9OvHuCJkU7dGlh5+e2DKO1s7M5jRU4hXHv1u0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=prolan.hu; spf=pass smtp.mailfrom=prolan.hu; dkim=pass (4096-bit key) header.d=prolan.hu header.i=@prolan.hu header.b=LtLskC1Q; arc=none smtp.client-ip=193.68.50.107 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=prolan.hu Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=prolan.hu Authentication-Results: smtp.subspace.kernel.org; dkim=pass (4096-bit key) header.d=prolan.hu header.i=@prolan.hu header.b="LtLskC1Q" Received: from proxmox-mailgw.intranet.prolan.hu (localhost.localdomain [127.0.0.1]) by proxmox-mailgw.intranet.prolan.hu (Proxmox) with ESMTP id AA7A3A03A7; Mon, 11 Nov 2024 08:47:48 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=prolan.hu; h=cc :cc:content-transfer-encoding:content-type:content-type:date :from:from:in-reply-to:message-id:mime-version:references :reply-to:subject:subject:to:to; s=mail; bh=4KBnznNW4mW6T1wsXkeA urj0zCpvuCLbvvtqL+9elhw=; b=LtLskC1QbGzjLUC0bsrVKJYe/I0+g2rZ1IGi x5IFpOvcbB7tp7K7uGEBJlpoH5LZKU/aAx7i1J9oDEx/vcS9Cut+CnBDUUv7guvl hCUXeBYh4AhGePNWQ7L9uOsVOwNIV4l+NB9R/M8+6izE8h1G1qLNBVWPZ6ARTF7d r85xsdI8jiRnN1/UykWtONcxCyO5DBCXOGzmVNNrVeVrtvy88WAlhb45C6CAOT/o HiMiQLP8u2zz5X+Wn+z52mcccwISDe+KDkVCmKoJH+qBltdmzPFGVniCiRObEMRO 3MZ7ZSkarwjGBWNaiCz5QVQ1pmBMU3KcjJeG73w3m2REhnzPwb+TW8z/AZW1SiM9 lew4vcV4JRh/GkjSfpdaRhA6xEEpJ5L/+NCYCl38EHFAovtujCQGFBz/7t7mBlYE dH2D37ffTCAMuWGpOtQRwnVqC9/zg8MuY99CZaVdGFjwusfJu4yPf2EGdOV3Kglg BI9LmNdUFjvJCNS3njm4fRoTrNoQtFPusxqrUvgpy6U/fKwCpcoxkhz9788er3Kc CH6EdEQQV1UgHbPa2KVZuMIRSzD6Qxv+HcgvPzZAIMKcLgLbHzjgRbEB0+YMuHWW MeHBzWZPVM+OPBS6PuYfvwOBovvi+W3+t75gw1JRwKcJNSyh7+kAyizMGvkpqcpZ oLMUwdQ= From: =?utf-8?b?Q3PDs2vDoXMsIEJlbmNl?= To: , CC: =?utf-8?b?Q3PDs2vDoXMsIEJlbmNl?= , "Samuel Holland" , Sebastian Reichel Subject: [PATCH v4 3/7] power: ip5xxx_power: Allow for more parameters to be configured Date: Mon, 11 Nov 2024 08:47:16 +0100 Message-ID: <20241111074720.1727163-3-csokas.bence@prolan.hu> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20241111074720.1727163-1-csokas.bence@prolan.hu> References: <20241111074720.1727163-1-csokas.bence@prolan.hu> Precedence: bulk X-Mailing-List: linux-pm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ESET-AS: R=OK;S=0;OP=CALC;TIME=1731311267;VERSION=7980;MC=599170532;ID=287557;TRN=0;CRV=0;IPC=;SP=0;SIPS=0;PI=3;F=0 X-ESET-Antispam: OK X-EsetResult: clean, is OK X-EsetId: 37303A2980D9485561716B Other parts such as IP5306 may support other battery voltages and have different constants for input voltage regulation. Allow these to be passed from `struct ip5xxx_regfield_config`. Signed-off-by: Csókás, Bence --- drivers/power/supply/ip5xxx_power.c | 40 ++++++++++++++++++++++++++--- 1 file changed, 36 insertions(+), 4 deletions(-) diff --git a/drivers/power/supply/ip5xxx_power.c b/drivers/power/supply/ip5xxx_power.c index 41d91504eb32..a55441f87cc1 100644 --- a/drivers/power/supply/ip5xxx_power.c +++ b/drivers/power/supply/ip5xxx_power.c @@ -96,6 +96,18 @@ struct ip5xxx { struct regmap_field *present; } wled; } regs; + + /* Maximum supported battery voltage (via regs.battery.type) */ + int vbat_max; + /* Scaling constants for regs.boost.undervolt_limit */ + struct { + int setpoint; + int microvolts_per_bit; + } boost_undervolt; + /* Scaling constants for regs.charger.const_curr_sel */ + struct { + int setpoint; + } const_curr; }; /* Register fields layout. Unsupported registers marked as { .lsb = 1 } */ @@ -133,6 +145,12 @@ struct ip5xxx_regfield_config { const struct reg_field wled_enable; const struct reg_field wled_detect_en; const struct reg_field wled_present; + + int vbat_max; + int boost_undervolt_setpoint; + int boost_undervolt_uv_per_bit; + int const_curr_setpoint; + u8 chg_end_inverted; }; /* @@ -328,6 +346,9 @@ static int ip5xxx_battery_get_voltage_max(struct ip5xxx *ip5xxx, int *val) if (ret) return ret; + if (*val > ip5xxx->vbat_max) + return -EINVAL; + /* * It is not clear what this will return if * IP5XXX_CHG_CTL4_BAT_TYPE_SEL_EN is not set... @@ -422,7 +443,7 @@ static int ip5xxx_battery_get_property(struct power_supply *psy, if (ret) return ret; - val->intval = 100000 * rval; + val->intval = ip5xxx->const_curr.setpoint + 100000 * rval; return 0; case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX: @@ -515,7 +536,7 @@ static int ip5xxx_battery_set_property(struct power_supply *psy, return ip5xxx_battery_set_voltage_max(ip5xxx, val->intval); case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT: - rval = val->intval / 100000; + rval = (val->intval - ip5xxx->const_curr.setpoint) / 100000; return ip5xxx_write(ip5xxx, ip5xxx->regs.charger.const_curr_sel, rval); case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE: @@ -581,7 +602,8 @@ static int ip5xxx_boost_get_property(struct power_supply *psy, if (ret) return ret; - val->intval = 4530000 + 100000 * rval; + val->intval = ip5xxx->boost_undervolt.setpoint + + ip5xxx->boost_undervolt.microvolts_per_bit * rval; return 0; default: @@ -606,7 +628,8 @@ static int ip5xxx_boost_set_property(struct power_supply *psy, return ip5xxx_write(ip5xxx, ip5xxx->regs.boost.enable, !!val->intval); case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN: - rval = (val->intval - 4530000) / 100000; + rval = (val->intval - ip5xxx->boost_undervolt.setpoint) / + ip5xxx->boost_undervolt.microvolts_per_bit; return ip5xxx_write(ip5xxx, ip5xxx->regs.boost.undervolt_limit, rval); default: @@ -670,6 +693,10 @@ static struct ip5xxx_regfield_config ip51xx_fields = { .wled_enable = REG_FIELD(0x01, 3, 3), .wled_detect_en = REG_FIELD(0x01, 4, 4), .wled_present = REG_FIELD(0x72, 7, 7), + + .vbat_max = 4350000, + .boost_undervolt_setpoint = 4530000, + .boost_undervolt_uv_per_bit = 100000, }; #define ip5xxx_setup_reg(_field, _reg) \ @@ -718,6 +745,11 @@ static void ip5xxx_setup_regs(struct device *dev, struct ip5xxx *ip5xxx, ip5xxx_setup_reg(wled_enable, wled.enable); ip5xxx_setup_reg(wled_detect_en, wled.detect_en); ip5xxx_setup_reg(wled_present, wled.present); + + ip5xxx->vbat_max = cfg->vbat_max; + ip5xxx->boost_undervolt.setpoint = cfg->boost_undervolt_setpoint; + ip5xxx->boost_undervolt.microvolts_per_bit = cfg->boost_undervolt_uv_per_bit; + ip5xxx->const_curr.setpoint = cfg->const_curr_setpoint; } static int ip5xxx_power_probe(struct i2c_client *client) From patchwork Mon Nov 11 07:47:17 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?Q3PDs2vDoXMsIEJlbmNl?= X-Patchwork-Id: 13870331 Received: from fw2.prolan.hu (fw2.prolan.hu [193.68.50.107]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C09AB14F9FF; Mon, 11 Nov 2024 07:47:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.68.50.107 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731311279; cv=none; b=gkf0gRPVXtQpGHs9BVtXQsp0+bSkNkuAdORe4YHUxAX9qRQPS2xsPXzIEgWfbF2XznrXM/Vy7KXYkyGjUOSXg2+kuadhRM3N5Ji65NiiBX8j99WHB7855gpRj5jONi9Z9Bqg8ASKzB/leS4IAdP10Vs/UdaEd2QhgzDJJ3hVttc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731311279; c=relaxed/simple; bh=8141MIeQteVO4xmHYABX+Gcz/sZ+OiBOCJf1oHf2DYI=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=n0GydFBJdAm4hWRSGdQU0xOkYhQc6VNrDIgz01yAnTehyAcpt2DOMuXTSHtIQtMJ1btjHvd0m/sGBCFw5VCbMgwUyv5qkwtNuDkV7OIC4Yf/BL5HM64M0ePSWDtDXXOF8baZETANPQdrWUDsh3Nl/yLMW5wDdZATjff9losbc50= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=prolan.hu; spf=pass smtp.mailfrom=prolan.hu; dkim=pass (4096-bit key) header.d=prolan.hu header.i=@prolan.hu header.b=AfkLZFW+; arc=none smtp.client-ip=193.68.50.107 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=prolan.hu Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=prolan.hu Authentication-Results: smtp.subspace.kernel.org; dkim=pass (4096-bit key) header.d=prolan.hu header.i=@prolan.hu header.b="AfkLZFW+" Received: from proxmox-mailgw.intranet.prolan.hu (localhost.localdomain [127.0.0.1]) by proxmox-mailgw.intranet.prolan.hu (Proxmox) with ESMTP id 13710A02C2; Mon, 11 Nov 2024 08:47:49 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=prolan.hu; h=cc :cc:content-transfer-encoding:content-type:content-type:date :from:from:in-reply-to:message-id:mime-version:references :reply-to:subject:subject:to:to; s=mail; bh=2i3QQlreelCEdwCoTEZ1 tiG1QMbQutV9WlIx5Sv6tSM=; b=AfkLZFW+VP0uMQG8Z1k4NeZKT9xYbNv5GOSE yc32X14mK7LzVh2H8RgTbGMFb5n/qM6jyqNNVvHqm5fgiYRBuY9vQ9ypJLCjRok8 ohP96toFlRFSIZTDmqZGYFV8N95xgZ6zL8/YwDRI4KffgoHA6ywxZMKaXapw0t2S X2MHr51Nr3jmB3ZNoGy1M0KUgV1rMjWwobDQDs5O7syWTtKA5LIRyXvBE1BRJuNQ s/ydof+KKVj+nOUn3QG/3M4tetZuOx8g+eXZ1tV/zQBLT7MQ1MX2hYcUUuFc4x54 65k9v+GqrJP9hA5YhbRju50mwW+2/URz2HwSuws27taQwtc9MWHEbhPPktxQY73w 5YARn5Qw1jAIxvS5PYiyR8+8v1c3ceJfRBEtCjsFDyn0BUGGpWMoECoLAO9o7bbY ioxqzijoR4lffQ4SSZNENSsu/rUxpbYp78OoLx/7qyVekuuCKsUoSB8E5vXop1dK k5hY1nYdcWVyJZBQQlKsalAOpVZ2voOAhrTsOMufkhWvcVwrHhZFbJm2U//HrRVV Hj2yc9e/RfysvB8lwk/IoUQOr8iJOhaJzFhPMgUxVBOtPY0awrRz+a1Evqn3kM4L SyqaMjWqF4jM2DCvSXkezwna9N54aG9ag8VVh+B10YS5Fj+JqcKMXdMv2nrE8Emv UFXLLwA= From: =?utf-8?b?Q3PDs2vDoXMsIEJlbmNl?= To: , CC: =?utf-8?b?Q3PDs2vDoXMsIEJlbmNl?= , "Samuel Holland" , Sebastian Reichel Subject: [PATCH v4 4/7] power: ip5xxx_power: Add battery type for 4.4V Date: Mon, 11 Nov 2024 08:47:17 +0100 Message-ID: <20241111074720.1727163-4-csokas.bence@prolan.hu> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20241111074720.1727163-1-csokas.bence@prolan.hu> References: <20241111074720.1727163-1-csokas.bence@prolan.hu> Precedence: bulk X-Mailing-List: linux-pm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ESET-AS: R=OK;S=0;OP=CALC;TIME=1731311268;VERSION=7980;MC=3195921940;ID=287558;TRN=0;CRV=0;IPC=;SP=0;SIPS=0;PI=3;F=0 X-ESET-Antispam: OK X-EsetResult: clean, is OK X-EsetId: 37303A2980D9485561716B IP53xx series supports 4.4V batteries. Add support for it to compatible parts (that have `vbat_max` set to >= 4.4 V). Signed-off-by: Csókás, Bence --- drivers/power/supply/ip5xxx_power.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/power/supply/ip5xxx_power.c b/drivers/power/supply/ip5xxx_power.c index a55441f87cc1..3a739a969dde 100644 --- a/drivers/power/supply/ip5xxx_power.c +++ b/drivers/power/supply/ip5xxx_power.c @@ -10,6 +10,7 @@ #define IP5XXX_BAT_TYPE_4_2V 0x0 #define IP5XXX_BAT_TYPE_4_3V 0x1 #define IP5XXX_BAT_TYPE_4_35V 0x2 +#define IP5XXX_BAT_TYPE_4_4V 0x3 #define IP5XXX_CHG_STAT_IDLE 0x0 #define IP5XXX_CHG_STAT_TRICKLE 0x1 #define IP5XXX_CHG_STAT_CONST_VOLT 0x2 @@ -363,6 +364,9 @@ static int ip5xxx_battery_get_voltage_max(struct ip5xxx *ip5xxx, int *val) case IP5XXX_BAT_TYPE_4_35V: *val = 4350000; break; + case IP5XXX_BAT_TYPE_4_4V: + *val = 4400000; + break; default: return -EINVAL; } @@ -490,6 +494,9 @@ static int ip5xxx_battery_set_voltage_max(struct ip5xxx *ip5xxx, int val) case 4350000: rval = IP5XXX_BAT_TYPE_4_35V; break; + case 4400000: + rval = IP5XXX_BAT_TYPE_4_4V; + break; default: return -EINVAL; } From patchwork Mon Nov 11 07:47:18 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?Q3PDs2vDoXMsIEJlbmNl?= X-Patchwork-Id: 13870333 Received: from fw2.prolan.hu (fw2.prolan.hu [193.68.50.107]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7A1DF155741; Mon, 11 Nov 2024 07:47:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.68.50.107 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731311279; cv=none; b=Fr+7huH71E3ZW6jo4K4/fVkYnHu17rwlpr+6senSqJFQjFFuFqpXxawoPHh6GdbyBIQEuxLeh/7po3pTkXqRAklPDVyo1X7UWIebTHRgdflbOzxRI7vSUuEt3zXWVhM2Af3yfSuM5cpPiloqrkSmOz6rGHLx7OvgPE/7eefgEWw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731311279; c=relaxed/simple; bh=FgBt3Jg123yYyp1wUYmUaLQCSARYYCtAyEm2IhlMMkg=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=iu/Ia/ru+DBU3bF7gKfgSD4VlF+YcBL7oVhFbKADNOGOGGxCwfJg7rBzFuERNRu3ry+me+hvFumgZmTtl6GHz6i0IJvxDskzH8yzvD6IfIGmKlrA4db3ahmJ9Jo8PiBXmOKM2HcahfH7BnCWSewanK9FPJBlzAlxDyAdU0qWeCs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=prolan.hu; spf=pass smtp.mailfrom=prolan.hu; dkim=pass (4096-bit key) header.d=prolan.hu header.i=@prolan.hu header.b=dZT6giQf; arc=none smtp.client-ip=193.68.50.107 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=prolan.hu Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=prolan.hu Authentication-Results: smtp.subspace.kernel.org; dkim=pass (4096-bit key) header.d=prolan.hu header.i=@prolan.hu header.b="dZT6giQf" Received: from proxmox-mailgw.intranet.prolan.hu (localhost.localdomain [127.0.0.1]) by proxmox-mailgw.intranet.prolan.hu (Proxmox) with ESMTP id C8744A043B; Mon, 11 Nov 2024 08:47:49 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=prolan.hu; h=cc :cc:content-transfer-encoding:content-type:content-type:date :from:from:in-reply-to:message-id:mime-version:references :reply-to:subject:subject:to:to; s=mail; bh=zsgQV6ELrg9oFQ/7FJ1q djm9jhFe9TnMay+N17iy5hQ=; b=dZT6giQfDuW+IGUa3NKO2gWhiBnqJ4u87f6Z N4JtRiz/GZ2XfnCFzuN02VF6ixz2Yw55nZvHRniwj1PhQs4M7Ie7q9xqDEo3AJ1m S/znaXvmNI2uL1lYWiKFEjfKU623VsKgB2UZamFG+Os7YqjoOUCOV9on3EUwwKDY MjkEjedCoofrV4vii6RQes09ULmrlFYpSrzgFzIFHple1p1LB4q1xxR63QL82YKm QmwuV/IarRgvagssfEgEYnUn9LoR5tPtJWJPBspKyNq6ASy5FSHg/7gdU4gDm7DW wLp5/DI4oeASiFLfORLDJUkz7miAS5U+Ei7Niah5BlnHhAVRBGFFOftpiDgzPM1M vgksv9+CpZ0Kyvbo0t5Xt8AfAqj2SX77SQ2DxrQNYMA1It4RZ7/5oTbC3JgMTYqJ +ztLEDlY+9o1zq0LSohPLS4gYb1jmUxR2g9a5yCuZQ5FII0SNWGfc63XE/bqZbIN IBe348wLvjBKKGOLphV8g+1dpNuSEtUuJqjKIZtKlckLUm1wOJCi0OQhkhm9DwvP SGzp4X/YmUZ6ugZVOJ88bUohWbev5w5F1eSfQWY9rAW6+Bkg0RiYctlMTY+JGgEs NKvZ1CMMJ9R/v+VHQ47n3Cc8TPE6COoegvGXvDIIwm181SD24jJHIqmrOFc1/9Qj 4JPnsXs= From: =?utf-8?b?Q3PDs2vDoXMsIEJlbmNl?= To: , CC: =?utf-8?b?Q3PDs2vDoXMsIEJlbmNl?= , "Samuel Holland" , Sebastian Reichel Subject: [PATCH v4 5/7] power: ip5xxx_power: Check for optional bits Date: Mon, 11 Nov 2024 08:47:18 +0100 Message-ID: <20241111074720.1727163-5-csokas.bence@prolan.hu> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20241111074720.1727163-1-csokas.bence@prolan.hu> References: <20241111074720.1727163-1-csokas.bence@prolan.hu> Precedence: bulk X-Mailing-List: linux-pm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ESET-AS: R=OK;S=0;OP=CALC;TIME=1731311269;VERSION=7980;MC=3696430840;ID=287559;TRN=0;CRV=0;IPC=;SP=0;SIPS=0;PI=3;F=0 X-ESET-Antispam: OK X-EsetResult: clean, is OK X-EsetId: 37303A2980D9485561716B Some parts may not have certain control bits. These bits however may be non-essential to the system's operation, as the default behaviour is the one we would set anyways, or the bits are not applicable for said part (e. g. enabling NTC on a part without an NTC pin, or one where it cannot be disabled via registers anyways). Signed-off-by: Csókás, Bence --- drivers/power/supply/ip5xxx_power.c | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/drivers/power/supply/ip5xxx_power.c b/drivers/power/supply/ip5xxx_power.c index 3a739a969dde..02e2a0c95407 100644 --- a/drivers/power/supply/ip5xxx_power.c +++ b/drivers/power/supply/ip5xxx_power.c @@ -111,6 +111,7 @@ struct ip5xxx { } const_curr; }; +#define REG_FIELD_UNSUPPORTED { .lsb = 1 } /* Register fields layout. Unsupported registers marked as { .lsb = 1 } */ struct ip5xxx_regfield_config { const struct reg_field charger_enable; @@ -204,9 +205,11 @@ static int ip5xxx_initialize(struct power_supply *psy) * Disable shutdown under light load. * Enable power on when under load. */ - ret = ip5xxx_write(ip5xxx, ip5xxx->regs.boost.light_load_shutdown.enable, 0); - if (ret) - return ret; + if (ip5xxx->regs.boost.light_load_shutdown.enable) { + ret = ip5xxx_write(ip5xxx, ip5xxx->regs.boost.light_load_shutdown.enable, 0); + if (ret) + return ret; + } ret = ip5xxx_write(ip5xxx, ip5xxx->regs.boost.load_powerup_en, 1); if (ret) return ret; @@ -229,9 +232,11 @@ static int ip5xxx_initialize(struct power_supply *psy) * Enable the NTC. * Configure the button for two presses => LED, long press => shutdown. */ - ret = ip5xxx_write(ip5xxx, ip5xxx->regs.battery.ntc_dis, 0); - if (ret) - return ret; + if (ip5xxx->regs.battery.ntc_dis) { + ret = ip5xxx_write(ip5xxx, ip5xxx->regs.battery.ntc_dis, 0); + if (ret) + return ret; + } ret = ip5xxx_write(ip5xxx, ip5xxx->regs.btn.wled_mode, 1); if (ret) return ret; @@ -505,9 +510,12 @@ static int ip5xxx_battery_set_voltage_max(struct ip5xxx *ip5xxx, int val) if (ret) return ret; - ret = ip5xxx_write(ip5xxx, ip5xxx->regs.battery.vset_en, 1); - if (ret) - return ret; + /* Don't try to auto-detect battery type, even if the IC could */ + if (ip5xxx->regs.battery.vset_en) { + ret = ip5xxx_write(ip5xxx, ip5xxx->regs.battery.vset_en, 1); + if (ret) + return ret; + } return 0; } From patchwork Mon Nov 11 07:47:20 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?Q3PDs2vDoXMsIEJlbmNl?= X-Patchwork-Id: 13870335 Received: from fw2.prolan.hu (fw2.prolan.hu [193.68.50.107]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D016215F330; Mon, 11 Nov 2024 07:48:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.68.50.107 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731311283; cv=none; b=efJi/LldFVf0rp/cRFePTZqN9DcHlvAWV6ApXoTHvHKcYCP/DiWw7IfBTfwFqv37K/TaulWZU73u4DQGCt/lsPwSKlaqRaDGMlr4tdfLTQQXLL4/Snwjwpfv60hSUTbbnD2gLrmL+X6qSSuPRuD7ThLGl301Q7FyxXKrkrDmgCU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731311283; c=relaxed/simple; bh=bLf0tpsER3DpJxb6HgrPCfaVeQxqDeqp2fPkip5+6JY=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=dnmWX8zEH2oHZR+7Aw9nxgmmhhAc4Hd4Bd7AgjwdSADXqDDA6pvNbKN3fuPLLurCugvtjcKh56Gu/4xbezQZUFE7eRy30cjuZyr0OoCeg1Bv3PVIZwr8KWq1s6sVKZBi1kpIQQY+5F2ZF3Q4j/rSA8J/CiJgadg4aKhzXyrCcMQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=prolan.hu; spf=pass smtp.mailfrom=prolan.hu; dkim=pass (4096-bit key) header.d=prolan.hu header.i=@prolan.hu header.b=ZlTzFEiM; arc=none smtp.client-ip=193.68.50.107 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=prolan.hu Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=prolan.hu Authentication-Results: smtp.subspace.kernel.org; dkim=pass (4096-bit key) header.d=prolan.hu header.i=@prolan.hu header.b="ZlTzFEiM" Received: from proxmox-mailgw.intranet.prolan.hu (localhost.localdomain [127.0.0.1]) by proxmox-mailgw.intranet.prolan.hu (Proxmox) with ESMTP id 43B95A07D9; Mon, 11 Nov 2024 08:47:51 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=prolan.hu; h=cc :cc:content-transfer-encoding:content-type:content-type:date :from:from:in-reply-to:message-id:mime-version:references :reply-to:subject:subject:to:to; s=mail; bh=OpE54i3OG//fb3hHcIkY 0cXwBz7J9rOx1NhY0ezsVyg=; b=ZlTzFEiM1i+LJwdiL8WqbWvcEf8Nx9UBvuER Qr2Hyghj45qs0nFLzZoJ71BAhEiGDBgjBjPHie3QYOkKsht3hDZgXi+s7qqnYwjc gC/munzCVIEPr1yPal0zE5Yf07ACjb8lkfNw9nWcWuyCi8/f+YPX/3TOrZDUaIaV q+lYSz3wt3W85AcBOY8BWyveMkU3x4+antwFIi1QFCkOH3cmRbC9PzF8yL3yBotK 4+5f7xWEb5ygPHar5tdy3O8XXAwJ/qBr4gmma2gho36AQUUmbvxBqNsBRrRvE/7I cnoszUElqVs3TJ/20HbNbTfhqLovmNwuWEekdkZe4YvuiJ/cCwFcYToJ/P3Xx6iB khpu4NLwg5uFhgFhOY/1lpb/1VXF7Bmc8ZXhHu8BU7s5djM9jr7uPNut5gvCRmX4 HAChDrk+Nfg19E4R8aCAnuNtOw5ZABiAh+vL4aLbd8FiJEdKT7K7+D0k736iQMKC ww75tA9QPi001DGVw8f+pdnalQZx4umkKfhmecb2c9cvsvdf1HAqMKM0zsVL+AB4 0Z+kK58/qtvRzaq7g7191CZLsCLEAvdAQhRjvlf+CJf9kprtXqi0HplrRbfXea5D MNWViFSa6SznFCT0+jbFaT/NwtVmHtx4KHxE+CrlOysUEEazM1gK6QwB0/atZ3pL 3Rulb9o= From: =?utf-8?b?Q3PDs2vDoXMsIEJlbmNl?= To: , CC: =?utf-8?b?Q3PDs2vDoXMsIEJlbmNl?= , "Samuel Holland" , Sebastian Reichel Subject: [PATCH v4 7/7] power: ip5xxx_power: Add support for IP5306 Date: Mon, 11 Nov 2024 08:47:20 +0100 Message-ID: <20241111074720.1727163-7-csokas.bence@prolan.hu> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20241111074720.1727163-1-csokas.bence@prolan.hu> References: <20241111074720.1727163-1-csokas.bence@prolan.hu> Precedence: bulk X-Mailing-List: linux-pm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ESET-AS: R=OK;S=0;OP=CALC;TIME=1731311270;VERSION=7980;MC=2118469096;ID=287561;TRN=0;CRV=0;IPC=;SP=0;SIPS=0;PI=3;F=0 X-ESET-Antispam: OK X-EsetResult: clean, is OK X-EsetId: 37303A2980D9485561716B Add ip5xxx_regfield_config for IP5306 Signed-off-by: Csókás, Bence --- drivers/power/supply/ip5xxx_power.c | 44 +++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/drivers/power/supply/ip5xxx_power.c b/drivers/power/supply/ip5xxx_power.c index 02e2a0c95407..7dd016792640 100644 --- a/drivers/power/supply/ip5xxx_power.c +++ b/drivers/power/supply/ip5xxx_power.c @@ -714,6 +714,49 @@ static struct ip5xxx_regfield_config ip51xx_fields = { .boost_undervolt_uv_per_bit = 100000, }; +static struct ip5xxx_regfield_config ip5306_fields = { + .charger_enable = REG_FIELD(0x00, 4, 4), + .charger_const_volt_sel = REG_FIELD(0x22, 0, 1), + .charger_const_curr_sel = REG_FIELD(0x24, 0, 4), + .charger_status = REG_FIELD_UNSUPPORTED, // other bits... + .charger_chg_end = REG_FIELD(0x71, 3, 3), + .charger_timeout = REG_FIELD_UNSUPPORTED, + .charger_vin_overvolt = REG_FIELD_UNSUPPORTED, + .boost_enable = REG_FIELD(0x00, 5, 5), + .boost_llshdn_enable = REG_FIELD_UNSUPPORTED, + .boost_llshdn_i_limit = REG_FIELD_UNSUPPORTED, + .boost_load_powerup_en = REG_FIELD(0x00, 2, 2), + .boost_vin_pullout_en = REG_FIELD(0x01, 2, 2), + .boost_undervolt_limit = REG_FIELD(0x21, 2, 4), + .boost_light_load_status = REG_FIELD(0x72, 2, 2), + .battery_ntc_dis = REG_FIELD_UNSUPPORTED, + .battery_type = REG_FIELD(0x22, 2, 3), + .battery_vset_en = REG_FIELD_UNSUPPORTED, + .battery_adc_volt_low = REG_FIELD_UNSUPPORTED, + .battery_adc_volt_high = REG_FIELD_UNSUPPORTED, + .battery_adc_curr_low = REG_FIELD_UNSUPPORTED, + .battery_adc_curr_high = REG_FIELD_UNSUPPORTED, + .battery_adc_ovolt_low = REG_FIELD_UNSUPPORTED, + .battery_adc_ovolt_high = REG_FIELD_UNSUPPORTED, + .btn_shdn_enable = REG_FIELD(0x00, 0, 0), + .btn_wled_mode = REG_FIELD(0x01, 6, 6), + .btn_shdn_mode = REG_FIELD(0x01, 7, 7), + .btn_long_press_time = REG_FIELD(0x02, 4, 4), // +1s + .btn_pressed = REG_FIELD_UNSUPPORTED, + // TODO double press + .btn_long_pressed = REG_FIELD(0x77, 1, 1), + .btn_short_pressed = REG_FIELD(0x77, 0, 0), + .wled_enable = REG_FIELD_UNSUPPORTED, + .wled_detect_en = REG_FIELD_UNSUPPORTED, + .wled_present = REG_FIELD_UNSUPPORTED, + + .vbat_max = 4400000, + .boost_undervolt_setpoint = 4450000, + .boost_undervolt_uv_per_bit = 50000, + .const_curr_setpoint = 50000, + .chg_end_inverted = 1, +}; + #define ip5xxx_setup_reg(_field, _reg) \ do { \ if (likely(cfg->_field.lsb <= cfg->_field.msb)) { \ @@ -808,6 +851,7 @@ static const struct of_device_id ip5xxx_power_of_match[] = { { .compatible = "injoinic,ip5109", .data = &ip51xx_fields }, { .compatible = "injoinic,ip5207", .data = &ip51xx_fields }, { .compatible = "injoinic,ip5209", .data = &ip51xx_fields }, + { .compatible = "injoinic,ip5306", .data = &ip5306_fields }, { } }; MODULE_DEVICE_TABLE(of, ip5xxx_power_of_match);