/** * vpbe_set_mode - Set mode in the current encoder using mode info * * Use the mode string to decide what timings to set in the encoder * This is typically useful when fbset command is used to change the current * timings by specifying a string to indicate the timings. */ static int vpbe_set_mode(struct vpbe_device *vpbe_dev, struct vpbe_enc_mode_info *mode_info) { struct vpbe_enc_mode_info *preset_mode = NULL; struct vpbe_config *cfg = vpbe_dev->cfg; struct v4l2_dv_timings dv_timings; struct osd_state *osd_device; int out_index = vpbe_dev->current_out_index; int ret = 0; int i; if ((NULL == mode_info) || (NULL == mode_info->name)) return -EINVAL; for (i = 0; i < cfg->outputs[out_index].num_modes; i++) { if (!strcmp(mode_info->name, cfg->outputs[out_index].modes[i].name)) { preset_mode = &cfg->outputs[out_index].modes[i]; /* * it may be one of the 3 timings type. Check and * invoke right API */ if (preset_mode->timings_type & VPBE_ENC_STD) return vpbe_s_std(vpbe_dev, &preset_mode->std_id); if (preset_mode->timings_type & VPBE_ENC_CUSTOM_TIMINGS) { dv_timings = preset_mode->dv_timings; return vpbe_s_dv_timings(vpbe_dev, &dv_timings); } } } /* Only custom timing should reach here */ if (preset_mode == NULL) return -EINVAL; mutex_lock(&vpbe_dev->lock); osd_device = vpbe_dev->osd_device; vpbe_dev->current_timings = *preset_mode; osd_device->ops.set_left_margin(osd_device, vpbe_dev->current_timings.left_margin); osd_device->ops.set_top_margin(osd_device, vpbe_dev->current_timings.upper_margin); mutex_unlock(&vpbe_dev->lock); return ret; }
/** * vpbe_set_mode - Set mode in the current encoder using mode info * * Use the mode string to decide what timings to set in the encoder * This is typically useful when fbset command is used to change the current * timings by specifying a string to indicate the timings. */ static int vpbe_set_mode(struct vpbe_device *vpbe_dev, struct vpbe_enc_mode_info *mode_info) { struct vpbe_display_config *vpbe_config = vpbe_dev->cfg; int out_index = vpbe_dev->current_out_index, ret = 0, i; struct vpbe_enc_mode_info *preset_mode = NULL; struct v4l2_dv_preset dv_preset; if ((NULL == mode_info) || (NULL == mode_info->name)) return -EINVAL; for (i = 0; i < vpbe_config->outputs[out_index].num_modes; i++) { if (!strcmp(mode_info->name, vpbe_config->outputs[out_index].modes[i].name)) { preset_mode = &vpbe_config->outputs[out_index].modes[i]; /* * it may be one of the 3 timings type. Check and * invoke right API */ if (preset_mode->timings_type & VPBE_ENC_STD) return vpbe_s_std(vpbe_dev, &preset_mode->timings.std_id); if (preset_mode->timings_type & VPBE_ENC_DV_PRESET) { dv_preset.preset = preset_mode->timings.dv_preset; return vpbe_s_dv_preset(vpbe_dev, &dv_preset); } } } /* Only custom timing should reach here */ if (preset_mode == NULL) return -EINVAL; mutex_lock(&vpbe_dev->lock); ret = v4l2_subdev_call(vpbe_dev->venc, core, ioctl, VENC_CONFIGURE, preset_mode); if (!ret) { vpbe_dev->current_timings = *preset_mode; osd_device->ops.set_left_margin(osd_device, vpbe_dev->current_timings.left_margin); osd_device->ops.set_top_margin(osd_device, vpbe_dev->current_timings.upper_margin); } mutex_unlock(&vpbe_dev->lock); return ret; }