The patch number 8333 was added via Mauro Carvalho Chehab <[EMAIL PROTECTED]> to http://linuxtv.org/hg/v4l-dvb master development tree.
Kernel patches in this development tree may be modified to be backward compatible with older kernels. Compatibility modifications will be removed before inclusion into the mainstream Kernel If anyone has any objections, please let us know by sending a message to: [EMAIL PROTECTED] ------ From: Mauro Carvalho Chehab <[EMAIL PROTECTED]> merge: http://linuxtv.org/hg/~awalls/v4l-dvb Signed-off-by: Mauro Carvalho Chehab <[EMAIL PROTECTED]> --- linux/drivers/media/video/cx18/cx18-cards.c | 2 linux/drivers/media/video/cx18/cx18-cards.h | 1 linux/drivers/media/video/cx18/cx18-driver.c | 1 linux/drivers/media/video/cx18/cx18-driver.h | 1 linux/drivers/media/video/cx18/cx18-gpio.c | 62 +++++++++++++++++-- linux/drivers/media/video/cx18/cx18-gpio.h | 1 linux/drivers/media/video/cx18/cx18-ioctl.c | 11 +++ 7 files changed, 74 insertions(+), 5 deletions(-) diff -r b9a689d0f685 -r 8320f75ad3a0 linux/drivers/media/video/cx18/cx18-cards.c --- a/linux/drivers/media/video/cx18/cx18-cards.c Wed Jul 16 11:46:25 2008 -0300 +++ b/linux/drivers/media/video/cx18/cx18-cards.c Wed Jul 16 11:55:09 2008 -0300 @@ -88,6 +88,7 @@ static const struct cx18_card cx18_card_ .active_lo_mask = 0x3001, .msecs_asserted = 10, .msecs_recovery = 40, + .ir_reset_mask = 0x0001, }, .i2c = &cx18_i2c_std, }; @@ -133,6 +134,7 @@ static const struct cx18_card cx18_card_ .active_lo_mask = 0x3001, .msecs_asserted = 10, .msecs_recovery = 40, + .ir_reset_mask = 0x0001, }, .i2c = &cx18_i2c_std, }; diff -r b9a689d0f685 -r 8320f75ad3a0 linux/drivers/media/video/cx18/cx18-cards.h --- a/linux/drivers/media/video/cx18/cx18-cards.h Wed Jul 16 11:46:25 2008 -0300 +++ b/linux/drivers/media/video/cx18/cx18-cards.h Wed Jul 16 11:55:09 2008 -0300 @@ -83,6 +83,7 @@ struct cx18_gpio_i2c_slave_reset { u32 active_hi_mask; /* GPIO outputs that reset i2c chips when high */ int msecs_asserted; /* time period reset must remain asserted */ int msecs_recovery; /* time after deassert for chips to be ready */ + u32 ir_reset_mask; /* GPIO to reset the Zilog Z8F0811 IR contoller */ }; struct cx18_gpio_audio_input { /* select tuner/line in input */ diff -r b9a689d0f685 -r 8320f75ad3a0 linux/drivers/media/video/cx18/cx18-driver.c --- a/linux/drivers/media/video/cx18/cx18-driver.c Wed Jul 16 11:46:25 2008 -0300 +++ b/linux/drivers/media/video/cx18/cx18-driver.c Wed Jul 16 11:55:09 2008 -0300 @@ -421,6 +421,7 @@ static int __devinit cx18_init_struct1(s mutex_init(&cx->serialize_lock); mutex_init(&cx->i2c_bus_lock[0]); mutex_init(&cx->i2c_bus_lock[1]); + mutex_init(&cx->gpio_lock); spin_lock_init(&cx->lock); spin_lock_init(&cx->dma_reg_lock); diff -r b9a689d0f685 -r 8320f75ad3a0 linux/drivers/media/video/cx18/cx18-driver.h --- a/linux/drivers/media/video/cx18/cx18-driver.h Wed Jul 16 11:46:25 2008 -0300 +++ b/linux/drivers/media/video/cx18/cx18-driver.h Wed Jul 16 11:55:09 2008 -0300 @@ -427,6 +427,7 @@ struct cx18 { /* gpio */ u32 gpio_dir; u32 gpio_val; + struct mutex gpio_lock; /* v4l2 and User settings */ diff -r b9a689d0f685 -r 8320f75ad3a0 linux/drivers/media/video/cx18/cx18-gpio.c --- a/linux/drivers/media/video/cx18/cx18-gpio.c Wed Jul 16 11:46:25 2008 -0300 +++ b/linux/drivers/media/video/cx18/cx18-gpio.c Wed Jul 16 11:55:09 2008 -0300 @@ -69,6 +69,7 @@ void cx18_reset_i2c_slaves_gpio(struct c /* Assuming that the masks are a subset of the bits in gpio_dir */ /* Assert */ + mutex_lock(&cx->gpio_lock); cx->gpio_val = (cx->gpio_val | p->active_hi_mask) & ~(p->active_lo_mask); gpio_write(cx); @@ -79,10 +80,53 @@ void cx18_reset_i2c_slaves_gpio(struct c (cx->gpio_val | p->active_lo_mask) & ~(p->active_hi_mask); gpio_write(cx); schedule_timeout_uninterruptible(msecs_to_jiffies(p->msecs_recovery)); -} + mutex_unlock(&cx->gpio_lock); +} + +void cx18_reset_ir_gpio(void *data) +{ + struct cx18 *cx = ((struct cx18_i2c_algo_callback_data *)data)->cx; + const struct cx18_gpio_i2c_slave_reset *p; + + p = &cx->card->gpio_i2c_slave_reset; + + if (p->ir_reset_mask == 0) + return; + + CX18_DEBUG_INFO("Resetting IR microcontroller\n"); + + /* + Assert timing for the Z8F0811 on HVR-1600 boards: + 1. Assert RESET for min of 4 clock cycles at 18.432 MHz to initiate + 2. Reset then takes 66 WDT cycles at 10 kHz + 16 xtal clock cycles + (6,601,085 nanoseconds ~= 7 milliseconds) + 3. DBG pin must be high before chip exits reset for normal operation. + DBG is open drain and hopefully pulled high since we don't + normally drive it (GPIO 1?) for the HVR-1600 + 4. Z8F0811 won't exit reset until RESET is deasserted + */ + mutex_lock(&cx->gpio_lock); + cx->gpio_val = cx->gpio_val & ~p->ir_reset_mask; + gpio_write(cx); + mutex_unlock(&cx->gpio_lock); + schedule_timeout_uninterruptible(msecs_to_jiffies(p->msecs_asserted)); + + /* + Zilog comes out of reset, loads reset vector address and executes + from there. Required recovery delay unknown. + */ + mutex_lock(&cx->gpio_lock); + cx->gpio_val = cx->gpio_val | p->ir_reset_mask; + gpio_write(cx); + mutex_unlock(&cx->gpio_lock); + schedule_timeout_uninterruptible(msecs_to_jiffies(p->msecs_recovery)); +} +EXPORT_SYMBOL(cx18_reset_ir_gpio); +/* This symbol is exported for use by an infrared module for the IR-blaster */ void cx18_gpio_init(struct cx18 *cx) { + mutex_lock(&cx->gpio_lock); cx->gpio_dir = cx->card->gpio_init.direction; cx->gpio_val = cx->card->gpio_init.initial_value; @@ -91,14 +135,17 @@ void cx18_gpio_init(struct cx18 *cx) cx->gpio_val |= 1 << cx->card->xceive_pin; } - if (cx->gpio_dir == 0) - return; + if (cx->gpio_dir == 0) { + mutex_unlock(&cx->gpio_lock); + return; + } CX18_DEBUG_INFO("GPIO initial dir: %08x/%08x out: %08x/%08x\n", read_reg(CX18_REG_GPIO_DIR1), read_reg(CX18_REG_GPIO_DIR2), read_reg(CX18_REG_GPIO_OUT1), read_reg(CX18_REG_GPIO_OUT2)); gpio_write(cx); + mutex_unlock(&cx->gpio_lock); } /* Xceive tuner reset function */ @@ -112,13 +159,16 @@ int cx18_reset_tuner_gpio(void *dev, int return 0; CX18_DEBUG_INFO("Resetting tuner\n"); + mutex_lock(&cx->gpio_lock); cx->gpio_val &= ~(1 << cx->card->xceive_pin); - - gpio_write(cx); + gpio_write(cx); + mutex_unlock(&cx->gpio_lock); schedule_timeout_interruptible(msecs_to_jiffies(1)); + mutex_lock(&cx->gpio_lock); cx->gpio_val |= 1 << cx->card->xceive_pin; gpio_write(cx); + mutex_unlock(&cx->gpio_lock); schedule_timeout_interruptible(msecs_to_jiffies(1)); return 0; } @@ -151,8 +201,10 @@ int cx18_gpio(struct cx18 *cx, unsigned return -EINVAL; } if (mask) { + mutex_lock(&cx->gpio_lock); cx->gpio_val = (cx->gpio_val & ~mask) | (data & mask); gpio_write(cx); + mutex_unlock(&cx->gpio_lock); } return 0; } diff -r b9a689d0f685 -r 8320f75ad3a0 linux/drivers/media/video/cx18/cx18-gpio.h --- a/linux/drivers/media/video/cx18/cx18-gpio.h Wed Jul 16 11:46:25 2008 -0300 +++ b/linux/drivers/media/video/cx18/cx18-gpio.h Wed Jul 16 11:55:09 2008 -0300 @@ -22,5 +22,6 @@ void cx18_gpio_init(struct cx18 *cx); void cx18_reset_i2c_slaves_gpio(struct cx18 *cx); +void cx18_reset_ir_gpio(void *data); int cx18_reset_tuner_gpio(void *dev, int cmd, int value); int cx18_gpio(struct cx18 *cx, unsigned int command, void *arg); diff -r b9a689d0f685 -r 8320f75ad3a0 linux/drivers/media/video/cx18/cx18-ioctl.c --- a/linux/drivers/media/video/cx18/cx18-ioctl.c Wed Jul 16 11:46:25 2008 -0300 +++ b/linux/drivers/media/video/cx18/cx18-ioctl.c Wed Jul 16 11:55:09 2008 -0300 @@ -821,8 +821,10 @@ static int cx18_log_status(struct file * cx18_get_audio_input(cx, cx->audio_input, &audin); CX18_INFO("Video Input: %s\n", vidin.name); CX18_INFO("Audio Input: %s\n", audin.name); + mutex_lock(&cx->gpio_lock); CX18_INFO("GPIO: direction 0x%08x, value 0x%08x\n", cx->gpio_dir, cx->gpio_val); + mutex_unlock(&cx->gpio_lock); CX18_INFO("Tuner: %s\n", test_bit(CX18_F_I_RADIO_USER, &cx->i_flags) ? "Radio" : "TV"); cx2341x_log_status(&cx->params, cx->name); @@ -857,6 +859,15 @@ static int cx18_default(struct file *fil cx18_audio_set_route(cx, route); break; } + + case VIDIOC_INT_RESET: { + u32 val = *(u32 *)arg; + + if ((val == 0) || (val & 0x01)) + cx18_reset_ir_gpio(&cx->i2c_algo_cb_data[0]); + break; + } + default: return -EINVAL; } --- Patch is available at: http://linuxtv.org/hg/v4l-dvb/rev/8320f75ad3a09c5f565f2fc70f5f2b3dc91473d6 _______________________________________________ linuxtv-commits mailing list linuxtv-commits@linuxtv.org http://www.linuxtv.org/cgi-bin/mailman/listinfo/linuxtv-commits