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

Commit bbc0c4eb authored by Florian Echtler's avatar Florian Echtler Committed by Mauro Carvalho Chehab
Browse files

media: add panel register access functions



These functions provide write access to the internal LCD panel registers
which also control the sensor. They can be used to disable the
preprocessor, set the illumination brightness, and adjust gain/contrast
(which are stored together in one register internally called "vsvideo").

Signed-off-by: default avatarFlorian Echtler <floe@butterbrot.org>
Signed-off-by: default avatarHans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@s-opensource.com>
parent 4e6c5581
Loading
Loading
Loading
Loading
+75 −0
Original line number Diff line number Diff line
@@ -257,6 +257,81 @@ static int sur40_command(struct sur40_state *dev,
			       0x00, index, buffer, size, 1000);
}

/* poke a byte in the panel register space */
static int sur40_poke(struct sur40_state *dev, u8 offset, u8 value)
{
	int result;
	u8 index = 0x96; // 0xae for permanent write

	result = usb_control_msg(dev->usbdev, usb_sndctrlpipe(dev->usbdev, 0),
		SUR40_POKE, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
		0x32, index, NULL, 0, 1000);
	if (result < 0)
		goto error;
	msleep(5);

	result = usb_control_msg(dev->usbdev, usb_sndctrlpipe(dev->usbdev, 0),
		SUR40_POKE, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
		0x72, offset, NULL, 0, 1000);
	if (result < 0)
		goto error;
	msleep(5);

	result = usb_control_msg(dev->usbdev, usb_sndctrlpipe(dev->usbdev, 0),
		SUR40_POKE, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
		0xb2, value, NULL, 0, 1000);
	if (result < 0)
		goto error;
	msleep(5);

error:
	return result;
}

static int sur40_set_preprocessor(struct sur40_state *dev, u8 value)
{
	u8 setting_07[2] = { 0x01, 0x00 };
	u8 setting_17[2] = { 0x85, 0x80 };
	int result;

	if (value > 1)
		return -ERANGE;

	result = usb_control_msg(dev->usbdev, usb_sndctrlpipe(dev->usbdev, 0),
		SUR40_POKE, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
		0x07, setting_07[value], NULL, 0, 1000);
	if (result < 0)
		goto error;
	msleep(5);

	result = usb_control_msg(dev->usbdev, usb_sndctrlpipe(dev->usbdev, 0),
		SUR40_POKE, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
		0x17, setting_17[value], NULL, 0, 1000);
	if (result < 0)
		goto error;
	msleep(5);

error:
	return result;
}

static void sur40_set_vsvideo(struct sur40_state *handle, u8 value)
{
	int i;

	for (i = 0; i < 4; i++)
		sur40_poke(handle, 0x1c+i, value);
	handle->vsvideo = value;
}

static void sur40_set_irlevel(struct sur40_state *handle, u8 value)
{
	int i;

	for (i = 0; i < 8; i++)
		sur40_poke(handle, 0x08+(2*i), value);
}

/* Initialization routine, called from sur40_open */
static int sur40_init(struct sur40_state *dev)
{