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