Commit 9eedaf2a authored by Andrew Morton's avatar Andrew Morton Committed by Greg Kroah-Hartman

[PATCH] v4l: saa7134 cleanups and new cards.

From: Gerd Knorr <kraxel@bytesex.org>

This patch is a update for the saa7134 driver in the linux kernel.

Changes:

* kernel thread cleanups (exit/rmmod sync using completions, wait queue
  fixes).

* add support for more cards.

* improved infrared remote support.
parent 98e769bc
...@@ -834,7 +834,7 @@ struct saa7134_board saa7134_boards[] = { ...@@ -834,7 +834,7 @@ struct saa7134_board saa7134_boards[] = {
}}, }},
}, },
[SAA7134_BOARD_ECS_TVP3XP] = { [SAA7134_BOARD_ECS_TVP3XP] = {
.name = "Elitegroup ECS TVP3XP FM1216 Tuner Card", .name = "Elitegroup ECS TVP3XP FM1216 Tuner Card(PAL-BG,FM) ",
.audio_clock = 0x187de7, // xtal 32.1 MHz .audio_clock = 0x187de7, // xtal 32.1 MHz
.tuner_type = TUNER_PHILIPS_PAL, .tuner_type = TUNER_PHILIPS_PAL,
.inputs = {{ .inputs = {{
...@@ -865,6 +865,82 @@ struct saa7134_board saa7134_boards[] = { ...@@ -865,6 +865,82 @@ struct saa7134_board saa7134_boards[] = {
.amux = LINE2, .amux = LINE2,
}, },
}, },
[SAA7134_BOARD_ECS_TVP3XP_4CB5] = {
.name = "Elitegroup ECS TVP3XP FM1236 Tuner Card (NTSC,FM)",
.audio_clock = 0x187de7,
.tuner_type = TUNER_PHILIPS_NTSC,
.inputs = {{
.name = name_tv,
.vmux = 1,
.amux = TV,
.tv = 1,
},{
.name = name_tv_mono,
.vmux = 1,
.amux = LINE2,
.tv = 1,
},{
.name = name_comp1,
.vmux = 3,
.amux = LINE1,
},{
.name = name_svideo,
.vmux = 8,
.amux = LINE1,
},{
.name = "CVid over SVid",
.vmux = 0,
.amux = LINE1,
}},
.radio = {
.name = name_radio,
.amux = LINE2,
},
},
[SAA7134_BOARD_AVACSSMARTTV] = {
/* Roman Pszonczenko <romka@kolos.math.uni.lodz.pl> */
.name = "AVACS SmartTV",
.audio_clock = 0x00187de7,
.tuner_type = TUNER_PHILIPS_PAL,
.inputs = {{
.name = name_tv,
.vmux = 1,
.amux = TV,
.tv = 1,
},{
.name = name_tv_mono,
.vmux = 1,
.amux = LINE2,
.tv = 1,
},{
.name = name_comp1,
.vmux = 0,
.amux = LINE2,
},{
.name = name_comp2,
.vmux = 3,
.amux = LINE2,
},{
.name = name_svideo,
.vmux = 8,
.amux = LINE2,
}},
.radio = {
.name = name_radio,
.amux = LINE2,
.gpio = 0x200000,
},
},
[SAA7134_BOARD_AVERMEDIA_DVD_EZMAKER] = {
/* Michael Smith <msmith@cbnco.com> */
.name = "AVerMedia DVD EZMaker",
.audio_clock = 0x00187de7,
.tuner_type = TUNER_ABSENT,
.inputs = {{
.name = name_comp1,
.vmux = 3,
}},
},
}; };
const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards); const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards);
...@@ -1023,6 +1099,12 @@ struct pci_device_id saa7134_pci_tbl[] = { ...@@ -1023,6 +1099,12 @@ struct pci_device_id saa7134_pci_tbl[] = {
.subvendor = 0x1461, /* Avermedia Technologies Inc */ .subvendor = 0x1461, /* Avermedia Technologies Inc */
.subdevice = 0x2115, .subdevice = 0x2115,
.driver_data = SAA7134_BOARD_MD2819, .driver_data = SAA7134_BOARD_MD2819,
},{
.vendor = PCI_VENDOR_ID_PHILIPS,
.device = PCI_DEVICE_ID_PHILIPS_SAA7130,
.subvendor = 0x1461, /* Avermedia Technologies Inc */
.subdevice = 0x10ff,
.driver_data = SAA7134_BOARD_AVERMEDIA_DVD_EZMAKER,
},{ },{
/* TransGear 3000TV */ /* TransGear 3000TV */
.vendor = PCI_VENDOR_ID_PHILIPS, .vendor = PCI_VENDOR_ID_PHILIPS,
...@@ -1043,6 +1125,12 @@ struct pci_device_id saa7134_pci_tbl[] = { ...@@ -1043,6 +1125,12 @@ struct pci_device_id saa7134_pci_tbl[] = {
.subdevice = 0x4cb4, .subdevice = 0x4cb4,
.driver_data = SAA7134_BOARD_ECS_TVP3XP, .driver_data = SAA7134_BOARD_ECS_TVP3XP,
},{ },{
.vendor = PCI_VENDOR_ID_PHILIPS,
.device = PCI_DEVICE_ID_PHILIPS_SAA7133,
.subvendor = 0x1019,
.subdevice = 0x4cb5,
.driver_data = SAA7134_BOARD_ECS_TVP3XP_4CB5,
},{
/* --- boards without eeprom + subsystem ID --- */ /* --- boards without eeprom + subsystem ID --- */
.vendor = PCI_VENDOR_ID_PHILIPS, .vendor = PCI_VENDOR_ID_PHILIPS,
...@@ -1149,6 +1237,8 @@ int saa7134_board_init(struct saa7134_dev *dev) ...@@ -1149,6 +1237,8 @@ int saa7134_board_init(struct saa7134_dev *dev)
break; break;
case SAA7134_BOARD_CINERGY400: case SAA7134_BOARD_CINERGY400:
case SAA7134_BOARD_CINERGY600: case SAA7134_BOARD_CINERGY600:
case SAA7134_BOARD_ECS_TVP3XP:
case SAA7134_BOARD_ECS_TVP3XP_4CB5:
dev->has_remote = 1; dev->has_remote = 1;
break; break;
} }
......
/* /*
* handle saa7134 IR remotes via linux kernel input layer.
*
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
...@@ -13,9 +15,6 @@ ...@@ -13,9 +15,6 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* *
* Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
*/ */
#include <linux/module.h> #include <linux/module.h>
...@@ -101,6 +100,63 @@ static IR_KEYTAB_TYPE cinergy_codes[IR_KEYTAB_SIZE] = { ...@@ -101,6 +100,63 @@ static IR_KEYTAB_TYPE cinergy_codes[IR_KEYTAB_SIZE] = {
[ 0x23 ] = KEY_STOP, [ 0x23 ] = KEY_STOP,
}; };
/* Alfons Geser <a.geser@cox.net> */
static IR_KEYTAB_TYPE eztv_codes[IR_KEYTAB_SIZE] = {
[ 18 ] = KEY_POWER,
[ 1 ] = KEY_TV, // DVR
[ 21 ] = KEY_VIDEO, // DVD
[ 23 ] = KEY_AUDIO, // music
// DVR mode / DVD mode / music mode
[ 27 ] = KEY_MUTE, // mute
[ 2 ] = KEY_RESERVED, // MTS/SAP / audio /autoseek
[ 30 ] = KEY_RESERVED, // closed captioning / subtitle / seek
[ 22 ] = KEY_ZOOM, // full screen
[ 28 ] = KEY_RESERVED, // video source / eject /delall
[ 29 ] = KEY_RESERVED, // playback / angle /del
[ 47 ] = KEY_SEARCH, // scan / menu / playlist
[ 48 ] = KEY_RESERVED, // CH surfing / bookmark / memo
[ 49 ] = KEY_HELP, // help
[ 50 ] = KEY_RESERVED, // num/memo
[ 51 ] = KEY_ESC, // cancel
[ 12 ] = KEY_UP, // up
[ 16 ] = KEY_DOWN, // down
[ 8 ] = KEY_LEFT, // left
[ 4 ] = KEY_RIGHT, // right
[ 3 ] = KEY_ENTER, // select
[ 31 ] = KEY_REWIND, // rewind
[ 32 ] = KEY_PLAYPAUSE, // play/pause
[ 41 ] = KEY_FORWARD, // forward
[ 20 ] = KEY_RESERVED, // repeat
[ 43 ] = KEY_RECORD, // recording
[ 44 ] = KEY_STOP, // stop
[ 45 ] = KEY_PLAY, // play
[ 46 ] = KEY_RESERVED, // snapshot
[ 0 ] = KEY_KP0,
[ 5 ] = KEY_KP1,
[ 6 ] = KEY_KP2,
[ 7 ] = KEY_KP3,
[ 9 ] = KEY_KP4,
[ 10 ] = KEY_KP5,
[ 11 ] = KEY_KP6,
[ 13 ] = KEY_KP7,
[ 14 ] = KEY_KP8,
[ 15 ] = KEY_KP9,
[ 42 ] = KEY_VOLUMEUP,
[ 17 ] = KEY_VOLUMEDOWN,
[ 24 ] = KEY_CHANNELUP, // CH.tracking up
[ 25 ] = KEY_CHANNELDOWN, // CH.tracking down
[ 19 ] = KEY_KPENTER, // enter
[ 33 ] = KEY_KPDOT, // . (decimal dot)
};
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
static int build_key(struct saa7134_dev *dev) static int build_key(struct saa7134_dev *dev)
...@@ -111,9 +167,15 @@ static int build_key(struct saa7134_dev *dev) ...@@ -111,9 +167,15 @@ static int build_key(struct saa7134_dev *dev)
/* rising SAA7134_GPIO_GPRESCAN reads the status */ /* rising SAA7134_GPIO_GPRESCAN reads the status */
saa_clearb(SAA7134_GPIO_GPMODE3,SAA7134_GPIO_GPRESCAN); saa_clearb(SAA7134_GPIO_GPMODE3,SAA7134_GPIO_GPRESCAN);
saa_setb(SAA7134_GPIO_GPMODE3,SAA7134_GPIO_GPRESCAN); saa_setb(SAA7134_GPIO_GPMODE3,SAA7134_GPIO_GPRESCAN);
gpio = saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2); gpio = saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2);
data = ir_extract_bits(gpio, ir->mask_keycode); if (ir->polling) {
if (ir->last_gpio == gpio)
return 0;
ir->last_gpio = gpio;
}
data = ir_extract_bits(gpio, ir->mask_keycode);
printk("%s: build_key gpio=0x%x mask=0x%x data=%d\n", printk("%s: build_key gpio=0x%x mask=0x%x data=%d\n",
dev->name, gpio, ir->mask_keycode, data); dev->name, gpio, ir->mask_keycode, data);
...@@ -130,7 +192,21 @@ static int build_key(struct saa7134_dev *dev) ...@@ -130,7 +192,21 @@ static int build_key(struct saa7134_dev *dev)
void saa7134_input_irq(struct saa7134_dev *dev) void saa7134_input_irq(struct saa7134_dev *dev)
{ {
struct saa7134_ir *ir = dev->remote;
if (!ir->polling)
build_key(dev);
}
static void saa7134_input_timer(unsigned long data)
{
struct saa7134_dev *dev = (struct saa7134_dev*)data;
struct saa7134_ir *ir = dev->remote;
unsigned long timeout;
build_key(dev); build_key(dev);
timeout = jiffies + (ir->polling * HZ / 1000);
mod_timer(&ir->timer, timeout);
} }
int saa7134_input_init1(struct saa7134_dev *dev) int saa7134_input_init1(struct saa7134_dev *dev)
...@@ -140,6 +216,7 @@ int saa7134_input_init1(struct saa7134_dev *dev) ...@@ -140,6 +216,7 @@ int saa7134_input_init1(struct saa7134_dev *dev)
u32 mask_keycode = 0; u32 mask_keycode = 0;
u32 mask_keydown = 0; u32 mask_keydown = 0;
u32 mask_keyup = 0; u32 mask_keyup = 0;
int polling = 0;
int ir_type = IR_TYPE_OTHER; int ir_type = IR_TYPE_OTHER;
/* detect & configure */ /* detect & configure */
...@@ -158,6 +235,13 @@ int saa7134_input_init1(struct saa7134_dev *dev) ...@@ -158,6 +235,13 @@ int saa7134_input_init1(struct saa7134_dev *dev)
mask_keycode = 0x00003f; mask_keycode = 0x00003f;
mask_keyup = 0x040000; mask_keyup = 0x040000;
break; break;
case SAA7134_BOARD_ECS_TVP3XP:
case SAA7134_BOARD_ECS_TVP3XP_4CB5:
ir_codes = eztv_codes;
mask_keycode = 0x00017c;
mask_keyup = 0x000002;
polling = 50; // ms
break;
} }
if (NULL == ir_codes) { if (NULL == ir_codes) {
printk("%s: Oops: IR config error [card=%d]\n", printk("%s: Oops: IR config error [card=%d]\n",
...@@ -174,6 +258,7 @@ int saa7134_input_init1(struct saa7134_dev *dev) ...@@ -174,6 +258,7 @@ int saa7134_input_init1(struct saa7134_dev *dev)
ir->mask_keycode = mask_keycode; ir->mask_keycode = mask_keycode;
ir->mask_keydown = mask_keydown; ir->mask_keydown = mask_keydown;
ir->mask_keyup = mask_keyup; ir->mask_keyup = mask_keyup;
ir->polling = polling;
/* init input device */ /* init input device */
snprintf(ir->name, sizeof(ir->name), "saa7134 IR (%s)", snprintf(ir->name, sizeof(ir->name), "saa7134 IR (%s)",
...@@ -196,6 +281,14 @@ int saa7134_input_init1(struct saa7134_dev *dev) ...@@ -196,6 +281,14 @@ int saa7134_input_init1(struct saa7134_dev *dev)
/* all done */ /* all done */
dev->remote = ir; dev->remote = ir;
if (ir->polling) {
init_timer(&ir->timer);
ir->timer.function = saa7134_input_timer;
ir->timer.data = (unsigned long)dev;
ir->timer.expires = jiffies + HZ;
add_timer(&ir->timer);
}
input_register_device(&dev->remote->dev); input_register_device(&dev->remote->dev);
printk("%s: registered input device for IR\n",dev->name); printk("%s: registered input device for IR\n",dev->name);
return 0; return 0;
...@@ -207,6 +300,8 @@ void saa7134_input_fini(struct saa7134_dev *dev) ...@@ -207,6 +300,8 @@ void saa7134_input_fini(struct saa7134_dev *dev)
return; return;
input_unregister_device(&dev->remote->dev); input_unregister_device(&dev->remote->dev);
if (dev->remote->polling)
del_timer_sync(&dev->remote->timer);
kfree(dev->remote); kfree(dev->remote);
dev->remote = NULL; dev->remote = NULL;
} }
......
...@@ -45,6 +45,9 @@ static unsigned int audio_ddep = 0; ...@@ -45,6 +45,9 @@ static unsigned int audio_ddep = 0;
MODULE_PARM(audio_ddep,"i"); MODULE_PARM(audio_ddep,"i");
MODULE_PARM_DESC(audio_ddep,"audio ddep overwrite"); MODULE_PARM_DESC(audio_ddep,"audio ddep overwrite");
static int audio_clock_override = UNSET;
MODULE_PARM(audio_clock_override, "i");
static int audio_clock_tweak = 0; static int audio_clock_tweak = 0;
MODULE_PARM(audio_clock_tweak, "i"); MODULE_PARM(audio_clock_tweak, "i");
MODULE_PARM_DESC(audio_clock_tweak, "Audio clock tick fine tuning for cards with audio crystal that's slightly off (range [-1024 .. 1024])"); MODULE_PARM_DESC(audio_clock_tweak, "Audio clock tick fine tuning for cards with audio crystal that's slightly off (range [-1024 .. 1024])");
...@@ -140,6 +143,9 @@ static void tvaudio_init(struct saa7134_dev *dev) ...@@ -140,6 +143,9 @@ static void tvaudio_init(struct saa7134_dev *dev)
{ {
int clock = saa7134_boards[dev->board].audio_clock; int clock = saa7134_boards[dev->board].audio_clock;
if (UNSET != audio_clock_override)
clock = audio_clock_override;
/* init all audio registers */ /* init all audio registers */
saa_writeb(SAA7134_AUDIO_PLL_CTRL, 0x00); saa_writeb(SAA7134_AUDIO_PLL_CTRL, 0x00);
if (need_resched()) if (need_resched())
...@@ -296,8 +302,13 @@ static int tvaudio_sleep(struct saa7134_dev *dev, int timeout) ...@@ -296,8 +302,13 @@ static int tvaudio_sleep(struct saa7134_dev *dev, int timeout)
DECLARE_WAITQUEUE(wait, current); DECLARE_WAITQUEUE(wait, current);
add_wait_queue(&dev->thread.wq, &wait); add_wait_queue(&dev->thread.wq, &wait);
if (dev->thread.scan1 == dev->thread.scan2 && !dev->thread.shutdown) {
set_current_state(TASK_INTERRUPTIBLE); set_current_state(TASK_INTERRUPTIBLE);
if (timeout < 0)
schedule();
else
schedule_timeout(timeout); schedule_timeout(timeout);
}
remove_wait_queue(&dev->thread.wq, &wait); remove_wait_queue(&dev->thread.wq, &wait);
return dev->thread.scan1 != dev->thread.scan2; return dev->thread.scan1 != dev->thread.scan2;
} }
...@@ -457,18 +468,11 @@ static int tvaudio_thread(void *data) ...@@ -457,18 +468,11 @@ static int tvaudio_thread(void *data)
unsigned int i, audio; unsigned int i, audio;
int max1,max2,carrier,rx,mode,lastmode; int max1,max2,carrier,rx,mode,lastmode;
lock_kernel();
daemonize("%s", dev->name); daemonize("%s", dev->name);
dev->thread.task = current; allow_signal(SIGTERM);
unlock_kernel();
if (dev->thread.notify != NULL)
up(dev->thread.notify);
for (;;) { for (;;) {
if (dev->thread.exit || signal_pending(current)) tvaudio_sleep(dev,-1);
goto done; if (dev->thread.shutdown || signal_pending(current))
interruptible_sleep_on(&dev->thread.wq);
if (dev->thread.exit || signal_pending(current))
goto done; goto done;
restart: restart:
...@@ -571,7 +575,7 @@ static int tvaudio_thread(void *data) ...@@ -571,7 +575,7 @@ static int tvaudio_thread(void *data)
for (;;) { for (;;) {
if (tvaudio_sleep(dev,5*HZ)) if (tvaudio_sleep(dev,5*HZ))
goto restart; goto restart;
if (dev->thread.exit || signal_pending(current)) if (dev->thread.shutdown || signal_pending(current))
break; break;
if (UNSET == dev->thread.mode) { if (UNSET == dev->thread.mode) {
rx = tvaudio_getstereo(dev,&tvaudio[i]); rx = tvaudio_getstereo(dev,&tvaudio[i]);
...@@ -587,9 +591,7 @@ static int tvaudio_thread(void *data) ...@@ -587,9 +591,7 @@ static int tvaudio_thread(void *data)
} }
done: done:
dev->thread.task = NULL; complete_and_exit(&dev->thread.exit, 0);
if(dev->thread.notify != NULL)
up(dev->thread.notify);
return 0; return 0;
} }
...@@ -721,22 +723,16 @@ static int tvaudio_thread_ddep(void *data) ...@@ -721,22 +723,16 @@ static int tvaudio_thread_ddep(void *data)
struct saa7134_dev *dev = data; struct saa7134_dev *dev = data;
u32 value, norms; u32 value, norms;
lock_kernel();
daemonize("%s", dev->name); daemonize("%s", dev->name);
dev->thread.task = current; allow_signal(SIGTERM);
unlock_kernel();
if (dev->thread.notify != NULL)
up(dev->thread.notify);
/* unmute */ /* unmute */
saa_dsp_writel(dev, 0x474 >> 2, 0x00); saa_dsp_writel(dev, 0x474 >> 2, 0x00);
saa_dsp_writel(dev, 0x450 >> 2, 0x00); saa_dsp_writel(dev, 0x450 >> 2, 0x00);
for (;;) { for (;;) {
if (dev->thread.exit || signal_pending(current)) tvaudio_sleep(dev,-1);
goto done; if (dev->thread.shutdown || signal_pending(current))
interruptible_sleep_on(&dev->thread.wq);
if (dev->thread.exit || signal_pending(current))
goto done; goto done;
restart: restart:
...@@ -808,9 +804,7 @@ static int tvaudio_thread_ddep(void *data) ...@@ -808,9 +804,7 @@ static int tvaudio_thread_ddep(void *data)
} }
done: done:
dev->thread.task = NULL; complete_and_exit(&dev->thread.exit, 0);
if(dev->thread.notify != NULL)
up(dev->thread.notify);
return 0; return 0;
} }
...@@ -893,7 +887,6 @@ int saa7134_tvaudio_init2(struct saa7134_dev *dev) ...@@ -893,7 +887,6 @@ int saa7134_tvaudio_init2(struct saa7134_dev *dev)
{ {
DECLARE_MUTEX_LOCKED(sem); DECLARE_MUTEX_LOCKED(sem);
int (*my_thread)(void *data) = NULL; int (*my_thread)(void *data) = NULL;
int rc;
/* enable I2S audio output */ /* enable I2S audio output */
if (saa7134_boards[dev->board].i2s_rate) { if (saa7134_boards[dev->board].i2s_rate) {
...@@ -915,17 +908,16 @@ int saa7134_tvaudio_init2(struct saa7134_dev *dev) ...@@ -915,17 +908,16 @@ int saa7134_tvaudio_init2(struct saa7134_dev *dev)
my_thread = tvaudio_thread_ddep; my_thread = tvaudio_thread_ddep;
break; break;
} }
dev->thread.pid = -1;
if (my_thread) { if (my_thread) {
/* start tvaudio thread */ /* start tvaudio thread */
init_waitqueue_head(&dev->thread.wq); init_waitqueue_head(&dev->thread.wq);
dev->thread.notify = &sem; init_completion(&dev->thread.exit);
rc = kernel_thread(my_thread,dev,0); dev->thread.pid = kernel_thread(my_thread,dev,0);
if (rc < 0) if (dev->thread.pid < 0)
printk(KERN_WARNING "%s: kernel_thread() failed\n", printk(KERN_WARNING "%s: kernel_thread() failed\n",
dev->name); dev->name);
else
down(&sem);
dev->thread.notify = NULL;
wake_up_interruptible(&dev->thread.wq); wake_up_interruptible(&dev->thread.wq);
} }
...@@ -934,15 +926,11 @@ int saa7134_tvaudio_init2(struct saa7134_dev *dev) ...@@ -934,15 +926,11 @@ int saa7134_tvaudio_init2(struct saa7134_dev *dev)
int saa7134_tvaudio_fini(struct saa7134_dev *dev) int saa7134_tvaudio_fini(struct saa7134_dev *dev)
{ {
DECLARE_MUTEX_LOCKED(sem);
/* shutdown tvaudio thread */ /* shutdown tvaudio thread */
if (dev->thread.task) { if (dev->thread.pid >= 0) {
dev->thread.notify = &sem; dev->thread.shutdown = 1;
dev->thread.exit = 1;
wake_up_interruptible(&dev->thread.wq); wake_up_interruptible(&dev->thread.wq);
down(&sem); wait_for_completion(&dev->thread.exit);
dev->thread.notify = NULL;
} }
saa_andorb(SAA7134_ANALOG_IO_SELECT, 0x07, 0x00); /* LINE1 */ saa_andorb(SAA7134_ANALOG_IO_SELECT, 0x07, 0x00); /* LINE1 */
return 0; return 0;
...@@ -950,7 +938,7 @@ int saa7134_tvaudio_fini(struct saa7134_dev *dev) ...@@ -950,7 +938,7 @@ int saa7134_tvaudio_fini(struct saa7134_dev *dev)
int saa7134_tvaudio_do_scan(struct saa7134_dev *dev) int saa7134_tvaudio_do_scan(struct saa7134_dev *dev)
{ {
if (dev->thread.task) { if (dev->thread.pid >= 0) {
dev->thread.mode = UNSET; dev->thread.mode = UNSET;
dev->thread.scan2++; dev->thread.scan2++;
wake_up_interruptible(&dev->thread.wq); wake_up_interruptible(&dev->thread.wq);
......
...@@ -151,6 +151,9 @@ struct saa7134_format { ...@@ -151,6 +151,9 @@ struct saa7134_format {
#define SAA7134_BOARD_MANLI_MTV001 28 #define SAA7134_BOARD_MANLI_MTV001 28
#define SAA7134_BOARD_TG3000TV 29 #define SAA7134_BOARD_TG3000TV 29
#define SAA7134_BOARD_ECS_TVP3XP 30 #define SAA7134_BOARD_ECS_TVP3XP 30
#define SAA7134_BOARD_ECS_TVP3XP_4CB5 31
#define SAA7134_BOARD_AVACSSMARTTV 32
#define SAA7134_BOARD_AVERMEDIA_DVD_EZMAKER 33
#define SAA7134_INPUT_MAX 8 #define SAA7134_INPUT_MAX 8
...@@ -212,10 +215,10 @@ struct saa7134_pgtable { ...@@ -212,10 +215,10 @@ struct saa7134_pgtable {
/* tvaudio thread status */ /* tvaudio thread status */
struct saa7134_thread { struct saa7134_thread {
struct task_struct *task; pid_t pid;
struct completion exit;
wait_queue_head_t wq; wait_queue_head_t wq;
struct semaphore *notify; unsigned int shutdown;
unsigned int exit;
unsigned int scan1; unsigned int scan1;
unsigned int scan2; unsigned int scan2;
unsigned int mode; unsigned int mode;
...@@ -319,6 +322,9 @@ struct saa7134_ir { ...@@ -319,6 +322,9 @@ struct saa7134_ir {
u32 mask_keycode; u32 mask_keycode;
u32 mask_keydown; u32 mask_keydown;
u32 mask_keyup; u32 mask_keyup;
int polling;
u32 last_gpio;
struct timer_list timer;
}; };
/* global device status */ /* global device status */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment