2 * Copyright (C) 2008 Sensoray Company Inc.
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.
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.
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.
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-i2c-drv.h>
27 #include <media/v4l2-subdev.h>
28 #include "go7007-priv.h"
30 MODULE_DESCRIPTION("Sensoray 2250/2251 i2c v4l2 subdev driver");
31 MODULE_LICENSE("GPL v2");
33 #define TLV320_ADDRESS 0x34
34 #define VPX322_ADDR_ANALOGCONTROL1 0x02
35 #define VPX322_ADDR_BRIGHTNESS0 0x0127
36 #define VPX322_ADDR_BRIGHTNESS1 0x0131
37 #define VPX322_ADDR_CONTRAST0 0x0128
38 #define VPX322_ADDR_CONTRAST1 0x0132
39 #define VPX322_ADDR_HUE 0x00dc
40 #define VPX322_ADDR_SAT 0x0030
42 struct go7007_usb_board
{
44 struct go7007_board_info main_info
;
48 struct go7007_usb_board
*board
;
49 struct mutex i2c_lock
;
50 struct usb_device
*usbdev
;
51 struct urb
*video_urbs
[8];
52 struct urb
*audio_urbs
[8];
56 static unsigned char aud_regs
[] = {
74 static unsigned char vid_regs
[] = {
81 static u16 vid_regs_fp
[] = {
106 /* PAL specific values */
107 static u16 vid_regs_fp_pal
[] =
120 struct v4l2_subdev sd
;
129 struct i2c_client
*audio
;
132 static inline struct s2250
*to_state(struct v4l2_subdev
*sd
)
134 return container_of(sd
, struct s2250
, sd
);
137 /* from go7007-usb.c which is Copyright (C) 2005-2006 Micronas USA Inc.*/
138 static int go7007_usb_vendor_request(struct go7007
*go
, u16 request
,
139 u16 value
, u16 index
, void *transfer_buffer
, int length
, int in
)
141 struct go7007_usb
*usb
= go
->hpi_context
;
145 return usb_control_msg(usb
->usbdev
,
146 usb_rcvctrlpipe(usb
->usbdev
, 0), request
,
147 USB_TYPE_VENDOR
| USB_RECIP_DEVICE
| USB_DIR_IN
,
148 value
, index
, transfer_buffer
, length
, timeout
);
150 return usb_control_msg(usb
->usbdev
,
151 usb_sndctrlpipe(usb
->usbdev
, 0), request
,
152 USB_TYPE_VENDOR
| USB_RECIP_DEVICE
,
153 value
, index
, transfer_buffer
, length
, timeout
);
156 /* end from go7007-usb.c which is Copyright (C) 2005-2006 Micronas USA Inc.*/
158 static int write_reg(struct i2c_client
*client
, u8 reg
, u8 value
)
160 struct go7007
*go
= i2c_get_adapdata(client
->adapter
);
161 struct go7007_usb
*usb
;
163 int dev_addr
= client
->addr
<< 1; /* firmware wants 8-bit address */
169 if (go
->status
== STATUS_SHUTDOWN
)
172 buf
= kzalloc(16, GFP_KERNEL
);
176 usb
= go
->hpi_context
;
177 if (mutex_lock_interruptible(&usb
->i2c_lock
) != 0) {
178 printk(KERN_INFO
"i2c lock failed\n");
182 rc
= go7007_usb_vendor_request(go
, 0x55, dev_addr
,
187 mutex_unlock(&usb
->i2c_lock
);
192 static int write_reg_fp(struct i2c_client
*client
, u16 addr
, u16 val
)
194 struct go7007
*go
= i2c_get_adapdata(client
->adapter
);
195 struct go7007_usb
*usb
;
197 struct s2250
*dec
= i2c_get_clientdata(client
);
202 if (go
->status
== STATUS_SHUTDOWN
)
205 buf
= kzalloc(16, GFP_KERNEL
);
212 memset(buf
, 0xcd, 6);
214 usb
= go
->hpi_context
;
215 if (mutex_lock_interruptible(&usb
->i2c_lock
) != 0) {
216 printk(KERN_INFO
"i2c lock failed\n");
220 if (go7007_usb_vendor_request(go
, 0x57, addr
, val
, buf
, 16, 1) < 0) {
225 mutex_unlock(&usb
->i2c_lock
);
227 unsigned int subaddr
, val_read
;
229 subaddr
= (buf
[4] << 8) + buf
[5];
230 val_read
= (buf
[2] << 8) + buf
[3];
232 if (val_read
!= val
) {
233 printk(KERN_INFO
"invalid fp write %x %x\n",
237 if (subaddr
!= addr
) {
238 printk(KERN_INFO
"invalid fp write addr %x %x\n",
247 /* save last 12b value */
249 dec
->reg12b_val
= val
;
254 static int read_reg_fp(struct i2c_client
*client
, u16 addr
, u16
*val
)
256 struct go7007
*go
= i2c_get_adapdata(client
->adapter
);
257 struct go7007_usb
*usb
;
263 if (go
->status
== STATUS_SHUTDOWN
)
266 buf
= kzalloc(16, GFP_KERNEL
);
273 memset(buf
, 0xcd, 6);
274 usb
= go
->hpi_context
;
275 if (mutex_lock_interruptible(&usb
->i2c_lock
) != 0) {
276 printk(KERN_INFO
"i2c lock failed\n");
280 if (go7007_usb_vendor_request(go
, 0x58, addr
, 0, buf
, 16, 1) < 0) {
284 mutex_unlock(&usb
->i2c_lock
);
286 *val
= (buf
[0] << 8) | buf
[1];
293 static int write_regs(struct i2c_client
*client
, u8
*regs
)
297 for (i
= 0; !((regs
[i
] == 0x00) && (regs
[i
+1] == 0x00)); i
+= 2) {
298 if (write_reg(client
, regs
[i
], regs
[i
+1]) < 0) {
299 printk(KERN_INFO
"s2250: failed\n");
306 static int write_regs_fp(struct i2c_client
*client
, u16
*regs
)
310 for (i
= 0; !((regs
[i
] == 0x00) && (regs
[i
+1] == 0x00)); i
+= 2) {
311 if (write_reg_fp(client
, regs
[i
], regs
[i
+1]) < 0) {
312 printk(KERN_INFO
"s2250: failed fp\n");
320 /* ------------------------------------------------------------------------- */
322 static int s2250_s_video_routing(struct v4l2_subdev
*sd
, u32 input
, u32 output
,
325 struct s2250
*state
= to_state(sd
);
326 struct i2c_client
*client
= v4l2_get_subdevdata(sd
);
329 vidsys
= (state
->std
== V4L2_STD_NTSC
) ? 0x01 : 0x00;
332 write_reg_fp(client
, 0x20, 0x020 | vidsys
);
333 write_reg_fp(client
, 0x21, 0x662);
334 write_reg_fp(client
, 0x140, 0x060);
335 } else if (input
== 1) {
337 write_reg_fp(client
, 0x20, 0x040 | vidsys
);
338 write_reg_fp(client
, 0x21, 0x666);
339 write_reg_fp(client
, 0x140, 0x060);
343 state
->input
= input
;
347 static int s2250_s_std(struct v4l2_subdev
*sd
, v4l2_std_id norm
)
349 struct s2250
*state
= to_state(sd
);
350 struct i2c_client
*client
= v4l2_get_subdevdata(sd
);
353 vidsource
= (state
->input
== 1) ? 0x040 : 0x020;
356 write_regs_fp(client
, vid_regs_fp
);
357 write_reg_fp(client
, 0x20, vidsource
| 1);
360 write_regs_fp(client
, vid_regs_fp
);
361 write_regs_fp(client
, vid_regs_fp_pal
);
362 write_reg_fp(client
, 0x20, vidsource
);
371 static int s2250_queryctrl(struct v4l2_subdev
*sd
, struct v4l2_queryctrl
*query
)
374 case V4L2_CID_BRIGHTNESS
:
375 return v4l2_ctrl_query_fill(query
, 0, 100, 1, 50);
376 case V4L2_CID_CONTRAST
:
377 return v4l2_ctrl_query_fill(query
, 0, 100, 1, 50);
378 case V4L2_CID_SATURATION
:
379 return v4l2_ctrl_query_fill(query
, 0, 100, 1, 50);
381 return v4l2_ctrl_query_fill(query
, -50, 50, 1, 0);
388 static int s2250_s_ctrl(struct v4l2_subdev
*sd
, struct v4l2_control
*ctrl
)
390 struct s2250
*state
= to_state(sd
);
391 struct i2c_client
*client
= v4l2_get_subdevdata(sd
);
396 case V4L2_CID_BRIGHTNESS
:
397 if (ctrl
->value
> 100)
398 state
->brightness
= 100;
399 else if (ctrl
->value
< 0)
400 state
->brightness
= 0;
402 state
->brightness
= ctrl
->value
;
403 value1
= (state
->brightness
- 50) * 255 / 100;
404 read_reg_fp(client
, VPX322_ADDR_BRIGHTNESS0
, &oldvalue
);
405 write_reg_fp(client
, VPX322_ADDR_BRIGHTNESS0
,
406 value1
| (oldvalue
& ~0xff));
407 read_reg_fp(client
, VPX322_ADDR_BRIGHTNESS1
, &oldvalue
);
408 write_reg_fp(client
, VPX322_ADDR_BRIGHTNESS1
,
409 value1
| (oldvalue
& ~0xff));
410 write_reg_fp(client
, 0x140, 0x60);
412 case V4L2_CID_CONTRAST
:
413 if (ctrl
->value
> 100)
414 state
->contrast
= 100;
415 else if (ctrl
->value
< 0)
418 state
->contrast
= ctrl
->value
;
419 value1
= state
->contrast
* 0x40 / 100;
421 value1
= 0x3f; /* max */
422 read_reg_fp(client
, VPX322_ADDR_CONTRAST0
, &oldvalue
);
423 write_reg_fp(client
, VPX322_ADDR_CONTRAST0
,
424 value1
| (oldvalue
& ~0x3f));
425 read_reg_fp(client
, VPX322_ADDR_CONTRAST1
, &oldvalue
);
426 write_reg_fp(client
, VPX322_ADDR_CONTRAST1
,
427 value1
| (oldvalue
& ~0x3f));
428 write_reg_fp(client
, 0x140, 0x60);
430 case V4L2_CID_SATURATION
:
431 if (ctrl
->value
> 100)
432 state
->saturation
= 100;
433 else if (ctrl
->value
< 0)
434 state
->saturation
= 0;
436 state
->saturation
= ctrl
->value
;
437 value1
= state
->saturation
* 4140 / 100;
440 write_reg_fp(client
, VPX322_ADDR_SAT
, value1
);
443 if (ctrl
->value
> 50)
445 else if (ctrl
->value
< -50)
448 state
->hue
= ctrl
->value
;
449 /* clamp the hue range */
450 value1
= state
->hue
* 280 / 50;
451 write_reg_fp(client
, VPX322_ADDR_HUE
, value1
);
459 static int s2250_g_ctrl(struct v4l2_subdev
*sd
, struct v4l2_control
*ctrl
)
461 struct s2250
*state
= to_state(sd
);
464 case V4L2_CID_BRIGHTNESS
:
465 ctrl
->value
= state
->brightness
;
467 case V4L2_CID_CONTRAST
:
468 ctrl
->value
= state
->contrast
;
470 case V4L2_CID_SATURATION
:
471 ctrl
->value
= state
->saturation
;
474 ctrl
->value
= state
->hue
;
482 static int s2250_s_fmt(struct v4l2_subdev
*sd
, struct v4l2_format
*fmt
)
484 struct s2250
*state
= to_state(sd
);
485 struct i2c_client
*client
= v4l2_get_subdevdata(sd
);
487 if (fmt
->fmt
.pix
.height
< 640) {
488 write_reg_fp(client
, 0x12b, state
->reg12b_val
| 0x400);
489 write_reg_fp(client
, 0x140, 0x060);
491 write_reg_fp(client
, 0x12b, state
->reg12b_val
& ~0x400);
492 write_reg_fp(client
, 0x140, 0x060);
497 static int s2250_s_audio_routing(struct v4l2_subdev
*sd
, u32 input
, u32 output
,
500 struct s2250
*state
= to_state(sd
);
504 write_reg(state
->audio
, 0x08, 0x02); /* Line In */
507 write_reg(state
->audio
, 0x08, 0x04); /* Mic */
510 write_reg(state
->audio
, 0x08, 0x05); /* Mic Boost */
515 state
->audio_input
= input
;
520 static int s2250_log_status(struct v4l2_subdev
*sd
)
522 struct s2250
*state
= to_state(sd
);
524 v4l2_info(sd
, "Standard: %s\n", state
->std
== V4L2_STD_NTSC
? "NTSC" :
525 state
->std
== V4L2_STD_PAL
? "PAL" :
526 state
->std
== V4L2_STD_SECAM
? "SECAM" :
528 v4l2_info(sd
, "Input: %s\n", state
->input
== 0 ? "Composite" :
529 state
->input
== 1 ? "S-video" :
531 v4l2_info(sd
, "Brightness: %d\n", state
->brightness
);
532 v4l2_info(sd
, "Contrast: %d\n", state
->contrast
);
533 v4l2_info(sd
, "Saturation: %d\n", state
->saturation
);
534 v4l2_info(sd
, "Hue: %d\n", state
->hue
); return 0;
535 v4l2_info(sd
, "Audio input: %s\n", state
->audio_input
== 0 ? "Line In" :
536 state
->audio_input
== 1 ? "Mic" :
537 state
->audio_input
== 2 ? "Mic Boost" :
542 /* --------------------------------------------------------------------------*/
544 static const struct v4l2_subdev_core_ops s2250_core_ops
= {
545 .log_status
= s2250_log_status
,
546 .g_ctrl
= s2250_g_ctrl
,
547 .s_ctrl
= s2250_s_ctrl
,
548 .queryctrl
= s2250_queryctrl
,
549 .s_std
= s2250_s_std
,
552 static const struct v4l2_subdev_audio_ops s2250_audio_ops
= {
553 .s_routing
= s2250_s_audio_routing
,
556 static const struct v4l2_subdev_video_ops s2250_video_ops
= {
557 .s_routing
= s2250_s_video_routing
,
558 .s_fmt
= s2250_s_fmt
,
561 static const struct v4l2_subdev_ops s2250_ops
= {
562 .core
= &s2250_core_ops
,
563 .audio
= &s2250_audio_ops
,
564 .video
= &s2250_video_ops
,
567 /* --------------------------------------------------------------------------*/
569 static int s2250_probe(struct i2c_client
*client
,
570 const struct i2c_device_id
*id
)
572 struct i2c_client
*audio
;
573 struct i2c_adapter
*adapter
= client
->adapter
;
575 struct v4l2_subdev
*sd
;
577 struct go7007
*go
= i2c_get_adapdata(adapter
);
578 struct go7007_usb
*usb
= go
->hpi_context
;
580 audio
= i2c_new_dummy(adapter
, TLV320_ADDRESS
>> 1);
584 state
= kmalloc(sizeof(struct s2250
), GFP_KERNEL
);
586 i2c_unregister_device(audio
);
591 v4l2_i2c_subdev_init(sd
, client
, &s2250_ops
);
593 v4l2_info(sd
, "initializing %s at address 0x%x on %s\n",
594 "Sensoray 2250/2251", client
->addr
, client
->adapter
->name
);
596 state
->std
= V4L2_STD_NTSC
;
597 state
->brightness
= 50;
598 state
->contrast
= 50;
599 state
->saturation
= 50;
601 state
->audio
= audio
;
603 /* initialize the audio */
604 if (write_regs(audio
, aud_regs
) < 0) {
606 "s2250: error initializing audio\n");
607 i2c_unregister_device(audio
);
612 if (write_regs(client
, vid_regs
) < 0) {
614 "s2250: error initializing decoder\n");
615 i2c_unregister_device(audio
);
619 if (write_regs_fp(client
, vid_regs_fp
) < 0) {
621 "s2250: error initializing decoder\n");
622 i2c_unregister_device(audio
);
626 /* set default channel */
628 write_reg_fp(client
, 0x20, 0x020 | 1);
629 write_reg_fp(client
, 0x21, 0x662);
630 write_reg_fp(client
, 0x140, 0x060);
632 /* set default audio input */
633 state
->audio_input
= 0;
634 write_reg(client
, 0x08, 0x02); /* Line In */
636 if (mutex_lock_interruptible(&usb
->i2c_lock
) == 0) {
637 data
= kzalloc(16, GFP_KERNEL
);
640 rc
= go7007_usb_vendor_request(go
, 0x41, 0, 0,
648 go7007_usb_vendor_request(go
, 0x40, 0,
655 mutex_unlock(&usb
->i2c_lock
);
658 v4l2_info(sd
, "initialized successfully\n");
662 static int s2250_remove(struct i2c_client
*client
)
664 struct v4l2_subdev
*sd
= i2c_get_clientdata(client
);
666 v4l2_device_unregister_subdev(sd
);
671 static const struct i2c_device_id s2250_id
[] = {
675 MODULE_DEVICE_TABLE(i2c
, s2250_id
);
677 static struct v4l2_i2c_driver_data v4l2_i2c_data
= {
679 .probe
= s2250_probe
,
680 .remove
= s2250_remove
,
681 .id_table
= s2250_id
,