Beispiel #1
0
static ssize_t lp855x_ctrl_register(struct file *file,
				    const char __user *userbuf, size_t count,
				    loff_t *ppos)
{
	char mode, buf[20];
	char *pos, *pos2;
	u8 i, arg1, arg2, val;
	struct lp855x *lp = file->private_data;
	int rc;
	size_t offs;

	if (copy_from_user(buf, userbuf, min(count, sizeof(buf))))
		return -EFAULT;

	mode = buf[count - 2];
	switch (mode) {
	case 'r':
		if (!lp855x_parse_register_cmd(buf, count, &arg1))
			return -EINVAL;

		rc = lp855x_read_byte(lp, arg1, &val);
		dev_info(lp->dev, "Read [0x%.2x] = 0x%.2x\n", arg1, val);
		break;
	case 'w':
		pos = lp855x_parse_register_cmd(buf, count, &arg1);
		if (!pos)
			return -EINVAL;
		offs = pos - buf;
		pos2 = lp855x_parse_register_cmd(pos + 1, count - offs, &arg2);
		if (!pos2)
			return -EINVAL;

		rc = lp855x_write_byte(lp, arg1, arg2);
		dev_info(lp->dev, "Written [0x%.2x] = 0x%.2x\n", arg1, arg2);
		break;
	case 'd':
		pos = lp855x_parse_register_cmd(buf, count, &arg1);
		if (!pos)
			return -EINVAL;
		offs = pos - buf;
		pos2 = lp855x_parse_register_cmd(pos + 1, count - offs, &arg2);
		if (!pos2)
			return -EINVAL;

		for (rc = 0, i = arg1; i <= arg2 && !rc; i++) {
			rc = lp855x_read_byte(lp, i, &val);
			dev_info(lp->dev, "Read [0x%.2x] = 0x%.2x\n", i, val);
		}
		break;
	default:
		rc = -EINVAL;
		break;
	}

	return rc ? rc : count;
}
Beispiel #2
0
static void lp855x_init_device(struct lp855x *lp)
{
	u8 val, addr;
	int i, ret;
	struct lp855x_platform_data *pd = lp->pdata;

	val = pd->device_control;
	ret = lp855x_write_byte(lp, DEVICE_CTRL, val);

	if (pd->load_new_rom_data && pd->size_program) {
		for (i = 0; i < pd->size_program; i++) {
			addr = pd->rom_data[i].addr;
			val = pd->rom_data[i].val;
			if (!lp855x_is_valid_rom_area(lp, addr))
				continue;

			if (addr == CFG98_CTRL) {
				u8 cfg98;
				lp855x_read_byte(lp, CFG98_CTRL, &cfg98);
				cfg98 &= ~IBOOST_LIM_2X_MASK;
				val = cfg98 | (val & IBOOST_LIM_2X_MASK);
			}

			ret |= lp855x_write_byte(lp, addr, val);
		}
	}
	ret |= lp855x_write_byte(lp, CFG3_CTRL, pd->cfg3);

	if (ret)
		dev_err(lp->dev, "i2c write err\n");
}
static int lp855x_resume_init(struct lp855x *lp)
{
	u8 val, addr;
	int i, ret = 0;

	if (lp->cfg->pre_init_device) {
		ret = lp->cfg->pre_init_device(lp);
		if (ret) {
			dev_err(lp->dev, "pre init device err: %d\n", ret);
			goto exit;
		}
	}

	if (lp->pdata->size_program > 0) {
		for (i = 0; i < lp->pdata->size_program; i++) {
			addr = lp->pdata->rom_data[i].addr;
			val = lp->pdata->rom_data[i].val;
			if (!lp855x_is_valid_rom_area(lp, addr))
				continue;

			if (addr == CFG98_CTRL) {
				u8 cfg98;
				lp855x_read_byte(lp,
					CFG98_CTRL, &cfg98);
				cfg98 &= ~IBOOST_LIM_2X_MASK;
				val = cfg98 |
					(val & IBOOST_LIM_2X_MASK);
			}
			ret = lp855x_write_byte(lp, addr, val);
			if (ret) {
				dev_err(lp->dev, "set register err: %d\n", ret);
			goto exit;
			}
		}
	}
	ret = lp855x_write_byte(lp, lp->cfg->reg_slope, lp->pdata->slope_reg);
	if (ret) {
		dev_err(lp->dev, "i2c write err\n");
		goto exit;
	}

	if (lp->cfg->post_init_device) {
		ret = lp->cfg->post_init_device(lp);
		if (ret) {
			dev_err(lp->dev, "post init device err: %d\n", ret);
			goto exit;
		}
	}
exit:
	return ret;
}
Beispiel #4
0
static int lp855x_init_registers(struct lp855x *lp)
{
	u8 val, addr, mask;
	int i, ret;
	struct lp855x_platform_data *pd = lp->pdata;

	val = pd->initial_brightness;
	ret = lp855x_write_byte(lp, BRIGHTNESS_CTRL, val);
	if (ret)
		return ret;

	val = pd->device_control;
	ret = lp855x_write_byte(lp, DEVICE_CTRL, val);
	if (ret)
		return ret;

	if (pd->load_new_rom_data && pd->size_program) {
		for (i = 0; i < pd->size_program; i++) {
			addr = pd->rom_data[i].addr;
			val = pd->rom_data[i].val;
			mask = pd->rom_data[i].mask;
			if (!lp855x_is_valid_rom_area(lp, addr))
				continue;

			if (mask) {
				u8 reg_val;

				ret = lp855x_read_byte(lp, addr, &reg_val);
				if (ret)
					return ret;
				val = (val & ~mask) | (reg_val & mask);
			}

			ret = lp855x_write_byte(lp, addr, val);
			if (ret)
				return ret;
		}
	}

	return ret;
}
Beispiel #5
0
static int lp855x_bl_get_brightness(struct backlight_device *bl)
{
	struct lp855x *lp = bl_get_data(bl);
	enum lp855x_brightness_ctrl_mode mode = lp->pdata->mode;

	if (mode == PWM_BASED) {
		struct lp855x_pwm_data *pd = &lp->pdata->pwm_data;
		int max_br = bl->props.max_brightness;

		if (pd->pwm_get_intensity)
			bl->props.brightness = pd->pwm_get_intensity(max_br);

	} else if (mode == REGISTER_BASED) {
		u8 val = 0;

		lp855x_read_byte(lp, BRIGHTNESS_CTRL, &val);
		bl->props.brightness = val;
	}

	return (bl->props.brightness);
}
static int lp855x_check_need_config(struct lp855x *lp, bool *need_config_flg)
{
	int ret = 0;
	u8 val;

	if (!bl_on_in_boot) {
		*need_config_flg = true;
		goto exit;
	}
	ret = lp855x_read_byte(lp, lp->cfg->reg_devicectrl, &val);
	if (ret) {
		dev_err(lp->dev,
			"Read ctrl register[0x%.04x] err: %d\n", lp->cfg->reg_devicectrl, ret);
		goto exit;
	}
	if (val & lp->cfg->reg_devicectrl_mask)
		*need_config_flg = false;
	else
		*need_config_flg = true;
exit:
	return ret;
}
/*
 * Device specific configuration flow
 *
 *    a) pre_init_device(optional)
 *    b) update the brightness register
 *    c) update ROM area(optional)
 *    d) post_init_device(optional)
 *
 */
