Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 103870
b: refs/heads/master
c: a9fc52b
h: refs/heads/master
v: v3
  • Loading branch information
Devin Heitmueller authored and Mauro Carvalho Chehab committed Jul 20, 2008
1 parent 081fc33 commit 8baf908
Show file tree
Hide file tree
Showing 6 changed files with 119 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 305519c924d8f2f2f85c390c6d456dc41dbe0284
refs/heads/master: a9fc52bcbeb5245b58d23c558f3e3e8f18bebbc3
1 change: 1 addition & 0 deletions trunk/Documentation/video4linux/CARDLIST.em28xx
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,4 @@
16 -> Hauppauge WinTV HVR 950 (em2880) [2040:6513,2040:6517,2040:651b,2040:651f]
17 -> Pinnacle PCTV HD Pro Stick (em2880) [2304:0227]
18 -> Hauppauge WinTV HVR 900 (R2) (em2880) [2040:6502]
19 -> PointNix Intra-Oral Camera (em2860)
18 changes: 18 additions & 0 deletions trunk/drivers/media/video/em28xx/em28xx-cards.c
Original file line number Diff line number Diff line change
Expand Up @@ -426,6 +426,19 @@ struct em28xx_board em28xx_boards[] = {
.amux = EM28XX_AMUX_LINE_IN,
} },
},
[EM2860_BOARD_POINTNIX_INTRAORAL_CAMERA] = {
.name = "PointNix Intra-Oral Camera",
.has_snapshot_button = 1,
.vchannels = 1,
.tda9887_conf = TDA9887_PRESENT,
.tuner_type = TUNER_ABSENT,
.decoder = EM28XX_SAA7113,
.input = { {
.type = EM28XX_VMUX_SVIDEO,
.vmux = SAA7115_SVIDEO3,
.amux = 0,
} },
},
};
const unsigned int em28xx_bcount = ARRAY_SIZE(em28xx_boards);

Expand Down Expand Up @@ -522,6 +535,7 @@ static struct em28xx_hash_table em28xx_eeprom_hash [] = {
static struct em28xx_hash_table em28xx_i2c_hash[] = {
{0xb06a32c3, EM2800_BOARD_TERRATEC_CINERGY_200, TUNER_LG_PAL_NEW_TAPC},
{0xf51200e3, EM2800_BOARD_VGEAR_POCKETTV, TUNER_LG_PAL_NEW_TAPC},
{0x1ba50080, EM2860_BOARD_POINTNIX_INTRAORAL_CAMERA, TUNER_ABSENT},
};

int em28xx_tuner_callback(void *ptr, int command, int arg)
Expand Down Expand Up @@ -554,6 +568,7 @@ static void em28xx_set_model(struct em28xx *dev)
dev->has_12mhz_i2s = em28xx_boards[dev->model].has_12mhz_i2s;
dev->max_range_640_480 = em28xx_boards[dev->model].max_range_640_480;
dev->has_dvb = em28xx_boards[dev->model].has_dvb;
dev->has_snapshot_button = em28xx_boards[dev->model].has_snapshot_button;
}

/* Since em28xx_pre_card_setup() requires a proper dev->model,
Expand Down Expand Up @@ -841,6 +856,9 @@ void em28xx_card_setup(struct em28xx *dev)
em28xx_set_model(dev);
}

if (dev->has_snapshot_button)
em28xx_register_snapshot_button(dev);

/* Allow override tuner type by a module parameter */
if (tuner >= 0)
dev->tuner_type = tuner;
Expand Down
87 changes: 87 additions & 0 deletions trunk/drivers/media/video/em28xx/em28xx-input.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@

#include "em28xx.h"

#define EM28XX_SNAPSHOT_KEY KEY_CAMERA
#define EM28XX_SBUTTON_QUERY_INTERVAL 500
#define EM28XX_R0C_USBSUSP_SNAPSHOT 0x20

static unsigned int ir_debug;
module_param(ir_debug, int, 0644);
MODULE_PARM_DESC(ir_debug, "enable debug messages [IR]");
Expand Down Expand Up @@ -124,6 +128,89 @@ int em28xx_get_key_pinnacle_usb_grey(struct IR_i2c *ir, u32 *ir_key,
return 1;
}

static void em28xx_query_sbutton(struct work_struct *work)
{
/* Poll the register and see if the button is depressed */
struct em28xx *dev =
container_of(work, struct em28xx, sbutton_query_work.work);
int ret;

ret = em28xx_read_reg(dev, EM28XX_R0C_USBSUSP);

if (ret & EM28XX_R0C_USBSUSP_SNAPSHOT) {
u8 cleared;
/* Button is depressed, clear the register */
cleared = ((u8) ret) & ~EM28XX_R0C_USBSUSP_SNAPSHOT;
em28xx_write_regs(dev, EM28XX_R0C_USBSUSP, &cleared, 1);

/* Not emulate the keypress */
input_report_key(dev->sbutton_input_dev, EM28XX_SNAPSHOT_KEY,
1);
/* Now unpress the key */
input_report_key(dev->sbutton_input_dev, EM28XX_SNAPSHOT_KEY,
0);
}

/* Schedule next poll */
schedule_delayed_work(&dev->sbutton_query_work,
msecs_to_jiffies(EM28XX_SBUTTON_QUERY_INTERVAL));
}

