static int max8925_backlight_set(struct backlight_device *bl, int brightness)
{
    struct max8925_backlight_data *data = bl_get_data(bl);
    struct max8925_chip *chip = data->chip;
    unsigned char value;
    int ret;

    if (brightness > MAX_BRIGHTNESS)
        value = MAX_BRIGHTNESS;
    else
        value = brightness;

    ret = max8925_reg_write(chip->i2c, MAX8925_WLED_CNTL, value);
    if (ret < 0)
        goto out;

    if (!data->current_brightness && brightness)
        /* enable WLED output */
        ret = max8925_set_bits(chip->i2c, MAX8925_WLED_MODE_CNTL, 1, 1);
    else if (!brightness)
        /* disable WLED output */
        ret = max8925_set_bits(chip->i2c, MAX8925_WLED_MODE_CNTL, 1, 0);
    if (ret < 0)
        goto out;
    dev_dbg(chip->dev, "set brightness %d\n", value);
    data->current_brightness = value;
    return 0;
out:
    dev_dbg(chip->dev, "set brightness %d failure with return value:%d\n",
            value, ret);
    return ret;
}
static int max8925_init_charger(struct max8925_chip *chip,
					  struct max8925_power_info *info)
{
	int ret;

	REQUEST_IRQ(MAX8925_IRQ_VCHG_DC_OVP, "ac-ovp");
	if (!info->no_insert_detect) {
		REQUEST_IRQ(MAX8925_IRQ_VCHG_DC_F, "ac-remove");
		REQUEST_IRQ(MAX8925_IRQ_VCHG_DC_R, "ac-insert");
	}
	if (!info->no_temp_support) {
		REQUEST_IRQ(MAX8925_IRQ_VCHG_THM_OK_R, "batt-temp-in-range");
		REQUEST_IRQ(MAX8925_IRQ_VCHG_THM_OK_F, "batt-temp-out-range");
	}
	REQUEST_IRQ(MAX8925_IRQ_VCHG_SYSLOW_F, "vsys-high");
	REQUEST_IRQ(MAX8925_IRQ_VCHG_SYSLOW_R, "vsys-low");
	REQUEST_IRQ(MAX8925_IRQ_VCHG_RST, "charger-reset");
	REQUEST_IRQ(MAX8925_IRQ_VCHG_DONE, "charger-done");
	REQUEST_IRQ(MAX8925_IRQ_VCHG_TOPOFF, "charger-topoff");
	REQUEST_IRQ(MAX8925_IRQ_VCHG_TMR_FAULT, "charger-timer-expire");

	info->usb_online = 0;
	info->bat_online = 0;

	/* check for power - can miss interrupt at boot time */
	if (start_measure(info, MEASURE_VCHG) * 2000 > 500000)
		info->ac_online = 1;
	else
		info->ac_online = 0;

