root/drivers/media/usb/go7007/s2250-board.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. to_state
  2. go7007_usb_vendor_request
  3. write_reg
  4. write_reg_fp
  5. read_reg_fp
  6. write_regs
  7. write_regs_fp
  8. s2250_s_video_routing
  9. s2250_s_std
  10. s2250_s_ctrl
  11. s2250_set_fmt
  12. s2250_s_audio_routing
  13. s2250_log_status
  14. s2250_probe
  15. s2250_remove

   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 
  16 MODULE_DESCRIPTION("Sensoray 2250/2251 i2c v4l2 subdev driver");
  17 MODULE_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 
  35 struct go7007_usb_board {
  36         unsigned int flags;
  37         struct go7007_board_info main_info;
  38 };
  39 
  40 struct 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 
  49 static 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 
  67 static unsigned char vid_regs[] = {
  68         0xF2, 0x0f,
  69         0xAA, 0x00,
  70         0xF8, 0xff,
  71         0x00, 0x00,
  72 };
  73 
  74 static 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 */
 100 static 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 
 111 struct 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 
 125 static 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.*/
 131 static 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 
 151 static 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 
 185 static 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 
 249 static 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 
 290 static 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 
 303 static 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 
 319 static 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 
 344 static 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 
 363 static 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 
 400 static 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 
 424 static 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 
 447 static 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 
 467 static const struct v4l2_ctrl_ops s2250_ctrl_ops = {
 468         .s_ctrl = s2250_s_ctrl,
 469 };
 470 
 471 static const struct v4l2_subdev_core_ops s2250_core_ops = {
 472         .log_status = s2250_log_status,
 473 };
 474 
 475 static const struct v4l2_subdev_audio_ops s2250_audio_ops = {
 476         .s_routing = s2250_s_audio_routing,
 477 };
 478 
 479 static const struct v4l2_subdev_video_ops s2250_video_ops = {
 480         .s_std = s2250_s_std,
 481         .s_routing = s2250_s_video_routing,
 482 };
 483 
 484 static const struct v4l2_subdev_pad_ops s2250_pad_ops = {
 485         .set_fmt = s2250_set_fmt,
 486 };
 487 
 488 static 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 
 497 static 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_device(adapter, TLV320_ADDRESS >> 1);
 509         if (IS_ERR(audio))
 510                 return PTR_ERR(audio);
 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 
 599 fail:
 600         i2c_unregister_device(audio);
 601         v4l2_ctrl_handler_free(&state->hdl);
 602         kfree(state);
 603         return -EIO;
 604 }
 605 
 606 static 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 
 616 static const struct i2c_device_id s2250_id[] = {
 617         { "s2250", 0 },
 618         { }
 619 };
 620 MODULE_DEVICE_TABLE(i2c, s2250_id);
 621 
 622 static 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 
 631 module_i2c_driver(s2250_driver);

/* [<][>][^][v][top][bottom][index][help] */