blob: 1a99329f33cb5b6375edd1736cfe7529976c5069 [file] [log] [blame]
Hans Verkuil1c1e45d2008-04-28 20:24:33 -03001/*
2 * cx18 gpio functions
3 *
4 * Derived from ivtv-gpio.c
5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
Andy Walls1ed9dcc2008-11-22 01:37:34 -03007 * Copyright (C) 2008 Andy Walls <awalls@radix.net>
Hans Verkuil1c1e45d2008-04-28 20:24:33 -03008 *
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"
Andy Wallsb1526422008-08-30 16:03:44 -030026#include "cx18-io.h"
Hans Verkuil1c1e45d2008-04-28 20:24:33 -030027#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
Hans Verkuil9dcbf352008-05-12 13:57:18 -030049static void gpio_write(struct cx18 *cx)
50{
Andy Wallsced07372008-11-02 10:59:04 -030051 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;
Hans Verkuilba60bc62008-05-25 14:34:36 -030055
Andy Wallsced07372008-11-02 10:59:04 -030056 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);
Hans Verkuil9dcbf352008-05-12 13:57:18 -030064}
65
Andy Walls1f09e8a2008-06-22 01:27:00 -030066void 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 */
Andy Walls8abdd002008-07-13 19:05:25 -030078 mutex_lock(&cx->gpio_lock);
Andy Walls1f09e8a2008-06-22 01:27:00 -030079 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));
Andy Walls8abdd002008-07-13 19:05:25 -030089 mutex_unlock(&cx->gpio_lock);
Andy Walls1f09e8a2008-06-22 01:27:00 -030090}
91
Andy Walls02fa2722008-07-13 19:30:15 -030092void 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}
130EXPORT_SYMBOL(cx18_reset_ir_gpio);
131/* This symbol is exported for use by an infrared module for the IR-blaster */
132
Hans Verkuil1c1e45d2008-04-28 20:24:33 -0300133void cx18_gpio_init(struct cx18 *cx)
134{
Andy Walls8abdd002008-07-13 19:05:25 -0300135 mutex_lock(&cx->gpio_lock);
Hans Verkuilba60bc62008-05-25 14:34:36 -0300136 cx->gpio_dir = cx->card->gpio_init.direction;
137 cx->gpio_val = cx->card->gpio_init.initial_value;
Hans Verkuil9dcbf352008-05-12 13:57:18 -0300138
Hans Verkuil4ecc2472008-05-30 11:03:12 -0300139 if (cx->card->tuners[0].tuner == TUNER_XC2028) {
Hans Verkuilba60bc62008-05-25 14:34:36 -0300140 cx->gpio_dir |= 1 << cx->card->xceive_pin;
141 cx->gpio_val |= 1 << cx->card->xceive_pin;
Hans Verkuil7f3917f2008-05-19 22:13:02 -0300142 }
143
Andy Walls8abdd002008-07-13 19:05:25 -0300144 if (cx->gpio_dir == 0) {
145 mutex_unlock(&cx->gpio_lock);
Hans Verkuil1c1e45d2008-04-28 20:24:33 -0300146 return;
Andy Walls8abdd002008-07-13 19:05:25 -0300147 }
Hans Verkuil1c1e45d2008-04-28 20:24:33 -0300148
Hans Verkuil9dcbf352008-05-12 13:57:18 -0300149 CX18_DEBUG_INFO("GPIO initial dir: %08x/%08x out: %08x/%08x\n",
Andy Wallsb1526422008-08-30 16:03:44 -0300150 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));
Hans Verkuil9dcbf352008-05-12 13:57:18 -0300154
155 gpio_write(cx);
Andy Walls8abdd002008-07-13 19:05:25 -0300156 mutex_unlock(&cx->gpio_lock);
Hans Verkuil1c1e45d2008-04-28 20:24:33 -0300157}
158
159/* Xceive tuner reset function */
Michael Krufkyd7cba042008-09-12 13:31:45 -0300160int cx18_reset_tuner_gpio(void *dev, int component, int cmd, int value)
Hans Verkuil1c1e45d2008-04-28 20:24:33 -0300161{
162 struct i2c_algo_bit_data *algo = dev;
Hans Verkuil9dcbf352008-05-12 13:57:18 -0300163 struct cx18_i2c_algo_callback_data *cb_data = algo->data;
164 struct cx18 *cx = cb_data->cx;
Hans Verkuil1c1e45d2008-04-28 20:24:33 -0300165
166 if (cmd != XC2028_TUNER_RESET)
167 return 0;
168 CX18_DEBUG_INFO("Resetting tuner\n");
Hans Verkuil9dcbf352008-05-12 13:57:18 -0300169
Andy Walls8abdd002008-07-13 19:05:25 -0300170 mutex_lock(&cx->gpio_lock);
Hans Verkuilba60bc62008-05-25 14:34:36 -0300171 cx->gpio_val &= ~(1 << cx->card->xceive_pin);
Hans Verkuil9dcbf352008-05-12 13:57:18 -0300172 gpio_write(cx);
Andy Walls8abdd002008-07-13 19:05:25 -0300173 mutex_unlock(&cx->gpio_lock);
Hans Verkuil9dcbf352008-05-12 13:57:18 -0300174 schedule_timeout_interruptible(msecs_to_jiffies(1));
175
Andy Walls8abdd002008-07-13 19:05:25 -0300176 mutex_lock(&cx->gpio_lock);
Hans Verkuilba60bc62008-05-25 14:34:36 -0300177 cx->gpio_val |= 1 << cx->card->xceive_pin;
Hans Verkuil9dcbf352008-05-12 13:57:18 -0300178 gpio_write(cx);
Andy Walls8abdd002008-07-13 19:05:25 -0300179 mutex_unlock(&cx->gpio_lock);
Hans Verkuil9dcbf352008-05-12 13:57:18 -0300180 schedule_timeout_interruptible(msecs_to_jiffies(1));
Hans Verkuil1c1e45d2008-04-28 20:24:33 -0300181 return 0;
182}
Sri Deevi03c28082008-06-21 11:06:44 -0300183
184int 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) {
Andy Walls8abdd002008-07-13 19:05:25 -0300212 mutex_lock(&cx->gpio_lock);
Sri Deevi03c28082008-06-21 11:06:44 -0300213 cx->gpio_val = (cx->gpio_val & ~mask) | (data & mask);
214 gpio_write(cx);
Andy Walls8abdd002008-07-13 19:05:25 -0300215 mutex_unlock(&cx->gpio_lock);
Sri Deevi03c28082008-06-21 11:06:44 -0300216 }
217 return 0;
218}