Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 55699964 authored by Mauro Carvalho Chehab's avatar Mauro Carvalho Chehab
Browse files

V4L/DVB (12239): em28xx: fix webcam scaling



While trying to fix an mt9v001 webcam, I noticed that HSCALE/VSCALE do
work with em28xx + webcam. The issue is that the scaling setup depends
on the number of visible rows/cols of the input image.

With mt9v011 (Silvercrest), the resolution is 640x480. So, the scaling
is different from a normal TV image (720x480 on NTSC). This were causing
a wrong scaling and a previous patch disabled scaling.

As each sensor have their different resolution setting, the xres/yres
should be adjusted accordingly with the input sensor.

Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent b04fb661
Loading
Loading
Loading
Loading
+3 −3
Original line number Original line Diff line number Diff line
@@ -58,8 +58,6 @@ static unsigned int card[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET };
module_param_array(card,  int, NULL, 0444);
module_param_array(card,  int, NULL, 0444);
MODULE_PARM_DESC(card,     "card type");
MODULE_PARM_DESC(card,     "card type");


#define MT9V011_VERSION                 0x8243

/* Bitmask marking allocated devices from 0 to EM28XX_MAXBOARDS */
/* Bitmask marking allocated devices from 0 to EM28XX_MAXBOARDS */
static unsigned long em28xx_devused;
static unsigned long em28xx_devused;


@@ -1730,10 +1728,12 @@ static int em28xx_hint_sensor(struct em28xx *dev)
	version = be16_to_cpu(version_be);
	version = be16_to_cpu(version_be);


	switch (version) {
	switch (version) {
	case MT9V011_VERSION:
	case 0x8243:		/* mt9v011 640x480 1.3 Mpix sensor */
		dev->model = EM2820_BOARD_SILVERCREST_WEBCAM;
		dev->model = EM2820_BOARD_SILVERCREST_WEBCAM;
		sensor_name = "mt9v011";
		sensor_name = "mt9v011";
		dev->em28xx_sensor = EM28XX_MT9V011;
		dev->em28xx_sensor = EM28XX_MT9V011;
		dev->sensor_xres = 640;
		dev->sensor_yres = 480;
		break;
		break;
	default:
	default:
		printk("Unknown Micron Sensor 0x%04x\n", be16_to_cpu(version));
		printk("Unknown Micron Sensor 0x%04x\n", be16_to_cpu(version));
+1 −4
Original line number Original line Diff line number Diff line
@@ -707,10 +707,7 @@ static int em28xx_scaler_set(struct em28xx *dev, u16 h, u16 v)
	u8 mode;
	u8 mode;
	/* the em2800 scaler only supports scaling down to 50% */
	/* the em2800 scaler only supports scaling down to 50% */


	if (dev->board.is_webcam) {
	if (dev->board.is_em2800) {
		/* FIXME: Don't use the scaler yet */
		mode = 0;
	} else if (dev->board.is_em2800) {
		mode = (v ? 0x20 : 0x00) | (h ? 0x10 : 0x00);
		mode = (v ? 0x20 : 0x00) | (h ? 0x10 : 0x00);
	} else {
	} else {
		u8 buf[2];
		u8 buf[2];
+3 −13
Original line number Original line Diff line number Diff line
@@ -726,11 +726,7 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
		return -EINVAL;
		return -EINVAL;
	}
	}


	if (dev->board.is_webcam) {
	if (dev->board.is_em2800) {
		/* FIXME: This is the only supported fmt */
		width  = 640;
		height = 480;
	} else if (dev->board.is_em2800) {
		/* the em2800 can only scale down to 50% */
		/* the em2800 can only scale down to 50% */
		height = height > (3 * maxh / 4) ? maxh : maxh / 2;
		height = height > (3 * maxh / 4) ? maxh : maxh / 2;
		width = width > (3 * maxw / 4) ? maxw : maxw / 2;
		width = width > (3 * maxw / 4) ? maxw : maxw / 2;
@@ -767,12 +763,6 @@ static int em28xx_set_video_format(struct em28xx *dev, unsigned int fourcc,
{
{
	struct em28xx_fmt     *fmt;
	struct em28xx_fmt     *fmt;


	/* FIXME: This is the only supported fmt */
	if (dev->board.is_webcam) {
		width  = 640;
		height = 480;
	}

	fmt = format_by_fourcc(fourcc);
	fmt = format_by_fourcc(fourcc);
	if (!fmt)
	if (!fmt)
		return -EINVAL;
		return -EINVAL;
+11 −4
Original line number Original line Diff line number Diff line
@@ -479,6 +479,7 @@ struct em28xx {
	struct em28xx_board board;
	struct em28xx_board board;


	enum em28xx_sensor em28xx_sensor;
	enum em28xx_sensor em28xx_sensor;
	int sensor_xres, sensor_yres;


	unsigned int stream_on:1;	/* Locks streams */
	unsigned int stream_on:1;	/* Locks streams */
	unsigned int has_audio_class:1;
	unsigned int has_audio_class:1;
@@ -760,17 +761,23 @@ static inline int em28xx_gamma_set(struct em28xx *dev, s32 val)
/*FIXME: maxw should be dependent of alt mode */
/*FIXME: maxw should be dependent of alt mode */
static inline unsigned int norm_maxw(struct em28xx *dev)
static inline unsigned int norm_maxw(struct em28xx *dev)
{
{
	if (dev->board.is_webcam)
		return dev->sensor_xres;

	if (dev->board.max_range_640_480)
	if (dev->board.max_range_640_480)
		return 640;
		return 640;
	else

	return 720;
	return 720;
}
}


static inline unsigned int norm_maxh(struct em28xx *dev)
static inline unsigned int norm_maxh(struct em28xx *dev)
{
{
	if (dev->board.is_webcam)
		return dev->sensor_yres;

	if (dev->board.max_range_640_480)
	if (dev->board.max_range_640_480)
		return 480;
		return 480;
	else

	return (dev->norm & V4L2_STD_625_50) ? 576 : 480;
	return (dev->norm & V4L2_STD_625_50) ? 576 : 480;
}
}
#endif
#endif