aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input
diff options
context:
space:
mode:
authorFlorian Echtler <floe@butterbrot.org>2018-02-08 03:43:05 -0500
committerMauro Carvalho Chehab <mchehab@s-opensource.com>2018-02-14 13:29:14 -0500
commitbbc0c4eb6b6b6bd5f5a83caa99d221a85f3063eb (patch)
tree9905cb8af9c23520d277ada7f2f4b8ad2c751df3 /drivers/input
parent4e6c55814897e7048c6d5dd0bb07725a4051d633 (diff)
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: Florian Echtler <floe@butterbrot.org> Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
Diffstat (limited to 'drivers/input')
-rw-r--r--drivers/input/touchscreen/sur40.c75
1 files changed, 75 insertions, 0 deletions
diff --git a/drivers/input/touchscreen/sur40.c b/drivers/input/touchscreen/sur40.c
index 45ad5746aad8..3b56f7d05ec5 100644
--- a/drivers/input/touchscreen/sur40.c
+++ b/drivers/input/touchscreen/sur40.c
@@ -257,6 +257,81 @@ static int sur40_command(struct sur40_state *dev,
257 0x00, index, buffer, size, 1000); 257 0x00, index, buffer, size, 1000);
258} 258}
259 259
260/* poke a byte in the panel register space */
261static int sur40_poke(struct sur40_state *dev, u8 offset, u8 value)
262{
263 int result;
264 u8 index = 0x96; // 0xae for permanent write
265
266 result = usb_control_msg(dev->usbdev, usb_sndctrlpipe(dev->usbdev, 0),
267 SUR40_POKE, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
268 0x32, index, NULL, 0, 1000);
269 if (result < 0)
270 goto error;
271 msleep(5);
272
273 result = usb_control_msg(dev->usbdev, usb_sndctrlpipe(dev->usbdev, 0),
274 SUR40_POKE, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
275 0x72, offset, NULL, 0, 1000);
276 if (result < 0)
277 goto error;
278 msleep(5);
279
280 result = usb_control_msg(dev->usbdev, usb_sndctrlpipe(dev->usbdev, 0),
281 SUR40_POKE, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
282 0xb2, value, NULL, 0, 1000);
283 if (result < 0)
284 goto error;
285 msleep(5);
286
287error:
288 return result;
289}
290
291static int sur40_set_preprocessor(struct sur40_state *dev, u8 value)
292{
293 u8 setting_07[2] = { 0x01, 0x00 };
294 u8 setting_17[2] = { 0x85, 0x80 };
295 int result;
296
297 if (value > 1)
298 return -ERANGE;
299
300 result = usb_control_msg(dev->usbdev, usb_sndctrlpipe(dev->usbdev, 0),
301 SUR40_POKE, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
302 0x07, setting_07[value], NULL, 0, 1000);
303 if (result < 0)
304 goto error;
305 msleep(5);
306
307 result = usb_control_msg(dev->usbdev, usb_sndctrlpipe(dev->usbdev, 0),
308 SUR40_POKE, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
309 0x17, setting_17[value], NULL, 0, 1000);
310 if (result < 0)
311 goto error;
312 msleep(5);
313
314error:
315 return result;
316}
317
318static void sur40_set_vsvideo(struct sur40_state *handle, u8 value)
319{
320 int i;
321
322 for (i = 0; i < 4; i++)
323 sur40_poke(handle, 0x1c+i, value);
324 handle->vsvideo = value;
325}
326
327static void sur40_set_irlevel(struct sur40_state *handle, u8 value)
328{
329 int i;
330
331 for (i = 0; i < 8; i++)
332 sur40_poke(handle, 0x08+(2*i), value);
333}
334
260/* Initialization routine, called from sur40_open */ 335/* Initialization routine, called from sur40_open */
261static int sur40_init(struct sur40_state *dev) 336static int sur40_init(struct sur40_state *dev)
262{ 337{