Skip to content

Commit

Permalink
V4L/DVB: gspca_ov519: Add support for the button on ov518 based cams
Browse files Browse the repository at this point in the history
Due to hardware limitations this only works while the camera is
streaming.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
  • Loading branch information
Hans de Goede authored and Mauro Carvalho Chehab committed Feb 26, 2010
1 parent 417a4d2 commit 92e232a
Showing 1 changed file with 29 additions and 25 deletions.
54 changes: 29 additions & 25 deletions drivers/media/video/gspca/ov519.c
Original file line number Diff line number Diff line change
Expand Up @@ -2702,6 +2702,11 @@ static void sd_reset_snapshot(struct gspca_dev *gspca_dev)
sd->snapshot_needs_reset = 0;

switch (sd->bridge) {
case BRIDGE_OV518:
case BRIDGE_OV518PLUS:
reg_w(sd, R51x_SYS_SNAP, 0x02); /* Reset */
reg_w(sd, R51x_SYS_SNAP, 0x01); /* Enable */
break;
case BRIDGE_OV519:
reg_w(sd, R51x_SYS_RESET, 0x40);
reg_w(sd, R51x_SYS_RESET, 0x00);
Expand Down Expand Up @@ -3977,6 +3982,28 @@ static void sd_stop0(struct gspca_dev *gspca_dev)
w9968cf_stop0(sd);
}

static void ov51x_handle_button(struct gspca_dev *gspca_dev, u8 state)
{
struct sd *sd = (struct sd *) gspca_dev;

if (sd->snapshot_pressed != state) {
#ifdef CONFIG_INPUT
input_report_key(gspca_dev->input_dev, KEY_CAMERA, state);
input_sync(gspca_dev->input_dev);
#endif
if (state)
sd->snapshot_needs_reset = 1;

sd->snapshot_pressed = state;
} else {
/* On the ov519 we need to reset the button state multiple
times, as resetting does not work as long as the button
stays pressed */
if (sd->bridge == BRIDGE_OV519 && state)
sd->snapshot_needs_reset = 1;
}
}

static void ov511_pkt_scan(struct gspca_dev *gspca_dev,
u8 *in, /* isoc packet */
int len) /* iso packet length */
Expand Down Expand Up @@ -4035,6 +4062,7 @@ static void ov518_pkt_scan(struct gspca_dev *gspca_dev,
/* A false positive here is likely, until OVT gives me
* the definitive SOF/EOF format */
if ((!(data[0] | data[1] | data[2] | data[3] | data[5])) && data[6]) {
ov51x_handle_button(gspca_dev, (data[6] >> 1) & 1);
gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
gspca_frame_add(gspca_dev, FIRST_PACKET, NULL, 0);
sd->packet_nr = 0;
Expand Down Expand Up @@ -4063,30 +4091,6 @@ static void ov518_pkt_scan(struct gspca_dev *gspca_dev,
gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
}

static void ov519_handle_button(struct gspca_dev *gspca_dev, u8 state)
{
struct sd *sd = (struct sd *) gspca_dev;

/* This should never happen, but better to check */
if (state != 0 && state != 1)
return;

/* We may need to reset the button state multiple times, as resetting
does not work as long as the button stays pressed, so always set
snapshot_needs_reset (instead of only on a state change to 1). */
if (state)
sd->snapshot_needs_reset = 1;

if (sd->snapshot_pressed != state) {
#ifdef CONFIG_INPUT
input_report_key(gspca_dev->input_dev, KEY_CAMERA, state);
input_sync(gspca_dev->input_dev);
#endif

sd->snapshot_pressed = state;
}
}

static void ov519_pkt_scan(struct gspca_dev *gspca_dev,
u8 *data, /* isoc packet */
int len) /* iso packet length */
Expand Down Expand Up @@ -4120,7 +4124,7 @@ static void ov519_pkt_scan(struct gspca_dev *gspca_dev,
gspca_dev->last_packet_type = DISCARD_PACKET;
return;
case 0x51: /* end of frame */
ov519_handle_button(gspca_dev, data[11]);
ov51x_handle_button(gspca_dev, data[11] & 1);
if (data[9] != 0)
gspca_dev->last_packet_type = DISCARD_PACKET;
gspca_frame_add(gspca_dev, LAST_PACKET,
Expand Down

0 comments on commit 92e232a

Please sign in to comment.