Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Andy Walls and committed by
Mauro Carvalho Chehab
02fa272f 8abdd00d

+54
+2
drivers/media/video/cx18/cx18-cards.c
··· 88 88 .active_lo_mask = 0x3001, 89 89 .msecs_asserted = 10, 90 90 .msecs_recovery = 40, 91 + .ir_reset_mask = 0x0001, 91 92 }, 92 93 .i2c = &cx18_i2c_std, 93 94 }; ··· 134 133 .active_lo_mask = 0x3001, 135 134 .msecs_asserted = 10, 136 135 .msecs_recovery = 40, 136 + .ir_reset_mask = 0x0001, 137 137 }, 138 138 .i2c = &cx18_i2c_std, 139 139 };
+1
drivers/media/video/cx18/cx18-cards.h
··· 83 83 u32 active_hi_mask; /* GPIO outputs that reset i2c chips when high */ 84 84 int msecs_asserted; /* time period reset must remain asserted */ 85 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 89 struct cx18_gpio_audio_input { /* select tuner/line in input */
+41
drivers/media/video/cx18/cx18-gpio.c
··· 83 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 127 void cx18_gpio_init(struct cx18 *cx) 87 128 { 88 129 mutex_lock(&cx->gpio_lock);
+1
drivers/media/video/cx18/cx18-gpio.h
··· 22 22 23 23 void cx18_gpio_init(struct cx18 *cx); 24 24 void cx18_reset_i2c_slaves_gpio(struct cx18 *cx); 25 + void cx18_reset_ir_gpio(void *data); 25 26 int cx18_reset_tuner_gpio(void *dev, int cmd, int value); 26 27 int cx18_gpio(struct cx18 *cx, unsigned int command, void *arg);
+9
drivers/media/video/cx18/cx18-ioctl.c
··· 754 754 cx18_audio_set_route(cx, route); 755 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 766 default: 758 767 return -EINVAL; 759 768 }