Exemplo n.º 1
0
static int adv7180_init(struct adv7180_state *state)
{
	int ret;

	/* ITU-R BT.656-4 compatible */
	ret = adv7180_write(state, ADV7180_REG_EXTENDED_OUTPUT_CONTROL,
			ADV7180_EXTENDED_OUTPUT_CONTROL_NTSCDIS);
	if (ret < 0)
		return ret;

	/* Manually set V bit end position in NTSC mode */
	return adv7180_write(state, ADV7180_REG_NTSC_V_BIT_END,
					ADV7180_NTSC_V_BIT_END_MANUAL_NVEND);
}
Exemplo n.º 2
0
static int adv7180_set_power(struct adv7180_state *state, bool on)
{
	u8 val;
	int ret;

	if (on)
		val = ADV7180_PWR_MAN_ON;
	else
		val = ADV7180_PWR_MAN_OFF;

	ret = adv7180_write(state, ADV7180_REG_PWR_MAN, val);
	if (ret)
		return ret;

	if (state->chip_info->flags & ADV7180_FLAG_MIPI_CSI2) {
		if (on) {
			adv7180_csi_write(state, 0xDE, 0x02);
			adv7180_csi_write(state, 0xD2, 0xF7);
			adv7180_csi_write(state, 0xD8, 0x65);
			adv7180_csi_write(state, 0xE0, 0x09);
			adv7180_csi_write(state, 0x2C, 0x00);
			if (state->field == V4L2_FIELD_NONE)
				adv7180_csi_write(state, 0x1D, 0x80);
			adv7180_csi_write(state, 0x00, 0x00);
		} else {
			adv7180_csi_write(state, 0x00, 0x80);
		}
	}

	return 0;
}
Exemplo n.º 3
0
static int adv7180_s_ctrl(struct v4l2_ctrl *ctrl)
{
	struct v4l2_subdev *sd = to_adv7180_sd(ctrl);
	struct adv7180_state *state = to_state(sd);
	int ret = mutex_lock_interruptible(&state->mutex);
	int val;

	if (ret)
		return ret;
	val = ctrl->val;
	switch (ctrl->id) {
	case V4L2_CID_BRIGHTNESS:
		ret = adv7180_write(state, ADV7180_REG_BRI, val);
		break;
	case V4L2_CID_HUE:
		/*Hue is inverted according to HSL chart */
		ret = adv7180_write(state, ADV7180_REG_HUE, -val);
		break;
	case V4L2_CID_CONTRAST:
		ret = adv7180_write(state, ADV7180_REG_CON, val);
		break;
	case V4L2_CID_SATURATION:
		/*
		 *This could be V4L2_CID_BLUE_BALANCE/V4L2_CID_RED_BALANCE
		 *Let's not confuse the user, everybody understands saturation
		 */
		ret = adv7180_write(state, ADV7180_REG_SD_SAT_CB, val);
		if (ret < 0)
			break;
		ret = adv7180_write(state, ADV7180_REG_SD_SAT_CR, val);
		break;
	case V4L2_CID_ADV_FAST_SWITCH:
		if (ctrl->val) {
			/* ADI required write */
			adv7180_write(state, 0x80d9, 0x44);
			adv7180_write(state, ADV7180_REG_FLCONTROL,
				ADV7180_FLCONTROL_FL_ENABLE);
		} else {
			/* ADI required write */
			adv7180_write(state, 0x80d9, 0xc4);
			adv7180_write(state, ADV7180_REG_FLCONTROL, 0x00);
		}
		break;
	default:
		ret = -EINVAL;
	}

	mutex_unlock(&state->mutex);
	return ret;
}
Exemplo n.º 4
0
static int adv7180_select_input(struct adv7180_state *state, unsigned int input)
{
	int ret;

	ret = adv7180_read(state, ADV7180_REG_INPUT_CONTROL);
	if (ret < 0)
		return ret;

	ret &= ~ADV7180_INPUT_CONTROL_INSEL_MASK;
	ret |= input;
	return adv7180_write(state, ADV7180_REG_INPUT_CONTROL, ret);
}
Exemplo n.º 5
0
static irqreturn_t adv7180_irq(int irq, void *devid)
{
	struct adv7180_state *state = devid;
	u8 isr3;

	mutex_lock(&state->mutex);
	isr3 = adv7180_read(state, ADV7180_REG_ISR3);
	/* clear */
	adv7180_write(state, ADV7180_REG_ICR3, isr3);

	if (isr3 & ADV7180_IRQ3_AD_CHANGE) {
		static const struct v4l2_event src_ch = {
			.type = V4L2_EVENT_SOURCE_CHANGE,
			.u.src_change.changes = V4L2_EVENT_SRC_CH_RESOLUTION,
		};

		v4l2_subdev_notify_event(&state->sd, &src_ch);
	}
	mutex_unlock(&state->mutex);

	return IRQ_HANDLED;
}

