| /* Copyright (c) 2015, The Linux Foundation. All rights reserved. |
| |
| Redistribution and use in source and binary forms, with or without |
| modification, are permitted provided that the following conditions are |
| met: |
| * Redistributions of source code must retain the above copyright |
| notice, this list of conditions and the following disclaimer. |
| * Redistributions in binary form must reproduce the above |
| copyright notice, this list of conditions and the following |
| disclaimer in the documentation and/or other materials provided |
| with the distribution. |
| * Neither the name of The Linux Foundation nor the names of its |
| contributors may be used to endorse or promote products derived |
| from this software without specific prior written permission. |
| |
| THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED |
| WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT |
| ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS |
| BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
| CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
| SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR |
| BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, |
| WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE |
| OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN |
| IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| */ |
| |
| /*=========================================================================== |
| |
| INCLUDE FILES |
| |
| ===========================================================================*/ |
| #include "pm_smbchg_chgr.h" |
| #include "pm_smbchg_driver.h" |
| #include <sys/types.h> |
| |
| static inline pm_err_flag_type pm_smbchg_chgr_unlock_perph_write(pm_smbchg_data_type *smbchg); |
| |
| |
| /*Find the nearest register value corresponding to input_data*/ |
| //static void pm_smbchg_chgr_return_reg_value(uint32 input_data, uint32 *array, uint32 array_size, pm_register_data_type *reg_value) |
| //{ |
| // uint32 position = 0; |
| // |
| // while (position < array_size) |
| // { |
| // if (input_data < array[position]) |
| // { |
| // break; |
| // } |
| // else |
| // { |
| // position++; |
| // } |
| // } |
| // |
| // *reg_value = (position) ? (position - 1) : 0; |
| // |
| // return; |
| //} |
| |
| //@todo: implement pm_smbchg_chgr_chg_option |
| |
| /*This API returns if battery is above VBAT_WEAK threshold or not*/ |
| pm_err_flag_type pm_smbchg_chgr_vbat_sts(uint32 device_index, boolean *is_above_vbat_weak) |
| { |
| pm_err_flag_type err_flag = PM_ERR_FLAG__SUCCESS; |
| pm_register_data_type data; |
| pm_smbchg_data_type *smbchg_ptr = pm_smbchg_get_data(device_index); |
| |
| if (NULL == smbchg_ptr) |
| { |
| err_flag = PM_ERR_FLAG__FEATURE_NOT_SUPPORTED; |
| } |
| else if (NULL == is_above_vbat_weak) |
| { |
| err_flag = PM_ERR_FLAG__PAR2_OUT_OF_RANGE; |
| } |
| else |
| { |
| pm_register_address_type vbat_status = smbchg_ptr->smbchg_register->chgr_register->base_address + smbchg_ptr->smbchg_register->chgr_register->vbat_status; |
| |
| err_flag = pm_comm_read_byte(smbchg_ptr->comm_ptr->slave_id, vbat_status, &data, 0); |
| |
| if (PM_ERR_FLAG__SUCCESS == err_flag) |
| { |
| *is_above_vbat_weak = (data & 0x2) ? TRUE : FALSE; |
| } |
| } |
| |
| return err_flag; |
| } |
| |
| //This API returns the float vlotage status |
| pm_err_flag_type pm_smbchg_chgr_get_float_volt_sts(uint32 device_index, boolean *aicl_in_hard_limit, uint32 *fv_mv) |
| { |
| pm_err_flag_type err_flag = PM_ERR_FLAG__SUCCESS; |
| pm_register_data_type data; |
| uint32 temp_data; |
| pm_smbchg_data_type *smbchg_ptr = pm_smbchg_get_data(device_index); |
| |
| if (NULL == smbchg_ptr) |
| { |
| err_flag = PM_ERR_FLAG__FEATURE_NOT_SUPPORTED; |
| } |
| else if (NULL == fv_mv) |
| { |
| err_flag = PM_ERR_FLAG__PAR2_OUT_OF_RANGE; |
| } |
| else |
| { |
| pm_register_address_type fv_sts = smbchg_ptr->smbchg_register->chgr_register->base_address + smbchg_ptr->smbchg_register->chgr_register->fv_sts; |
| |
| err_flag = pm_comm_read_byte(smbchg_ptr->comm_ptr->slave_id, fv_sts, &data, 0); |
| |
| if (PM_ERR_FLAG__SUCCESS == err_flag) |
| { |
| *aicl_in_hard_limit = (data & 0x40) ? TRUE : FALSE; |
| temp_data = data & 0x3F; |
| if (temp_data < 0x5) |
| { |
| temp_data = 3600; |
| } |
| if (temp_data >= 0x22) |
| { |
| temp_data = 4500; |
| } |
| else |
| { |
| temp_data = (temp_data > 0x2D) ? (3620 + ((temp_data - 0x5) * 20)) : (3600 + ((temp_data - 0x5) * 20)); |
| } |
| |
| *fv_mv = temp_data; |
| } |
| } |
| |
| return err_flag; |
| } |
| |
| /*This API returns the pre charger and fast charger current status in milliamp*/ |
| pm_err_flag_type pm_smbchg_chgr_get_chg_i_sts(uint32 device_index, uint32 *pre_charge_current_ma, uint32 *fast_charge_current_ma) |
| { |
| pm_err_flag_type err_flag = PM_ERR_FLAG__SUCCESS; |
| pm_register_data_type data; |
| |
| |
| pm_smbchg_data_type *smbchg_ptr = pm_smbchg_get_data(device_index); |
| |
| if (NULL == smbchg_ptr) |
| { |
| err_flag = PM_ERR_FLAG__FEATURE_NOT_SUPPORTED; |
| } |
| else if (NULL == fast_charge_current_ma) |
| { |
| err_flag = PM_ERR_FLAG__PAR3_OUT_OF_RANGE; |
| } |
| else |
| { |
| uint32 *charge_current = smbchg_ptr->chg_range_data->usbin_current_limits; |
| if ( NULL == charge_current) |
| { |
| err_flag |= PM_ERR_FLAG__FEATURE_NOT_SUPPORTED; |
| } |
| pm_register_address_type ichg_sts = smbchg_ptr->smbchg_register->chgr_register->base_address + smbchg_ptr->smbchg_register->chgr_register->ichg_sts; |
| |
| err_flag = pm_comm_read_byte(smbchg_ptr->comm_ptr->slave_id, ichg_sts, &data, 0); |
| |
| if (PM_ERR_FLAG__SUCCESS == err_flag) |
| { |
| *pre_charge_current_ma = ((data >> 5) & 0x04) ? 550 : (100 + ((data >> 5) * 50)); |
| |
| *fast_charge_current_ma = charge_current[data & 0x1F]; |
| } |
| } |
| |
| return err_flag; |
| } |
| |
| /*This API reads the various charging status*/ |
| pm_err_flag_type pm_smbchg_chgr_get_chgr_sts(uint32 device_index, pm_smbchg_chgr_chgr_status_type *chgr_sts) |
| { |
| pm_err_flag_type err_flag = PM_ERR_FLAG__SUCCESS; |
| pm_register_data_type data; |
| pm_register_address_type chgr_sts_reg; |
| |
| pm_smbchg_data_type *smbchg_ptr = pm_smbchg_get_data(device_index); |
| |
| if (NULL == smbchg_ptr) |
| { |
| err_flag = PM_ERR_FLAG__FEATURE_NOT_SUPPORTED; |
| } |
| else if (NULL == chgr_sts) |
| { |
| err_flag = PM_ERR_FLAG__PAR2_OUT_OF_RANGE; |
| } |
| else |
| { |
| chgr_sts_reg = smbchg_ptr->smbchg_register->chgr_register->base_address + smbchg_ptr->smbchg_register->chgr_register->chgr_sts; |
| |
| err_flag = pm_comm_read_byte(smbchg_ptr->comm_ptr->slave_id, chgr_sts_reg, &data, 0); |
| |
| if (PM_ERR_FLAG__SUCCESS == err_flag) |
| { |
| chgr_sts->is_net_i_discharg = (data & 0x80) ? TRUE : FALSE; |
| chgr_sts->is_auto_fv_comp_active = (data & 0x40) ? TRUE : FALSE; |
| chgr_sts->is_chgr_done_once = (data & 0x20) ? TRUE : FALSE; |
| chgr_sts->is_batt_lt_2v = (data & 0x10) ? TRUE : FALSE; |
| chgr_sts->is_chgr_in_hold_off = (data & 0x8) ? TRUE : FALSE; |
| chgr_sts->charging_type = (pm_smbchg_chgr_charging_type)((data & 0x6) >> 1); |
| chgr_sts->charger_enable = (data & 0x1) ? TRUE : FALSE; |
| } |
| } |
| |
| return err_flag; |
| } |
| |
| /*This API configures the pre-charger current value in milliamp. Valid values are 100 to 550 mAmp*/ |
| pm_err_flag_type pm_smbchg_chgr_set_pre_chg_i(uint32 device_index, uint32 pre_chg_i_ma) |
| { |
| pm_err_flag_type err_flag = PM_ERR_FLAG__SUCCESS; |
| pm_register_data_type data; |
| pm_register_address_type pcc_cfg; |
| |
| pm_smbchg_data_type *smbchg_ptr = pm_smbchg_get_data(device_index); |
| if (NULL == smbchg_ptr) |
| { |
| err_flag = PM_ERR_FLAG__FEATURE_NOT_SUPPORTED; |
| } |
| else |
| { |
| pcc_cfg = smbchg_ptr->smbchg_register->chgr_register->base_address + smbchg_ptr->smbchg_register->chgr_register->pcc_cfg; |
| |
| pre_chg_i_ma = (pre_chg_i_ma<100)? 100 : pre_chg_i_ma; |
| |
| data = (pre_chg_i_ma > 250) ? 0x4 : ((pre_chg_i_ma - 100) / 50); |
| |
| err_flag = pm_smbchg_chgr_unlock_perph_write(smbchg_ptr); |
| err_flag |= pm_comm_write_byte_mask(smbchg_ptr->comm_ptr->slave_id, pcc_cfg, 0x7, data, 0); |
| } |
| |
| return err_flag; |
| } |
| |
| /*This API configures the fast-charger current value in milliamp. Valid values are 300 to 3000 mAmp*/ |
| pm_err_flag_type pm_smbchg_chgr_set_fast_chg_i(uint32 device_index, uint32 fast_chag_i_ma) |
| { |
| pm_err_flag_type err_flag = PM_ERR_FLAG__SUCCESS; |
| pm_register_data_type data = 0; |
| |
| |
| pm_smbchg_data_type *smbchg_ptr = pm_smbchg_get_data(device_index); |
| if (NULL == smbchg_ptr) |
| { |
| err_flag = PM_ERR_FLAG__FEATURE_NOT_SUPPORTED; |
| } |
| else |
| { |
| uint32 *charge_current = smbchg_ptr->chg_range_data->usbin_current_limits; |
| pm_register_address_type fcc_cfg = smbchg_ptr->smbchg_register->chgr_register->base_address + smbchg_ptr->smbchg_register->chgr_register->fcc_cfg; |
| |
| while (data < USBIN_SIZE) |
| { |
| if (charge_current[data] > fast_chag_i_ma) |
| { |
| break; |
| } |
| else |
| { |
| data++; |
| } |
| } |
| |
| data = (data < USBIN_SIZE) ? (data - 1) : 0; |
| |
| err_flag = pm_smbchg_chgr_unlock_perph_write(smbchg_ptr); |
| err_flag |= pm_comm_write_byte_mask(smbchg_ptr->comm_ptr->slave_id, fcc_cfg, 0x1F, data, 0); |
| } |
| |
| return err_flag; |
| } |
| |
| /*This API configures the fast-charger current compensation value in milliamp. Valid values are 300 to 1200 mAmp*/ |
| pm_err_flag_type pm_smbchg_chgr_set_fast_chg_i_cmpn(uint32 device_index, uint32 fast_chg_i_cmp_ma) |
| { |
| pm_err_flag_type err_flag = PM_ERR_FLAG__SUCCESS; |
| pm_register_data_type data; |
| pm_smbchg_data_type *smbchg_ptr = pm_smbchg_get_data(device_index); |
| if (NULL == smbchg_ptr) |
| { |
| err_flag = PM_ERR_FLAG__FEATURE_NOT_SUPPORTED; |
| } |
| else |
| { |
| pm_register_address_type fcc_cmp_cfg = smbchg_ptr->smbchg_register->chgr_register->base_address + smbchg_ptr->smbchg_register->chgr_register->fcc_cmp_cfg; |
| |
| if (fast_chg_i_cmp_ma < 700) |
| { |
| data = 0x00; |
| } |
| else if (fast_chg_i_cmp_ma < 900) |
| { |
| data = 0x01; |
| } |
| else if (fast_chg_i_cmp_ma < 1200) |
| { |
| data = 0x02; |
| } |
| else |
| { |
| data = 0x03; |
| } |
| |
| err_flag = pm_smbchg_chgr_unlock_perph_write(smbchg_ptr); |
| err_flag |= pm_comm_write_byte_mask(smbchg_ptr->comm_ptr->slave_id, fcc_cmp_cfg, 0x3, data, 0); |
| } |
| |
| return err_flag; |
| } |
| |
| /*This API configures the floating voltage. Valid range is 3600mV to 4500 mv*/ |
| pm_err_flag_type pm_smbchg_chgr_set_float_volt(uint32 device_index, uint32 float_volt_mv) |
| { |
| pm_err_flag_type err_flag = PM_ERR_FLAG__SUCCESS; |
| pm_register_data_type data; |
| pm_smbchg_data_type *smbchg_ptr = pm_smbchg_get_data(device_index); |
| if (NULL == smbchg_ptr) |
| { |
| err_flag = PM_ERR_FLAG__FEATURE_NOT_SUPPORTED; |
| } |
| else |
| { |
| pm_register_address_type fv_cfg = smbchg_ptr->smbchg_register->chgr_register->base_address + smbchg_ptr->smbchg_register->chgr_register->fv_cfg; |
| |
| if (float_volt_mv < 3600) |
| { |
| data = 0x5; |
| } |
| else if (float_volt_mv > 4500) |
| { |
| data = 0x33; |
| } |
| else |
| { |
| data = ((float_volt_mv - 3600) / 20) + 5; |
| } |
| |
| err_flag = pm_smbchg_chgr_unlock_perph_write(smbchg_ptr); |
| err_flag |= pm_comm_write_byte_mask(smbchg_ptr->comm_ptr->slave_id, fv_cfg, 0x3F, data, 0); |
| } |
| |
| return err_flag; |
| } |
| |
| |
| pm_err_flag_type pm_smbchg_chgr_get_float_volt_cfg(uint32 device_index, uint32 *float_volt_mv) |
| { |
| pm_err_flag_type err_flag = PM_ERR_FLAG__SUCCESS; |
| pm_register_data_type data; |
| pm_smbchg_data_type *smbchg_ptr = pm_smbchg_get_data(device_index); |
| if (NULL == smbchg_ptr) |
| { |
| err_flag = PM_ERR_FLAG__FEATURE_NOT_SUPPORTED; |
| } |
| else if (NULL == float_volt_mv) |
| { |
| err_flag = PM_ERR_FLAG__PAR2_OUT_OF_RANGE; |
| } |
| else |
| { |
| pm_register_address_type fv_cfg = smbchg_ptr->smbchg_register->chgr_register->base_address + smbchg_ptr->smbchg_register->chgr_register->fv_cfg; |
| err_flag = pm_comm_read_byte_mask(smbchg_ptr->comm_ptr->slave_id, fv_cfg, 0x3F, &data, 0); |
| *float_volt_mv = (data > 0x5) ? 0x00 : (3600 + ((data - 0x5) * 20)); |
| } |
| |
| return err_flag; |
| } |
| |
| /*This api sets floating voltage conpmensation code. Valid value is from 0 to 6300 mV*/ |
| pm_err_flag_type pm_smbchg_chgr_set_float_volt_cmpn(uint32 device_index, uint32 float_volt_cmpn) |
| { |
| pm_err_flag_type err_flag = PM_ERR_FLAG__SUCCESS; |
| pm_register_data_type data; |
| pm_smbchg_data_type *smbchg_ptr = pm_smbchg_get_data(device_index); |
| if (NULL == smbchg_ptr) |
| { |
| err_flag = PM_ERR_FLAG__FEATURE_NOT_SUPPORTED; |
| } |
| else |
| { |
| pm_register_address_type fv_cmp_cfg = smbchg_ptr->smbchg_register->chgr_register->base_address + smbchg_ptr->smbchg_register->chgr_register->fv_cmp_cfg; |
| |
| data = (float_volt_cmpn > 6300) ? 63 : float_volt_cmpn/100; |
| err_flag = pm_smbchg_chgr_unlock_perph_write(smbchg_ptr); |
| err_flag |= pm_comm_write_byte_mask(smbchg_ptr->comm_ptr->slave_id, fv_cmp_cfg, 0x3F, data, 0); |
| } |
| |
| return err_flag; |
| } |
| |
| |
| /*This api reads floating voltage conpmensation code settings. Valid value is from 0 to 63*/ |
| pm_err_flag_type pm_smbchg_chgr_get_float_volt_cmpn(uint32 device_index, uint32 *float_volt_cmpn) |
| { |
| pm_err_flag_type err_flag = PM_ERR_FLAG__SUCCESS; |
| pm_register_data_type data; |
| pm_smbchg_data_type *smbchg_ptr = pm_smbchg_get_data(device_index); |
| if (NULL == smbchg_ptr) |
| { |
| err_flag = PM_ERR_FLAG__FEATURE_NOT_SUPPORTED; |
| } |
| else if (NULL == float_volt_cmpn) |
| { |
| err_flag = PM_ERR_FLAG__PAR2_OUT_OF_RANGE; |
| } |
| else |
| { |
| pm_register_address_type fv_cmp_cfg = smbchg_ptr->smbchg_register->chgr_register->base_address + smbchg_ptr->smbchg_register->chgr_register->fv_cmp_cfg; |
| err_flag = pm_comm_read_byte_mask(smbchg_ptr->comm_ptr->slave_id, fv_cmp_cfg, 0x3F, &data, 0); |
| *float_volt_cmpn = data * 10; |
| } |
| |
| return err_flag; |
| } |
| |
| /*This api enables/disables Charger Auto Float Voltage Compensation*/ |
| pm_err_flag_type pm_smbchg_chgr_en_afvc(uint32 device_index, boolean enable) |
| { |
| pm_err_flag_type err_flag = PM_ERR_FLAG__SUCCESS; |
| pm_register_data_type data; |
| pm_smbchg_data_type *smbchg_ptr = pm_smbchg_get_data(device_index); |
| if (NULL == smbchg_ptr) |
| { |
| err_flag = PM_ERR_FLAG__FEATURE_NOT_SUPPORTED; |
| } |
| else |
| { |
| pm_register_address_type cfg_afvc = smbchg_ptr->smbchg_register->chgr_register->base_address + smbchg_ptr->smbchg_register->chgr_register->cfg_afvc; |
| data = (enable) ? TRUE : FALSE; |
| err_flag = pm_smbchg_chgr_unlock_perph_write(smbchg_ptr); |
| err_flag |= pm_comm_write_byte_mask(smbchg_ptr->comm_ptr->slave_id, cfg_afvc, 0x7, data, 0); |
| } |
| |
| return err_flag; |
| } |
| |
| /*This API sets charge inhibit level*/ |
| pm_err_flag_type pm_smbchg_chgr_set_inhibi_threshold(uint32 device_index, uint32 inhibit_lvl_mv) |
| { |
| pm_err_flag_type err_flag = PM_ERR_FLAG__SUCCESS; |
| pm_register_data_type data; |
| pm_smbchg_data_type *smbchg_ptr = pm_smbchg_get_data(device_index); |
| if (NULL == smbchg_ptr) |
| { |
| err_flag = PM_ERR_FLAG__FEATURE_NOT_SUPPORTED; |
| } |
| else |
| { |
| if (inhibit_lvl_mv < 100) |
| { |
| data = 0x00; |
| } |
| else if (inhibit_lvl_mv < 200) |
| { |
| data = 0x1; |
| } |
| else if (inhibit_lvl_mv < 300) |
| { |
| data = 0x2; |
| } |
| else |
| { |
| data = 0x3; |
| } |
| |
| pm_register_address_type cfg_chg_inhib = smbchg_ptr->smbchg_register->chgr_register->base_address + smbchg_ptr->smbchg_register->chgr_register->cfg_chg_inhib; |
| err_flag = pm_smbchg_chgr_unlock_perph_write(smbchg_ptr); |
| err_flag |= pm_comm_write_byte_mask(smbchg_ptr->comm_ptr->slave_id, cfg_chg_inhib, 0x3, data, 0); |
| } |
| |
| return err_flag; |
| } |
| |
| /*This API reads charge inhibit level configured*/ |
| pm_err_flag_type pm_smbchg_chgr_get_inhibi_threshold(uint32 device_index, uint32 *inhibit_lvl_mv) |
| { |
| pm_err_flag_type err_flag = PM_ERR_FLAG__SUCCESS; |
| pm_register_data_type data; |
| pm_smbchg_data_type *smbchg_ptr = pm_smbchg_get_data(device_index); |
| if (NULL == smbchg_ptr) |
| { |
| err_flag = PM_ERR_FLAG__FEATURE_NOT_SUPPORTED; |
| } |
| else if (NULL == inhibit_lvl_mv) |
| { |
| err_flag = PM_ERR_FLAG__PAR2_OUT_OF_RANGE; |
| } |
| else |
| { |
| pm_register_address_type cfg_chg_inhib = smbchg_ptr->smbchg_register->chgr_register->base_address + smbchg_ptr->smbchg_register->chgr_register->cfg_chg_inhib; |
| err_flag = pm_comm_read_byte_mask(smbchg_ptr->comm_ptr->slave_id, cfg_chg_inhib, 0x3, &data, 0); |
| *inhibit_lvl_mv = (data == 0x00) ? 50 : (data * 100); |
| } |
| |
| return err_flag; |
| } |
| |
| /*This API sets the pre-charge to full charger threshold. Valid range is 2400mV to 3000mV*/ |
| pm_err_flag_type pm_smbchg_chgr_set_p2f_threshold(uint32 device_index, uint32 milli_volt) |
| |
| { |
| pm_err_flag_type err_flag = PM_ERR_FLAG__SUCCESS; |
| pm_register_data_type data; |
| pm_smbchg_data_type *smbchg_ptr = pm_smbchg_get_data(device_index); |
| if (NULL == smbchg_ptr) |
| { |
| err_flag = PM_ERR_FLAG__FEATURE_NOT_SUPPORTED; |
| } |
| else |
| { |
| if (milli_volt < 2600) |
| { |
| data = 0x00; |
| } |
| else if (milli_volt < 2800) |
| { |
| data = 0x1; |
| } |
| else if (milli_volt < 3000) |
| { |
| data = 0x2; |
| } |
| else |
| { |
| data = 0x3; |
| } |
| |
| pm_register_address_type cfg_p2f = smbchg_ptr->smbchg_register->chgr_register->base_address + smbchg_ptr->smbchg_register->chgr_register->cfg_p2f; |
| err_flag = pm_smbchg_chgr_unlock_perph_write(smbchg_ptr); |
| err_flag |= pm_comm_write_byte_mask(smbchg_ptr->comm_ptr->slave_id, cfg_p2f, 0x3, data, 0); |
| } |
| |
| return err_flag; |
| } |
| |
| |
| /*This API reads the pre-charge to full charger threshold. Valid range is 2400mV to 3000mV*/ |
| pm_err_flag_type pm_smbchg_chgr_get_p2f_threshold(uint32 device_index, uint32 *milli_volt) |
| { |
| pm_err_flag_type err_flag = PM_ERR_FLAG__SUCCESS; |
| pm_register_data_type data; |
| pm_smbchg_data_type *smbchg_ptr = pm_smbchg_get_data(device_index); |
| if (NULL == smbchg_ptr) |
| { |
| err_flag = PM_ERR_FLAG__FEATURE_NOT_SUPPORTED; |
| } |
| else if (NULL == milli_volt) |
| { |
| err_flag = PM_ERR_FLAG__PAR2_OUT_OF_RANGE; |
| } |
| else |
| { |
| pm_register_address_type cfg_p2f = smbchg_ptr->smbchg_register->chgr_register->base_address + smbchg_ptr->smbchg_register->chgr_register->cfg_p2f; |
| err_flag = pm_comm_read_byte_mask(smbchg_ptr->comm_ptr->slave_id, cfg_p2f, 0x3, &data, 0); |
| *milli_volt = 2400 + (200 * data); |
| } |
| |
| return err_flag; |
| } |
| |
| |
| /*This API sets the charge termination current in milliamp */ |
| pm_err_flag_type pm_smbchg_chgr_set_charge_termination_current(uint32 device_index, uint32 current_ma) |
| { |
| pm_err_flag_type err_flag = PM_ERR_FLAG__SUCCESS; |
| pm_register_data_type data; |
| pm_smbchg_data_type *smbchg_ptr = pm_smbchg_get_data(device_index); |
| if (NULL == smbchg_ptr) |
| { |
| err_flag = PM_ERR_FLAG__FEATURE_NOT_SUPPORTED; |
| } |
| else |
| { |
| /* 000 = 300mA, 001 = 50mA, 010 = 100mA, 011 = 150mA, 100 = 200mA, 101 = 250mA, 110 =500mA, 111 = 600mA */ |
| if (current_ma < 300) |
| { |
| data = (current_ma / 50) ? (current_ma / 50) : 0x1; |
| } |
| else if (current_ma < 500) |
| { |
| data = 0x00; |
| } |
| else |
| { |
| data = (current_ma < 600) ? 0x6 : 0x7; |
| } |
| |
| pm_register_address_type cfg_tcc = smbchg_ptr->smbchg_register->chgr_register->base_address + smbchg_ptr->smbchg_register->chgr_register->cfg_tcc; |
| err_flag = pm_smbchg_chgr_unlock_perph_write(smbchg_ptr); |
| err_flag |= pm_comm_write_byte_mask(smbchg_ptr->comm_ptr->slave_id, cfg_tcc, 0x7, data, 0); |
| } |
| |
| return err_flag; |
| } |
| |
| |
| /*This API reads the charge termination current_ma*/ |
| pm_err_flag_type pm_smbchg_chgr_get_charge_termination_current(uint32 device_index, uint32 *current_ma) |
| { |
| pm_err_flag_type err_flag = PM_ERR_FLAG__SUCCESS; |
| pm_register_data_type data; |
| pm_smbchg_data_type *smbchg_ptr = pm_smbchg_get_data(device_index); |
| if (NULL == smbchg_ptr) |
| { |
| err_flag = PM_ERR_FLAG__FEATURE_NOT_SUPPORTED; |
| } |
| else if (NULL == current_ma) |
| { |
| err_flag = PM_ERR_FLAG__PAR2_OUT_OF_RANGE; |
| } |
| else |
| { |
| pm_register_address_type cfg_tcc = smbchg_ptr->smbchg_register->chgr_register->base_address + smbchg_ptr->smbchg_register->chgr_register->cfg_tcc; |
| err_flag = pm_comm_read_byte_mask(smbchg_ptr->comm_ptr->slave_id, cfg_tcc, 0x7, &data, 0); |
| if (data == 0) |
| { |
| *current_ma = 300; |
| } |
| else if (data < 5) |
| { |
| *current_ma = 50 * data; |
| } |
| else |
| { |
| *current_ma = 100 * (data - 1); |
| } |
| } |
| |
| return err_flag; |
| } |
| |
| |
| /*This API configures charge temperature compensation type*/ |
| pm_err_flag_type pm_smbchg_chgr_config_chgr_temp_cmpn(uint32 device_index, pm_smbchg_chgr_ccmpn_type ccmpn_type, boolean enable) |
| { |
| pm_err_flag_type err_flag = PM_ERR_FLAG__SUCCESS; |
| |
| pm_smbchg_data_type *smbchg_ptr = pm_smbchg_get_data(device_index); |
| |
| if (NULL == smbchg_ptr) |
| { |
| err_flag = PM_ERR_FLAG__FEATURE_NOT_SUPPORTED; |
| } |
| else if (PM_SMBCHG_CHGR_CCMPN__INVALID == ccmpn_type) |
| { |
| err_flag = PM_ERR_FLAG__PAR2_OUT_OF_RANGE; |
| } |
| else |
| { |
| pm_register_address_type ccmp_cfg = smbchg_ptr->smbchg_register->chgr_register->base_address + smbchg_ptr->smbchg_register->chgr_register->ccmp_cfg; |
| err_flag = pm_smbchg_chgr_unlock_perph_write(smbchg_ptr); |
| err_flag |= pm_comm_write_byte_mask(smbchg_ptr->comm_ptr->slave_id, ccmp_cfg, (0x1 << ccmpn_type), (pm_register_data_type)(enable << ccmpn_type), 0); |
| } |
| |
| return err_flag; |
| } |
| |
| |
| /*This API reads configured charge temperature compensation type*/ |
| pm_err_flag_type pm_smbchg_chgr_get_chgr_temp_cmpn_config(uint32 device_index, pm_smbchg_chgr_ccmpn_type ccmpn_type, boolean *enable) |
| { |
| pm_err_flag_type err_flag = PM_ERR_FLAG__SUCCESS; |
| pm_register_data_type data; |
| pm_smbchg_data_type *smbchg_ptr = pm_smbchg_get_data(device_index); |
| |
| if (NULL == smbchg_ptr) |
| { |
| err_flag = PM_ERR_FLAG__FEATURE_NOT_SUPPORTED; |
| } |
| else if (PM_SMBCHG_CHGR_CCMPN__INVALID == ccmpn_type) |
| { |
| err_flag = PM_ERR_FLAG__PAR2_OUT_OF_RANGE; |
| } |
| else |
| { |
| pm_register_address_type ccmp_cfg = smbchg_ptr->smbchg_register->chgr_register->base_address + smbchg_ptr->smbchg_register->chgr_register->ccmp_cfg; |
| err_flag = pm_comm_read_byte(smbchg_ptr->comm_ptr->slave_id, ccmp_cfg, &data, 0); |
| *enable = (data & (0x1 << ccmpn_type)) ? TRUE : FALSE; |
| } |
| |
| return err_flag; |
| } |
| |
| |
| /*This API sets charger configuration */ |
| pm_err_flag_type pm_smbchg_chgr_config_chgr(uint32 device_index, pm_chgr_chgr_cfg_type *chgr_cfg_type) |
| { |
| pm_err_flag_type err_flag = PM_ERR_FLAG__SUCCESS; |
| pm_register_data_type data1, data2; |
| pm_smbchg_data_type *smbchg_ptr = pm_smbchg_get_data(device_index); |
| |
| if (NULL == smbchg_ptr) |
| { |
| err_flag = PM_ERR_FLAG__FEATURE_NOT_SUPPORTED; |
| } |
| else if (NULL == chgr_cfg_type) |
| { |
| err_flag = PM_ERR_FLAG__PAR2_OUT_OF_RANGE; |
| } |
| else if (chgr_cfg_type->sysok_opt >= PM_SMBCHG_CHGR_SYSOK_OPT__INVALID) |
| { |
| err_flag = PM_ERR_FLAG__PAR2_OUT_OF_RANGE; |
| } |
| else |
| { |
| data1 = (chgr_cfg_type->cont_without_fg_ready) | (chgr_cfg_type->is_rchg_threshold_src_fg << 1) | (chgr_cfg_type->is_term_current_src_fg << 2) |
| | (chgr_cfg_type->en_early_current_termination << 3) | (chgr_cfg_type->sysok_opt << 4) | (chgr_cfg_type->en_sysok_pol_table_n << 7); |
| |
| data2 = (chgr_cfg_type->en_charger_inhibit) | (chgr_cfg_type->is_holdoff_tmr_350ms << 1) | (chgr_cfg_type->auto_rchg_dis << 2) | (chgr_cfg_type->current_termination_dis << 3) |
| | (chgr_cfg_type->batt_ov_ends_cycle_en << 4) | (chgr_cfg_type->p2f_chg_tran_require_cmd << 5); |
| |
| pm_register_address_type chgr_cfg1 = smbchg_ptr->smbchg_register->chgr_register->base_address + smbchg_ptr->smbchg_register->chgr_register->chgr_cfg1; |
| pm_register_address_type chgr_cfg2 = smbchg_ptr->smbchg_register->chgr_register->base_address + smbchg_ptr->smbchg_register->chgr_register->chgr_cfg2; |
| |
| err_flag = pm_smbchg_chgr_unlock_perph_write(smbchg_ptr); |
| err_flag |= pm_comm_write_byte(smbchg_ptr->comm_ptr->slave_id, chgr_cfg1, data1, 0); |
| |
| err_flag |= pm_smbchg_chgr_unlock_perph_write(smbchg_ptr); |
| err_flag |= pm_comm_write_byte(smbchg_ptr->comm_ptr->slave_id, chgr_cfg2, data2, 0); |
| } |
| |
| return err_flag; |
| } |
| |
| /*This API reads charger configuration */ |
| pm_err_flag_type pm_smbchg_chgr_get_chgr_config(uint32 device_index, pm_chgr_chgr_cfg_type *chgr_cfg_type) |
| { |
| pm_err_flag_type err_flag = PM_ERR_FLAG__SUCCESS; |
| pm_register_data_type data1, data2; |
| pm_smbchg_data_type *smbchg_ptr = pm_smbchg_get_data(device_index); |
| |
| if (NULL == smbchg_ptr) |
| { |
| err_flag = PM_ERR_FLAG__FEATURE_NOT_SUPPORTED; |
| } |
| else if (NULL == chgr_cfg_type) |
| { |
| err_flag = PM_ERR_FLAG__PAR2_OUT_OF_RANGE; |
| } |
| else |
| { |
| pm_register_address_type chgr_cfg1 = smbchg_ptr->smbchg_register->chgr_register->base_address + smbchg_ptr->smbchg_register->chgr_register->chgr_cfg1; |
| pm_register_address_type chgr_cfg2 = smbchg_ptr->smbchg_register->chgr_register->base_address + smbchg_ptr->smbchg_register->chgr_register->chgr_cfg2; |
| |
| err_flag = pm_comm_read_byte(smbchg_ptr->comm_ptr->slave_id, chgr_cfg1, &data1, 0); |
| err_flag |= pm_comm_read_byte(smbchg_ptr->comm_ptr->slave_id, chgr_cfg2, &data2, 0); |
| |
| chgr_cfg_type->cont_without_fg_ready = (data1 & 0x1) ? TRUE : FALSE; |
| chgr_cfg_type->is_rchg_threshold_src_fg = (data1 & 0x2) ? TRUE : FALSE; |
| chgr_cfg_type->is_term_current_src_fg = (data1 & 0x4) ? TRUE : FALSE; |
| chgr_cfg_type->en_early_current_termination = (data1 & 0x8) ? TRUE : FALSE; |
| chgr_cfg_type->sysok_opt = (pm_smbchg_chgr_sysok_opt_type)((data1 & 0x70) >> 4); |
| chgr_cfg_type->en_sysok_pol_table_n = (data1 & 0x80) ? TRUE : FALSE;; |
| |
| chgr_cfg_type->en_charger_inhibit = (data2 & 0x1) ? TRUE : FALSE; |
| chgr_cfg_type->is_holdoff_tmr_350ms = (data2 & 0x2) ? TRUE : FALSE; |
| chgr_cfg_type->auto_rchg_dis = (data2 & 0x4) ? TRUE : FALSE; |
| chgr_cfg_type->current_termination_dis = (data2 & 0x8) ? TRUE : FALSE; |
| chgr_cfg_type->batt_ov_ends_cycle_en = (data2 & 0x10) ? TRUE : FALSE; |
| chgr_cfg_type->p2f_chg_tran_require_cmd = (data2 & 0x20) ? TRUE : FALSE; |
| } |
| |
| return err_flag; |
| } |
| |
| pm_err_flag_type pm_smbchg_chgr_config_sfty_timer(uint32 device_index, uint32 pre_chg_sfty_min, uint32 total_chg_sfty_min, pm_smbchg_chgr_sfty_timer_type sfty_timer_type) |
| |
| { |
| pm_err_flag_type err_flag = PM_ERR_FLAG__SUCCESS; |
| pm_register_data_type data1, data2, data; |
| pm_smbchg_data_type *smbchg_ptr = pm_smbchg_get_data(device_index); |
| if (NULL == smbchg_ptr) |
| { |
| err_flag = PM_ERR_FLAG__FEATURE_NOT_SUPPORTED; |
| } |
| else if (sfty_timer_type >= PM_SMBCHG_CHGR_SFTY_TIMER__INVAID_TYPE) |
| { |
| err_flag = PM_ERR_FLAG__PAR2_OUT_OF_RANGE; |
| } |
| else |
| { |
| if (pre_chg_sfty_min < 96) |
| { |
| data1 = (pre_chg_sfty_min < 48) ? 0x0 : 0x1; |
| } |
| else |
| { |
| data1 = (pre_chg_sfty_min < 192) ? 0x2 : 0x3; |
| } |
| |
| if (total_chg_sfty_min < 768) |
| { |
| data2 = (total_chg_sfty_min < 384) ? 0x0 : 0x1; |
| } |
| else |
| { |
| data2 = (total_chg_sfty_min < 1536) ? 0x2 : 0x3; |
| } |
| |
| data = (sfty_timer_type << 4) | (data2 << 2) | data1; |
| |
| pm_register_address_type sft_cfg = smbchg_ptr->smbchg_register->chgr_register->base_address + smbchg_ptr->smbchg_register->chgr_register->sft_cfg; |
| |
| err_flag = pm_smbchg_chgr_unlock_perph_write(smbchg_ptr); |
| err_flag |= pm_comm_write_byte_mask(smbchg_ptr->comm_ptr->slave_id, sft_cfg, 0x3F, data, 0); |
| } |
| |
| return err_flag; |
| } |
| |
| |
| pm_err_flag_type pm_smbchg_chgr_get_sfty_timer_config(uint32 device_index, uint32 *pre_chg_sfty_min, uint32 *total_chg_sfty_min, pm_smbchg_chgr_sfty_timer_type *sfty_timer_type) |
| { |
| pm_err_flag_type err_flag = PM_ERR_FLAG__SUCCESS; |
| pm_register_data_type data; |
| pm_smbchg_data_type *smbchg_ptr = pm_smbchg_get_data(device_index); |
| |
| if (NULL == smbchg_ptr) |
| { |
| err_flag = PM_ERR_FLAG__FEATURE_NOT_SUPPORTED; |
| } |
| else if (NULL == pre_chg_sfty_min || NULL == total_chg_sfty_min || NULL == sfty_timer_type) |
| { |
| err_flag = PM_ERR_FLAG__INVALID_POINTER; |
| } |
| else |
| { |
| pm_register_address_type sft_cfg = smbchg_ptr->smbchg_register->chgr_register->base_address + smbchg_ptr->smbchg_register->chgr_register->sft_cfg; |
| err_flag = pm_comm_read_byte(smbchg_ptr->comm_ptr->slave_id, sft_cfg, &data, 0); |
| |
| *sfty_timer_type = (pm_smbchg_chgr_sfty_timer_type)((data & 0x30) >> 0x4); |
| |
| switch (data & 0x3) |
| { |
| case 0: |
| *pre_chg_sfty_min = 24; break; |
| case 1: |
| *pre_chg_sfty_min = 48; break; |
| case 2: |
| *pre_chg_sfty_min = 96; break; |
| default: |
| *pre_chg_sfty_min = 192; |
| } |
| |
| switch ((data & 0x6) >> 2) |
| { |
| case 0: |
| *total_chg_sfty_min = 192; break; |
| case 1: |
| *total_chg_sfty_min = 384; break; |
| case 2: |
| *total_chg_sfty_min = 768; break; |
| default: |
| *total_chg_sfty_min = 1536; |
| } |
| |
| } |
| |
| return err_flag; |
| } |
| |
| |
| pm_err_flag_type pm_smbchg_chgr_irq_enable(uint32 device_index, pm_smbchg_chgr_irq_type irq, boolean enable) |
| { |
| pm_err_flag_type err_flag = PM_ERR_FLAG__SUCCESS; |
| pm_register_address_type irq_reg; |
| pm_register_data_type data = 1 << irq; |
| pm_smbchg_data_type *smbchg_ptr = pm_smbchg_get_data(device_index); |
| |
| if (NULL == smbchg_ptr) |
| { |
| err_flag = PM_ERR_FLAG__FEATURE_NOT_SUPPORTED; |
| } |
| else if (irq >= PM_SMBCHG_CHGR_IRQ_INVALID) |
| { |
| err_flag = PM_ERR_FLAG__PAR2_OUT_OF_RANGE; |
| } |
| else |
| { |
| if (enable) |
| { |
| irq_reg = smbchg_ptr->smbchg_register->chgr_register->base_address + smbchg_ptr->smbchg_register->chgr_register->int_en_set; |
| } |
| else |
| { |
| irq_reg = smbchg_ptr->smbchg_register->chgr_register->base_address + smbchg_ptr->smbchg_register->chgr_register->int_en_clr; |
| } |
| |
| err_flag = pm_comm_write_byte(smbchg_ptr->comm_ptr->slave_id, irq_reg, data, 0); |
| } |
| return err_flag; |
| } |
| |
| pm_err_flag_type pm_smbchg_chgr_irq_clear(uint32 device_index, pm_smbchg_chgr_irq_type irq) |
| { |
| pm_err_flag_type err_flag = PM_ERR_FLAG__SUCCESS; |
| pm_register_data_type data = 1 << irq; |
| |
| pm_smbchg_data_type *smbchg_ptr = pm_smbchg_get_data(device_index); |
| |
| if (NULL == smbchg_ptr) |
| { |
| err_flag = PM_ERR_FLAG__FEATURE_NOT_SUPPORTED; |
| } |
| else if (irq >= PM_SMBCHG_CHGR_IRQ_INVALID) |
| { |
| err_flag = PM_ERR_FLAG__FEATURE_NOT_SUPPORTED; |
| } |
| else |
| { |
| pm_register_address_type int_latched_clr = smbchg_ptr->smbchg_register->chgr_register->base_address + smbchg_ptr->smbchg_register->chgr_register->int_latched_clr; |
| err_flag = pm_comm_write_byte(smbchg_ptr->comm_ptr->slave_id, int_latched_clr, data, 0); |
| } |
| |
| return err_flag; |
| } |
| |
| |
| pm_err_flag_type pm_smbchg_chgr_irq_set_trigger(uint32 device_index, pm_smbchg_chgr_irq_type irq, pm_irq_trigger_type trigger) |
| { |
| pm_err_flag_type err_flag = PM_ERR_FLAG__SUCCESS; |
| uint8 mask = 1 << irq; |
| pm_register_data_type set_type, polarity_high, polarity_low; |
| pm_smbchg_data_type *smbchg_ptr = pm_smbchg_get_data(device_index); |
| |
| if (NULL == smbchg_ptr) |
| { |
| err_flag = PM_ERR_FLAG__FEATURE_NOT_SUPPORTED; |
| } |
| else if (irq >= PM_SMBCHG_CHGR_IRQ_INVALID) |
| { |
| err_flag = PM_ERR_FLAG__PAR2_OUT_OF_RANGE; |
| } |
| else |
| { |
| switch (trigger) |
| { |
| case PM_IRQ_TRIGGER_ACTIVE_LOW: |
| set_type = 0x00; |
| polarity_high = 0x00; |
| polarity_low = 0xFF; |
| break; |
| case PM_IRQ_TRIGGER_ACTIVE_HIGH: |
| set_type = 0x00; |
| polarity_high = 0xFF; |
| polarity_low = 0x00; |
| break; |
| case PM_IRQ_TRIGGER_RISING_EDGE: |
| set_type = 0xFF; |
| polarity_high = 0xFF; |
| polarity_low = 0x00; |
| break; |
| case PM_IRQ_TRIGGER_FALLING_EDGE: |
| set_type = 0xFF; |
| polarity_high = 0x00; |
| polarity_low = 0xFF; |
| break; |
| case PM_IRQ_TRIGGER_DUAL_EDGE: |
| set_type = 0xFF; |
| polarity_high = 0xFF; |
| polarity_low = 0xFF; |
| break; |
| default: |
| return PM_ERR_FLAG__FEATURE_NOT_SUPPORTED; |
| } |
| |
| pm_register_address_type int_set_type = smbchg_ptr->smbchg_register->chgr_register->base_address + smbchg_ptr->smbchg_register->chgr_register->int_set_type; |
| pm_register_address_type int_polarity_high = smbchg_ptr->smbchg_register->chgr_register->base_address + smbchg_ptr->smbchg_register->chgr_register->int_polarity_high; |
| pm_register_address_type int_polarity_low = smbchg_ptr->smbchg_register->chgr_register->base_address + smbchg_ptr->smbchg_register->chgr_register->int_polarity_low; |
| |
| err_flag = pm_comm_write_byte_mask(smbchg_ptr->comm_ptr->slave_id, int_set_type, mask, set_type, 0); |
| err_flag |= pm_comm_write_byte_mask(smbchg_ptr->comm_ptr->slave_id, int_polarity_high, mask, polarity_high, 0); |
| err_flag |= pm_comm_write_byte_mask(smbchg_ptr->comm_ptr->slave_id, int_polarity_low, mask, polarity_low, 0); |
| } |
| |
| return err_flag; |
| } |
| |
| pm_err_flag_type pm_smbchg_chgr_irq_status(uint32 device_index, pm_smbchg_chgr_irq_type irq, pm_irq_status_type type, boolean *status) |
| { |
| pm_err_flag_type err_flag = PM_ERR_FLAG__SUCCESS; |
| pm_register_data_type data; |
| uint8 mask = 1 << irq; |
| pm_register_address_type int_sts; |
| pm_smbchg_data_type *smbchg_ptr = pm_smbchg_get_data(device_index); |
| |
| if (NULL == smbchg_ptr) |
| { |
| err_flag = PM_ERR_FLAG__FEATURE_NOT_SUPPORTED; |
| } |
| else if (irq >= PM_SMBCHG_CHGR_IRQ_INVALID) |
| { |
| err_flag = PM_ERR_FLAG__PAR2_OUT_OF_RANGE; |
| } |
| else if (NULL == status) |
| { |
| err_flag = PM_ERR_FLAG__PAR4_OUT_OF_RANGE; |
| } |
| else |
| { |
| switch (type) |
| { |
| case PM_IRQ_STATUS_RT: |
| int_sts = smbchg_ptr->smbchg_register->chgr_register->base_address + smbchg_ptr->smbchg_register->chgr_register->int_rt_sts; |
| break; |
| case PM_IRQ_STATUS_LATCHED: |
| int_sts = smbchg_ptr->smbchg_register->chgr_register->base_address + smbchg_ptr->smbchg_register->chgr_register->int_latched_sts; |
| break; |
| case PM_IRQ_STATUS_PENDING: |
| int_sts = smbchg_ptr->smbchg_register->chgr_register->base_address + smbchg_ptr->smbchg_register->chgr_register->int_pending_sts; |
| break; |
| default: |
| return PM_ERR_FLAG__FEATURE_NOT_SUPPORTED; |
| } |
| |
| err_flag = pm_comm_read_byte_mask(smbchg_ptr->comm_ptr->slave_id, int_sts, mask, &data, 0); |
| *status = data ? TRUE : FALSE; |
| } |
| |
| return err_flag; |
| } |
| |
| static inline pm_err_flag_type pm_smbchg_chgr_unlock_perph_write(pm_smbchg_data_type *smbchg_ptr) |
| { |
| pm_err_flag_type err_flag = PM_ERR_FLAG__SUCCESS; |
| |
| if (NULL == smbchg_ptr) |
| { |
| err_flag = PM_ERR_FLAG__FEATURE_NOT_SUPPORTED; |
| } |
| else |
| { |
| pm_register_address_type sec_access = smbchg_ptr->smbchg_register->chgr_register->base_address + smbchg_ptr->smbchg_register->chgr_register->sec_access; |
| err_flag = pm_comm_write_byte(smbchg_ptr->comm_ptr->slave_id, sec_access, 0xA5, 0); |
| } |
| |
| return err_flag; |
| } |
| |
| |
| /*This API sets charger source */ |
| pm_err_flag_type pm_smbchg_chgr_enable_src(uint32 device_index, boolean chg_en_src) |
| { |
| pm_err_flag_type err_flag = PM_ERR_FLAG__SUCCESS; |
| pm_smbchg_data_type *smbchg_ptr = pm_smbchg_get_data(device_index); |
| |
| if (NULL == smbchg_ptr) |
| { |
| err_flag = PM_ERR_FLAG__FEATURE_NOT_SUPPORTED; |
| } |
| else |
| { |
| pm_register_address_type chgr_cfg2 = smbchg_ptr->smbchg_register->chgr_register->base_address + smbchg_ptr->smbchg_register->chgr_register->chgr_cfg2; |
| |
| err_flag = pm_smbchg_chgr_unlock_perph_write(smbchg_ptr); |
| err_flag |= pm_comm_write_byte_mask(smbchg_ptr->comm_ptr->slave_id, chgr_cfg2, 0x80, chg_en_src, 0); |
| } |
| |
| return err_flag; |
| } |
| |
| /*This API sets charger polarity */ |
| pm_err_flag_type pm_smbchg_chgr_set_chg_polarity_low (uint32 device_index, boolean chg_pol_low) |
| { |
| pm_err_flag_type err_flag = PM_ERR_FLAG__SUCCESS; |
| pm_smbchg_data_type *smbchg_ptr = pm_smbchg_get_data(device_index); |
| |
| if (NULL == smbchg_ptr) |
| { |
| err_flag = PM_ERR_FLAG__FEATURE_NOT_SUPPORTED; |
| } |
| else |
| { |
| pm_register_address_type chgr_cfg2 = smbchg_ptr->smbchg_register->chgr_register->base_address + smbchg_ptr->smbchg_register->chgr_register->chgr_cfg2; |
| |
| err_flag = pm_smbchg_chgr_unlock_perph_write(smbchg_ptr); |
| err_flag |= pm_comm_write_byte_mask(smbchg_ptr->comm_ptr->slave_id, chgr_cfg2, 0x40, (chg_pol_low ? 0x40 : 0), 0); |
| } |
| |
| return err_flag; |
| } |