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