V4L/DVB (9724): cx18: Streamline cx18-io[ch] wrappers and enforce MMIO retry strategy
[safe/jmp/linux-2.6] / drivers / media / video / cx18 / cx18-gpio.c
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"
25 #include "cx18-io.h"
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
48 static void gpio_write(struct cx18 *cx)
49 {
50         u32 dir_lo = cx->gpio_dir & 0xffff;
51         u32 val_lo = cx->gpio_val & 0xffff;
52         u32 dir_hi = cx->gpio_dir >> 16;
53         u32 val_hi = cx->gpio_val >> 16;
54
55         cx18_write_reg_expect(cx, dir_lo << 16,
56                                         CX18_REG_GPIO_DIR1, ~dir_lo, dir_lo);
57         cx18_write_reg_expect(cx, (dir_lo << 16) | val_lo,
58                                         CX18_REG_GPIO_OUT1, val_lo, dir_lo);
59         cx18_write_reg_expect(cx, dir_hi << 16,
60                                         CX18_REG_GPIO_DIR2, ~dir_hi, dir_hi);
61         cx18_write_reg_expect(cx, (dir_hi << 16) | val_hi,
62                                         CX18_REG_GPIO_OUT2, val_hi, dir_hi);
63 }
64
65 void cx18_reset_i2c_slaves_gpio(struct cx18 *cx)
66 {
67         const struct cx18_gpio_i2c_slave_reset *p;
68
69         p = &cx->card->gpio_i2c_slave_reset;
70
71         if ((p->active_lo_mask | p->active_hi_mask) == 0)
72                 return;
73
74         /* Assuming that the masks are a subset of the bits in gpio_dir */
75
76         /* Assert */
77         mutex_lock(&cx->gpio_lock);
78         cx->gpio_val =
79                 (cx->gpio_val | p->active_hi_mask) & ~(p->active_lo_mask);
80         gpio_write(cx);
81         schedule_timeout_uninterruptible(msecs_to_jiffies(p->msecs_asserted));
82
83         /* Deassert */
84         cx->gpio_val =
85                 (cx->gpio_val | p->active_lo_mask) & ~(p->active_hi_mask);
86         gpio_write(cx);
87         schedule_timeout_uninterruptible(msecs_to_jiffies(p->msecs_recovery));
88         mutex_unlock(&cx->gpio_lock);
89 }
90
91 void cx18_reset_ir_gpio(void *data)
92 {
93         struct cx18 *cx = ((struct cx18_i2c_algo_callback_data *)data)->cx;
94         const struct cx18_gpio_i2c_slave_reset *p;
95
96         p = &cx->card->gpio_i2c_slave_reset;
97
98         if (p->ir_reset_mask == 0)
99                 return;
100
101         CX18_DEBUG_INFO("Resetting IR microcontroller\n");
102
103         /*
104            Assert timing for the Z8F0811 on HVR-1600 boards:
105            1. Assert RESET for min of 4 clock cycles at 18.432 MHz to initiate
106            2. Reset then takes 66 WDT cycles at 10 kHz + 16 xtal clock cycles
107                 (6,601,085 nanoseconds ~= 7 milliseconds)
108            3. DBG pin must be high before chip exits reset for normal operation.
109                 DBG is open drain and hopefully pulled high since we don't
110                 normally drive it (GPIO 1?) for the HVR-1600
111            4. Z8F0811 won't exit reset until RESET is deasserted
112         */
113         mutex_lock(&cx->gpio_lock);
114         cx->gpio_val = cx->gpio_val & ~p->ir_reset_mask;
115         gpio_write(cx);
116         mutex_unlock(&cx->gpio_lock);
117         schedule_timeout_uninterruptible(msecs_to_jiffies(p->msecs_asserted));
118
119         /*
120            Zilog comes out of reset, loads reset vector address and executes
121            from there. Required recovery delay unknown.
122         */
123         mutex_lock(&cx->gpio_lock);
124         cx->gpio_val = cx->gpio_val | p->ir_reset_mask;
125         gpio_write(cx);
126         mutex_unlock(&cx->gpio_lock);
127         schedule_timeout_uninterruptible(msecs_to_jiffies(p->msecs_recovery));
128 }
129 EXPORT_SYMBOL(cx18_reset_ir_gpio);
130 /* This symbol is exported for use by an infrared module for the IR-blaster */
131
132 void cx18_gpio_init(struct cx18 *cx)
133 {
134         mutex_lock(&cx->gpio_lock);
135         cx->gpio_dir = cx->card->gpio_init.direction;
136         cx->gpio_val = cx->card->gpio_init.initial_value;
137
138         if (cx->card->tuners[0].tuner == TUNER_XC2028) {
139                 cx->gpio_dir |= 1 << cx->card->xceive_pin;
140                 cx->gpio_val |= 1 << cx->card->xceive_pin;
141         }
142
143         if (cx->gpio_dir == 0) {
144                 mutex_unlock(&cx->gpio_lock);
145                 return;
146         }
147
148         CX18_DEBUG_INFO("GPIO initial dir: %08x/%08x out: %08x/%08x\n",
149                         cx18_read_reg(cx, CX18_REG_GPIO_DIR1),
150                         cx18_read_reg(cx, CX18_REG_GPIO_DIR2),
151                         cx18_read_reg(cx, CX18_REG_GPIO_OUT1),
152                         cx18_read_reg(cx, CX18_REG_GPIO_OUT2));
153
154         gpio_write(cx);
155         mutex_unlock(&cx->gpio_lock);
156 }
157
158 /* Xceive tuner reset function */
159 int cx18_reset_tuner_gpio(void *dev, int component, int cmd, int value)
160 {
161         struct i2c_algo_bit_data *algo = dev;
162         struct cx18_i2c_algo_callback_data *cb_data = algo->data;
163         struct cx18 *cx = cb_data->cx;
164
165         if (cmd != XC2028_TUNER_RESET)
166                 return 0;
167         CX18_DEBUG_INFO("Resetting tuner\n");
168
169         mutex_lock(&cx->gpio_lock);
170         cx->gpio_val &= ~(1 << cx->card->xceive_pin);
171         gpio_write(cx);
172         mutex_unlock(&cx->gpio_lock);
173         schedule_timeout_interruptible(msecs_to_jiffies(1));
174
175         mutex_lock(&cx->gpio_lock);
176         cx->gpio_val |= 1 << cx->card->xceive_pin;
177         gpio_write(cx);
178         mutex_unlock(&cx->gpio_lock);
179         schedule_timeout_interruptible(msecs_to_jiffies(1));
180         return 0;
181 }
182
183 int cx18_gpio(struct cx18 *cx, unsigned int command, void *arg)
184 {
185         struct v4l2_routing *route = arg;
186         u32 mask, data;
187
188         switch (command) {
189         case VIDIOC_INT_S_AUDIO_ROUTING:
190                 if (route->input > 2)
191                         return -EINVAL;
192                 mask = cx->card->gpio_audio_input.mask;
193                 switch (route->input) {
194                 case 0:
195                         data = cx->card->gpio_audio_input.tuner;
196                         break;
197                 case 1:
198                         data = cx->card->gpio_audio_input.linein;
199                         break;
200                 case 2:
201                 default:
202                         data = cx->card->gpio_audio_input.radio;
203                         break;
204                 }
205                 break;
206
207         default:
208                 return -EINVAL;
209         }
210         if (mask) {
211                 mutex_lock(&cx->gpio_lock);
212                 cx->gpio_val = (cx->gpio_val & ~mask) | (data & mask);
213                 gpio_write(cx);
214                 mutex_unlock(&cx->gpio_lock);
215         }
216         return 0;
217 }