static int cn_set_property(struct power_supply *psy, enum power_supply_property psp, const union power_supply_propval *val) { int ret; struct cn_chip *chip = container_of(psy, struct cn_chip, cn_psy); switch (psp) { case POWER_SUPPLY_PROP_VIRT_ENABLE_BMS: if (!val->intval) ret = cn_masked_write_base(chip, BMS_EN_CTL, BMS_EN_MASK, 0x00); else ret = cn_masked_write_base(chip, BMS_EN_CTL, BMS_EN_MASK, 0x80); if (ret) { chip->bms_enabled = 0; pr_err("fail to enable bms\n"); } else { chip->bms_enabled = 1; } break; default: return -EINVAL; } return 0; }
static int __devinit cn_probe(struct spmi_device *spmi) { int rc; struct cn_chip *chip; struct device *dev = &spmi->dev; chip = kzalloc(sizeof(*chip), GFP_KERNEL); if (unlikely(!chip)) { pr_err("cn_probe: out of memory space\n"); return -ENOMEM; } dev_set_drvdata(dev, chip); if (chip == NULL) { pr_err("kzalloc() failed.\n"); return -ENOMEM; } chip->iadc_base = IADC_BASE; chip->base = BMS_BASE; chip->r_sense_uohm = RSENSE_MICRO_OHM; /* */ rc = spmi_cn_add_controller(chip, spmi); if (rc) { pr_info("error registering spmi resource %d\n", rc); goto error_read; } rc = set_cn_iadc_channel(chip); if (rc) { pr_err("Unable to get iadc selected channel = %d\n", rc); goto error_read; } chip->cn_psy.name = "cn"; chip->cn_psy.type = POWER_SUPPLY_TYPE_BMS; chip->cn_psy.get_property = cn_get_property; chip->cn_psy.set_property = cn_set_property; chip->cn_psy.properties = cn_props; chip->cn_psy.num_properties = ARRAY_SIZE(cn_props); chip->cn_psy.property_is_writeable = cn_power_property_is_writeable; rc = power_supply_register(chip->dev, &chip->cn_psy); if (rc < 0) { pr_err("power_supply_register bms failed rc = %d\n", rc); goto unregister_dc; } /* */ rc = cn_masked_write_base(chip, BMS_EN_CTL, BMS_EN_MASK, 0x80); if (rc) pr_err("Fail to enable BMS_EN_CTL!! rc=%d\n", rc); return 0; unregister_dc: power_supply_unregister(&chip->cn_psy); error_read: kfree(chip); return rc; }
static int cn_suspend(struct device *dev) { int rc; struct cn_chip *chip = dev_get_drvdata(dev); rc = cn_masked_write_base(chip, BMS_EN_CTL, BMS_EN_MASK, 0x00); if (rc) pr_err("Fail to disable BMS_EN_CTL!! rc=%d\n", rc); return rc; }
static int cn_set_property(struct power_supply *psy, enum power_supply_property psp, const union power_supply_propval *val) { int ret; struct cn_chip *chip = container_of(psy, struct cn_chip, cn_psy); switch (psp) { case POWER_SUPPLY_PROP_PRESENT: if (val->intval) ret = cn_masked_write_base(chip, BMS_EN_CTL, BMS_EN_MASK, 0x80); else ret = cn_masked_write_base(chip, BMS_EN_CTL, BMS_EN_MASK, 0x00); break; default: return -EINVAL; } return 0; }
static int cn_masked_write_iadc(struct cn_chip *chip, u16 addr, u8 mask, u8 val) { return cn_masked_write_base(chip, chip->iadc_base + addr, mask, val); }