~ubuntu-branches/ubuntu/precise/linux-lowlatency/precise

« back to all changes in this revision

Viewing changes to drivers/media/video/ivtv/ivtv-gpio.c

  • Committer: Package Import Robot
  • Author(s): Alessio Igor Bogani
  • Date: 2011-10-26 11:13:05 UTC
  • Revision ID: package-import@ubuntu.com-20111026111305-tz023xykf0i6eosh
Tags: upstream-3.2.0
ImportĀ upstreamĀ versionĀ 3.2.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
    gpio functions.
 
3
    Merging GPIO support into driver:
 
4
    Copyright (C) 2004  Chris Kennedy <c@groovy.org>
 
5
    Copyright (C) 2005-2007  Hans Verkuil <hverkuil@xs4all.nl>
 
6
 
 
7
    This program is free software; you can redistribute it and/or modify
 
8
    it under the terms of the GNU General Public License as published by
 
9
    the Free Software Foundation; either version 2 of the License, or
 
10
    (at your option) any later version.
 
11
 
 
12
    This program is distributed in the hope that it will be useful,
 
13
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
15
    GNU General Public License for more details.
 
16
 
 
17
    You should have received a copy of the GNU General Public License
 
18
    along with this program; if not, write to the Free Software
 
19
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
20
 */
 
21
 
 
22
#include "ivtv-driver.h"
 
23
#include "ivtv-cards.h"
 
24
#include "ivtv-gpio.h"
 
25
#include "tuner-xc2028.h"
 
26
#include <media/tuner.h>
 
27
#include <media/v4l2-ctrls.h>
 
28
 
 
29
/*
 
30
 * GPIO assignment of Yuan MPG600/MPG160
 
31
 *
 
32
 *    bit 15  14  13  12 |  11  10   9   8 |   7   6   5   4 |   3   2   1   0
 
33
 * OUTPUT         IN1 IN0                                       AM3 AM2 AM1 AM0
 
34
 *  INPUT                   DM1         DM0
 
35
 *
 
36
 *   IN* : Input selection
 
37
 *          IN1 IN0
 
38
 *           1   1  N/A
 
39
 *           1   0  Line
 
40
 *           0   1  N/A
 
41
 *           0   0  Tuner
 
42
 *
 
43
 *   AM* : Audio Mode
 
44
 *          AM3  0: Normal        1: Mixed(Sub+Main channel)
 
45
 *          AM2  0: Subchannel    1: Main channel
 
46
 *          AM1  0: Stereo        1: Mono
 
47
 *          AM0  0: Normal        1: Mute
 
48
 *
 
49
 *   DM* : Detected tuner audio Mode
 
50
 *          DM1  0: Stereo        1: Mono
 
51
 *          DM0  0: Multiplex     1: Normal
 
52
 *
 
53
 * GPIO Initial Settings
 
54
 *           MPG600   MPG160
 
55
 *     DIR   0x3080   0x7080
 
56
 *  OUTPUT   0x000C   0x400C
 
57
 *
 
58
 *  Special thanks to Makoto Iguchi <iguchi@tahoo.org> and Mr. Anonymous
 
59
 *  for analyzing GPIO of MPG160.
 
60
 *
 
61
 *****************************************************************************
 
62
 *
 
63
 * GPIO assignment of Avermedia M179 (per information direct from AVerMedia)
 
64
 *
 
65
 *    bit 15  14  13  12 |  11  10   9   8 |   7   6   5   4 |   3   2   1   0
 
66
 * OUTPUT IN0 AM0 IN1               AM1 AM2       IN2     BR0   BR1
 
67
 *  INPUT
 
68
 *
 
69
 *   IN* : Input selection
 
70
 *          IN0 IN1 IN2
 
71
 *           *   1   *  Mute
 
72
 *           0   0   0  Line-In
 
73
 *           1   0   0  TV Tuner Audio
 
74
 *           0   0   1  FM Audio
 
75
 *           1   0   1  Mute
 
76
 *
 
77
 *   AM* : Audio Mode
 
78
 *          AM0 AM1 AM2
 
79
 *           0   0   0  TV Tuner Audio: L_OUT=(L+R)/2, R_OUT=SAP
 
80
 *           0   0   1  TV Tuner Audio: L_OUT=R_OUT=SAP   (SAP)
 
81
 *           0   1   0  TV Tuner Audio: L_OUT=L, R_OUT=R   (stereo)
 
82
 *           0   1   1  TV Tuner Audio: mute
 
83
 *           1   *   *  TV Tuner Audio: L_OUT=R_OUT=(L+R)/2   (mono)
 
84
 *
 
85
 *   BR* : Audio Sample Rate (BR stands for bitrate for some reason)
 
86
 *          BR0 BR1
 
87
 *           0   0   32 kHz
 
88
 *           0   1   44.1 kHz
 
89
 *           1   0   48 kHz
 
90
 *
 
91
 *   DM* : Detected tuner audio Mode
 
92
 *         Unknown currently
 
93
 *
 
94
 * Special thanks to AVerMedia Technologies, Inc. and Jiun-Kuei Jung at
 
95
 * AVerMedia for providing the GPIO information used to add support
 
96
 * for the M179 cards.
 
97
 */
 
