Пример #1
0
static irqreturn_t max8998_int_work_func(int irq, void *max8998_chg)
{
	int ret;
	u8 data = 0;
	struct chg_data *chg;
	struct i2c_client *i2c;

	chg = max8998_chg;
	i2c = chg->iodev->i2c;

	ret = max8998_read_reg(i2c, MAX8998_REG_IRQ1, &data);
	if (ret < 0)
		goto err;

	ret = max8998_read_reg(i2c, MAX8998_REG_IRQ3, &data);
	if (ret < 0)
		goto err;

	if ((data & 0x4) || (ret != 0)) {
		pr_info("%s : pmic battery full interrupt\n", __func__);
		chg->set_batt_full = 1;
		chg->bat_info.batt_is_full = true;
	}

	wake_lock(&chg->work_wake_lock);
	queue_work(chg->monitor_wqueue, &chg->bat_work);

	return IRQ_HANDLED;
err:
	pr_err("%s : pmic read error\n", __func__);
	return IRQ_HANDLED;
}
Пример #2
0
static int max8998_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
{
	struct max8998_rtc_info *info = dev_get_drvdata(dev);
	u8 data[8];
	u8 val;
	int ret;

	ret = max8998_bulk_read(info->rtc, MAX8998_ALARM0_SEC, 8, data);
	if (ret < 0)
		return ret;

	max8998_data_to_tm(data, &alrm->time);

	ret = max8998_read_reg(info->rtc, MAX8998_ALARM0_CONF, &val);
	if (ret < 0)
		return ret;

	alrm->enabled = !!val;

	ret = max8998_read_reg(info->rtc, MAX8998_RTC_STATUS, &val);
	if (ret < 0)
		return ret;

	if (val & ALARM0_STATUS)
		alrm->pending = 1;
	else
		alrm->pending = 0;

	return 0;
}
Пример #3
0
static irqreturn_t max8998_int_work_func(int irq, void *max8998_chg)
{
	int ret;
	u8 data = 0;
	struct chg_data *chg;

	chg = max8998_chg;

	ret = max8998_read_reg(chg->iodev, MAX8998_REG_IRQ1, &data);
	if (ret < 0)
		goto err;

	ret = max8998_read_reg(chg->iodev, MAX8998_REG_IRQ3, &data);
	if (ret < 0)
		goto err;

	if ((data & 0x4) || (ret != 0)) {
		pr_info("%s : pmic interrupt\n", __func__);
		chg->set_batt_full = 1;
		chg->bat_info.batt_is_full = true;
        if (chg->bat_info.batt_soc > 0) {
            chg->bat_info.batt_max_soc = chg->bat_info.batt_soc;
            pr_info("%s : batt_max_soc=%d\n", __func__, chg->bat_info.batt_max_soc);
        }
	}

	wake_lock(&chg->work_wake_lock);
	queue_work(chg->monitor_wqueue, &chg->bat_work);

	return IRQ_HANDLED;
err:
	pr_err("%s : pmic read error\n", __func__);
	return IRQ_HANDLED;
}
Пример #4
0
int max8998_ldo_is_enabled_direct(int ldo)
{
	struct max8998_data *max8998 = client_data_p;
	int value, shift;
	if((ldo < MAX8998_LDO1) || (ldo > MAX8998_DCDC4))
	{
		printk("ERROR: Invalid argument passed\n");
		return -EINVAL;
	}
	DBG("func =%s called for regulator = %d\n",__func__,ldo);
	if (ldo <= MAX8998_LDO5) {
		value = max8998_read_reg(max8998, MAX8998_REG_ONOFF1);
		shift = 5 - ldo;
	} else if (ldo <= MAX8998_LDO13) {
		value = max8998_read_reg(max8998, MAX8998_REG_ONOFF2);
		shift = 13 - ldo;
	} else if (ldo <= MAX8998_LDO17) {
		value = max8998_read_reg(max8998, MAX8998_REG_ONOFF3);
		shift = 21 - ldo;
	} else {
		value = max8998_read_reg(max8998, MAX8998_REG_ONOFF1);
		shift = 7 - (ldo - MAX8998_DCDC1);
	}
	return (value >> shift) & 0x1;
}
Пример #5
0
/* Save registers before hibernation */
static int max8998_freeze(struct device *dev)
{
	struct i2c_client *i2c = to_i2c_client(dev);
	int i;

	for (i = 0; i < ARRAY_SIZE(max8998_dump); i++)
		max8998_read_reg(i2c, max8998_dump[i].addr,
				&max8998_dump[i].val);

	return 0;
}
static int max8998_check_charger(struct max8998_power_info *info)
{
	int ret;
	u8 val;

	ret = max8998_read_reg(info->i2c, MAX8998_REG_STATUS2, &val);
	if (ret >= 0) {
		/*
		 * If battery detection is enabled, ID pin of battery is
		 * connected to MBDET pin of MAX8998. It could be used to
		 * detect battery presence.
		 * Otherwise, we have to assume that battery is always on.
		 */
		if (info->batt_detect)
			info->bat_online =
			    (val & MAX8998_REG_STATUS2_BDET_MASK) ? 0 : 1;
		else
			info->bat_online = 1;

		if (val & MAX8998_REG_STATUS2_VCHGIN_MASK) {
			info->ac_online = 1;
			info->usb_online = 1;
			wake_lock(&info->vbus_wake_lock);
		} else {
			info->ac_online = 0;
			info->usb_online = 0;
			wake_lock_timeout(&info->vbus_wake_lock, HZ / 2);
		}
	}

#if 0
	if (enable) {
		/* enable charger in platform */
		if (info->set_charger)
			info->set_charger(1);
		/* enable charger */
		max8998_set_bits(info->i2c, MAX8998_CHG_CNTL1, 1 << 7, 0);
	} else {
		/* disable charge */
		max8998_set_bits(info->i2c, MAX8998_CHG_CNTL1, 1 << 7, 1 << 7);
		if (info->set_charger)
			info->set_charger(0);
	}

	dev_dbg(chip->dev, "%s\n", (enable) ? "Enable charger"
		: "Disable charger");
#endif

	power_supply_changed(&max8998_power_supplies[0]);
	power_supply_changed(&max8998_power_supplies[1]);
	power_supply_changed(&max8998_power_supplies[2]);

	return 0;
}
Пример #7
0
int max8998_ldo_disable_direct(int ldo)
{
	struct max8998_data *max8998 = client_data_p;
	int value, shift;

	if((ldo < MAX8998_LDO1) || (ldo > MAX8998_DCDC4))
	{
		printk("ERROR: Invalid argument passed\n");
		return -EINVAL;
	}

	DBG("func =%s called for regulator = %d\n",__func__,ldo);

	spin_lock(&pmic_access_lock);

	if (ldo <= MAX8998_LDO5) {
		value = max8998_read_reg(max8998, MAX8998_REG_ONOFF1);
		shift = 5 - ldo;
		value &= ~(1 << shift);
		max8998_write_reg(max8998, value, MAX8998_REG_ONOFF1);
	} else if (ldo <= MAX8998_LDO13) {
		value = max8998_read_reg(max8998, MAX8998_REG_ONOFF2);
		shift = 13 - ldo;
		value &= ~(1 << shift);
		max8998_write_reg(max8998, value, MAX8998_REG_ONOFF2);
	} else if (ldo <= MAX8998_LDO17) {
		value = max8998_read_reg(max8998, MAX8998_REG_ONOFF3);
		shift = 21 - ldo;
		value &= ~(1 << shift);
		max8998_write_reg(max8998, value, MAX8998_REG_ONOFF3);
	} else {
		value = max8998_read_reg(max8998, MAX8998_REG_ONOFF1);
		shift = 7 - (ldo - MAX8998_DCDC1);
		value &= ~(1 << shift);
		max8998_write_reg(max8998, value, MAX8998_REG_ONOFF1);
	}

	spin_unlock(&pmic_access_lock);

	return 0;
}
Пример #8
0
static int max8998_ldo_is_enabled(struct regulator_dev *rdev)
{
	struct max8998_data *max8998 = rdev_get_drvdata(rdev);
	int ldo = max8998_get_ldo(rdev);
	int value, shift;

	if (ldo <= MAX8998_LDO5) {
		value = max8998_read_reg(max8998, MAX8998_REG_ONOFF1);
		//shift = 6 - ldo;
		shift = 5 - ldo;
	} else if (ldo <= MAX8998_LDO13) {
		value = max8998_read_reg(max8998, MAX8998_REG_ONOFF2);
		shift = 13 - ldo;
	} else if (ldo <= MAX8998_LDO17) {
		value = max8998_read_reg(max8998, MAX8998_REG_ONOFF3);
		shift = 21 - ldo;
	} else {
		value = max8998_read_reg(max8998, MAX8998_REG_ONOFF1);
		shift = 7 - (ldo - MAX8998_DCDC1);
	}
	return (value >> shift) & 0x1;
}
Пример #9
0
static bool max8998_check_vdcin(struct chg_data *chg)
{
	u8 data = 0;
	int ret;

	ret = max8998_read_reg(chg->iodev->i2c, MAX8998_REG_STATUS2, &data);

	if (ret < 0) {
		pr_err("max8998_read_reg error\n");
		return ret;
	}

	return data & MAX8998_MASK_VDCIN;
}
Пример #10
0
static int max8998_ldo_disable(struct regulator_dev *rdev)
{
	struct max8998_data *max8998 = rdev_get_drvdata(rdev);
	int ldo = max8998_get_ldo(rdev);
	int value, shift;
	
	DBG("func =%s called for regulator = %d\n",__func__,ldo);

	spin_lock(&pmic_access_lock);

	if (ldo <= MAX8998_LDO5) {
		value = max8998_read_reg(max8998, MAX8998_REG_ONOFF1);
		//shift = 6 - ldo;
		shift = 5 - ldo;
		value &= ~(1 << shift);
		max8998_write_reg(max8998, value, MAX8998_REG_ONOFF1);
	} else if (ldo <= MAX8998_LDO13) {
		value = max8998_read_reg(max8998, MAX8998_REG_ONOFF2);
		shift = 13 - ldo;
		value &= ~(1 << shift);
		max8998_write_reg(max8998, value, MAX8998_REG_ONOFF2);
	} else if (ldo <= MAX8998_LDO17) {
		value = max8998_read_reg(max8998, MAX8998_REG_ONOFF3);
		shift = 21 - ldo;
		value &= ~(1 << shift);
		max8998_write_reg(max8998, value, MAX8998_REG_ONOFF3);
	} else {
		value = max8998_read_reg(max8998, MAX8998_REG_ONOFF1);
		shift = 7 - (ldo - MAX8998_DCDC1);
		value &= ~(1 << shift);
		max8998_write_reg(max8998, value, MAX8998_REG_ONOFF1);
	}

	spin_unlock(&pmic_access_lock);

	return 0;
}
Пример #11
0
static int max8998_check_vdcin(struct chg_data *chg)
{
        struct i2c_client *i2c = chg->iodev->i2c;
	u8 data = 0;
	int ret;

	ret = max8998_read_reg(i2c, MAX8998_REG_STATUS2, &data);

	if (ret < 0) {
		pr_err("max8998_read_reg error\n");
		return ret;
	}

	return (data & MAX8998_MASK_VDCIN) ? 1 : 0;
}
static int max8998_check_vdcin(void)
{
	struct max8998_chg_data *chg = max8998_chg;
	u8 data = 0;
	int ret;

	ret = max8998_read_reg(chg->iodev, MAX8998_REG_STATUS2, &data);

	if (ret < 0) {
		pr_err("max8998_read_reg error\n");
		return ret;
	}

	return data & MAX8998_MASK_VDCIN;
}
Пример #13
0
static int max8998_i2c_probe(struct i2c_client *i2c,
			    const struct i2c_device_id *id)
{
        struct max8998_platform_data *pdata = i2c->dev.platform_data;
	struct max8998_dev *max8998;
	int ret = 0;
	u8 val;

	max8998 = kzalloc(sizeof(struct max8998_dev), GFP_KERNEL);
	if (max8998 == NULL)
		return -ENOMEM;

	i2c_set_clientdata(i2c, max8998);
	max8998->dev = &i2c->dev;
	max8998->i2c_client = i2c;
	max8998->irq = i2c->irq;
	if (pdata) {
		max8998->ono = pdata->ono;
		max8998->irq_base = pdata->irq_base;
	}
	max8998->dev_read = max8998_i2c_device_read;
	max8998->dev_write = max8998_i2c_device_write;
	max8998->dev_update = max8998_i2c_device_update;
	mutex_init(&max8998->iolock);

	max8998_irq_init(max8998);

	max8998_read_reg(max8998, MAX8998_REG_ONOFF1, &val);
	val &= ~(MAX8998_MASK_EN1|MAX8998_MASK_EN2|MAX8998_MASK_EN4);
	max8998_write_reg(max8998, MAX8998_REG_ONOFF1, val);

	ret = mfd_add_devices(max8998->dev, -1,
			      max8998_devs, ARRAY_SIZE(max8998_devs),
			      NULL, 0);
	if (ret < 0)
		goto err;

	return ret;

err:
	mfd_remove_devices(max8998->dev);
	kfree(max8998);
	return ret;
}
Пример #14
0
int max8998_ldo_set_voltage_direct(int ldo,
				int min_uV, int max_uV)
{
	struct max8998_data *max8998 = client_data_p;
	int value, shift = 0, mask = 0xff, reg;
	int min_vol = min_uV / 1000, max_vol = max_uV / 1000;
	int i = 0;
	const int *vol_map = NULL;

	if((ldo < MAX8998_LDO1) || (ldo > MAX8998_DCDC4))
	{
		printk("ERROR: Invalid argument passed\n");
		return -EINVAL;
	}

	vol_map = ldo_voltage_map[ldo];
	DBG("func =%s called for regulator = %d, min_v=%d, max_v=%d\n",__func__,ldo,min_uV,max_uV);

	if (min_vol < 750 ||
	    max_vol > 3600)
		return -EINVAL;

	while (vol_map[i]) {
		if (vol_map[i] >= min_vol)
			break;
		i++;
	}
	
	DBG("Found voltage=%d\n",vol_map[i]);

	if (!vol_map[i])
		return -EINVAL;

	if (vol_map[i] > max_vol)
		return -EINVAL;

	if (ldo == MAX8998_LDO3) {
		reg  = MAX8998_REG_LDO23;
		mask = 0x0F;
	} else if (ldo == MAX8998_LDO2) {
		reg  = MAX8998_REG_LDO23;
		shift = 4;
		mask = 0x0F;
	} else if (ldo == MAX8998_LDO8) {
		reg  = MAX8998_REG_LDO89;
		shift = 4;
		mask = 0x07;
	} else if (ldo == MAX8998_LDO9) {
		reg  = MAX8998_REG_LDO89;
		shift = 2;
		mask = 0x03;
	} else if (ldo == MAX8998_LDO10) {
		reg  = MAX8998_REG_LDO1011;
		shift = 5;
		mask = 0x07;
	} else if (ldo == MAX8998_LDO11) {
		reg  = MAX8998_REG_LDO1011;
		mask = 0x1F;
	} else if (ldo == MAX8998_LDO12) {
		reg  = MAX8998_REG_LDO12;
		mask = 0xFF;
	} else if (ldo == MAX8998_LDO13) {
		reg  = MAX8998_REG_LDO13;
		mask = 0xFF;
	} else if (ldo == MAX8998_LDO14) {
		reg  = MAX8998_REG_LDO14;
		mask = 0xFF;
	} else if (ldo == MAX8998_LDO15) {
		reg  = MAX8998_REG_LDO15;
		mask = 0xFF;
	} else if (ldo == MAX8998_LDO16) {
		reg  = MAX8998_REG_LDO16;
		mask = 0xFF;
	} else if (ldo == MAX8998_LDO17) {
		reg  = MAX8998_REG_LDO17;
		mask = 0xFF;
	} else if (ldo == MAX8998_DCDC1) {
		//reg = 0x04;
		reg = MAX8998_REG_DVSARM1;
		mask = 0x1f;
	} else if (ldo == MAX8998_DCDC2) {
		//reg = 0x06;
		reg = MAX8998_REG_DVSINT1;
		mask = 0x1f;
	} else if (ldo == MAX8998_DCDC3) {
		reg = MAX8998_REG_BUCK3;
		mask = 0xff;
	} else if (ldo == MAX8998_DCDC4) {
		reg = MAX8998_REG_BUCK4;
		mask = 0xff;
	} else {// for ldo4,5,6,7
		reg = MAX8998_REG_LDO23 + (ldo - MAX8998_LDO3);
		mask = 0xff;
	}

	spin_lock(&pmic_access_lock);

	value = max8998_read_reg(max8998, reg);
	value &= ~(mask << shift);
	value |= (i << shift);
	max8998_write_reg(max8998, value, reg);

	spin_unlock(&pmic_access_lock);

	return 0;
}
Пример #15
0
static int max8998_ldo_get_voltage(struct regulator_dev *rdev)
{
	struct max8998_data *max8998 = rdev_get_drvdata(rdev);
	int ldo = max8998_get_ldo(rdev);
	int value, shift = 0, mask = 0xff, reg;

	DBG("func =%s called for regulator = %d\n",__func__,ldo);

	if (ldo == MAX8998_LDO3) {
		reg  = MAX8998_REG_LDO23;
		mask = 0x0F;
	} else if (ldo == MAX8998_LDO2) {
		reg  = MAX8998_REG_LDO23;
		shift = 4;
		mask = 0x0F;
	} else if (ldo == MAX8998_LDO8) {
		reg  = MAX8998_REG_LDO89;
		shift = 4;
		mask = 0x07;
	} else if (ldo == MAX8998_LDO9) {
		reg  = MAX8998_REG_LDO89;
		shift = 2;
		mask = 0x03;
	} else if (ldo == MAX8998_LDO10) {
		reg  = MAX8998_REG_LDO1011;
		shift = 5;
		mask = 0x07;
	} else if (ldo == MAX8998_LDO11) {
		reg  = MAX8998_REG_LDO1011;
		mask = 0x1F;
	} else if (ldo == MAX8998_LDO12) {
		reg  = MAX8998_REG_LDO12;
	} else if (ldo == MAX8998_LDO13) {
		reg  = MAX8998_REG_LDO13;
	} else if (ldo == MAX8998_LDO14) {
		reg  = MAX8998_REG_LDO14;
	} else if (ldo == MAX8998_LDO15) {
		reg  = MAX8998_REG_LDO15;
	} else if (ldo == MAX8998_LDO16) {
		reg  = MAX8998_REG_LDO16;
	} else if (ldo == MAX8998_LDO17) {
		reg  = MAX8998_REG_LDO17;
	} else if (ldo == MAX8998_DCDC1) {
		//reg = 0x04;
		reg = MAX8998_REG_DVSARM1;
		mask = 0x1f;
	} else if (ldo == MAX8998_DCDC2) {
		//reg = 0x06;
		reg = MAX8998_REG_DVSINT1;
		mask = 0x1f;
	} else if (ldo == MAX8998_DCDC3) {
		reg = MAX8998_REG_BUCK3;
		mask = 0xFF;
	} else if (ldo == MAX8998_DCDC4) {
		reg = MAX8998_REG_BUCK4;
		mask = 0xff;
	} else {// for ldo4,5,6,7
		reg = MAX8998_REG_LDO23 + (ldo - MAX8998_LDO3);
		mask = 0xff;
	}

	value = max8998_read_reg(max8998, reg);
	value >>= shift;
	value &= mask;

	return 1000 * ldo_voltage_map[ldo][value];
}