diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-09-21 09:03:10 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-09-21 09:03:10 -0700 |
commit | c720f5655df159a630fa0290a0bd67c93e92b0bf (patch) | |
tree | 940d139d0ec1ff5201efddef6cc663166a8a2df3 /drivers/staging/go7007/s2250-board.c | |
parent | 33e6c1a0de818d3698cdab27c42915661011319d (diff) | |
parent | 84d6ae431f315e8973aac3c3fe1d550fc9240ef3 (diff) |
Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6
* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6: (222 commits)
V4L/DVB (13033): pt1: Don't use a deprecated DMA_BIT_MASK macro
V4L/DVB (13029): radio-si4713: remove #include <linux/version.h>
V4L/DVB (13027): go7007: convert printks to v4l2_info
V4L/DVB (13026): s2250-board: Implement brightness and contrast controls
V4L/DVB (13025): s2250-board: Fix memory leaks
V4L/DVB (13024): go7007: Implement vidioc_g_std and vidioc_querystd
V4L/DVB (13023): go7007: Merge struct gofh and go declarations
V4L/DVB (13022): go7007: Fix mpeg controls
V4L/DVB (13021): go7007: Fix whitespace and line lengths
V4L/DVB (13020): go7007: Updates to Kconfig and Makefile
V4L/DVB (13019): video: initial support for ADV7180
V4L/DVB (13018): kzalloc failure ignored in au8522_probe()
V4L/DVB (13017): gspca: kmalloc failure ignored in sd_start()
V4L/DVB (13016): kmalloc failure ignored in lgdt3304_attach() and s921_attach()
V4L/DVB (13015): kmalloc failure ignored in m920x_firmware_download()
V4L/DVB (13014): Add support for Compro VideoMate E800 (DVB-T part only)
V4L/DVB (13013): FM TX: si4713: Kconfig: Fixed two typos.
V4L/DVB (13012): uvc: introduce missing kfree
V4L/DVB (13011): Change tuner type of BeholdTV cards
V4L/DVB (13009): gspca - stv06xx-hdcs: Reduce exposure range
...
Diffstat (limited to 'drivers/staging/go7007/s2250-board.c')
-rw-r--r-- | drivers/staging/go7007/s2250-board.c | 107 |
1 files changed, 89 insertions, 18 deletions
diff --git a/drivers/staging/go7007/s2250-board.c b/drivers/staging/go7007/s2250-board.c index 1706fbf0684..8c85a9c3665 100644 --- a/drivers/staging/go7007/s2250-board.c +++ b/drivers/staging/go7007/s2250-board.c @@ -21,12 +21,10 @@ #include <linux/i2c.h> #include <linux/videodev2.h> #include <media/v4l2-common.h> +#include "s2250-loader.h" #include "go7007-priv.h" #include "wis-i2c.h" -extern int s2250loader_init(void); -extern void s2250loader_cleanup(void); - #define TLV320_ADDRESS 0x34 #define VPX322_ADDR_ANALOGCONTROL1 0x02 #define VPX322_ADDR_BRIGHTNESS0 0x0127 @@ -34,7 +32,7 @@ extern void s2250loader_cleanup(void); #define VPX322_ADDR_CONTRAST0 0x0128 #define VPX322_ADDR_CONTRAST1 0x0132 #define VPX322_ADDR_HUE 0x00dc -#define VPX322_ADDR_SAT 0x0030 +#define VPX322_ADDR_SAT 0x0030 struct go7007_usb_board { unsigned int flags; @@ -43,7 +41,7 @@ struct go7007_usb_board { struct go7007_usb { struct go7007_usb_board *board; - struct semaphore i2c_lock; + struct mutex i2c_lock; struct usb_device *usbdev; struct urb *video_urbs[8]; struct urb *audio_urbs[8]; @@ -114,7 +112,7 @@ static u16 vid_regs_fp_pal[] = }; struct s2250 { - int std; + v4l2_std_id std; int input; int brightness; int contrast; @@ -165,7 +163,7 @@ static int write_reg(struct i2c_client *client, u8 reg, u8 value) return -ENOMEM; usb = go->hpi_context; - if (down_interruptible(&usb->i2c_lock) != 0) { + if (mutex_lock_interruptible(&usb->i2c_lock) != 0) { printk(KERN_INFO "i2c lock failed\n"); kfree(buf); return -EINTR; @@ -175,7 +173,7 @@ static int write_reg(struct i2c_client *client, u8 reg, u8 value) buf, 16, 1); - up(&usb->i2c_lock); + mutex_unlock(&usb->i2c_lock); kfree(buf); return rc; } @@ -203,19 +201,23 @@ static int write_reg_fp(struct i2c_client *client, u16 addr, u16 val) memset(buf, 0xcd, 6); usb = go->hpi_context; - if (down_interruptible(&usb->i2c_lock) != 0) { + if (mutex_lock_interruptible(&usb->i2c_lock) != 0) { printk(KERN_INFO "i2c lock failed\n"); + kfree(buf); return -EINTR; } - if (go7007_usb_vendor_request(go, 0x57, addr, val, buf, 16, 1) < 0) + if (go7007_usb_vendor_request(go, 0x57, addr, val, buf, 16, 1) < 0) { + kfree(buf); return -EFAULT; + } - up(&usb->i2c_lock); + mutex_unlock(&usb->i2c_lock); if (buf[0] == 0) { unsigned int subaddr, val_read; subaddr = (buf[4] << 8) + buf[5]; val_read = (buf[2] << 8) + buf[3]; + kfree(buf); if (val_read != val) { printk(KERN_INFO "invalid fp write %x %x\n", val_read, val); @@ -226,8 +228,10 @@ static int write_reg_fp(struct i2c_client *client, u16 addr, u16 val) subaddr, addr); return -EFAULT; } - } else + } else { + kfree(buf); return -EFAULT; + } /* save last 12b value */ if (addr == 0x12b) @@ -236,6 +240,45 @@ static int write_reg_fp(struct i2c_client *client, u16 addr, u16 val) return 0; } +static int read_reg_fp(struct i2c_client *client, u16 addr, u16 *val) +{ + struct go7007 *go = i2c_get_adapdata(client->adapter); + struct go7007_usb *usb; + u8 *buf; + + if (go == NULL) + return -ENODEV; + + if (go->status == STATUS_SHUTDOWN) + return -EBUSY; + + buf = kzalloc(16, GFP_KERNEL); + + if (buf == NULL) + return -ENOMEM; + + + + memset(buf, 0xcd, 6); + usb = go->hpi_context; + if (down_interruptible(&usb->i2c_lock) != 0) { + printk(KERN_INFO "i2c lock failed\n"); + kfree(buf); + return -EINTR; + } + if (go7007_usb_vendor_request(go, 0x58, addr, 0, buf, 16, 1) < 0) { + kfree(buf); + return -EFAULT; + } + up(&usb->i2c_lock); + + *val = (buf[0] << 8) | buf[1]; + kfree(buf); + + return 0; +} + + static int write_regs(struct i2c_client *client, u8 *regs) { int i; @@ -350,14 +393,42 @@ static int s2250_command(struct i2c_client *client, { struct v4l2_control *ctrl = arg; int value1; + u16 oldvalue; switch (ctrl->id) { case V4L2_CID_BRIGHTNESS: - printk(KERN_INFO "s2250: future setting\n"); - return -EINVAL; + if (ctrl->value > 100) + dec->brightness = 100; + else if (ctrl->value < 0) + dec->brightness = 0; + else + dec->brightness = ctrl->value; + value1 = (dec->brightness - 50) * 255 / 100; + read_reg_fp(client, VPX322_ADDR_BRIGHTNESS0, &oldvalue); + write_reg_fp(client, VPX322_ADDR_BRIGHTNESS0, + value1 | (oldvalue & ~0xff)); + read_reg_fp(client, VPX322_ADDR_BRIGHTNESS1, &oldvalue); + write_reg_fp(client, VPX322_ADDR_BRIGHTNESS1, + value1 | (oldvalue & ~0xff)); + write_reg_fp(client, 0x140, 0x60); + break; case V4L2_CID_CONTRAST: - printk(KERN_INFO "s2250: future setting\n"); - return -EINVAL; + if (ctrl->value > 100) + dec->contrast = 100; + else if (ctrl->value < 0) + dec->contrast = 0; + else + dec->contrast = ctrl->value; + value1 = dec->contrast * 0x40 / 100; + if (value1 > 0x3f) + value1 = 0x3f; /* max */ + read_reg_fp(client, VPX322_ADDR_CONTRAST0, &oldvalue); + write_reg_fp(client, VPX322_ADDR_CONTRAST0, + value1 | (oldvalue & ~0x3f)); + read_reg_fp(client, VPX322_ADDR_CONTRAST1, &oldvalue); + write_reg_fp(client, VPX322_ADDR_CONTRAST1, + value1 | (oldvalue & ~0x3f)); + write_reg_fp(client, 0x140, 0x60); break; case V4L2_CID_SATURATION: if (ctrl->value > 127) @@ -541,7 +612,7 @@ static int s2250_probe(struct i2c_client *client, dec->audio_input = 0; write_reg(client, 0x08, 0x02); /* Line In */ - if (down_interruptible(&usb->i2c_lock) == 0) { + if (mutex_lock_interruptible(&usb->i2c_lock) == 0) { data = kzalloc(16, GFP_KERNEL); if (data != NULL) { int rc; @@ -560,7 +631,7 @@ static int s2250_probe(struct i2c_client *client, } kfree(data); } - up(&usb->i2c_lock); + mutex_unlock(&usb->i2c_lock); } printk("s2250: initialized successfully\n"); |