summaryrefslogtreecommitdiff
path: root/linux/drivers/media/video/em28xx/em28xx-core.c
diff options
context:
space:
mode:
Diffstat (limited to 'linux/drivers/media/video/em28xx/em28xx-core.c')
-rw-r--r--linux/drivers/media/video/em28xx/em28xx-core.c143
1 files changed, 75 insertions, 68 deletions
diff --git a/linux/drivers/media/video/em28xx/em28xx-core.c b/linux/drivers/media/video/em28xx/em28xx-core.c
index eb8515895..f62b05eae 100644
--- a/linux/drivers/media/video/em28xx/em28xx-core.c
+++ b/linux/drivers/media/video/em28xx/em28xx-core.c
@@ -66,7 +66,8 @@ MODULE_PARM_DESC(alt, "alternate setting to use for video endpoint");
int em28xx_read_reg_req_len(struct em28xx *dev, u8 req, u16 reg,
char *buf, int len)
{
- int ret, byte;
+ int ret;
+ int pipe = usb_rcvctrlpipe(dev->udev, 0);
if (dev->state & DEV_DISCONNECTED)
return -ENODEV;
@@ -74,10 +75,18 @@ int em28xx_read_reg_req_len(struct em28xx *dev, u8 req, u16 reg,
if (len > URB_MAX_CTRL_SIZE)
return -EINVAL;
- em28xx_regdbg("req=%02x, reg=%02x ", req, reg);
+ if (reg_debug) {
+ printk( KERN_DEBUG "(pipe 0x%08x): "
+ "IN: %02x %02x %02x %02x %02x %02x %02x %02x ",
+ pipe,
+ USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ req, 0, 0,
+ reg & 0xff, reg >> 8,
+ len & 0xff, len >> 8);
+ }
mutex_lock(&dev->ctrl_urb_lock);
- ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), req,
+ ret = usb_control_msg(dev->udev, pipe, req,
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0x0000, reg, dev->urb_buf, len, HZ);
if (ret < 0) {
@@ -93,7 +102,9 @@ int em28xx_read_reg_req_len(struct em28xx *dev, u8 req, u16 reg,
mutex_unlock(&dev->ctrl_urb_lock);
if (reg_debug) {
- printk("%02x values: ", ret);
+ int byte;
+
+ printk("<<<");
for (byte = 0; byte < len; byte++)
printk(" %02x", (unsigned char)buf[byte]);
printk("\n");
@@ -108,28 +119,12 @@ int em28xx_read_reg_req_len(struct em28xx *dev, u8 req, u16 reg,
*/
int em28xx_read_reg_req(struct em28xx *dev, u8 req, u16 reg)
{
- u8 val;
int ret;
+ u8 val;
- if (dev->state & DEV_DISCONNECTED)
- return(-ENODEV);
-
- em28xx_regdbg("req=%02x, reg=%02x:", req, reg);
-
- mutex_lock(&dev->ctrl_urb_lock);
- ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), req,
- USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- 0x0000, reg, dev->urb_buf, 1, HZ);
- val = dev->urb_buf[0];
- mutex_unlock(&dev->ctrl_urb_lock);
-
- if (ret < 0) {
- printk(" failed!\n");
+ ret = em28xx_read_reg_req_len(dev, req, reg, &val, 1);
+ if (ret < 0)
return ret;
- }
-
- if (reg_debug)
- printk("%02x\n", (unsigned char) val);
return val;
}
@@ -147,6 +142,7 @@ int em28xx_write_regs_req(struct em28xx *dev, u8 req, u16 reg, char *buf,
int len)
{
int ret;
+ int pipe = usb_sndctrlpipe(dev->udev, 0);
if (dev->state & DEV_DISCONNECTED)
return -ENODEV;
@@ -154,17 +150,25 @@ int em28xx_write_regs_req(struct em28xx *dev, u8 req, u16 reg, char *buf,
if ((len < 1) || (len > URB_MAX_CTRL_SIZE))
return -EINVAL;
- em28xx_regdbg("req=%02x reg=%02x:", req, reg);
if (reg_debug) {
- int i;
- for (i = 0; i < len; ++i)
- printk(" %02x", (unsigned char)buf[i]);
+ int byte;
+
+ printk( KERN_DEBUG "(pipe 0x%08x): "
+ "OUT: %02x %02x %02x %02x %02x %02x %02x %02x >>>",
+ pipe,
+ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ req, 0, 0,
+ reg & 0xff, reg >> 8,
+ len & 0xff, len >> 8);
+
+ for (byte = 0; byte < len; byte++)
+ printk(" %02x", (unsigned char)buf[byte]);
printk("\n");
}
mutex_lock(&dev->ctrl_urb_lock);
memcpy(dev->urb_buf, buf, len);
- ret = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0), req,
+ ret = usb_control_msg(dev->udev, pipe, req,
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0x0000, reg, dev->urb_buf, len, HZ);
mutex_unlock(&dev->ctrl_urb_lock);
@@ -349,7 +353,7 @@ static int em28xx_set_audio_source(struct em28xx *dev)
int ret;
u8 input;
- if (dev->is_em2800) {
+ if (dev->board.is_em2800) {
if (dev->ctl_ainput == EM28XX_AMUX_VIDEO)
input = EM2800_AUDIO_SRC_TUNER;
else
@@ -360,7 +364,7 @@ static int em28xx_set_audio_source(struct em28xx *dev)
return ret;
}
- if (dev->has_msp34xx)
+ if (dev->board.has_msp34xx)
input = EM28XX_AUDIO_SRC_TUNER;
else {
switch (dev->ctl_ainput) {
@@ -399,7 +403,7 @@ struct em28xx_vol_table outputs[] = {
int em28xx_audio_analog_set(struct em28xx *dev)
{
int ret, i;
- u8 xclk = 0x07;
+ u8 xclk;
if (!dev->audio_mode.has_audio)
return 0;
@@ -417,13 +421,11 @@ int em28xx_audio_analog_set(struct em28xx *dev)
}
}
- if (dev->has_12mhz_i2s)
- xclk |= 0x20;
-
+ xclk = dev->board.xclk & 0x7f;
if (!dev->mute)
xclk |= 0x80;
- ret = em28xx_write_reg_bits(dev, EM28XX_R0F_XCLK, xclk, 0xa7);
+ ret = em28xx_write_reg(dev, EM28XX_R0F_XCLK, xclk);
if (ret < 0)
return ret;
msleep(10);
@@ -556,20 +558,20 @@ EXPORT_SYMBOL_GPL(em28xx_audio_setup);
int em28xx_colorlevels_set_default(struct em28xx *dev)
{
- em28xx_write_regs(dev, EM28XX_R20_YGAIN, "\x10", 1); /* contrast */
- em28xx_write_regs(dev, EM28XX_R21_YOFFSET, "\x00", 1); /* brightness */
- em28xx_write_regs(dev, EM28XX_R22_UVGAIN, "\x10", 1); /* saturation */
- em28xx_write_regs(dev, EM28XX_R23_UOFFSET, "\x00", 1);
- em28xx_write_regs(dev, EM28XX_R24_VOFFSET, "\x00", 1);
- em28xx_write_regs(dev, EM28XX_R25_SHARPNESS, "\x00", 1);
-
- em28xx_write_regs(dev, EM28XX_R14_GAMMA, "\x20", 1);
- em28xx_write_regs(dev, EM28XX_R15_RGAIN, "\x20", 1);
- em28xx_write_regs(dev, EM28XX_R16_GGAIN, "\x20", 1);
- em28xx_write_regs(dev, EM28XX_R17_BGAIN, "\x20", 1);
- em28xx_write_regs(dev, EM28XX_R18_ROFFSET, "\x00", 1);
- em28xx_write_regs(dev, EM28XX_R19_GOFFSET, "\x00", 1);
- return em28xx_write_regs(dev, EM28XX_R1A_BOFFSET, "\x00", 1);
+ em28xx_write_reg(dev, EM28XX_R20_YGAIN, 0x10); /* contrast */
+ em28xx_write_reg(dev, EM28XX_R21_YOFFSET, 0x00); /* brightness */
+ em28xx_write_reg(dev, EM28XX_R22_UVGAIN, 0x10); /* saturation */
+ em28xx_write_reg(dev, EM28XX_R23_UOFFSET, 0x00);
+ em28xx_write_reg(dev, EM28XX_R24_VOFFSET, 0x00);
+ em28xx_write_reg(dev, EM28XX_R25_SHARPNESS, 0x00);
+
+ em28xx_write_reg(dev, EM28XX_R14_GAMMA, 0x20);
+ em28xx_write_reg(dev, EM28XX_R15_RGAIN, 0x20);
+ em28xx_write_reg(dev, EM28XX_R16_GGAIN, 0x20);
+ em28xx_write_reg(dev, EM28XX_R17_BGAIN, 0x20);
+ em28xx_write_reg(dev, EM28XX_R18_ROFFSET, 0x00);
+ em28xx_write_reg(dev, EM28XX_R19_GOFFSET, 0x00);
+ return em28xx_write_reg(dev, EM28XX_R1A_BOFFSET, 0x00);
}
int em28xx_capture_start(struct em28xx *dev, int start)
@@ -602,17 +604,17 @@ int em28xx_capture_start(struct em28xx *dev, int start)
if (!start) {
/* disable video capture */
- rc = em28xx_write_regs(dev, EM28XX_R12_VINENABLE, "\x27", 1);
+ rc = em28xx_write_reg(dev, EM28XX_R12_VINENABLE, 0x27);
return rc;
}
/* enable video capture */
- rc = em28xx_write_regs_req(dev, 0x00, 0x48, "\x00", 1);
+ rc = em28xx_write_reg(dev, 0x48, 0x00);
if (dev->mode == EM28XX_ANALOG_MODE)
- rc = em28xx_write_regs(dev, EM28XX_R12_VINENABLE, "\x67", 1);
+ rc = em28xx_write_reg(dev, EM28XX_R12_VINENABLE, 0x67);
else
- rc = em28xx_write_regs(dev, EM28XX_R12_VINENABLE, "\x37", 1);
+ rc = em28xx_write_reg(dev, EM28XX_R12_VINENABLE, 0x37);
msleep(6);
@@ -621,9 +623,9 @@ int em28xx_capture_start(struct em28xx *dev, int start)
int em28xx_outfmt_set_yuv422(struct em28xx *dev)
{
- em28xx_write_regs(dev, EM28XX_R27_OUTFMT, "\x34", 1);
- em28xx_write_regs(dev, EM28XX_R10_VINMODE, "\x10", 1);
- return em28xx_write_regs(dev, EM28XX_R11_VINCTRL, "\x11", 1);
+ em28xx_write_reg(dev, EM28XX_R27_OUTFMT, 0x34);
+ em28xx_write_reg(dev, EM28XX_R10_VINMODE, 0x10);
+ return em28xx_write_reg(dev, EM28XX_R11_VINCTRL, 0x11);
}
static int em28xx_accumulator_set(struct em28xx *dev, u8 xmin, u8 xmax,
@@ -660,7 +662,7 @@ static int em28xx_scaler_set(struct em28xx *dev, u16 h, u16 v)
{
u8 mode;
/* the em2800 scaler only supports scaling down to 50% */
- if (dev->is_em2800)
+ if (dev->board.is_em2800)
mode = (v ? 0x20 : 0x00) | (h ? 0x10 : 0x00);
else {
u8 buf[2];
@@ -739,12 +741,14 @@ int em28xx_gpio_set(struct em28xx *dev, struct em28xx_reg_seq *gpio)
if (!gpio)
return rc;
- dev->em28xx_write_regs_req(dev, 0x00, 0x48, "\x00", 1);
- if (dev->mode == EM28XX_ANALOG_MODE)
- dev->em28xx_write_regs_req(dev, 0x00, 0x12, "\x67", 1);
- else
- dev->em28xx_write_regs_req(dev, 0x00, 0x12, "\x37", 1);
- msleep(6);
+ if (dev->mode != EM28XX_SUSPEND) {
+ em28xx_write_reg(dev, 0x48, 0x00);
+ if (dev->mode == EM28XX_ANALOG_MODE)
+ em28xx_write_reg(dev, EM28XX_R12_VINENABLE, 0x67);
+ else
+ em28xx_write_reg(dev, EM28XX_R12_VINENABLE, 0x37);
+ msleep(6);
+ }
/* Send GPIO reset sequences specified at board entry */
while (gpio->sleep >= 0) {
@@ -769,22 +773,25 @@ int em28xx_set_mode(struct em28xx *dev, enum em28xx_mode set_mode)
if (dev->mode == set_mode)
return 0;
- if (set_mode == EM28XX_MODE_UNDEFINED) {
+ if (set_mode == EM28XX_SUSPEND) {
dev->mode = set_mode;
- return 0;
+
+ /* FIXME: add suspend support for ac97 */
+
+ return em28xx_gpio_set(dev, dev->board.suspend_gpio);
}
#if 0
/* Resource is locked */
- if (dev->mode != EM28XX_MODE_UNDEFINED)
+ if (dev->mode != EM28XX_SUSPEND)
return -EINVAL;
#endif
dev->mode = set_mode;
if (dev->mode == EM28XX_DIGITAL_MODE)
- return em28xx_gpio_set(dev, dev->digital_gpio);
+ return em28xx_gpio_set(dev, dev->board.dvb_gpio);
else
- return em28xx_gpio_set(dev, dev->analog_gpio);
+ return em28xx_gpio_set(dev, INPUT(dev->ctl_input)->gpio);
}
EXPORT_SYMBOL_GPL(em28xx_set_mode);