@@ -6,6 +6,7 @@
*
* Separated from Pixart PAC7311 library by Márton Németh
* Camera button input handling by Márton Németh <nm127@freemail.hu>
+ * LED control by Márton Németh <nm127@freemail.hu>
* Copyright (C) 2009-2010 Márton Németh <nm127@freemail.hu>
*
* This program is free software; you can redistribute it and/or modify
@@ -62,6 +63,7 @@
0 | 0xc6 | setwhitebalance()
0 | 0xc7 | setbluebalance()
0 | 0xdc | setbrightcont(), setcolors()
+ 1 | 0x78 | set_streaming_led()
3 | 0x02 | setexposure()
3 | 0x10 | setgain()
3 | 0x11 | setcolors(), setgain(), setexposure(), sethvflip()
@@ -91,6 +93,7 @@
unsigned char gain;
unsigned char exposure;
unsigned char autogain;
+ unsigned char led;
__u8 hflip;
__u8 vflip;
u8 flags;
@@ -126,6 +129,8 @@
static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val);
static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val);
static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setled(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getled(struct gspca_dev *gspca_dev, __s32 *val);
static const struct ctrl sd_ctrls[] = {
/* This control is pac7302 only */
@@ -293,6 +298,20 @@
.set = sd_setvflip,
.get = sd_getvflip,
},
+ {
+ {
+ .id = V4L2_CID_LED,
+ .type = V4L2_CTRL_TYPE_MENU,
+ .name = "LED",
+ .minimum = 0,
+ .maximum = 2, /* 0: Auto, 1: On, 2: Off */
+ .step = 1,
+#define LED_DEF V4L2_LED_AUTO
+ .default_value = LED_DEF,
+ },
+ .set = sd_setled,
+ .get = sd_getled,
+ },
};
static const struct v4l2_pix_format vga_mode[] = {
@@ -572,6 +591,7 @@
sd->gain = GAIN_DEF;
sd->exposure = EXPOSURE_DEF;
sd->autogain = AUTOGAIN_DEF;
+ sd->led = LED_DEF;
sd->hflip = HFLIP_DEF;
sd->vflip = VFLIP_DEF;
sd->flags = id->driver_info;
@@ -716,6 +736,36 @@
reg_w(gspca_dev, 0x11, 0x01);
}
+static void set_streaming_led(struct gspca_dev *gspca_dev, u8 streaming)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ u8 data = 0;
+
+ switch (sd->led) {
+ case V4L2_LED_AUTO:
+ if (streaming)
+ data = 0x01;
+ else
+ data = 0x40;
+ break;
+ case V4L2_LED_ON:
+ if (streaming)
+ data = 0x01;
+ else
+ data = 0x00;
+ break;
+ case V4L2_LED_OFF:
+ if (streaming)
+ data = 0x41;
+ else
+ data = 0x40;
+ break;
+ }
+
+ reg_w(gspca_dev, 0xff, 0x01);
+ reg_w(gspca_dev, 0x78, data);
+}
+
/* this function is called at probe and resume time for pac7302 */
static int sd_init(struct gspca_dev *gspca_dev)
{
@@ -747,18 +797,15 @@
atomic_set(&sd->avg_lum, -1);
/* start stream */
- reg_w(gspca_dev, 0xff, 0x01);
- reg_w(gspca_dev, 0x78, 0x01);
+ set_streaming_led(gspca_dev, 1);
return gspca_dev->usb_err;
}
static void sd_stopN(struct gspca_dev *gspca_dev)
{
-
/* stop stream */
- reg_w(gspca_dev, 0xff, 0x01);
- reg_w(gspca_dev, 0x78, 0x00);
+ set_streaming_led(gspca_dev, 0);
}
/* called on streamoff with alt 0 and on disconnect for pac7302 */
@@ -766,8 +813,7 @@
{
if (!gspca_dev->present)
return;
- reg_w(gspca_dev, 0xff, 0x01);
- reg_w(gspca_dev, 0x78, 0x40);
+ set_streaming_led(gspca_dev, 0);
}
/* Include pac common sof detection functions */
@@ -1121,6 +1167,44 @@
return 0;
}
+static int sd_setled(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->led = val;
+ set_streaming_led(gspca_dev, gspca_dev->streaming);
+ return gspca_dev->usb_err;
+}
+
+static int sd_getled(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ *val = sd->led;
+ return 0;
+}
+
+static int sd_querymenu(struct gspca_dev *gspca_dev,
+ struct v4l2_querymenu *menu)
+{
+ switch (menu->id) {
+ case V4L2_CID_LED:
+ switch (menu->index) {
+ case V4L2_LED_AUTO:
+ strcpy((char *)menu->name, "Auto");
+ return 0;
+ case V4L2_LED_OFF:
+ strcpy((char *)menu->name, "Off");
+ return 0;
+ case V4L2_LED_ON:
+ strcpy((char *)menu->name, "On");
+ return 0;
+ }
+ break;
+ }
+ return -EINVAL;
+}
+
#ifdef CONFIG_VIDEO_ADV_DEBUG
static int sd_dbg_s_register(struct gspca_dev *gspca_dev,
struct v4l2_dbg_register *reg)
@@ -1210,6 +1294,7 @@
.stop0 = sd_stop0,
.pkt_scan = sd_pkt_scan,
.dq_callback = do_autogain,
+ .querymenu = sd_querymenu,
#ifdef CONFIG_VIDEO_ADV_DEBUG
.set_register = sd_dbg_s_register,
.get_chip_ident = sd_chip_ident,