Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/davej/cpufreq
[deliverable/linux.git] / 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-cards.h"
26 #include "cx18-gpio.h"
27 #include "tuner-xc2028.h"
28
29 /********************* GPIO stuffs *********************/
30
31 /* GPIO registers */
32 #define CX18_REG_GPIO_IN 0xc72010
33 #define CX18_REG_GPIO_OUT1 0xc78100
34 #define CX18_REG_GPIO_DIR1 0xc78108
35 #define CX18_REG_GPIO_OUT2 0xc78104
36 #define CX18_REG_GPIO_DIR2 0xc7810c
37
38 /*
39 * HVR-1600 GPIO pins, courtesy of Hauppauge:
40 *
41 * gpio0: zilog ir process reset pin
42 * gpio1: zilog programming pin (you should never use this)
43 * gpio12: cx24227 reset pin
44 * gpio13: cs5345 reset pin
45 */
46
47 static void gpio_write(struct cx18 *cx)
48 {
49 u32 dir = cx->gpio_dir;
50 u32 val = cx->gpio_val;
51
52 write_reg((dir & 0xffff) << 16, CX18_REG_GPIO_DIR1);
53 write_reg(((dir & 0xffff) << 16) | (val & 0xffff),
54 CX18_REG_GPIO_OUT1);
55 write_reg(dir & 0xffff0000, CX18_REG_GPIO_DIR2);
56 write_reg_sync((dir & 0xffff0000) | ((val & 0xffff0000) >> 16),
57 CX18_REG_GPIO_OUT2);
58 }
59
60 void cx18_reset_i2c_slaves_gpio(struct cx18 *cx)
61 {
62 const struct cx18_gpio_i2c_slave_reset *p;
63
64 p = &cx->card->gpio_i2c_slave_reset;
65
66 if ((p->active_lo_mask | p->active_hi_mask) == 0)
67 return;
68
69 /* Assuming that the masks are a subset of the bits in gpio_dir */
70
71 /* Assert */
72 mutex_lock(&cx->gpio_lock);
73 cx->gpio_val =
74 (cx->gpio_val | p->active_hi_mask) & ~(p->active_lo_mask);
75 gpio_write(cx);
76 schedule_timeout_uninterruptible(msecs_to_jiffies(p->msecs_asserted));
77
78 /* Deassert */
79 cx->gpio_val =
80 (cx->gpio_val | p->active_lo_mask) & ~(p->active_hi_mask);
81 gpio_write(cx);
82 schedule_timeout_uninterruptible(msecs_to_jiffies(p->msecs_recovery));
83 mutex_unlock(&cx->gpio_lock);
84 }
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
127 void cx18_gpio_init(struct cx18 *cx)
128 {
129 mutex_lock(&cx->gpio_lock);
130 cx->gpio_dir = cx->card->gpio_init.direction;
131 cx->gpio_val = cx->card->gpio_init.initial_value;
132
133 if (cx->card->tuners[0].tuner == TUNER_XC2028) {
134 cx->gpio_dir |= 1 << cx->card->xceive_pin;
135 cx->gpio_val |= 1 << cx->card->xceive_pin;
136 }
137
138 if (cx->gpio_dir == 0) {
139 mutex_unlock(&cx->gpio_lock);
140 return;
141 }
142
143 CX18_DEBUG_INFO("GPIO initial dir: %08x/%08x out: %08x/%08x\n",
144 read_reg(CX18_REG_GPIO_DIR1), read_reg(CX18_REG_GPIO_DIR2),
145 read_reg(CX18_REG_GPIO_OUT1), read_reg(CX18_REG_GPIO_OUT2));
146
147 gpio_write(cx);
148 mutex_unlock(&cx->gpio_lock);
149 }
150
151 /* Xceive tuner reset function */
152 int cx18_reset_tuner_gpio(void *dev, int cmd, int value)
153 {
154 struct i2c_algo_bit_data *algo = dev;
155 struct cx18_i2c_algo_callback_data *cb_data = algo->data;
156 struct cx18 *cx = cb_data->cx;
157
158 if (cmd != XC2028_TUNER_RESET)
159 return 0;
160 CX18_DEBUG_INFO("Resetting tuner\n");
161
162 mutex_lock(&cx->gpio_lock);
163 cx->gpio_val &= ~(1 << cx->card->xceive_pin);
164 gpio_write(cx);
165 mutex_unlock(&cx->gpio_lock);
166 schedule_timeout_interruptible(msecs_to_jiffies(1));
167
168 mutex_lock(&cx->gpio_lock);
169 cx->gpio_val |= 1 << cx->card->xceive_pin;
170 gpio_write(cx);
171 mutex_unlock(&cx->gpio_lock);
172 schedule_timeout_interruptible(msecs_to_jiffies(1));
173 return 0;
174 }
175
176 int cx18_gpio(struct cx18 *cx, unsigned int command, void *arg)
177 {
178 struct v4l2_routing *route = arg;
179 u32 mask, data;
180
181 switch (command) {
182 case VIDIOC_INT_S_AUDIO_ROUTING:
183 if (route->input > 2)
184 return -EINVAL;
185 mask = cx->card->gpio_audio_input.mask;
186 switch (route->input) {
187 case 0:
188 data = cx->card->gpio_audio_input.tuner;
189 break;
190 case 1:
191 data = cx->card->gpio_audio_input.linein;
192 break;
193 case 2:
194 default:
195 data = cx->card->gpio_audio_input.radio;
196 break;
197 }
198 break;
199
200 default:
201 return -EINVAL;
202 }
203 if (mask) {
204 mutex_lock(&cx->gpio_lock);
205 cx->gpio_val = (cx->gpio_val & ~mask) | (data & mask);
206 gpio_write(cx);
207 mutex_unlock(&cx->gpio_lock);
208 }
209 return 0;
210 }
This page took 0.046883 seconds and 6 git commands to generate.