98
 
 
99
/********************* GPIO stuffs *********************/
 
100
 
 
101
/* GPIO registers */
 
102
#define IVTV_REG_GPIO_IN    0x9008
 
103
#define IVTV_REG_GPIO_OUT   0x900c
 
104
#define IVTV_REG_GPIO_DIR   0x9020
 
105
 
 
106
void ivtv_reset_ir_gpio(struct ivtv *itv)
 
107
{
 
108
        int curdir, curout;
 
109
 
 
110
        if (itv->card->type != IVTV_CARD_PVR_150)
 
111
                return;
 
112
        IVTV_DEBUG_INFO("Resetting PVR150 IR\n");
 
113
        curout = read_reg(IVTV_REG_GPIO_OUT);
 
114
        curdir = read_reg(IVTV_REG_GPIO_DIR);
 
115
        curdir |= 0x80;
 
116
        write_reg(curdir, IVTV_REG_GPIO_DIR);
 
117
        curout = (curout & ~0xF) | 1;
 
118
        write_reg(curout, IVTV_REG_GPIO_OUT);
 
119
        /* We could use something else for smaller time */
 
120
        schedule_timeout_interruptible(msecs_to_jiffies(1));
 
121
        curout |= 2;
 
122
        write_reg(curout, IVTV_REG_GPIO_OUT);
 
123
        curdir &= ~0x80;
 
124
        write_reg(curdir, IVTV_REG_GPIO_DIR);
 
125
}
 
126
 
 
127
/* Xceive tuner reset function */
 
128
int ivtv_reset_tuner_gpio(void *dev, int component, int cmd, int value)
 
129
{
 
130
        struct i2c_algo_bit_data *algo = dev;
 
131
        struct ivtv *itv = algo->data;
 
132
        u32 curout;
 
133
 
 
134
        if (cmd != XC2028_TUNER_RESET)
 
135
                return 0;
 
136
        IVTV_DEBUG_INFO("Resetting tuner\n");
 
137
        curout = read_reg(IVTV_REG_GPIO_OUT);
 
138
        curout &= ~(1 << itv->card->xceive_pin);
 
139
        write_reg(curout, IVTV_REG_GPIO_OUT);
 
140
        schedule_timeout_interruptible(msecs_to_jiffies(1));
 
141
 
 
142
        curout |= 1 << itv->card->xceive_pin;
 
143
        write_reg(curout, IVTV_REG_GPIO_OUT);
 
144
        schedule_timeout_interruptible(msecs_to_jiffies(1));
 
145
        return 0;
 
146
}
 
147
 
 
148
static inline struct ivtv *sd_to_ivtv(struct v4l2_subdev *sd)
 
149
{
 
150
        return container_of(sd, struct ivtv, sd_gpio);
 
151
}
 
152
 
 
153
static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
 
154
{
 
155
        return &container_of(ctrl->handler, struct ivtv, hdl_gpio)->sd_gpio;
 
156
}
 
157
 
 
158
static int subdev_s_clock_freq(struct v4l2_subdev *sd, u32 freq)
 
159
{
 
160
        struct ivtv *itv = sd_to_ivtv(sd);
 
161
        u16 mask, data;
 
162
 
 
163
        mask = itv->card->gpio_audio_freq.mask;
 
164
        switch (freq) {
 
165
        case 32000:
 
166
                data = itv->card->gpio_audio_freq.f32000;
 
167
                break;
 
168
        case 44100:
 
169
                data = itv->card->gpio_audio_freq.f44100;
 
170
                break;
 
171
        case 48000:
 
172
        default:
 
173
                data = itv->card->gpio_audio_freq.f48000;
 
174
                break;
 
175
        }
 
176
        if (mask)
 
177
                write_reg((read_reg(IVTV_REG_GPIO_OUT) & ~mask) | (data & mask), IVTV_REG_GPIO_OUT);
 
178
        return 0;
 
179
}
 
180
 
 
181
static int subdev_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
 
