linux/drivers/media/usb/go7007/s2250-board.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2008 Sensoray Company Inc.
   3 *
   4 * This program is free software; you can redistribute it and/or modify
   5 * it under the terms of the GNU General Public License (Version 2) as
   6 * published by the Free Software Foundation.
   7 *
   8 * This program is distributed in the hope that it will be useful,
   9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11 * GNU General Public License for more details.
  12 */
  13
  14#include <linux/module.h>
  15#include <linux/usb.h>
  16#include <linux/i2c.h>
  17#include <linux/videodev2.h>
  18#include <linux/slab.h>
  19#include <media/v4l2-device.h>
  20#include <media/v4l2-common.h>
  21#include <media/v4l2-subdev.h>
  22#include "go7007-priv.h"
  23
  24MODULE_DESCRIPTION("Sensoray 2250/2251 i2c v4l2 subdev driver");
  25MODULE_LICENSE("GPL v2");
  26
  27/*
  28 * Note: this board has two i2c devices: a vpx3226f and a tlv320aic23b.
  29 * Due to the unusual way these are accessed on this device we do not
  30 * reuse the i2c drivers, but instead they are implemented in this
  31 * driver. It would be nice to improve on this, though.
  32 */
  33
  34#define TLV320_ADDRESS      0x34
  35#define VPX322_ADDR_ANALOGCONTROL1      0x02
  36#define VPX322_ADDR_BRIGHTNESS0         0x0127
  37#define VPX322_ADDR_BRIGHTNESS1         0x0131
  38#define VPX322_ADDR_CONTRAST0           0x0128
  39#define VPX322_ADDR_CONTRAST1           0x0132
  40#define VPX322_ADDR_HUE                 0x00dc
  41#define VPX322_ADDR_SAT                 0x0030
  42
  43struct go7007_usb_board {
  44        unsigned int flags;
  45        struct go7007_board_info main_info;
  46};
  47
  48struct go7007_usb {
  49        struct go7007_usb_board *board;
  50        struct mutex i2c_lock;
  51        struct usb_device *usbdev;
  52        struct urb *video_urbs[8];
  53        struct urb *audio_urbs[8];
  54        struct urb *intr_urb;
  55};
  56
  57static unsigned char aud_regs[] = {
  58        0x1e, 0x00,
  59        0x00, 0x17,
  60        0x02, 0x17,
  61        0x04, 0xf9,
  62        0x06, 0xf9,
  63        0x08, 0x02,
  64        0x0a, 0x00,
  65        0x0c, 0x00,
  66        0x0a, 0x00,
  67        0x0c, 0x00,
  68        0x0e, 0x02,
  69        0x10, 0x00,
  70        0x12, 0x01,
  71        0x00, 0x00,
  72};
  73
  74
  75static unsigned char vid_regs[] = {
  76        0xF2, 0x0f,
  77        0xAA, 0x00,
  78        0xF8, 0xff,
  79        0x00, 0x00,
  80};
  81
  82static u16 vid_regs_fp[] = {
  83        0x028, 0x067,
  84        0x120, 0x016,
  85        0x121, 0xcF2,
  86        0x122, 0x0F2,
  87        0x123, 0x00c,
  88        0x124, 0x2d0,
  89        0x125, 0x2e0,
  90        0x126, 0x004,
  91        0x128, 0x1E0,
  92        0x12A, 0x016,
  93        0x12B, 0x0F2,
  94        0x12C, 0x0F2,
  95        0x12D, 0x00c,
  96        0x12E, 0x2d0,
  97        0x12F, 0x2e0,
  98        0x130, 0x004,
  99        0x132, 0x1E0,
 100        0x140, 0x060,
 101        0x153, 0x00C,
 102        0x154, 0x200,
 103        0x150, 0x801,
 104        0x000, 0x000
 105};
 106
 107/* PAL specific values */
 108static u16 vid_regs_fp_pal[] = {
 109        0x120, 0x017,
 110        0x121, 0xd22,
 111        0x122, 0x122,
 112        0x12A, 0x017,
 113        0x12B, 0x122,
 114        0x12C, 0x122,
 115        0x140, 0x060,
 116        0x000, 0x000,
 117};
 118
 119struct s2250 {
 120        struct v4l2_subdev sd;
 121        struct v4l2_ctrl_handler hdl;
 122        v4l2_std_id std;
 123        int input;
 124        int brightness;
 125        int contrast;
 126        int saturation;
 127        int hue;
 128        int reg12b_val;
 129        int audio_input;
 130        struct i2c_client *audio;
 131};
 132
 133static inline struct s2250 *to_state(struct v4l2_subdev *sd)
 134{
 135        return container_of(sd, struct s2250, sd);
 136}
 137
 138/* from go7007-usb.c which is Copyright (C) 2005-2006 Micronas USA Inc.*/
 139static int go7007_usb_vendor_request(struct go7007 *go, u16 request,
 140        u16 value, u16 index, void *transfer_buffer, int length, int in)
 141{
 142        struct go7007_usb *usb = go->hpi_context;
 143        int timeout = 5000;
 144
 145        if (in) {
 146                return usb_control_msg(usb->usbdev,
 147                                usb_rcvctrlpipe(usb->usbdev, 0), request,
 148                                USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
 149                                value, index, transfer_buffer, length, timeout);
 150        } else {
 151                return usb_control_msg(usb->usbdev,
 152                                usb_sndctrlpipe(usb->usbdev, 0), request,
 153                                USB_TYPE_VENDOR | USB_RECIP_DEVICE,
 154                                value, index, transfer_buffer, length, timeout);
 155        }
 156}
 157/* end from go7007-usb.c which is Copyright (C) 2005-2006 Micronas USA Inc.*/
 158
 159static int write_reg(struct i2c_client *client, u8 reg, u8 value)
 160{
 161        struct go7007 *go = i2c_get_adapdata(client->adapter);
 162        struct go7007_usb *usb;
 163        int rc;
 164        int dev_addr = client->addr << 1;  /* firmware wants 8-bit address */
 165        u8 *buf;
 166
 167        if (go == NULL)
 168                return -ENODEV;
 169
 170        if (go->status == STATUS_SHUTDOWN)
 171                return -EBUSY;
 172
 173        buf = kzalloc(16, GFP_KERNEL);
 174        if (buf == NULL)
 175                return -ENOMEM;
 176
 177        usb = go->hpi_context;
 178        if (mutex_lock_interruptible(&usb->i2c_lock) != 0) {
 179                dev_info(&client->dev, "i2c lock failed\n");
 180                kfree(buf);
 181                return -EINTR;
 182        }
 183        rc = go7007_usb_vendor_request(go, 0x55, dev_addr,
 184                                       (reg<<8 | value),
 185                                       buf,
 186                                       16, 1);
 187
 188        mutex_unlock(&usb->i2c_lock);
 189        kfree(buf);
 190        return rc;
 191}
 192
 193static int write_reg_fp(struct i2c_client *client, u16 addr, u16 val)
 194{
 195        struct go7007 *go = i2c_get_adapdata(client->adapter);
 196        struct go7007_usb *usb;
 197        int rc;
 198        u8 *buf;
 199        struct s2250 *dec = i2c_get_clientdata(client);
 200
 201        if (go == NULL)
 202                return -ENODEV;
 203
 204        if (go->status == STATUS_SHUTDOWN)
 205                return -EBUSY;
 206
 207        buf = kzalloc(16, GFP_KERNEL);
 208
 209        if (buf == NULL)
 210                return -ENOMEM;
 211
 212
 213
 214        memset(buf, 0xcd, 6);
 215
 216        usb = go->hpi_context;
 217        if (mutex_lock_interruptible(&usb->i2c_lock) != 0) {
 218                dev_info(&client->dev, "i2c lock failed\n");
 219                kfree(buf);
 220                return -EINTR;
 221        }
 222        rc = go7007_usb_vendor_request(go, 0x57, addr, val, buf, 16, 1);
 223        mutex_unlock(&usb->i2c_lock);
 224        if (rc < 0) {
 225                kfree(buf);
 226                return rc;
 227        }
 228
 229        if (buf[0] == 0) {
 230                unsigned int subaddr, val_read;
 231
 232                subaddr = (buf[4] << 8) + buf[5];
 233                val_read = (buf[2] << 8) + buf[3];
 234                kfree(buf);
 235                if (val_read != val) {
 236                        dev_info(&client->dev, "invalid fp write %x %x\n",
 237                                 val_read, val);
 238                        return -EFAULT;
 239                }
 240                if (subaddr != addr) {
 241                        dev_info(&client->dev, "invalid fp write addr %x %x\n",
 242                                 subaddr, addr);
 243                        return -EFAULT;
 244                }
 245        } else {
 246                kfree(buf);
 247                return -EFAULT;
 248        }
 249
 250        /* save last 12b value */
 251        if (addr == 0x12b)
 252                dec->reg12b_val = val;
 253
 254        return 0;
 255}
 256
 257static int read_reg_fp(struct i2c_client *client, u16 addr, u16 *val)
 258{
 259        struct go7007 *go = i2c_get_adapdata(client->adapter);
 260        struct go7007_usb *usb;
 261        int rc;
 262        u8 *buf;
 263
 264        if (go == NULL)
 265                return -ENODEV;
 266
 267        if (go->status == STATUS_SHUTDOWN)
 268                return -EBUSY;
 269
 270        buf = kzalloc(16, GFP_KERNEL);
 271
 272        if (buf == NULL)
 273                return -ENOMEM;
 274
 275
 276
 277        memset(buf, 0xcd, 6);
 278        usb = go->hpi_context;
 279        if (mutex_lock_interruptible(&usb->i2c_lock) != 0) {
 280                dev_info(&client->dev, "i2c lock failed\n");
 281                kfree(buf);
 282                return -EINTR;
 283        }
 284        rc = go7007_usb_vendor_request(go, 0x58, addr, 0, buf, 16, 1);
 285        mutex_unlock(&usb->i2c_lock);
 286        if (rc < 0) {
 287                kfree(buf);
 288                return rc;
 289        }
 290
 291        *val = (buf[0] << 8) | buf[1];
 292        kfree(buf);
 293
 294        return 0;
 295}
 296
 297
 298static int write_regs(struct i2c_client *client, u8 *regs)
 299{
 300        int i;
 301
 302        for (i = 0; !((regs[i] == 0x00) && (regs[i+1] == 0x00)); i += 2) {
 303                if (write_reg(client, regs[i], regs[i+1]) < 0) {
 304                        dev_info(&client->dev, "failed\n");
 305                        return -1;
 306                }
 307        }
 308        return 0;
 309}
 310
 311static int write_regs_fp(struct i2c_client *client, u16 *regs)
 312{
 313        int i;
 314
 315        for (i = 0; !((regs[i] == 0x00) && (regs[i+1] == 0x00)); i += 2) {
 316                if (write_reg_fp(client, regs[i], regs[i+1]) < 0) {
 317                        dev_info(&client->dev, "failed fp\n");
 318                        return -1;
 319                }
 320        }
 321        return 0;
 322}
 323
 324
 325/* ------------------------------------------------------------------------- */
 326
 327static int s2250_s_video_routing(struct v4l2_subdev *sd, u32 input, u32 output,
 328                                 u32 config)
 329{
 330        struct s2250 *state = to_state(sd);
 331        struct i2c_client *client = v4l2_get_subdevdata(sd);
 332        int vidsys;
 333
 334        vidsys = (state->std == V4L2_STD_NTSC) ? 0x01 : 0x00;
 335        if (input == 0) {
 336                /* composite */
 337                write_reg_fp(client, 0x20, 0x020 | vidsys);
 338                write_reg_fp(client, 0x21, 0x662);
 339                write_reg_fp(client, 0x140, 0x060);
 340        } else if (input == 1) {
 341                /* S-Video */
 342                write_reg_fp(client, 0x20, 0x040 | vidsys);
 343                write_reg_fp(client, 0x21, 0x666);
 344                write_reg_fp(client, 0x140, 0x060);
 345        } else {
 346                return -EINVAL;
 347        }
 348        state->input = input;
 349        return 0;
 350}
 351
 352static int s2250_s_std(struct v4l2_subdev *sd, v4l2_std_id norm)
 353{
 354        struct s2250 *state = to_state(sd);
 355        struct i2c_client *client = v4l2_get_subdevdata(sd);
 356        u16 vidsource;
 357
 358        vidsource = (state->input == 1) ? 0x040 : 0x020;
 359        if (norm & V4L2_STD_625_50) {
 360                write_regs_fp(client, vid_regs_fp);
 361                write_regs_fp(client, vid_regs_fp_pal);
 362                write_reg_fp(client, 0x20, vidsource);
 363        } else {
 364                write_regs_fp(client, vid_regs_fp);
 365                write_reg_fp(client, 0x20, vidsource | 1);
 366        }
 367        state->std = norm;
 368        return 0;
 369}
 370
 371static int s2250_s_ctrl(struct v4l2_ctrl *ctrl)
 372{
 373        struct s2250 *state = container_of(ctrl->handler, struct s2250, hdl);
 374        struct i2c_client *client = v4l2_get_subdevdata(&state->sd);
 375        u16 oldvalue;
 376
 377        switch (ctrl->id) {
 378        case V4L2_CID_BRIGHTNESS:
 379                read_reg_fp(client, VPX322_ADDR_BRIGHTNESS0, &oldvalue);
 380                write_reg_fp(client, VPX322_ADDR_BRIGHTNESS0,
 381                             ctrl->val | (oldvalue & ~0xff));
 382                read_reg_fp(client, VPX322_ADDR_BRIGHTNESS1, &oldvalue);
 383                write_reg_fp(client, VPX322_ADDR_BRIGHTNESS1,
 384                             ctrl->val | (oldvalue & ~0xff));
 385                write_reg_fp(client, 0x140, 0x60);
 386                break;
 387        case V4L2_CID_CONTRAST:
 388                read_reg_fp(client, VPX322_ADDR_CONTRAST0, &oldvalue);
 389                write_reg_fp(client, VPX322_ADDR_CONTRAST0,
 390                             ctrl->val | (oldvalue & ~0x3f));
 391                read_reg_fp(client, VPX322_ADDR_CONTRAST1, &oldvalue);
 392                write_reg_fp(client, VPX322_ADDR_CONTRAST1,
 393                             ctrl->val | (oldvalue & ~0x3f));
 394                write_reg_fp(client, 0x140, 0x60);
 395                break;
 396        case V4L2_CID_SATURATION:
 397                write_reg_fp(client, VPX322_ADDR_SAT, ctrl->val);
 398                break;
 399        case V4L2_CID_HUE:
 400                write_reg_fp(client, VPX322_ADDR_HUE, ctrl->val);
 401                break;
 402        default:
 403                return -EINVAL;
 404        }
 405        return 0;
 406}
 407
 408static int s2250_set_fmt(struct v4l2_subdev *sd,
 409                struct v4l2_subdev_pad_config *cfg,
 410                struct v4l2_subdev_format *format)
 411{
 412        struct v4l2_mbus_framefmt *fmt = &format->format;
 413        struct s2250 *state = to_state(sd);
 414        struct i2c_client *client = v4l2_get_subdevdata(sd);
 415
 416        if (format->pad)
 417                return -EINVAL;
 418
 419        if (format->which == V4L2_SUBDEV_FORMAT_TRY)
 420                return 0;
 421
 422        if (fmt->height < 640) {
 423                write_reg_fp(client, 0x12b, state->reg12b_val | 0x400);
 424                write_reg_fp(client, 0x140, 0x060);
 425        } else {
 426                write_reg_fp(client, 0x12b, state->reg12b_val & ~0x400);
 427                write_reg_fp(client, 0x140, 0x060);
 428        }
 429        return 0;
 430}
 431
 432static int s2250_s_audio_routing(struct v4l2_subdev *sd, u32 input, u32 output,
 433                                 u32 config)
 434{
 435        struct s2250 *state = to_state(sd);
 436
 437        switch (input) {
 438        case 0:
 439                write_reg(state->audio, 0x08, 0x02); /* Line In */
 440                break;
 441        case 1:
 442                write_reg(state->audio, 0x08, 0x04); /* Mic */
 443                break;
 444        case 2:
 445                write_reg(state->audio, 0x08, 0x05); /* Mic Boost */
 446                break;
 447        default:
 448                return -EINVAL;
 449        }
 450        state->audio_input = input;
 451        return 0;
 452}
 453
 454
 455static int s2250_log_status(struct v4l2_subdev *sd)
 456{
 457        struct s2250 *state = to_state(sd);
 458
 459        v4l2_info(sd, "Standard: %s\n", state->std == V4L2_STD_NTSC ? "NTSC" :
 460                                        state->std == V4L2_STD_PAL ? "PAL" :
 461                                        state->std == V4L2_STD_SECAM ? "SECAM" :
 462                                        "unknown");
 463        v4l2_info(sd, "Input: %s\n", state->input == 0 ? "Composite" :
 464                                        state->input == 1 ? "S-video" :
 465                                        "error");
 466        v4l2_info(sd, "Audio input: %s\n", state->audio_input == 0 ? "Line In" :
 467                                        state->audio_input == 1 ? "Mic" :
 468                                        state->audio_input == 2 ? "Mic Boost" :
 469                                        "error");
 470        return v4l2_ctrl_subdev_log_status(sd);
 471}
 472
 473/* --------------------------------------------------------------------------*/
 474
 475static const struct v4l2_ctrl_ops s2250_ctrl_ops = {
 476        .s_ctrl = s2250_s_ctrl,
 477};
 478
 479static const struct v4l2_subdev_core_ops s2250_core_ops = {
 480        .log_status = s2250_log_status,
 481};
 482
 483static const struct v4l2_subdev_audio_ops s2250_audio_ops = {
 484        .s_routing = s2250_s_audio_routing,
 485};
 486
 487static const struct v4l2_subdev_video_ops s2250_video_ops = {
 488        .s_std = s2250_s_std,
 489        .s_routing = s2250_s_video_routing,
 490};
 491
 492static const struct v4l2_subdev_pad_ops s2250_pad_ops = {
 493        .set_fmt = s2250_set_fmt,
 494};
 495
 496static const struct v4l2_subdev_ops s2250_ops = {
 497        .core = &s2250_core_ops,
 498        .audio = &s2250_audio_ops,
 499        .video = &s2250_video_ops,
 500        .pad = &s2250_pad_ops,
 501};
 502
 503/* --------------------------------------------------------------------------*/
 504
 505static int s2250_probe(struct i2c_client *client,
 506                       const struct i2c_device_id *id)
 507{
 508        struct i2c_client *audio;
 509        struct i2c_adapter *adapter = client->adapter;
 510        struct s2250 *state;
 511        struct v4l2_subdev *sd;
 512        u8 *data;
 513        struct go7007 *go = i2c_get_adapdata(adapter);
 514        struct go7007_usb *usb = go->hpi_context;
 515
 516        audio = i2c_new_dummy(adapter, TLV320_ADDRESS >> 1);
 517        if (audio == NULL)
 518                return -ENOMEM;
 519
 520        state = kzalloc(sizeof(struct s2250), GFP_KERNEL);
 521        if (state == NULL) {
 522                i2c_unregister_device(audio);
 523                return -ENOMEM;
 524        }
 525
 526        sd = &state->sd;
 527        v4l2_i2c_subdev_init(sd, client, &s2250_ops);
 528
 529        v4l2_info(sd, "initializing %s at address 0x%x on %s\n",
 530               "Sensoray 2250/2251", client->addr, client->adapter->name);
 531
 532        v4l2_ctrl_handler_init(&state->hdl, 4);
 533        v4l2_ctrl_new_std(&state->hdl, &s2250_ctrl_ops,
 534                V4L2_CID_BRIGHTNESS, -128, 127, 1, 0);
 535        v4l2_ctrl_new_std(&state->hdl, &s2250_ctrl_ops,
 536                V4L2_CID_CONTRAST, 0, 0x3f, 1, 0x32);
 537        v4l2_ctrl_new_std(&state->hdl, &s2250_ctrl_ops,
 538                V4L2_CID_SATURATION, 0, 4094, 1, 2070);
 539        v4l2_ctrl_new_std(&state->hdl, &s2250_ctrl_ops,
 540                V4L2_CID_HUE, -512, 511, 1, 0);
 541        sd->ctrl_handler = &state->hdl;
 542        if (state->hdl.error) {
 543                int err = state->hdl.error;
 544
 545                v4l2_ctrl_handler_free(&state->hdl);
 546                kfree(state);
 547                return err;
 548        }
 549
 550        state->std = V4L2_STD_NTSC;
 551        state->brightness = 50;
 552        state->contrast = 50;
 553        state->saturation = 50;
 554        state->hue = 0;
 555        state->audio = audio;
 556
 557        /* initialize the audio */
 558        if (write_regs(audio, aud_regs) < 0) {
 559                dev_err(&client->dev, "error initializing audio\n");
 560                goto fail;
 561        }
 562
 563        if (write_regs(client, vid_regs) < 0) {
 564                dev_err(&client->dev, "error initializing decoder\n");
 565                goto fail;
 566        }
 567        if (write_regs_fp(client, vid_regs_fp) < 0) {
 568                dev_err(&client->dev, "error initializing decoder\n");
 569                goto fail;
 570        }
 571        /* set default channel */
 572        /* composite */
 573        write_reg_fp(client, 0x20, 0x020 | 1);
 574        write_reg_fp(client, 0x21, 0x662);
 575        write_reg_fp(client, 0x140, 0x060);
 576
 577        /* set default audio input */
 578        state->audio_input = 0;
 579        write_reg(client, 0x08, 0x02); /* Line In */
 580
 581        if (mutex_lock_interruptible(&usb->i2c_lock) == 0) {
 582                data = kzalloc(16, GFP_KERNEL);
 583                if (data != NULL) {
 584                        int rc = go7007_usb_vendor_request(go, 0x41, 0, 0,
 585                                                       data, 16, 1);
 586
 587                        if (rc > 0) {
 588                                u8 mask;
 589
 590                                data[0] = 0;
 591                                mask = 1<<5;
 592                                data[0] &= ~mask;
 593                                data[1] |= mask;
 594                                go7007_usb_vendor_request(go, 0x40, 0,
 595                                                          (data[1]<<8)
 596                                                          + data[1],
 597                                                          data, 16, 0);
 598                        }
 599                        kfree(data);
 600                }
 601                mutex_unlock(&usb->i2c_lock);
 602        }
 603
 604        v4l2_info(sd, "initialized successfully\n");
 605        return 0;
 606
 607fail:
 608        i2c_unregister_device(audio);
 609        v4l2_ctrl_handler_free(&state->hdl);
 610        kfree(state);
 611        return -EIO;
 612}
 613
 614static int s2250_remove(struct i2c_client *client)
 615{
 616        struct s2250 *state = to_state(i2c_get_clientdata(client));
 617
 618        v4l2_device_unregister_subdev(&state->sd);
 619        v4l2_ctrl_handler_free(&state->hdl);
 620        kfree(state);
 621        return 0;
 622}
 623
 624static const struct i2c_device_id s2250_id[] = {
 625        { "s2250", 0 },
 626        { }
 627};
 628MODULE_DEVICE_TABLE(i2c, s2250_id);
 629
 630static struct i2c_driver s2250_driver = {
 631        .driver = {
 632                .name   = "s2250",
 633        },
 634        .probe          = s2250_probe,
 635        .remove         = s2250_remove,
 636        .id_table       = s2250_id,
 637};
 638
 639module_i2c_driver(s2250_driver);
 640