	ret = max8925_reg_read(info->gpm, MAX8925_CHG_STATUS);
	if (ret >= 0) {
		/*
		 * If battery detection is enabled, ID pin of battery is
		 * connected to MBDET pin of MAX8925. 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 = (ret & MAX8925_CHG_MBDET) ? 0 : 1;
		else
			info->bat_online = 1;
		if (ret & MAX8925_CHG_AC_RANGE_MASK)
			info->ac_online = 1;
		else
			info->ac_online = 0;
	}
	/* disable charge */
	max8925_set_bits(info->gpm, MAX8925_CHG_CNTL1, 1 << 7, 1 << 7);
	/* set charging current in charge topoff mode */
	max8925_set_bits(info->gpm, MAX8925_CHG_CNTL1, 3 << 5,
			 info->topoff_threshold << 5);
	/* set charing current in fast charge mode */
	max8925_set_bits(info->gpm, MAX8925_CHG_CNTL1, 7, info->fast_charge);

	return 0;
}
static int max8925_disable(struct regulator_dev *rdev)
{
    struct max8925_regulator_info *info = rdev_get_drvdata(rdev);
    int ret;

    ret = max8925_set_bits(info->i2c, info->enable_reg,
                           1 << info->enable_bit, 0);
    if (ret < 0)
        return ret;
    /* set enable sequence as I2C */
    return max8925_set_bits(info->i2c, info->enable_reg, 7 << 2, 7 << 2);
}
Exemple #4
0
static int max8925_set_dvm_enable(struct regulator_dev *rdev)
{
	struct max8925_regulator_info *info = rdev_get_drvdata(rdev);

	return max8925_set_bits(info->i2c, info->vol_reg, 1 << SD1_DVM_EN,
				1 << SD1_DVM_EN);
}
static int max8925_disable(struct regulator_dev *rdev)
{
	struct max8925_regulator_info *info = rdev_get_drvdata(rdev);

	return max8925_set_bits(info->i2c, info->enable_reg,
				1 << info->enable_bit, 0);
}
static int __set_charger(struct max8925_power_info *info, int enable)
{
	struct max8925_chip *chip = info->chip;
	if (enable) {
		/* enable charger in platform */
		if (info->set_charger)
			info->set_charger(1);
		/* enable charger */
		max8925_set_bits(info->gpm, MAX8925_CHG_CNTL1, 1 << 7, 0);
	} else {
		/* disable charge */
		max8925_set_bits(info->gpm, MAX8925_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");
	return 0;
}
Exemple #7
0
static int max8925_set_dvm_voltage(struct regulator_dev *rdev, int uV)
{
	struct max8925_regulator_info *info = rdev_get_drvdata(rdev);
	unsigned char data, mask;

	if (uV < SD1_DVM_VMIN || uV > SD1_DVM_VMAX)
		return -EINVAL;

	data = (uV - SD1_DVM_VMIN + SD1_DVM_STEP - 1) / SD1_DVM_STEP;
	data <<= SD1_DVM_SHIFT;
	mask = 3 << SD1_DVM_SHIFT;

	return max8925_set_bits(info->i2c, info->enable_reg, mask, data);
}
static int max8925_set_voltage(struct regulator_dev *rdev,
			       int min_uV, int max_uV)
{
	struct max8925_regulator_info *info = rdev_get_drvdata(rdev);
	unsigned char data, mask;

	if (check_range(info, min_uV, max_uV)) {
		dev_err(info->chip->dev, "invalid voltage range (%d, %d) uV\n",
			min_uV, max_uV);
		return -EINVAL;
	}
	data = (min_uV - info->min_uV + info->step_uV - 1) / info->step_uV;
	data <<= info->vol_shift;
	mask = ((1 << info->vol_nbits) - 1) << info->vol_shift;

	return max8925_set_bits(info->i2c, info->vol_reg, mask, data);
}
/*
 * MAX8925 gives us an interrupt when ONKEY is pressed or released.
 * max8925_set_bits() operates I2C bus and may sleep. So implement
 * it in thread IRQ handler.
 */
static irqreturn_t max8925_onkey_handler(int irq, void *data)
{
	struct max8925_onkey_info *info = data;
	int state;

	state = max8925_reg_read(info->i2c, MAX8925_ON_OFF_STATUS);

	input_report_key(info->idev, KEY_POWER, state & SW_INPUT);
	input_sync(info->idev);

	dev_dbg(info->dev, "onkey state:%d\n", state);

	/* Enable hardreset to halt if system isn't shutdown on time */
	max8925_set_bits(info->i2c, MAX8925_SYSENSEL,
			 HARDRESET_EN, HARDRESET_EN);

	return IRQ_HANDLED;
}
static int __devinit max8925_backlight_probe(struct platform_device *pdev)
{
    struct max8925_chip *chip = dev_get_drvdata(pdev->dev.parent);
    struct max8925_platform_data *max8925_pdata;
    struct max8925_backlight_pdata *pdata = NULL;
    struct max8925_backlight_data *data;
    struct backlight_device *bl;
    struct backlight_properties props;
    struct resource *res;
    char name[MAX8925_NAME_SIZE];
    unsigned char value;
    int ret;

    res = platform_get_resource(pdev, IORESOURCE_IO, 0);
    if (res == NULL) {
        dev_err(&pdev->dev, "No I/O resource!\n");
        return -EINVAL;
    }

    if (pdev->dev.parent->platform_data) {
        max8925_pdata = pdev->dev.parent->platform_data;
        pdata = max8925_pdata->backlight;
    }

    if (!pdata) {
        dev_err(&pdev->dev, "platform data isn't assigned to "
                "backlight\n");
        return -EINVAL;
    }

    data = kzalloc(sizeof(struct max8925_backlight_data), GFP_KERNEL);
    if (data == NULL)
        return -ENOMEM;
    strncpy(name, res->name, MAX8925_NAME_SIZE);
    data->chip = chip;
    data->current_brightness = 0;

    memset(&props, 0, sizeof(struct backlight_properties));
    props.type = BACKLIGHT_RAW;
    props.max_brightness = MAX_BRIGHTNESS;
    bl = backlight_device_register(name, &pdev->dev, data,
                                   &max8925_backlight_ops, &props);
    if (IS_ERR(bl)) {
        dev_err(&pdev->dev, "failed to register backlight\n");
        kfree(data);
        return PTR_ERR(bl);
    }
    bl->props.brightness = MAX_BRIGHTNESS;

    platform_set_drvdata(pdev, bl);

    value = 0;
    if (pdata->lxw_scl)
        value |= (1 << 7);
    if (pdata->lxw_freq)
        value |= (LWX_FREQ(pdata->lxw_freq) << 4);
    if (pdata->dual_string)
        value |= (1 << 1);
    ret = max8925_set_bits(chip->i2c, MAX8925_WLED_MODE_CNTL, 0xfe, value);
    if (ret < 0)
        goto out;

    backlight_update_status(bl);
    return 0;
out:
    backlight_device_unregister(bl);
    kfree(data);
    return ret;
}