182
{
 
183
        struct ivtv *itv = sd_to_ivtv(sd);
 
184
        u16 mask;
 
185
 
 
186
        mask = itv->card->gpio_audio_detect.mask;
 
187
        if (mask == 0 || (read_reg(IVTV_REG_GPIO_IN) & mask))
 
188
                vt->rxsubchans = V4L2_TUNER_SUB_STEREO |
 
189
                        V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
 
190
        else
 
191
                vt->rxsubchans = V4L2_TUNER_SUB_MONO;
 
192
        return 0;
 
193
}
 
194
 
 
195
static int subdev_s_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
 
196
{
 
197
        struct ivtv *itv = sd_to_ivtv(sd);
 
198
        u16 mask, data;
 
199
 
 
200
        mask = itv->card->gpio_audio_mode.mask;
 
201
        switch (vt->audmode) {
 
202
        case V4L2_TUNER_MODE_LANG1:
 
203
                data = itv->card->gpio_audio_mode.lang1;
 
204
                break;
 
205
        case V4L2_TUNER_MODE_LANG2:
 
206
                data = itv->card->gpio_audio_mode.lang2;
 
207
                break;
 
208
        case V4L2_TUNER_MODE_MONO:
 
209
                data = itv->card->gpio_audio_mode.mono;
 
210
                break;
 
211
        case V4L2_TUNER_MODE_STEREO:
 
212
        case V4L2_TUNER_MODE_LANG1_LANG2:
 
213
        default:
 
214
                data = itv->card->gpio_audio_mode.stereo;
 
215
                break;
 
216
        }
 
217
        if (mask)
 
218
                write_reg((read_reg(IVTV_REG_GPIO_OUT) & ~mask) | (data & mask), IVTV_REG_GPIO_OUT);
 
219
        return 0;
 
220
}
 
221
 
 
222
static int subdev_s_radio(struct v4l2_subdev *sd)
 
223
{
 
224
        struct ivtv *itv = sd_to_ivtv(sd);
 
225
        u16 mask, data;
 
226
 
 
227
        mask = itv->card->gpio_audio_input.mask;
 
228
        data = itv->card->gpio_audio_input.radio;
 
229
        if (mask)
 
230
                write_reg((read_reg(IVTV_REG_GPIO_OUT) & ~mask) | (data & mask), IVTV_REG_GPIO_OUT);
 
231
        return 0;
 
232
}
 
233
 
 
234
static int subdev_s_audio_routing(struct v4l2_subdev *sd,
 
235
                                  u32 input, u32 output, u32 config)
 
236
{
 
237
        struct ivtv *itv = sd_to_ivtv(sd);
 
238
        u16 mask, data;
 
239
 
 
240
        if (input > 2)
 
241
                return -EINVAL;
 
242
        mask = itv->card->gpio_audio_input.mask;
 
243
        switch (input) {
 
244
        case 0:
 
245
                data = itv->card->gpio_audio_input.tuner;
 
246
                break;
 
247
        case 1:
 
248
                data = itv->card->gpio_audio_input.linein;
 
249
                break;
 
250
        case 2:
 
251
        default:
 
252
                data = itv->card->gpio_audio_input.radio;
 
253
                break;
 
254
        }
 
255
        if (mask)
 
256
                write_reg((read_reg(IVTV_REG_GPIO_OUT) & ~mask) | (data & mask), IVTV_REG_GPIO_OUT);
 
257
        return 0;
 
258
}
 
259
 
 
260
static int subdev_s_ctrl(struct v4l2_ctrl *ctrl)
 
261
{
 
262
        struct v4l2_subdev *sd = to_sd(ctrl);
 
263
        struct ivtv *itv = sd_to_ivtv(sd);
 
264
        u16 mask, data;
 
265
 
 
266
        switch (ctrl->id) {
 
267
        case V4L2_CID_AUDIO_MUTE:
 
268
                mask = itv->card->gpio_audio_mute.mask;
 
269
                data = ctrl->val ? itv->card->gpio_audio_mute.mute : 0;
 
270
                if (mask)
 
271
                        write_reg((read_reg(IVTV_REG_GPIO_OUT) & ~mask) |
 
272
                                        (data & mask), IVTV_REG_GPIO_OUT);
 
273
                return 0;
 
274
        }
 
275
        return -EINVAL;
 
276
}
 
277
 
 
278
 
 
279
static int subdev_log_status(struct v4l2_subdev *sd)
 
280
{
 
281
        struct ivtv *itv = sd_to_ivtv(sd);
 
282
 
 
283
        IVTV_INFO("GPIO status: DIR=0x%04x OUT=0x%04x IN=0x%04x\n",
 
284
                        read_reg(IVTV_REG_GPIO_DIR), read_reg(IVTV_REG_GPIO_OUT),
 
285
                        read_reg(IVTV_REG_GPIO_IN));
 
286
        v4l2_ctrl_handler_log_status(&itv->hdl_gpio, sd->name);
 
287
        return 0;
 
288
}
 
