V4L/DVB (12199): remove redundant tests on unsigned
[safe/jmp/linux-2.6] / drivers / media / video / cx18 / cx18-ioctl.c
index 3277b3d..fc76e4d 100644 (file)
@@ -208,7 +208,7 @@ static int cx18_g_fmt_sliced_vbi_cap(struct file *file, void *fh,
         * digitizer/slicer.  Note, cx18_av_vbi() wipes the passed in
         * fmt->fmt.sliced under valid calling conditions
         */
-       if (cx18_av_cmd(cx, VIDIOC_G_FMT, fmt))
+       if (v4l2_subdev_call(cx->sd_av, video, g_fmt, fmt))
                return -EINVAL;
 
        /* Ensure V4L2 spec compliant output */
@@ -295,7 +295,7 @@ static int cx18_s_fmt_vid_cap(struct file *file, void *fh,
 
        cx->params.width = w;
        cx->params.height = h;
-       cx18_av_cmd(cx, VIDIOC_S_FMT, fmt);
+       v4l2_subdev_call(cx->sd_av, video, s_fmt, fmt);
        return cx18_g_fmt_vid_cap(file, fh, fmt);
 }
 
@@ -322,7 +322,7 @@ static int cx18_s_fmt_vbi_cap(struct file *file, void *fh,
         * Note cx18_av_vbi_wipes out alot of the passed in fmt under valid
         * calling conditions
         */
-       ret = cx18_av_cmd(cx, VIDIOC_S_FMT, fmt);
+       ret = v4l2_subdev_call(cx->sd_av, video, s_fmt, fmt);
        if (ret)
                return ret;
 
@@ -359,7 +359,7 @@ static int cx18_s_fmt_sliced_vbi_cap(struct file *file, void *fh,
         * Note, cx18_av_vbi() wipes some "impossible" service lines in the
         * passed in fmt->fmt.sliced under valid calling conditions
         */
-       ret = cx18_av_cmd(cx, VIDIOC_S_FMT, fmt);
+       ret = v4l2_subdev_call(cx->sd_av, video, s_fmt, fmt);
        if (ret)
                return ret;
        /* Store our current v4l2 sliced VBI settings */
@@ -372,15 +372,52 @@ static int cx18_g_chip_ident(struct file *file, void *fh,
                                struct v4l2_dbg_chip_ident *chip)
 {
        struct cx18 *cx = ((struct cx18_open_id *)fh)->cx;
+       int err = 0;
 
        chip->ident = V4L2_IDENT_NONE;
        chip->revision = 0;
-       if (v4l2_chip_match_host(&chip->match)) {
-               chip->ident = V4L2_IDENT_CX23418;
-               return 0;
+       switch (chip->match.type) {
+       case V4L2_CHIP_MATCH_HOST:
+               switch (chip->match.addr) {
+               case 0:
+                       chip->ident = V4L2_IDENT_CX23418;
+                       chip->revision = cx18_read_reg(cx, 0xC72028);
+                       break;
+               case 1:
+                       /*
+                        * The A/V decoder is always present, but in the rare
+                        * case that the card doesn't have analog, we don't
+                        * use it.  We find it w/o using the cx->sd_av pointer
+                        */
+                       cx18_call_hw(cx, CX18_HW_418_AV,
+                                    core, g_chip_ident, chip);
+                       break;
+               default:
+                       /*
+                        * Could return ident = V4L2_IDENT_UNKNOWN if we had
+                        * other host chips at higher addresses, but we don't
+                        */
+                       err = -EINVAL; /* per V4L2 spec */
+                       break;
+               }
+               break;
+       case V4L2_CHIP_MATCH_I2C_DRIVER:
+               /* If needed, returns V4L2_IDENT_AMBIGUOUS without extra work */
+               cx18_call_all(cx, core, g_chip_ident, chip);
+               break;
+       case V4L2_CHIP_MATCH_I2C_ADDR:
+               /*
+                * We could return V4L2_IDENT_UNKNOWN, but we don't do the work
+                * to look if a chip is at the address with no driver.  That's a
+                * dangerous thing to do with EEPROMs anyway.
+                */
+               cx18_call_all(cx, core, g_chip_ident, chip);
+               break;
+       default:
+               err = -EINVAL;
+               break;
        }
-       cx18_call_i2c_clients(cx, VIDIOC_DBG_G_CHIP_IDENT, chip);
-       return 0;
+       return err;
 }
 
 #ifdef CONFIG_VIDEO_ADV_DEBUG
@@ -394,10 +431,10 @@ static int cx18_cxc(struct cx18 *cx, unsigned int cmd, void *arg)
                return -EINVAL;
 
        regs->size = 4;
-       if (cmd == VIDIOC_DBG_G_REGISTER)
-               regs->val = cx18_read_enc(cx, regs->reg);
-       else
+       if (cmd == VIDIOC_DBG_S_REGISTER)
                cx18_write_enc(cx, regs->val, regs->reg);
+       else
+               regs->val = cx18_read_enc(cx, regs->reg);
        return 0;
 }
 
@@ -408,7 +445,8 @@ static int cx18_g_register(struct file *file, void *fh,
 
        if (v4l2_chip_match_host(&reg->match))
                return cx18_cxc(cx, VIDIOC_DBG_G_REGISTER, reg);
-       cx18_call_i2c_clients(cx, VIDIOC_DBG_G_REGISTER, reg);
+       /* FIXME - errors shouldn't be ignored */
+       cx18_call_all(cx, core, g_register, reg);
        return 0;
 }
 
@@ -419,7 +457,8 @@ static int cx18_s_register(struct file *file, void *fh,
 
        if (v4l2_chip_match_host(&reg->match))
                return cx18_cxc(cx, VIDIOC_DBG_S_REGISTER, reg);
-       cx18_call_i2c_clients(cx, VIDIOC_DBG_S_REGISTER, reg);
+       /* FIXME - errors shouldn't be ignored */
+       cx18_call_all(cx, core, s_register, reg);
        return 0;
 }
 #endif
@@ -516,7 +555,8 @@ static int cx18_s_crop(struct file *file, void *fh, struct v4l2_crop *crop)
 
        if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
                return -EINVAL;
-       return cx18_av_cmd(cx, VIDIOC_S_CROP, crop);
+       CX18_DEBUG_WARN("VIDIOC_S_CROP not implemented\n");
+       return -EINVAL;
 }
 
 static int cx18_g_crop(struct file *file, void *fh, struct v4l2_crop *crop)
@@ -525,7 +565,8 @@ static int cx18_g_crop(struct file *file, void *fh, struct v4l2_crop *crop)
 
        if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
                return -EINVAL;
-       return cx18_av_cmd(cx, VIDIOC_G_CROP, crop);
+       CX18_DEBUG_WARN("VIDIOC_G_CROP not implemented\n");
+       return -EINVAL;
 }
 
 static int cx18_enum_fmt_vid_cap(struct file *file, void *fh,
@@ -564,7 +605,7 @@ int cx18_s_input(struct file *file, void *fh, unsigned int inp)
        if (ret)
                return ret;
 
-       if (inp < 0 || inp >= cx->nof_inputs)
+       if (inp >= cx->nof_inputs)
                return -EINVAL;
 
        if (inp == cx->active_input) {
@@ -596,7 +637,7 @@ static int cx18_g_frequency(struct file *file, void *fh,
        if (vf->tuner != 0)
                return -EINVAL;
 
-       cx18_call_i2c_clients(cx, VIDIOC_G_FREQUENCY, vf);
+       cx18_call_all(cx, tuner, g_frequency, vf);
        return 0;
 }
 
@@ -615,7 +656,7 @@ int cx18_s_frequency(struct file *file, void *fh, struct v4l2_frequency *vf)
 
        cx18_mute(cx);
        CX18_DEBUG_INFO("v4l2 ioctl: set frequency %d\n", vf->frequency);
-       cx18_call_i2c_clients(cx, VIDIOC_S_FREQUENCY, vf);
+       cx18_call_all(cx, tuner, s_frequency, vf);
        cx18_unmute(cx);
        return 0;
 }
@@ -664,7 +705,7 @@ int cx18_s_std(struct file *file, void *fh, v4l2_std_id *std)
                        (unsigned long long) cx->std);
 
        /* Tuner */
-       cx18_call_i2c_clients(cx, VIDIOC_S_STD, &cx->std);
+       cx18_call_all(cx, core, s_std, cx->std);
        return 0;
 }
 
