diff options
author | Andy Walls <awalls@radix.net> | 2008-07-13 18:30:15 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2008-07-20 06:25:03 -0400 |
commit | 02fa272fcb6edda9059d6dbaab20dfe919f4f4d2 (patch) | |
tree | dcce1b6957c1a355c6ebcb80e61aa8651e84a93a | |
parent | 8abdd00dcc6a58cab3afe6a23a0ce819dc08049a (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>
-rw-r--r-- | drivers/media/video/cx18/cx18-cards.c | 2 | ||||
-rw-r--r-- | drivers/media/video/cx18/cx18-cards.h | 1 | ||||
-rw-r--r-- | drivers/media/video/cx18/cx18-gpio.c | 41 | ||||
-rw-r--r-- | drivers/media/video/cx18/cx18-gpio.h | 1 | ||||
-rw-r--r-- | drivers/media/video/cx18/cx18-ioctl.c | 9 |
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 | ||
88 | struct cx18_gpio_audio_input { /* select tuner/line in input */ | 89 | struct 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 | ||
86 | void 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 | } | ||
124 | EXPORT_SYMBOL(cx18_reset_ir_gpio); | ||
125 | /* This symbol is exported for use by an infrared module for the IR-blaster */ | ||
126 | |||
86 | void cx18_gpio_init(struct cx18 *cx) | 127 | void 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 | ||
23 | void cx18_gpio_init(struct cx18 *cx); | 23 | void cx18_gpio_init(struct cx18 *cx); |
24 | void cx18_reset_i2c_slaves_gpio(struct cx18 *cx); | 24 | void cx18_reset_i2c_slaves_gpio(struct cx18 *cx); |
25 | void cx18_reset_ir_gpio(void *data); | ||
25 | int cx18_reset_tuner_gpio(void *dev, int cmd, int value); | 26 | int cx18_reset_tuner_gpio(void *dev, int cmd, int value); |
26 | int cx18_gpio(struct cx18 *cx, unsigned int command, void *arg); | 27 | int 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 | } |