289
 
 
290
static int subdev_s_video_routing(struct v4l2_subdev *sd,
 
291
                                  u32 input, u32 output, u32 config)
 
292
{
 
293
        struct ivtv *itv = sd_to_ivtv(sd);
 
294
        u16 mask, data;
 
295
 
 
296
        if (input > 2) /* 0:Tuner 1:Composite 2:S-Video */
 
297
                return -EINVAL;
 
298
        mask = itv->card->gpio_video_input.mask;
 
299
        if (input == 0)
 
300
                data = itv->card->gpio_video_input.tuner;
 
301
        else if (input == 1)
 
302
                data = itv->card->gpio_video_input.composite;
 
303
        else
 
304
                data = itv->card->gpio_video_input.svideo;
 
305
        if (mask)
 
306
                write_reg((read_reg(IVTV_REG_GPIO_OUT) & ~mask) | (data & mask), IVTV_REG_GPIO_OUT);
 
307
        return 0;
 
308
}
 
309
 
 
310
static const struct v4l2_ctrl_ops gpio_ctrl_ops = {
 
311
        .s_ctrl = subdev_s_ctrl,
 
312
};
 
313
 
 
314
static const struct v4l2_subdev_core_ops subdev_core_ops = {
 
315
        .log_status = subdev_log_status,
 
316
        .g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
 
317
        .try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
 
318
        .s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
 
319
        .g_ctrl = v4l2_subdev_g_ctrl,
 
320
        .s_ctrl = v4l2_subdev_s_ctrl,
 
321
        .queryctrl = v4l2_subdev_queryctrl,
 
322
        .querymenu = v4l2_subdev_querymenu,
 
323
};
 
324
 
 
325
static const struct v4l2_subdev_tuner_ops subdev_tuner_ops = {
 
326
        .s_radio = subdev_s_radio,
 
327
        .g_tuner = subdev_g_tuner,
 
328
        .s_tuner = subdev_s_tuner,
 
329
};
 
330
 
 
331
static const struct v4l2_subdev_audio_ops subdev_audio_ops = {
 
332
        .s_clock_freq = subdev_s_clock_freq,
 
333
        .s_routing = subdev_s_audio_routing,
 
334
};
 
335
 
 
336
static const struct v4l2_subdev_video_ops subdev_video_ops = {
 
337
        .s_routing = subdev_s_video_routing,
 
338
};
 
339
 
 
340
static const struct v4l2_subdev_ops subdev_ops = {
 
341
        .core = &subdev_core_ops,
 
342
        .tuner = &subdev_tuner_ops,
 
343
        .audio = &subdev_audio_ops,
 
344
        .video = &subdev_video_ops,
 
345
};
 
346
 
 
347
int ivtv_gpio_init(struct ivtv *itv)
 
348
{
 
349
        u16 pin = 0;
 
350
 
 
351
        if (itv->card->xceive_pin)
 
352
                pin = 1 << itv->card->xceive_pin;
 
353
 
 
354
        if ((itv->card->gpio_init.direction | pin) == 0)
 
355
                return 0;
 
356
 
 
357
        IVTV_DEBUG_INFO("GPIO initial dir: %08x out: %08x\n",
 
358
                   read_reg(IVTV_REG_GPIO_DIR), read_reg(IVTV_REG_GPIO_OUT));
 
359
 
 
360
        /* init output data then direction */
 
361
        write_reg(itv->card->gpio_init.initial_value | pin, IVTV_REG_GPIO_OUT);
 
362
        write_reg(itv->card->gpio_init.direction | pin, IVTV_REG_GPIO_DIR);
 
363
        v4l2_subdev_init(&itv->sd_gpio, &subdev_ops);
 
364
        snprintf(itv->sd_gpio.name, sizeof(itv->sd_gpio.name), "%s-gpio", itv->v4l2_dev.name);
 
365
        itv->sd_gpio.grp_id = IVTV_HW_GPIO;
 
366
        v4l2_ctrl_handler_init(&itv->hdl_gpio, 1);
 
367
        v4l2_ctrl_new_std(&itv->hdl_gpio, &gpio_ctrl_ops,
 
368
                        V4L2_CID_AUDIO_MUTE, 0, 1, 1, 0);
 
369
        if (itv->hdl_gpio.error)
 
370
                return itv->hdl_gpio.error;
 
371
        itv->sd_gpio.ctrl_handler = &itv->hdl_gpio;
 
372
        v4l2_ctrl_handler_setup(&itv->hdl_gpio);
 
373
        return v4l2_device_register_subdev(&itv->v4l2_dev, &itv->sd_gpio);
 
374
}