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_s_mbus_fmt(struct v4l2_subdev *sd,
 409                        struct v4l2_mbus_framefmt *fmt)
 410{
 411        struct s2250 *state = to_state(sd);
 412        struct i2c_client *client = v4l2_get_subdevdata(sd);
 413
 414        if (fmt->height < 640) {
 415                write_reg_fp(client, 0x12b, state->reg12b_val | 0x400);
 416                write_reg_fp(client, 0x140, 0x060);
 417        } else {
 418                write_reg_fp(client, 0x12b, state->reg12b_val & ~0x400);
 419                write_reg_fp(client, 0x140, 0x060);
 420        }
 421        return 0;
 422}
 423
 424static int s2250_s_audio_routing(struct v4l2_subdev *sd, u32 input, u32 output,
 425                                 u32 config)
 426{
 427        struct s2250 *state = to_state(sd);
 428
 429        switch (input) {
 430        case 0:
 431                write_reg(state->audio, 0x08, 0x02); /* Line In */
 432                break;
 433        case 1:
 434                write_reg(state->audio, 0x08, 0x04); /* Mic */
 435                break;
 436        case 2:
 437                write_reg(state->audio, 0x08, 0x05); /* Mic Boost */
 438                break;
 439        default:
 440                return -EINVAL;
 441        }
 442        state->audio_input = input;
 443        return 0;
 444}
 445
 446
 447static int s2250_log_status(struct v4l2_subdev *sd)
 448{
 449        struct s2250 *state = to_state(sd);
 450
 451        v4l2_info(sd, "Standard: %s\n", state->std == V4L2_STD_NTSC ? "NTSC" :
 452                                        state->std == V4L2_STD_PAL ? "PAL" :
 453                                        state->std == V4L2_STD_SECAM ? "SECAM" :
 454                                        "unknown");
 455        v4l2_info(sd, "Input: %s\n", state->input == 0 ? "Composite" :
 456                                        state->input == 1 ? "S-video" :
 457                                        "error");
 458        v4l2_info(sd, "Audio input: %s\n", state->audio_input == 0 ? "Line In" :
 459                                        state->audio_input == 1 ? "Mic" :
 460                                        state->audio_input == 2 ? "Mic Boost" :
 461                                        "error");
 462        return v4l2_ctrl_subdev_log_status(sd);
 463}
 464
 465/* --------------------------------------------------------------------------*/
 466
 467static const struct v4l2_ctrl_ops s2250_ctrl_ops = {
 468        .s_ctrl = s2250_s_ctrl,
 469};
 470
 471static const struct v4l2_subdev_core_ops s2250_core_ops = {
 472        .log_status = s2250_log_status,
 473};
 474
 475static const struct v4l2_subdev_audio_ops s2250_audio_ops = {
 476        .s_routing = s2250_s_audio_routing,
 477};
 478
 479static const struct v4l2_subdev_video_ops s2250_video_ops = {
 480        .s_std = s2250_s_std,
 481        .s_routing = s2250_s_video_routing,
 482        .s_mbus_fmt = s2250_s_mbus_fmt,
 483};
 484
 485static const struct v4l2_subdev_ops s2250_ops = {
 486        .core = &s2250_core_ops,
 487        .audio = &s2250_audio_ops,
 488        .video = &s2250_video_ops,
 489};
 490
 491/* --------------------------------------------------------------------------*/
 492
 493static int s2250_probe(struct i2c_client *client,
 494                       const struct i2c_device_id *id)
 495{
 496        struct i2c_client *audio;
 497        struct i2c_adapter *adapter = client->adapter;
 498        struct s2250 *state;
 499        struct v4l2_subdev *sd;
 500        u8 *data;
 501        struct go7007 *go = i2c_get_adapdata(adapter);
 502        struct go7007_usb *usb = go->hpi_context;
 503
 504        audio = i2c_new_dummy(adapter, TLV320_ADDRESS >> 1);
 505        if (audio == NULL)
 506                return -ENOMEM;
 507
 508        state = kzalloc(sizeof(struct s2250), GFP_KERNEL);
 509        if (state == NULL) {
 510                i2c_unregister_device(audio);
 511                return -ENOMEM;
 512        }
 513
 514        sd = &state->sd;
 515        v4l2_i2c_subdev_init(sd, client, &s2250_ops);
 516
 517        v4l2_info(sd, "initializing %s at address 0x%x on %s\n",
 518               "Sensoray 2250/2251", client->addr, client->adapter->name);
 519
 520        v4l2_ctrl_handler_init(&state->hdl, 4);
 521        v4l2_ctrl_new_std(&state->hdl, &s2250_ctrl_ops,
 522                V4L2_CID_BRIGHTNESS, -128, 127, 1, 0);
 523        v4l2_ctrl_new_std(&state->hdl, &s2250_ctrl_ops,
 524                V4L2_CID_CONTRAST, 0, 0x3f, 1, 0x32);
 525        v4l2_ctrl_new_std(&state->hdl, &s2250_ctrl_ops,
 526                V4L2_CID_SATURATION, 0, 4094, 1, 2070);
 527        v4l2_ctrl_new_std(&state->hdl, &s2250_ctrl_ops,
 528                V4L2_CID_HUE, -512, 511, 1, 0);
 529        sd->ctrl_handler = &state->hdl;
 530        if (state->hdl.error) {
 531                int err = state->hdl.error;
 532
 533                v4l2_ctrl_handler_free(&state->hdl);
 534                kfree(state);
 535                return err;
 536        }
 537
 538        state->std = V4L2_STD_NTSC;
 539        state->brightness = 50;
 540        state->contrast = 50;
 541        state->saturation = 50;
 542        state->hue = 0;
 543        state->audio = audio;
 544
 545        /* initialize the audio */
 546        if (write_regs(audio, aud_regs) < 0) {
 547                dev_err(&client->dev, "error initializing audio\n");
 548                goto fail;
 549        }
 550
 551        if (write_regs(client, vid_regs) < 0) {
 552                dev_err(&client->dev, "error initializing decoder\n");
 553                goto fail;
 554        }
 555        if (write_regs_fp(client, vid_regs_fp) < 0) {
 556                dev_err(&client->dev, "error initializing decoder\n");
 557                goto fail;
 558        }
 559        /* set default channel */
 560        /* composite */
 561        write_reg_fp(client, 0x20, 0x020 | 1);
 562        write_reg_fp(client, 0x21, 0x662);
 563        write_reg_fp(client, 0x140, 0x060);
 564
 565        /* set default audio input */
 566        state->audio_input = 0;
 567        write_reg(client, 0x08, 0x02); /* Line In */
 568
 569        if (mutex_lock_interruptible(&usb->i2c_lock) == 0) {
 570                data = kzalloc(16, GFP_KERNEL);
 571                if (data != NULL) {
 572                        int rc = go7007_usb_vendor_request(go, 0x41, 0, 0,
 573                                                       data, 16, 1);
 574
 575                        if (rc > 0) {
 576                                u8 mask;
 577
 578                                data[0] = 0;
 579                                mask = 1<<5;
 580                                data[0] &= ~mask;
 581                                data[1] |= mask;
 582                                go7007_usb_vendor_request(go, 0x40, 0,
 583                                                          (data[1]<<8)
 584                                                          + data[1],
 585                                                          data, 16, 0);
 586                        }
 587                        kfree(data);
 588                }
 589                mutex_unlock(&usb->i2c_lock);
 590        }
 591
 592        v4l2_info(sd, "initialized successfully\n");
 593        return 0;
 594
 595fail:
 596        i2c_unregister_device(audio);
 597        v4l2_ctrl_handler_free(&state->hdl);
 598        kfree(state);
 599        return -EIO;
 600}
 601
 602static int s2250_remove(struct i2c_client *client)
 603{
 604        struct s2250 *state = to_state(i2c_get_clientdata(client));
 605
 606        v4l2_device_unregister_subdev(&state->sd);
 607        v4l2_ctrl_handler_free(&state->hdl);
 608        kfree(state);
 609        return 0;
 610}
 611
 612static const struct i2c_device_id s2250_id[] = {
 613        { "s2250", 0 },
 614        { }
 615};
 616MODULE_DEVICE_TABLE(i2c, s2250_id);
 617
 618static struct i2c_driver s2250_driver = {
 619        .driver = {
 620                .owner  = THIS_MODULE,
 621                .name   = "s2250",
 622        },
 623        .probe          = s2250_probe,
 624        .remove         = s2250_remove,
 625        .id_table       = s2250_id,
 626};
 627
 628module_i2c_driver(s2250_driver);
 629