adv7842 自定义分辨率timing代码

 

最近有一个1600*1200 50HZ的VGA信号需要用adv7842转出来,在网上搜了好久找了好久,在github上找到了这一段代码还挺管用的。根据这个代码中的计算方式配出了图像一点点调整把问题解决了,分享一下,希望对大家有帮助。

static void configure_custom_video_timings(struct v4l2_subdev *sd,
	const struct v4l2_bt_timings *bt)
	{
	struct adv7842_state *state = to_state(sd);
	struct i2c_client *client = v4l2_get_subdevdata(sd);
	u32 width = htotal(bt);
	u32 height = vtotal(bt);
	u16 cp_start_sav = bt->hsync + bt->hbackporch - 4;
	u16 cp_start_eav = width - bt->hfrontporch;
	u16 cp_start_vbi = height - bt->vfrontporch + 1;
	u16 cp_end_vbi = bt->vsync + bt->vbackporch + 1;
	u16 ch1_fr_ll = (((u32)bt->pixelclock / 100) > 0) ?
	((width * (ADV7842_fsc / 100)) / ((u32)bt->pixelclock / 100)) : 0;
	const u8 pll[2] = {
	0xc0 | ((width >> 8) & 0x1f),
	width & 0xff
	};
	
	v4l2_dbg(2, debug, sd, "%s\n", __func__);
	
	switch (state->mode) {
	case ADV7842_MODE_COMP:
	case ADV7842_MODE_RGB:
	/* auto graphics */
	io_write(sd, 0x00, 0x07); /* video std */
	io_write(sd, 0x01, 0x02); /* prim mode */
	/* enable embedded syncs for auto graphics mode */
	cp_write_and_or(sd, 0x81, 0xef, 0x10);
	
	/* Should only be set in auto-graphics mode [REF_02, p. 91-92] */
	/* setup PLL_DIV_MAN_EN and PLL_DIV_RATIO */
	/* IO-map reg. 0x16 and 0x17 should be written in sequence */
	if (adv_smbus_write_i2c_block_data(client, 0x16, 2, pll)) {
	v4l2_err(sd, "writing to reg 0x16 and 0x17 failed\n");
	break;
	}
	
	/* active video - horizontal timing */
	cp_write(sd, 0x26, (cp_start_sav >> 8) & 0xf);
	cp_write(sd, 0x27, (cp_start_sav & 0xff));
	cp_write(sd, 0x28, (cp_start_eav >> 8) & 0xf);
	cp_write(sd, 0x29, (cp_start_eav & 0xff));
	
	/* active video - vertical timing */
	cp_write(sd, 0xa5, (cp_start_vbi >> 4) & 0xff);
	cp_write(sd, 0xa6, ((cp_start_vbi & 0xf) << 4) |
	((cp_end_vbi >> 8) & 0xf));
	cp_write(sd, 0xa7, cp_end_vbi & 0xff);
	break;
	case ADV7842_MODE_HDMI:
	/* set default prim_mode/vid_std for HDMI
	according to [REF_03, c. 4.2] */
	io_write(sd, 0x00, 0x02); /* video std */
	io_write(sd, 0x01, 0x06); /* prim mode */
	break;
	default:
	v4l2_dbg(2, debug, sd, "%s: Unknown mode %d\n",
	__func__, state->mode);
	break;
	}
	
	cp_write(sd, 0x8f, (ch1_fr_ll >> 8) & 0x7);
	cp_write(sd, 0x90, ch1_fr_ll & 0xff);
	cp_write(sd, 0xab, (height >> 4) & 0xff);
	cp_write(sd, 0xac, (height & 0x0f) << 4);
}

static s32 adv_smbus_write_i2c_block_data(struct i2c_client *client,
	u8 command, unsigned length, const u8 *values)
{
	union i2c_smbus_data data;
	
	if (length > I2C_SMBUS_BLOCK_MAX)
	length = I2C_SMBUS_BLOCK_MAX;
	data.block[0] = length;
	memcpy(data.block + 1, values, length);
	return i2c_smbus_xfer(client->adapter, client->addr, client->flags,
	I2C_SMBUS_WRITE, command,
	I2C_SMBUS_I2C_BLOCK_DATA, &data);
}

static inline int cp_write_and_or(struct v4l2_subdev *sd, u8 reg, u8 mask, u8 val)
{
	return cp_write(sd, reg, (cp_read(sd, reg) & mask) | val);
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值