Commit | Line | Data |
---|---|---|
1c1e45d1 HV |
1 | /* |
2 | * cx18 gpio functions | |
3 | * | |
4 | * Derived from ivtv-gpio.c | |
5 | * | |
6 | * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> | |
7 | * | |
8 | * This program is free software; you can redistribute it and/or modify | |
9 | * it under the terms of the GNU General Public License as published by | |
10 | * the Free Software Foundation; either version 2 of the License, or | |
11 | * (at your option) any later version. | |
12 | * | |
13 | * This program is distributed in the hope that it will be useful, | |
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | * GNU General Public License for more details. | |
17 | * | |
18 | * You should have received a copy of the GNU General Public License | |
19 | * along with this program; if not, write to the Free Software | |
20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | |
21 | * 02111-1307 USA | |
22 | */ | |
23 | ||
24 | #include "cx18-driver.h" | |
b1526421 | 25 | #include "cx18-io.h" |
1c1e45d1 HV |
26 | #include "cx18-cards.h" |
27 | #include "cx18-gpio.h" | |
28 | #include "tuner-xc2028.h" | |
29 | ||
30 | /********************* GPIO stuffs *********************/ | |
31 | ||
32 | /* GPIO registers */ | |
33 | #define CX18_REG_GPIO_IN 0xc72010 | |
34 | #define CX18_REG_GPIO_OUT1 0xc78100 | |
35 | #define CX18_REG_GPIO_DIR1 0xc78108 | |
36 | #define CX18_REG_GPIO_OUT2 0xc78104 | |
37 | #define CX18_REG_GPIO_DIR2 0xc7810c | |
38 | ||
39 | /* | |
40 | * HVR-1600 GPIO pins, courtesy of Hauppauge: | |
41 | * | |
42 | * gpio0: zilog ir process reset pin | |
43 | * gpio1: zilog programming pin (you should never use this) | |
44 | * gpio12: cx24227 reset pin | |
45 | * gpio13: cs5345 reset pin | |
46 | */ | |
47 | ||
9dcbf35a HV |
48 | static void gpio_write(struct cx18 *cx) |
49 | { | |
ba60bc67 HV |
50 | u32 dir = cx->gpio_dir; |
51 | u32 val = cx->gpio_val; | |
52 | ||
b1526421 AW |
53 | cx18_write_reg(cx, (dir & 0xffff) << 16, CX18_REG_GPIO_DIR1); |
54 | cx18_write_reg(cx, ((dir & 0xffff) << 16) | (val & 0xffff), | |
9dcbf35a | 55 | CX18_REG_GPIO_OUT1); |
b1526421 AW |
56 | cx18_write_reg(cx, dir & 0xffff0000, CX18_REG_GPIO_DIR2); |
57 | cx18_write_reg_sync(cx, (dir & 0xffff0000) | ((val & 0xffff0000) >> 16), | |
9dcbf35a HV |
58 | CX18_REG_GPIO_OUT2); |
59 | } | |
60 | ||
1f09e8a2 AW |
61 | void cx18_reset_i2c_slaves_gpio(struct cx18 *cx) |
62 | { | |
63 | const struct cx18_gpio_i2c_slave_reset *p; | |
64 | ||
65 | p = &cx->card->gpio_i2c_slave_reset; | |
66 | ||
67 | if ((p->active_lo_mask | p->active_hi_mask) == 0) | |
68 | return; | |
69 | ||
70 | /* Assuming that the masks are a subset of the bits in gpio_dir */ | |
71 | ||
72 | /* Assert */ | |
8abdd00d | 73 | mutex_lock(&cx->gpio_lock); |
1f09e8a2 AW |
74 | cx->gpio_val = |
75 | (cx->gpio_val | p->active_hi_mask) & ~(p->active_lo_mask); | |
76 | gpio_write(cx); | |
77 | schedule_timeout_uninterruptible(msecs_to_jiffies(p->msecs_asserted)); | |
78 | ||
79 | /* Deassert */ | |
80 | cx->gpio_val = | |
81 | (cx->gpio_val | p->active_lo_mask) & ~(p->active_hi_mask); | |
82 | gpio_write(cx); | |
83 | schedule_timeout_uninterruptible(msecs_to_jiffies(p->msecs_recovery)); | |
8abdd00d | 84 | mutex_unlock(&cx->gpio_lock); |
1f09e8a2 AW |
85 | } |
86 | ||
02fa272f AW |
87 | void cx18_reset_ir_gpio(void *data) |
88 | { | |
89 | struct cx18 *cx = ((struct cx18_i2c_algo_callback_data *)data)->cx; | |
90 | const struct cx18_gpio_i2c_slave_reset *p; | |
91 | ||
92 | p = &cx->card->gpio_i2c_slave_reset; | |
93 | ||
94 | if (p->ir_reset_mask == 0) | |
95 | return; | |
96 | ||
97 | CX18_DEBUG_INFO("Resetting IR microcontroller\n"); | |
98 | ||
99 | /* | |
100 | Assert timing for the Z8F0811 on HVR-1600 boards: | |
101 | 1. Assert RESET for min of 4 clock cycles at 18.432 MHz to initiate | |
102 | 2. Reset then takes 66 WDT cycles at 10 kHz + 16 xtal clock cycles | |
103 | (6,601,085 nanoseconds ~= 7 milliseconds) | |
104 | 3. DBG pin must be high before chip exits reset for normal operation. | |
105 | DBG is open drain and hopefully pulled high since we don't | |
106 | normally drive it (GPIO 1?) for the HVR-1600 | |
107 | 4. Z8F0811 won't exit reset until RESET is deasserted | |
108 | */ | |
109 | mutex_lock(&cx->gpio_lock); | |
110 | cx->gpio_val = cx->gpio_val & ~p->ir_reset_mask; | |
111 | gpio_write(cx); | |
112 | mutex_unlock(&cx->gpio_lock); | |
113 | schedule_timeout_uninterruptible(msecs_to_jiffies(p->msecs_asserted)); | |
114 | ||
115 | /* | |
116 | Zilog comes out of reset, loads reset vector address and executes | |
117 | from there. Required recovery delay unknown. | |
118 | */ | |
119 | mutex_lock(&cx->gpio_lock); | |
120 | cx->gpio_val = cx->gpio_val | p->ir_reset_mask; | |
121 | gpio_write(cx); | |
122 | mutex_unlock(&cx->gpio_lock); | |
123 | schedule_timeout_uninterruptible(msecs_to_jiffies(p->msecs_recovery)); | |
124 | } | |
125 | EXPORT_SYMBOL(cx18_reset_ir_gpio); | |
126 | /* This symbol is exported for use by an infrared module for the IR-blaster */ | |
127 | ||
1c1e45d1 HV |
128 | void cx18_gpio_init(struct cx18 *cx) |
129 | { | |
8abdd00d | 130 | mutex_lock(&cx->gpio_lock); |
ba60bc67 HV |
131 | cx->gpio_dir = cx->card->gpio_init.direction; |
132 | cx->gpio_val = cx->card->gpio_init.initial_value; | |
9dcbf35a | 133 | |
4ecc2473 | 134 | if (cx->card->tuners[0].tuner == TUNER_XC2028) { |
ba60bc67 HV |
135 | cx->gpio_dir |= 1 << cx->card->xceive_pin; |
136 | cx->gpio_val |= 1 << cx->card->xceive_pin; | |
7f3917f6 HV |
137 | } |
138 | ||
8abdd00d AW |
139 | if (cx->gpio_dir == 0) { |
140 | mutex_unlock(&cx->gpio_lock); | |
1c1e45d1 | 141 | return; |
8abdd00d | 142 | } |
1c1e45d1 | 143 | |
9dcbf35a | 144 | CX18_DEBUG_INFO("GPIO initial dir: %08x/%08x out: %08x/%08x\n", |
b1526421 AW |
145 | cx18_read_reg(cx, CX18_REG_GPIO_DIR1), |
146 | cx18_read_reg(cx, CX18_REG_GPIO_DIR2), | |
147 | cx18_read_reg(cx, CX18_REG_GPIO_OUT1), | |
148 | cx18_read_reg(cx, CX18_REG_GPIO_OUT2)); | |
9dcbf35a HV |
149 | |
150 | gpio_write(cx); | |
8abdd00d | 151 | mutex_unlock(&cx->gpio_lock); |
1c1e45d1 HV |
152 | } |
153 | ||
154 | /* Xceive tuner reset function */ | |
d7cba043 | 155 | int cx18_reset_tuner_gpio(void *dev, int component, int cmd, int value) |
1c1e45d1 HV |
156 | { |
157 | struct i2c_algo_bit_data *algo = dev; | |
9dcbf35a HV |
158 | struct cx18_i2c_algo_callback_data *cb_data = algo->data; |
159 | struct cx18 *cx = cb_data->cx; | |
1c1e45d1 HV |
160 | |
161 | if (cmd != XC2028_TUNER_RESET) | |
162 | return 0; | |
163 | CX18_DEBUG_INFO("Resetting tuner\n"); | |
9dcbf35a | 164 | |
8abdd00d | 165 | mutex_lock(&cx->gpio_lock); |
ba60bc67 | 166 | cx->gpio_val &= ~(1 << cx->card->xceive_pin); |
9dcbf35a | 167 | gpio_write(cx); |
8abdd00d | 168 | mutex_unlock(&cx->gpio_lock); |
9dcbf35a HV |
169 | schedule_timeout_interruptible(msecs_to_jiffies(1)); |
170 | ||
8abdd00d | 171 | mutex_lock(&cx->gpio_lock); |
ba60bc67 | 172 | cx->gpio_val |= 1 << cx->card->xceive_pin; |
9dcbf35a | 173 | gpio_write(cx); |
8abdd00d | 174 | mutex_unlock(&cx->gpio_lock); |
9dcbf35a | 175 | schedule_timeout_interruptible(msecs_to_jiffies(1)); |
1c1e45d1 HV |
176 | return 0; |
177 | } | |
03c28085 SD |
178 | |
179 | int cx18_gpio(struct cx18 *cx, unsigned int command, void *arg) | |
180 | { | |
181 | struct v4l2_routing *route = arg; | |
182 | u32 mask, data; | |
183 | ||
184 | switch (command) { | |
185 | case VIDIOC_INT_S_AUDIO_ROUTING: | |
186 | if (route->input > 2) | |
187 | return -EINVAL; | |
188 | mask = cx->card->gpio_audio_input.mask; | |
189 | switch (route->input) { | |
190 | case 0: | |
191 | data = cx->card->gpio_audio_input.tuner; | |
192 | break; | |
193 | case 1: | |
194 | data = cx->card->gpio_audio_input.linein; | |
195 | break; | |
196 | case 2: | |
197 | default: | |
198 | data = cx->card->gpio_audio_input.radio; | |
199 | break; | |
200 | } | |
201 | break; | |
202 | ||
203 | default: | |
204 | return -EINVAL; | |
205 | } | |
206 | if (mask) { | |
8abdd00d | 207 | mutex_lock(&cx->gpio_lock); |
03c28085 SD |
208 | cx->gpio_val = (cx->gpio_val & ~mask) | (data & mask); |
209 | gpio_write(cx); | |
8abdd00d | 210 | mutex_unlock(&cx->gpio_lock); |
03c28085 SD |
211 | } |
212 | return 0; | |
213 | } |