static int adv7180_init(struct adv7180_state *state)
{
	int ret;

	/* ITU-R BT.656-4 compatible */
	ret = adv7180_write(state, ADV7180_REG_EXTENDED_OUTPUT_CONTROL,
			ADV7180_EXTENDED_OUTPUT_CONTROL_NTSCDIS);
	if (ret < 0)
		return ret;

	/* Manually set V bit end position in NTSC mode */
	return adv7180_write(state, ADV7180_REG_NTSC_V_BIT_END,
					ADV7180_NTSC_V_BIT_END_MANUAL_NVEND);
}
Exemplo n.º 6
0
static irqreturn_t adv7180_irq(int irq, void *devid)
{
	struct adv7180_state *state = devid;
	u8 isr3;

	mutex_lock(&state->mutex);
	isr3 = adv7180_read(state, ADV7180_REG_ISR3);
	/* clear */
	adv7180_write(state, ADV7180_REG_ICR3, isr3);

	if (isr3 & ADV7180_IRQ3_AD_CHANGE && state->autodetect)
		__adv7180_status(state, NULL, &state->curr_norm);
	mutex_unlock(&state->mutex);

	return IRQ_HANDLED;
}
Exemplo n.º 7
0
static int init_device(struct adv7180_state *state)
{
	int ret;

	mutex_lock(&state->mutex);

	adv7180_write(state, ADV7180_REG_PWR_MAN, ADV7180_PWR_MAN_RES);
	usleep_range(5000, 10000);

	ret = state->chip_info->init(state);
	if (ret)
		goto out_unlock;

	ret = adv7180_program_std(state);
	if (ret)
		goto out_unlock;

	adv7180_set_field_mode(state);

	/* register for interrupts */
	if (state->irq > 0) {
		/* config the Interrupt pin to be active low */
		ret = adv7180_write(state, ADV7180_REG_ICONF1,
						ADV7180_ICONF1_ACTIVE_LOW |
						ADV7180_ICONF1_PSYNC_ONLY);
		if (ret < 0)
			goto out_unlock;

		ret = adv7180_write(state, ADV7180_REG_IMR1, 0);
		if (ret < 0)
			goto out_unlock;

		ret = adv7180_write(state, ADV7180_REG_IMR2, 0);
		if (ret < 0)
			goto out_unlock;

		/* enable AD change interrupts interrupts */
		ret = adv7180_write(state, ADV7180_REG_IMR3,
						ADV7180_IRQ3_AD_CHANGE);
		if (ret < 0)
			goto out_unlock;

		ret = adv7180_write(state, ADV7180_REG_IMR4, 0);
		if (ret < 0)
			goto out_unlock;
	}

out_unlock:
	mutex_unlock(&state->mutex);

	return ret;
}
Exemplo n.º 8
0
static int adv7182_select_input(struct adv7180_state *state, unsigned int input)
{
	enum adv7182_input_type input_type;
	unsigned int *lbias;
	unsigned int i;
	int ret;

	ret = adv7180_write(state, ADV7180_REG_INPUT_CONTROL, input);
	if (ret)
		return ret;

	/* Reset clamp circuitry - ADI recommended writes */
	adv7180_write(state, 0x809c, 0x00);
	adv7180_write(state, 0x809c, 0xff);

	input_type = adv7182_get_input_type(input);

	switch (input_type) {
	case ADV7182_INPUT_TYPE_CVBS:
	case ADV7182_INPUT_TYPE_DIFF_CVBS:
		/* ADI recommends to use the SH1 filter */
		adv7180_write(state, 0x0017, 0x41);
		break;
	default:
		adv7180_write(state, 0x0017, 0x01);
		break;
	}

	if (state->chip_info->flags & ADV7180_FLAG_V2)
		lbias = adv7280_lbias_settings[input_type];
	else
		lbias = adv7182_lbias_settings[input_type];

	for (i = 0; i < ARRAY_SIZE(adv7182_lbias_settings[0]); i++)
		adv7180_write(state, 0x0052 + i, lbias[i]);

	if (input_type == ADV7182_INPUT_TYPE_DIFF_CVBS) {
		/* ADI required writes to make differential CVBS work */
		adv7180_write(state, 0x005f, 0xa8);
		adv7180_write(state, 0x005a, 0x90);
		adv7180_write(state, 0x0060, 0xb0);
		adv7180_write(state, 0x80b6, 0x08);
		adv7180_write(state, 0x80c0, 0xa0);
	} else {
		adv7180_write(state, 0x005f, 0xf0);
		adv7180_write(state, 0x005a, 0xd0);
		adv7180_write(state, 0x0060, 0x10);
		adv7180_write(state, 0x80b6, 0x9c);
		adv7180_write(state, 0x80c0, 0x00);
	}

	return 0;
}
Exemplo n.º 9
0
static int adv7182_set_std(struct adv7180_state *state, unsigned int std)
{
	return adv7180_write(state, ADV7182_REG_INPUT_VIDSEL, std << 4);
}
Exemplo n.º 10
0
static int adv7182_init(struct adv7180_state *state)
{
	if (state->chip_info->flags & ADV7180_FLAG_MIPI_CSI2)
		adv7180_write(state, ADV7180_REG_CSI_SLAVE_ADDR,
			ADV7180_DEFAULT_CSI_I2C_ADDR << 1);

	if (state->chip_info->flags & ADV7180_FLAG_I2P)
		adv7180_write(state, ADV7180_REG_VPP_SLAVE_ADDR,
			ADV7180_DEFAULT_VPP_I2C_ADDR << 1);

	if (state->chip_info->flags & ADV7180_FLAG_V2) {
		/* ADI recommended writes for improved video quality */
		adv7180_write(state, 0x0080, 0x51);
		adv7180_write(state, 0x0081, 0x51);
		adv7180_write(state, 0x0082, 0x68);
	}

	/* ADI required writes */
	if (state->chip_info->flags & ADV7180_FLAG_MIPI_CSI2) {
		adv7180_write(state, 0x0003, 0x4e);
		adv7180_write(state, 0x0004, 0x57);
		adv7180_write(state, 0x001d, 0xc0);
	} else {
		if (state->chip_info->flags & ADV7180_FLAG_V2)
			adv7180_write(state, 0x0004, 0x17);
		else
			adv7180_write(state, 0x0004, 0x07);
		adv7180_write(state, 0x0003, 0x0c);
		adv7180_write(state, 0x001d, 0x40);
	}

	adv7180_write(state, 0x0013, 0x00);

	return 0;
}
Exemplo n.º 11
0
static int adv7180_set_std(struct adv7180_state *state, unsigned int std)
{
	return adv7180_write(state, ADV7180_REG_INPUT_CONTROL,
		(std << 4) | state->input);
}
Exemplo n.º 12
0
/*
 * adv7180_init
 *	Initializes adv7180 via I2C
 */
