Exemplo n.º 1
0
/* initialize chip */
static int lm3630a_chip_init(struct lm3630a_chip *pchip)
{
	int rval;
	struct lm3630a_platform_data *pdata = pchip->pdata;

	usleep_range(1000, 2000);
	/* set Filter Strength Register */
	rval = lm3630a_write(pchip, 0x50, 0x03);
	/* set Cofig. register */
	rval |= lm3630a_update(pchip, REG_CONFIG, 0x07, pdata->pwm_ctrl);
	/* set boost control */
	rval |= lm3630a_write(pchip, REG_BOOST, 0x38);
	/* set current A */
	rval |= lm3630a_update(pchip, REG_I_A, 0x1F, 0x1F);
	/* set current B */
	rval |= lm3630a_write(pchip, REG_I_B, 0x1F);
	/* set control */
	rval |= lm3630a_update(pchip, REG_CTRL, 0x14, pdata->leda_ctrl);
	rval |= lm3630a_update(pchip, REG_CTRL, 0x0B, pdata->ledb_ctrl);
	usleep_range(1000, 2000);
	/* set brightness A and B */
	rval |= lm3630a_write(pchip, REG_BRT_A, pdata->leda_init_brt);
	rval |= lm3630a_write(pchip, REG_BRT_B, pdata->ledb_init_brt);

	if (rval < 0)
		dev_err(pchip->dev, "i2c failed to access register\n");
	return rval;
}
Exemplo n.º 2
0
/* Configure chip registers */
static int lm3630a_chip_config(struct lm3630a_chip *pchip)
{
	int rval = 0;
	struct lm3630a_platform_data *pdata = pchip->pdata;

	dev_dbg(pchip->dev, "Configure registers\n");
	/* exit sleep mode */
	rval |= lm3630a_update(pchip, REG_CTRL, 0x80, 0x00);
	/* set Filter Strength Register */
	rval = lm3630a_write(pchip, 0x50, pdata->flt_str);
	/* set Cofig. register */
	rval |= lm3630a_update(pchip, REG_CONFIG, 0x1f, pdata->config);
	/* set boost control */
	rval |= lm3630a_write(pchip, REG_BOOST, pdata->boost_ctrl);
	/* set current A */
	rval |= lm3630a_update(pchip, REG_I_A, 0x1F, pdata->leda_max_cur);
	/* set current B */
	rval |= lm3630a_write(pchip, REG_I_B, pdata->ledb_max_cur);
	/* set control */
	rval |= lm3630a_update(pchip, REG_CTRL, 0x14, pdata->leda_ctrl);
	rval |= lm3630a_update(pchip, REG_CTRL, 0x0B, pdata->ledb_ctrl);
	/* wait for a while to make sure configuration effective */
	usleep_range(1000, 2000);
	if (rval < 0)
		dev_err(pchip->dev, "Failed to configure registers\n");
	return rval;

}
Exemplo n.º 3
0
/* initialize chip */
static int lm3630a_chip_init(struct lm3630a_chip *pchip)
{
	int rval = 0;
	struct lm3630a_platform_data *pdata = pchip->pdata;

	/* enable vddio power supply */
	if (pdata->vddio_name[0] != 0) {
		pchip->vddio = devm_regulator_get(pchip->dev,
						pdata->vddio_name);
		if (IS_ERR(pchip->vddio)) {
			dev_err(pchip->dev, "Fail to get regulator rc = %ld\n",
				PTR_ERR(pchip->vddio));
			rval = -ENXIO;
			goto err;
		}
	}

	/* enable chip */
	if (gpio_is_valid(pdata->hwen_gpio)) {
		if (devm_gpio_request(pchip->dev, pdata->hwen_gpio,
				LM3630A_NAME)) {
			dev_err(pchip->dev, "gpio %d unavailable\n",
					pdata->hwen_gpio);
			rval = -EOPNOTSUPP;
			goto err;
		}
	}

	lm3630a_chip_enable(pchip);

	if (pdata->skip_init_config) {
		dev_info(pchip->dev, "Skip init configuration.");
		goto end;
	}

	usleep_range(1000, 2000);
	rval = lm3630a_chip_config(pchip);
	/* set brightness A and B */
	rval |= lm3630a_write(pchip, REG_BRT_A, pdata->leda_init_brt);
	rval |= lm3630a_write(pchip, REG_BRT_B, pdata->ledb_init_brt);
	if (rval < 0)
		dev_err(pchip->dev, "i2c failed to access register\n");

end:
	return rval;
err:
	if (!IS_ERR(pchip->vddio))
		devm_regulator_put(pchip->vddio);
	return rval;
}
Exemplo n.º 4
0
/* update and get brightness */
static int lm3630a_bank_b_update_status(struct backlight_device *bl)
{
	int ret;
	struct lm3630a_chip *pchip = bl_get_data(bl);
	enum lm3630a_pwm_ctrl pwm_ctrl = pchip->pdata->pwm_ctrl;

	/* pwm control */
	if ((pwm_ctrl & LM3630A_PWM_BANK_B) != 0) {
		lm3630a_pwm_ctrl(pchip, bl->props.brightness,
				 bl->props.max_brightness);
		return bl->props.brightness;
	}

	/* disable sleep */
	ret = lm3630a_update(pchip, REG_CTRL, 0x80, 0x00);
	if (ret < 0)
		goto out_i2c_err;
	usleep_range(1000, 2000);
	/* minimum brightness is 0x04 */
	ret = lm3630a_write(pchip, REG_BRT_B, bl->props.brightness);
	if (bl->props.brightness < 0x4)
		ret |= lm3630a_update(pchip, REG_CTRL, LM3630A_LEDB_ENABLE, 0);
	else
		ret |= lm3630a_update(pchip, REG_CTRL,
				      LM3630A_LEDB_ENABLE, LM3630A_LEDB_ENABLE);
	if (ret < 0)
		goto out_i2c_err;
	return bl->props.brightness;

out_i2c_err:
	dev_err(pchip->dev, "i2c failed to access REG_CTRL\n");
	return bl->props.brightness;
}
Exemplo n.º 5
0
static int lm3630a_remove(struct i2c_client *client)
{
	int rval;
	struct lm3630a_chip *pchip = i2c_get_clientdata(client);

	rval = lm3630a_write(pchip, REG_BRT_A, 0);
	if (rval < 0)
		dev_err(pchip->dev, "i2c failed to access register\n");

	rval = lm3630a_write(pchip, REG_BRT_B, 0);
	if (rval < 0)
		dev_err(pchip->dev, "i2c failed to access register\n");

	if (pchip->irq) {
		free_irq(pchip->irq, pchip);
		flush_workqueue(pchip->irqthread);
		destroy_workqueue(pchip->irqthread);
	}
	return 0;
}
Exemplo n.º 6
0
static int lm3630a_remove(struct i2c_client *client)
{
	int rval;
	struct lm3630a_chip *pchip = i2c_get_clientdata(client);

	rval = lm3630a_write(pchip, REG_BRT_A, 0);
	if (rval < 0)
		dev_err(pchip->dev, "i2c failed to access register\n");

	rval = lm3630a_write(pchip, REG_BRT_B, 0);
	if (rval < 0)
		dev_err(pchip->dev, "i2c failed to access register\n");

	if (pchip->irq) {
		free_irq(pchip->irq, pchip);
		flush_workqueue(pchip->irqthread);
		destroy_workqueue(pchip->irqthread);
	}

	if (!IS_ERR_OR_NULL(pchip->pwmd))
		pwm_free(pchip->pwmd);

	lm3630a_chip_disable(pchip);

	if (is_fb_backlight) {
		if (!IS_ERR_OR_NULL(pchip->bleda))
			backlight_device_unregister(pchip->bleda);
		if (!IS_ERR_OR_NULL(pchip->bledb))
			backlight_device_unregister(pchip->bledb);
	} else {
		destroy_workqueue(pchip->ledwq);
		led_classdev_unregister(&pchip->ledcdev);
	}

	return 0;
}
Exemplo n.º 7
0
static int lm3630a_intr_config(struct lm3630a_chip *pchip)
{
	int rval;

	rval = lm3630a_write(pchip, REG_INT_EN, 0x87);
	if (rval < 0)
		return rval;

	INIT_DELAYED_WORK(&pchip->work, lm3630a_delayed_func);
	pchip->irqthread = create_singlethread_workqueue("lm3630a-irqthd");
	if (!pchip->irqthread) {
		dev_err(pchip->dev, "create irq thread fail\n");
		return -ENOMEM;
	}
	if (request_threaded_irq
	    (pchip->irq, NULL, lm3630a_isr_func,
	     IRQF_TRIGGER_FALLING | IRQF_ONESHOT, "lm3630a_irq", pchip)) {
		dev_err(pchip->dev, "request threaded irq fail\n");
		destroy_workqueue(pchip->irqthread);
		return -ENOMEM;
	}
	return rval;
}
Exemplo n.º 8
0
static void lm3630a_led_set_func(struct work_struct *work)
{
	struct lm3630a_chip *pchip;
	struct lm3630a_platform_data *pdata;
	int ret = 0, brt, ledval;
	bool new_hbm = false;
	static bool cur_hbm;
	static int cur_brt = LM3630A_MAX_BRIGHTNESS;

	pchip = container_of(work, struct lm3630a_chip, ledwork);
	ledval = pchip->ledval;
	pdata = pchip->pdata;

	dev_dbg(pchip->dev, "led value = %d\n", ledval);
	if (ledval == LM3630A_HBM_ON_BRIGHTNESS ||
	    ledval == LM3630A_HBM_OFF_BRIGHTNESS) {
		new_hbm = ledval == LM3630A_HBM_ON_BRIGHTNESS ? true : false;
		if (new_hbm == cur_hbm) {
			dev_warn(pchip->dev, "HBM state is %s already\n",
					new_hbm ? "ON" : "OFF");
			goto out;
		}
	} else {
		cur_brt = ledval;
		/* In HBM mode, brightness setting is not effective */
		if (cur_hbm)
			goto out;
	}

	if (lm3630a_read(pchip, REG_CTRL) & LM3630A_SLEEP_STATUS) {
		dev_info(pchip->dev, "wake up and re-init chip\n");
		ret = lm3630a_chip_config(pchip);
		if (ret < 0)
			goto out;
	}

	if (new_hbm != cur_hbm) {
		cur_hbm = new_hbm;
		dev_info(pchip->dev, "HBM state: %s\n", new_hbm ?
					"ON" : "OFF");
		ledval = new_hbm ?
			max(pdata->leda_max_brt, pdata->ledb_max_brt)
			: cur_brt;
		ret |= lm3630a_update(pchip, REG_I_A, 0x1F, new_hbm ?
			pdata->leda_max_hbm_cur : pdata->leda_max_cur);
		ret |= lm3630a_write(pchip, REG_I_B, new_hbm ?
			pdata->ledb_max_hbm_cur : pdata->ledb_max_cur);
	}

	if (pdata->leda_ctrl != LM3630A_LEDA_DISABLE) {
		/* pwm control */
		if ((pdata->pwm_ctrl & LM3630A_PWM_BANK_A) != 0)
			lm3630a_pwm_ctrl(pchip, ledval, pdata->leda_max_brt);
		else {
			brt = ledval > pdata->leda_max_brt ?
				pdata->leda_max_brt : ledval;
			if (!brt)
				ret = lm3630a_update(pchip, REG_CTRL,
						LM3630A_LEDA_ENABLE, 0);
			else {
				ret = lm3630a_update(pchip, REG_CTRL,
						LM3630A_LEDA_ENABLE,
						LM3630A_LEDA_ENABLE);
				ret |= lm3630a_write(pchip, REG_BRT_A, brt);
			}
			if (ret < 0)
				goto out;
		}
	}

	if ((pdata->ledb_ctrl != LM3630A_LEDB_DISABLE) &&
	    (pdata->ledb_ctrl != LM3630A_LEDB_ON_A)) {
		/* pwm control */
		if ((pdata->pwm_ctrl & LM3630A_PWM_BANK_B) != 0)
			lm3630a_pwm_ctrl(pchip, ledval, pdata->ledb_max_brt);
		else {
			brt = ledval > pdata->ledb_max_brt ?
				pdata->ledb_max_brt : ledval;
			if (!brt)
				ret = lm3630a_update(pchip, REG_CTRL,
						LM3630A_LEDB_ENABLE, 0);
			else {
				ret = lm3630a_update(pchip, REG_CTRL,
						LM3630A_LEDB_ENABLE,
						LM3630A_LEDB_ENABLE);
				ret |= lm3630a_write(pchip, REG_BRT_B, brt);
			}
			if (ret < 0)
				goto out;
		}
	}

	if (!ledval)
		ret = lm3630a_update(pchip, REG_CTRL, LM3630A_SLEEP_ENABLE,
				LM3630A_SLEEP_ENABLE);
out:
	if (ret < 0)
		dev_err(pchip->dev, "fail to set brightness\n");
	return;
}