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-subdev.h>
27 #include "go7007-priv.h"
29 MODULE_DESCRIPTION("Sensoray 2250/2251 i2c v4l2 subdev driver");
30 MODULE_LICENSE("GPL v2");
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
41 struct go7007_usb_board
{
43 struct go7007_board_info main_info
;
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];
55 static unsigned char aud_regs
[] = {
73 static unsigned char vid_regs
[] = {
80 static u16 vid_regs_fp
[] = {
105 /* PAL specific values */
106 static u16 vid_regs_fp_pal
[] =
119 struct v4l2_subdev sd
;
128 struct i2c_client
*audio
;
131 static inline struct s2250
*to_state(struct v4l2_subdev
*sd
)
133 return container_of(sd
, struct s2250
, sd
);
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
)
140 struct go7007_usb
*usb
= go
->hpi_context
;
144 return usb_control_msg(usb
->usbdev
,
145 usb_rcvctrlpipe(usb
->usbdev
, 0), request
,
146 USB_TYPE_VENDOR
| USB_RECIP_DEVICE
| USB_DIR_IN
,
147 value
, index
, transfer_buffer
, length
, timeout
);
149 return usb_control_msg(usb
->usbdev
,
150 usb_sndctrlpipe(usb
->usbdev
, 0), request
,
151 USB_TYPE_VENDOR
| USB_RECIP_DEVICE
,
152 value
, index
, transfer_buffer
, length
, timeout
);
155 /* end from go7007-usb.c which is Copyright (C) 2005-2006 Micronas USA Inc.*/
157 static int write_reg(struct i2c_client
*client
, u8 reg
, u8 value
)
159 struct go7007
*go
= i2c_get_adapdata(client
->adapter
);
160 struct go7007_usb
*usb
;
162 int dev_addr
= client
->addr
<< 1; /* firmware wants 8-bit address */
168 if (go
->status
== STATUS_SHUTDOWN
)
171 buf
= kzalloc(16, GFP_KERNEL
);
175 usb
= go
->hpi_context
;
176 if (mutex_lock_interruptible(&usb
->i2c_lock
) != 0) {
177 printk(KERN_INFO
"i2c lock failed\n");
181 rc
= go7007_usb_vendor_request(go
, 0x55, dev_addr
,
186 mutex_unlock(&usb
->i2c_lock
);
191 static int write_reg_fp(struct i2c_client
*client
, u16 addr
, u16 val
)
193 struct go7007
*go
= i2c_get_adapdata(client
->adapter
);
194 struct go7007_usb
*usb
;
196 struct s2250
*dec
= i2c_get_clientdata(client
);
201 if (go
->status
== STATUS_SHUTDOWN
)
204 buf
= kzalloc(16, GFP_KERNEL
);
211 memset(buf
, 0xcd, 6);
213 usb
= go
->hpi_context
;
214 if (mutex_lock_interruptible(&usb
->i2c_lock
) != 0) {
215 printk(KERN_INFO
"i2c lock failed\n");
219 if (go7007_usb_vendor_request(go
, 0x57, addr
, val
, buf
, 16, 1) < 0) {
224 mutex_unlock(&usb
->i2c_lock
);
226 unsigned int subaddr
, val_read
;
228 subaddr
= (buf
[4] << 8) + buf
[5];
229 val_read
= (buf
[2] << 8) + buf
[3];
231 if (val_read
!= val
) {
232 printk(KERN_INFO
"invalid fp write %x %x\n",
236 if (subaddr
!= addr
) {
237 printk(KERN_INFO
"invalid fp write addr %x %x\n",
246 /* save last 12b value */
248 dec
->reg12b_val
= val
;
253 static int read_reg_fp(struct i2c_client
*client
, u16 addr
, u16
*val
)
255 struct go7007
*go
= i2c_get_adapdata(client
->adapter
);
256 struct go7007_usb
*usb
;
262 if (go
->status
== STATUS_SHUTDOWN
)
265 buf
= kzalloc(16, GFP_KERNEL
);
272 memset(buf
, 0xcd, 6);
273 usb
= go
->hpi_context
;
274 if (mutex_lock_interruptible(&usb
->i2c_lock
) != 0) {
275 printk(KERN_INFO
"i2c lock failed\n");
279 if (go7007_usb_vendor_request(go
, 0x58, addr
, 0, buf
, 16, 1) < 0) {
283 mutex_unlock(&usb
->i2c_lock
);
285 *val
= (buf
[0] << 8) | buf
[1];
292 static int write_regs(struct i2c_client
*client
, u8
*regs
)
296 for (i
= 0; !((regs
[i
] == 0x00) && (regs
[i
+1] == 0x00)); i
+= 2) {
297 if (write_reg(client
, regs
[i
], regs
[i
+1]) < 0) {
298 printk(KERN_INFO
"s2250: failed\n");
305 static int write_regs_fp(struct i2c_client
*client
, u16
*regs
)
309 for (i
= 0; !((regs
[i
] == 0x00) && (regs
[i
+1] == 0x00)); i
+= 2) {
310 if (write_reg_fp(client
, regs
[i
], regs
[i
+1]) < 0) {
311 printk(KERN_INFO
"s2250: failed fp\n");
319 /* ------------------------------------------------------------------------- */
321 static int s2250_s_video_routing(struct v4l2_subdev
*sd
, u32 input
, u32 output
,
324 struct s2250
*state
= to_state(sd
);
325 struct i2c_client
*client
= v4l2_get_subdevdata(sd
);
328 vidsys
= (state
->std
== V4L2_STD_NTSC
) ? 0x01 : 0x00;
331 write_reg_fp(client
, 0x20, 0x020 | vidsys
);
332 write_reg_fp(client
, 0x21, 0x662);
333 write_reg_fp(client
, 0x140, 0x060);
334 } else if (input
== 1) {
336 write_reg_fp(client
, 0x20, 0x040 | vidsys
);
337 write_reg_fp(client
, 0x21, 0x666);
338 write_reg_fp(client
, 0x140, 0x060);
342 state
->input
= input
;
346 static int s2250_s_std(struct v4l2_subdev
*sd
, v4l2_std_id norm
)
348 struct s2250
*state
= to_state(sd
);
349 struct i2c_client
*client
= v4l2_get_subdevdata(sd
);
352 vidsource
= (state
->input
== 1) ? 0x040 : 0x020;
355 write_regs_fp(client
, vid_regs_fp
);
356 write_reg_fp(client
, 0x20, vidsource
| 1);
359 write_regs_fp(client
, vid_regs_fp
);
360 write_regs_fp(client
, vid_regs_fp_pal
);
361 write_reg_fp(client
, 0x20, vidsource
);
370 static int s2250_queryctrl(struct v4l2_subdev
*sd
, struct v4l2_queryctrl
*query
)
373 case V4L2_CID_BRIGHTNESS
:
374 return v4l2_ctrl_query_fill(query
, 0, 100, 1, 50);
375 case V4L2_CID_CONTRAST
:
376 return v4l2_ctrl_query_fill(query
, 0, 100, 1, 50);
377 case V4L2_CID_SATURATION
:
378 return v4l2_ctrl_query_fill(query
, 0, 100, 1, 50);
380 return v4l2_ctrl_query_fill(query
, -50, 50, 1, 0);
387 static int s2250_s_ctrl(struct v4l2_subdev
*sd
, struct v4l2_control
*ctrl
)
389 struct s2250
*state
= to_state(sd
);
390 struct i2c_client
*client
= v4l2_get_subdevdata(sd
);
395 case V4L2_CID_BRIGHTNESS
:
396 if (ctrl
->value
> 100)
397 state
->brightness
= 100;
398 else if (ctrl
->value
< 0)
399 state
->brightness
= 0;
401 state
->brightness
= ctrl
->value
;
402 value1
= (state
->brightness
- 50) * 255 / 100;
403 read_reg_fp(client
, VPX322_ADDR_BRIGHTNESS0
, &oldvalue
);
404 write_reg_fp(client
, VPX322_ADDR_BRIGHTNESS0
,
405 value1
| (oldvalue
& ~0xff));
406 read_reg_fp(client
, VPX322_ADDR_BRIGHTNESS1
, &oldvalue
);
407 write_reg_fp(client
, VPX322_ADDR_BRIGHTNESS1
,
408 value1
| (oldvalue
& ~0xff));
409 write_reg_fp(client
, 0x140, 0x60);
411 case V4L2_CID_CONTRAST
:
412 if (ctrl
->value
> 100)
413 state
->contrast
= 100;
414 else if (ctrl
->value
< 0)
417 state
->contrast
= ctrl
->value
;
418 value1
= state
->contrast
* 0x40 / 100;
420 value1
= 0x3f; /* max */
421 read_reg_fp(client
, VPX322_ADDR_CONTRAST0
, &oldvalue
);
422 write_reg_fp(client
, VPX322_ADDR_CONTRAST0
,
423 value1
| (oldvalue
& ~0x3f));
424 read_reg_fp(client
, VPX322_ADDR_CONTRAST1
, &oldvalue
);
425 write_reg_fp(client
, VPX322_ADDR_CONTRAST1
,
426 value1
| (oldvalue
& ~0x3f));
427 write_reg_fp(client
, 0x140, 0x60);
429 case V4L2_CID_SATURATION
:
430 if (ctrl
->value
> 100)
431 state
->saturation
= 100;
432 else if (ctrl
->value
< 0)
433 state
->saturation
= 0;
435 state
->saturation
= ctrl
->value
;
436 value1
= state
->saturation
* 4140 / 100;
439 write_reg_fp(client
, VPX322_ADDR_SAT
, value1
);
442 if (ctrl
->value
> 50)
444 else if (ctrl
->value
< -50)
447 state
->hue
= ctrl
->value
;
448 /* clamp the hue range */
449 value1
= state
->hue
* 280 / 50;
450 write_reg_fp(client
, VPX322_ADDR_HUE
, value1
);
458 static int s2250_g_ctrl(struct v4l2_subdev
*sd
, struct v4l2_control
*ctrl
)
460 struct s2250
*state
= to_state(sd
);
463 case V4L2_CID_BRIGHTNESS
:
464 ctrl
->value
= state
->brightness
;
466 case V4L2_CID_CONTRAST
:
467 ctrl
->value
= state
->contrast
;
469 case V4L2_CID_SATURATION
:
470 ctrl
->value
= state
->saturation
;
473 ctrl
->value
= state
->hue
;
481 static int s2250_s_mbus_fmt(struct v4l2_subdev
*sd
,
482 struct v4l2_mbus_framefmt
*fmt
)
484 struct s2250
*state
= to_state(sd
);
485 struct i2c_client
*client
= v4l2_get_subdevdata(sd
);
487 if (fmt
->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_mbus_fmt
= s2250_s_mbus_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 i2c_driver s2250_driver
= {
679 .owner
= THIS_MODULE
,
682 .probe
= s2250_probe
,
683 .remove
= s2250_remove
,
684 .id_table
= s2250_id
,
687 static __init
int init_s2250(void)
689 return i2c_add_driver(&s2250_driver
);
692 static __exit
void exit_s2250(void)
694 i2c_del_driver(&s2250_driver
);
697 module_init(init_s2250
);
698 module_exit(exit_s2250
);