@@ -681,9 +722,7 @@ static int cx18_s_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
        if (vt->index != 0)
                return -EINVAL;
 
-       /* Setting tuner can only set audio mode */
-       cx18_call_i2c_clients(cx, VIDIOC_S_TUNER, vt);
-
+       cx18_call_all(cx, tuner, s_tuner, vt);
        return 0;
 }
 
@@ -694,7 +733,7 @@ static int cx18_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
        if (vt->index != 0)
                return -EINVAL;
 
-       cx18_call_i2c_clients(cx, VIDIOC_G_TUNER, vt);
+       cx18_call_all(cx, tuner, g_tuner, vt);
 
        if (test_bit(CX18_F_I_RADIO_USER, &cx->i_flags)) {
                strlcpy(vt->name, "cx18 Radio Tuner", sizeof(vt->name));
@@ -851,7 +890,7 @@ static int cx18_log_status(struct file *file, void *fh)
 
                cx18_read_eeprom(cx, &tv);
        }
-       cx18_call_i2c_clients(cx, VIDIOC_LOG_STATUS, NULL);
+       cx18_call_all(cx, core, log_status);
        cx18_get_input(cx, cx->active_input, &vidin);
        cx18_get_audio_input(cx, cx->audio_input, &audin);
        CX18_INFO("Video Input: %s\n", vidin.name);
@@ -887,20 +926,12 @@ static long cx18_default(struct file *file, void *fh, int cmd, void *arg)
        struct cx18 *cx = ((struct cx18_open_id *)fh)->cx;
 
        switch (cmd) {
-       case VIDIOC_INT_S_AUDIO_ROUTING: {
-               struct v4l2_routing *route = arg;
-
-               CX18_DEBUG_IOCTL("VIDIOC_INT_S_AUDIO_ROUTING(%d, %d)\n",
-                       route->input, route->output);
-               cx18_audio_set_route(cx, route);
-               break;
-       }
-
        case VIDIOC_INT_RESET: {
                u32 val = *(u32 *)arg;
 
                if ((val == 0) || (val & 0x01))
-                       cx18_reset_ir_gpio(&cx->i2c_algo_cb_data[0]);
+                       cx18_call_hw(cx, CX18_HW_GPIO_RESET_CTRL, core, reset,
+                                    (u32) CX18_GPIO_RESET_Z8F0811);
                break;
        }
 
@@ -920,6 +951,8 @@ long cx18_v4l2_ioctl(struct file *filp, unsigned int cmd,
 
        mutex_lock(&cx->serialize_lock);
 
+       /* FIXME - consolidate v4l2_prio_check()'s here */
+
        if (cx18_debug & CX18_DBGFLG_IOCTL)
                vfd->debug = V4L2_DEBUG_IOCTL | V4L2_DEBUG_IOCTL_ARG;
        res = video_ioctl2(filp, cmd, arg);