aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video
diff options
context:
space:
mode:
authorAndy Walls <awalls@radix.net>2008-07-13 18:30:15 -0400
committerMauro Carvalho Chehab <mchehab@infradead.org>2008-07-20 06:25:03 -0400
commit02fa272fcb6edda9059d6dbaab20dfe919f4f4d2 (patch)
treedcce1b6957c1a355c6ebcb80e61aa8651e84a93a /drivers/media/video
parent8abdd00dcc6a58cab3afe6a23a0ce819dc08049a (diff)
V4L/DVB (8332): cx18: Suport external reset of the Z8F0811 IR controller on HVR-1600 for lirc
cx18: added in cx18_ir_reset_gpio function for lirc_pvr150 like module. Also added the ability to reset the IR chip via ioctl like ivtv. This needs the mutex to protect gpio_dir and gpio_val in struct cx18 as gpio changes can come from a few different asynchronous sources now. Signed-off-by: Andy Walls <awalls@radix.net> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media/video')
-rw-r--r--drivers/media/video/cx18/cx18-cards.c2
-rw-r--r--drivers/media/video/cx18/cx18-cards.h1
-rw-r--r--drivers/media/video/cx18/cx18-gpio.c41
-rw-r--r--drivers/media/video/cx18/cx18-gpio.h1
-rw-r--r--drivers/media/video/cx18/cx18-ioctl.c9
5 files changed, 54 insertions, 0 deletions
diff --git a/drivers/media/video/cx18/cx18-cards.c b/drivers/media/video/cx18/cx18-cards.c
index 0caae1a5edc4..8fe5f38c4d7c 100644
--- a/drivers/media/video/cx18/cx18-cards.c
+++ b/drivers/media/video/cx18/cx18-cards.c
@@ -88,6 +88,7 @@ static const struct cx18_card cx18_card_hvr1600_esmt = {
88 .active_lo_mask = 0x3001, 88 .active_lo_mask = 0x3001,
89 .msecs_asserted = 10, 89 .msecs_asserted = 10,
90 .msecs_recovery = 40, 90 .msecs_recovery = 40,
91 .ir_reset_mask = 0x0001,
91 }, 92 },
92 .i2c = &cx18_i2c_std, 93 .i2c = &cx18_i2c_std,
93}; 94};
@@ -133,6 +134,7 @@ static const struct cx18_card cx18_card_hvr1600_samsung = {
133 .active_lo_mask = 0x3001, 134 .active_lo_mask = 0x3001,
134 .msecs_asserted = 10, 135 .msecs_asserted = 10,
135 .msecs_recovery = 40, 136 .msecs_recovery = 40,
137 .ir_reset_mask = 0x0001,
136 }, 138 },
137 .i2c = &cx18_i2c_std, 139 .i2c = &cx18_i2c_std,
138}; 140};
diff --git a/drivers/media/video/cx18/cx18-cards.h b/drivers/media/video/cx18/cx18-cards.h
index dc283d756907..32155f6e6fe4 100644
--- a/drivers/media/video/cx18/cx18-cards.h
+++ b/drivers/media/video/cx18/cx18-cards.h
@@ -83,6 +83,7 @@ struct cx18_gpio_i2c_slave_reset {
83 u32 active_hi_mask; /* GPIO outputs that reset i2c chips when high */ 83 u32 active_hi_mask; /* GPIO outputs that reset i2c chips when high */
84 int msecs_asserted; /* time period reset must remain asserted */ 84 int msecs_asserted; /* time period reset must remain asserted */
85 int msecs_recovery; /* time after deassert for chips to be ready */ 85 int msecs_recovery; /* time after deassert for chips to be ready */
86 u32 ir_reset_mask; /* GPIO to reset the Zilog Z8F0811 IR contoller */
86}; 87};
87 88
88struct cx18_gpio_audio_input { /* select tuner/line in input */ 89struct cx18_gpio_audio_input { /* select tuner/line in input */
diff --git a/drivers/media/video/cx18/cx18-gpio.c b/drivers/media/video/cx18/cx18-gpio.c
index d753a40973ba..3d495dba4983 100644
--- a/drivers/media/video/cx18/cx18-gpio.c
+++ b/drivers/media/video/cx18/cx18-gpio.c
@@ -83,6 +83,47 @@ void cx18_reset_i2c_slaves_gpio(struct cx18 *cx)
83 mutex_unlock(&cx->gpio_lock); 83 mutex_unlock(&cx->gpio_lock);
84} 84}
85 85
86void cx18_reset_ir_gpio(void *data)
87{
88 struct cx18 *cx = ((struct cx18_i2c_algo_callback_data *)data)->cx;
89 const struct cx18_gpio_i2c_slave_reset *p;
90
91 p = &cx->card->gpio_i2c_slave_reset;
92
93 if (p->ir_reset_mask == 0)
94 return;
95
96 CX18_DEBUG_INFO("Resetting IR microcontroller\n");
97
98 /*
99 Assert timing for the Z8F0811 on HVR-1600 boards:
100 1. Assert RESET for min of 4 clock cycles at 18.432 MHz to initiate
101 2. Reset then takes 66 WDT cycles at 10 kHz + 16 xtal clock cycles
102 (6,601,085 nanoseconds ~= 7 milliseconds)
103 3. DBG pin must be high before chip exits reset for normal operation.
104 DBG is open drain and hopefully pulled high since we don't
105 normally drive it (GPIO 1?) for the HVR-1600
106 4. Z8F0811 won't exit reset until RESET is deasserted
107 */
108 mutex_lock(&cx->gpio_lock);
109 cx->gpio_val = cx->gpio_val & ~p->ir_reset_mask;
110 gpio_write(cx);
111 mutex_unlock(&cx->gpio_lock);
112 schedule_timeout_uninterruptible(msecs_to_jiffies(p->msecs_asserted));
113
114 /*
115 Zilog comes out of reset, loads reset vector address and executes
116 from there. Required recovery delay unknown.
117 */
118 mutex_lock(&cx->gpio_lock);
119 cx->gpio_val = cx->gpio_val | p->ir_reset_mask;
120 gpio_write(cx);
121 mutex_unlock(&cx->gpio_lock);
122 schedule_timeout_uninterruptible(msecs_to_jiffies(p->msecs_recovery));
123}
124EXPORT_SYMBOL(cx18_reset_ir_gpio);
125/* This symbol is exported for use by an infrared module for the IR-blaster */
126
86void cx18_gpio_init(struct cx18 *cx) 127void cx18_gpio_init(struct cx18 *cx)
87{ 128{
88 mutex_lock(&cx->gpio_lock); 129 mutex_lock(&cx->gpio_lock);
diff --git a/drivers/media/video/cx18/cx18-gpio.h b/drivers/media/video/cx18/cx18-gpio.h
index 7447fed35767..22cd7ddf8554 100644
--- a/drivers/media/video/cx18/cx18-gpio.h
+++ b/drivers/media/video/cx18/cx18-gpio.h
@@ -22,5 +22,6 @@
22 22
23void cx18_gpio_init(struct cx18 *cx); 23void cx18_gpio_init(struct cx18 *cx);
24void cx18_reset_i2c_slaves_gpio(struct cx18 *cx); 24void cx18_reset_i2c_slaves_gpio(struct cx18 *cx);
25void cx18_reset_ir_gpio(void *data);
25int cx18_reset_tuner_gpio(void *dev, int cmd, int value); 26int cx18_reset_tuner_gpio(void *dev, int cmd, int value);
26int cx18_gpio(struct cx18 *cx, unsigned int command, void *arg); 27int cx18_gpio(struct cx18 *cx, unsigned int command, void *arg);
diff --git a/drivers/media/video/cx18/cx18-ioctl.c b/drivers/media/video/cx18/cx18-ioctl.c
index 146a4b856496..0d74e59e503e 100644
--- a/drivers/media/video/cx18/cx18-ioctl.c
+++ b/drivers/media/video/cx18/cx18-ioctl.c
@@ -754,6 +754,15 @@ static int cx18_default(struct file *file, void *fh, int cmd, void *arg)
754 cx18_audio_set_route(cx, route); 754 cx18_audio_set_route(cx, route);
755 break; 755 break;
756 } 756 }
757
758 case VIDIOC_INT_RESET: {
759 u32 val = *(u32 *)arg;
760
761 if ((val == 0) || (val & 0x01))
762 cx18_reset_ir_gpio(&cx->i2c_algo_cb_data[0]);
763 break;
764 }
765
757 default: 766 default:
758 return -EINVAL; 767 return -EINVAL;
759 } 768 }