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