void em28xx_register_snapshot_button(struct em28xx *dev)
{
struct input_dev *input_dev;
int err;

em28xx_info("Registering snapshot button...\n");
input_dev = input_allocate_device();
if (!input_dev) {
em28xx_errdev("input_allocate_device failed\n");
return;
}

usb_make_path(dev->udev, dev->snapshot_button_path,
sizeof(dev->snapshot_button_path));
strlcat(dev->snapshot_button_path, "/sbutton",
sizeof(dev->snapshot_button_path));
INIT_DELAYED_WORK(&dev->sbutton_query_work, em28xx_query_sbutton);

input_dev->name = "em28xx snapshot button";
input_dev->phys = dev->snapshot_button_path;
input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);
set_bit(EM28XX_SNAPSHOT_KEY, input_dev->keybit);
input_dev->keycodesize = 0;
input_dev->keycodemax = 0;
input_dev->id.bustype = BUS_USB;
input_dev->id.vendor = le16_to_cpu(dev->udev->descriptor.idVendor);
input_dev->id.product = le16_to_cpu(dev->udev->descriptor.idProduct);
input_dev->id.version = 1;
input_dev->dev.parent = &dev->udev->dev;

err = input_register_device(input_dev);
if (err) {
em28xx_errdev("input_register_device failed\n");
input_free_device(input_dev);
return;
}

dev->sbutton_input_dev = input_dev;
schedule_delayed_work(&dev->sbutton_query_work,
msecs_to_jiffies(EM28XX_SBUTTON_QUERY_INTERVAL));
return;

}

void em28xx_deregister_snapshot_button(struct em28xx *dev)
{
if (dev->sbutton_input_dev != NULL) {
em28xx_info("Deregistering snapshot button\n");
cancel_rearming_delayed_work(&dev->sbutton_query_work);
input_unregister_device(dev->sbutton_input_dev);
dev->sbutton_input_dev = NULL;
}
return;
}

/* ----------------------------------------------------------------------
* Local variables:
* c-basic-offset: 8
Expand Down
2 changes: 2 additions & 0 deletions trunk/drivers/media/video/em28xx/em28xx-video.c
Original file line number Diff line number Diff line change
Expand Up @@ -1590,6 +1590,8 @@ static void em28xx_release_resources(struct em28xx *dev)
dev->vdev->minor-MINOR_VFL_TYPE_GRABBER_MIN,
dev->vbi_dev->minor-MINOR_VFL_TYPE_VBI_MIN);
list_del(&dev->devlist);
if (dev->sbutton_input_dev)
em28xx_deregister_snapshot_button(dev);
if (dev->radio_dev) {
if (-1 != dev->radio_dev->minor)
video_unregister_device(dev->radio_dev);
Expand Down
10 changes: 10 additions & 0 deletions trunk/drivers/media/video/em28xx/em28xx.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
#define EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950 16
#define EM2880_BOARD_PINNACLE_PCTV_HD_PRO 17
#define EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2 18
#define EM2860_BOARD_POINTNIX_INTRAORAL_CAMERA 19

/* Limits minimum and default number of buffers */
#define EM28XX_MIN_BUF 4
Expand Down Expand Up @@ -249,6 +250,7 @@ struct em28xx_board {
unsigned int has_12mhz_i2s:1;
unsigned int max_range_640_480:1;
unsigned int has_dvb:1;
unsigned int has_snapshot_button:1;

enum em28xx_decoder decoder;

Expand Down Expand Up @@ -328,6 +330,7 @@ struct em28xx {
unsigned int has_12mhz_i2s:1;
unsigned int max_range_640_480:1;
unsigned int has_dvb:1;
unsigned int has_snapshot_button:1;

/* Some older em28xx chips needs a waiting time after writing */
unsigned int wait_after_write;
Expand Down Expand Up @@ -418,6 +421,11 @@ struct em28xx {
/* Caches GPO and GPIO registers */
unsigned char reg_gpo, reg_gpio;

/* Snapshot button */
char snapshot_button_path[30]; /* path of the input dev */
struct input_dev *sbutton_input_dev;
struct delayed_work sbutton_query_work;

struct em28xx_dvb *dvb;
};

Expand Down Expand Up @@ -483,6 +491,8 @@ int em28xx_get_key_terratec(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw);
int em28xx_get_key_em_haup(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw);
int em28xx_get_key_pinnacle_usb_grey(struct IR_i2c *ir, u32 *ir_key,
u32 *ir_raw);
void em28xx_register_snapshot_button(struct em28xx *dev);
void em28xx_deregister_snapshot_button(struct em28xx *dev);

/* printk macros */

Expand Down

0 comments on commit 8baf908

Please sign in to comment.