int __init adv7180_init(int i2c_adapt, int i2c_addr, int reset_gpio, int input)
{
	int err = 0;

	printk(KERN_INFO "Initializing ADV7180\n");

	/*
	 * Reset the adv7180
	 */
	if (reset_gpio) {
		if (gpio_request(reset_gpio, "ADV7180 Reset")) {
			printk(KERN_WARNING "%s: failed to allocate ADV7180 Reset\n", __FUNCTION__);
			return -EBUSY;
		}
		gpio_direction_output(reset_gpio, 0);
		udelay(1);
		gpio_set_value(reset_gpio, 1);
		udelay(1);
	}

	/*
	 * Turn on transmitter.
	 */
	err = adv7180_write(i2c_adapt, i2c_addr, 0x00, 0x10 | input);
	err = adv7180_write(i2c_adapt, i2c_addr, 0x03, 0x08);
	err = adv7180_write(i2c_adapt, i2c_addr, 0x04, 0x5d);
	err = adv7180_write(i2c_adapt, i2c_addr, 0x17, 0x41);
	err = adv7180_write(i2c_adapt, i2c_addr, 0x31, 0x12);
	err = adv7180_write(i2c_adapt, i2c_addr, 0x3d, 0xa2);
	err = adv7180_write(i2c_adapt, i2c_addr, 0x3e, 0x6a);
	err = adv7180_write(i2c_adapt, i2c_addr, 0x3f, 0xa0);
	err = adv7180_write(i2c_adapt, i2c_addr, 0x0e, 0x80);
	err = adv7180_write(i2c_adapt, i2c_addr, 0x55, 0x81);
	err = adv7180_write(i2c_adapt, i2c_addr, 0x0e, 0x00);
	err = adv7180_write(i2c_adapt, i2c_addr, 0x8f, 0x50);
	err = adv7180_write(i2c_adapt, i2c_addr, 0xe6, 0x10);
	err = adv7180_write(i2c_adapt, i2c_addr, 0x34, 0x00);
	err = adv7180_write(i2c_adapt, i2c_addr, 0x35, 240);
	err = adv7180_write(i2c_adapt, i2c_addr, 0x36, 0x00);
	if (err) {
		printk(KERN_WARNING "%s: failed to write ADV7180\n", __FUNCTION__);
		return err;
	}

	return 0;
}