static int lp855x_configure(struct lp855x *lp)
{
	u8 val, addr;
	bool need_config;
	int i, ret, brightness;
	struct lp855x_platform_data *pd = lp->pdata;

	switch (lp->chipid->driver_data) {
	case LP8550 ... LP8556:
		lp->cfg = &lp855x_dev_cfg;
		break;
	case LP8557:
		lp->cfg = &lp8557_dev_cfg;
		break;
	default:
		ret = -EINVAL;
		dev_err(lp->dev, "device support err: %d\n", ret);
		goto exit;
	}

	ret = lp855x_check_need_config(lp, &need_config);
	if (ret || !need_config)
		goto exit;

	if (lp->cfg->pre_init_device) {
		ret = lp->cfg->pre_init_device(lp);
		if (ret) {
			dev_err(lp->dev, "pre init device err: %d\n", ret);
			goto exit;
		}
	}

	brightness = pd->initial_brightness;
	ret = lp855x_write_brightness(lp,
		lp->cfg->is_8bit_brightness, brightness);
	if (ret) {
		dev_err(lp->dev, "set initial brightness err: %d\n", ret);
		goto exit;
	}

	if (pd->size_program > 0) {
		for (i = 0; i < pd->size_program; i++) {
			addr = pd->rom_data[i].addr;
			val = pd->rom_data[i].val;
			if (!lp855x_is_valid_rom_area(lp, addr))
				continue;

			if (addr == CFG98_CTRL) {
				u8 cfg98;
				lp855x_read_byte(lp,
					CFG98_CTRL, &cfg98);
				cfg98 &= ~IBOOST_LIM_2X_MASK;
				val = cfg98 |
					(val & IBOOST_LIM_2X_MASK);
			}
			ret = lp855x_write_byte(lp, addr, val);
			if (ret) {
				dev_err(lp->dev, "set register err: %d\n", ret);
				goto exit;
			}
		}
	}
	ret = lp855x_write_byte(lp, lp->cfg->reg_slope, pd->slope_reg);
	if (ret) {
		dev_err(lp->dev, "i2c write err\n");
		goto exit;
	}

	if (lp->cfg->post_init_device) {
		ret = lp->cfg->post_init_device(lp);
		if (ret) {
			dev_err(lp->dev, "post init device err: %d\n", ret);
			goto exit;
		}
	}
exit:
	return ret;
}