linux/drivers/media/pci/ivtv/ivtv-gpio.c
<<
>>
Prefs
   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
 106void 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 */
 128int 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
 148static inline struct ivtv *sd_to_ivtv(struct v4l2_subdev *sd)
 149{
 150        return container_of(sd, struct ivtv, sd_gpio);
 151}
 152
 153static 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
 158static 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
 181static 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
 195static int subdev_s_tuner(struct v4l2_subdev *sd, const 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
 222static 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
 234static 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
 260static 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
 279static 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
 290static 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
 310static const struct v4l2_ctrl_ops gpio_ctrl_ops = {
 311        .s_ctrl = subdev_s_ctrl,
 312};
 313
 314static 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
 325static 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
 331static 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
 336static const struct v4l2_subdev_video_ops subdev_video_ops = {
 337        .s_routing = subdev_s_video_routing,
 338};
 339
 340static 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
 347int 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}
 375