static void ccdc_restore_defaults(void) { enum vpss_ccdc_source_sel source = VPSS_CCDCIN; int i; memcpy(&ccdc_cfg.bayer.config_params, &ccdc_config_defaults, sizeof(struct ccdc_config_params_raw)); dev_dbg(dev, "\nstarting ccdc_restore_defaults..."); /* Enable clock to ISIF, IPIPEIF and BL */ vpss_enable_clock(VPSS_CCDC_CLOCK, 1); vpss_enable_clock(VPSS_IPIPEIF_CLOCK, 1); vpss_enable_clock(VPSS_BL_CLOCK, 1); /* set all registers to default value */ for (i = 0; i <= 0x1f8; i += 4) regw(0, i); /* no culling support */ regw(0xffff, CULH); regw(0xff, CULV); /* Set default offset and gain */ ccdc_config_gain_offset(); vpss_select_ccdc_source(source); dev_dbg(dev, "\nEnd of ccdc_restore_defaults..."); }
static int ccdc_close(struct device *device) { /* disable clock */ vpss_enable_clock(VPSS_CCDC_CLOCK, 0); /* do nothing for now */ return 0; }
/* * ccdc_restore_defaults() * This function restore power on defaults in the ccdc registers */ static int ccdc_restore_defaults(void) { int i; dev_dbg(dev, "\nstarting ccdc_restore_defaults..."); /* set all registers to zero */ for (i = 0; i <= CCDC_REG_LAST; i += 4) regw(0, i); /* now override the values with power on defaults in registers */ regw(MODESET_DEFAULT, MODESET); /* no culling support */ regw(CULH_DEFAULT, CULH); regw(CULV_DEFAULT, CULV); /* Set default Gain and Offset */ ccdc_hw_params_raw.gain.r_ye = GAIN_DEFAULT; ccdc_hw_params_raw.gain.gb_g = GAIN_DEFAULT; ccdc_hw_params_raw.gain.gr_cy = GAIN_DEFAULT; ccdc_hw_params_raw.gain.b_mg = GAIN_DEFAULT; ccdc_config_gain_offset(); regw(OUTCLIP_DEFAULT, OUTCLIP); regw(LSCCFG2_DEFAULT, LSCCFG2); /* select ccdc input */ if (vpss_select_ccdc_source(VPSS_CCDCIN)) { dev_dbg(dev, "\ncouldn't select ccdc input source"); return -EFAULT; } /* select ccdc clock */ if (vpss_enable_clock(VPSS_CCDC_CLOCK, 1) < 0) { dev_dbg(dev, "\ncouldn't enable ccdc clock"); return -EFAULT; } dev_dbg(dev, "\nEnd of ccdc_restore_defaults..."); return 0; }
/** * vpbe_deinitialize() - de-initialize the vpbe display controller * @dev - Master and slave device ptr * * vpbe_master and slave frame buffer devices calls this to de-initialize * the display controller. It is called when master and slave device * driver modules are removed and no longer requires the display controller. */ void vpbe_deinitialize(struct device *dev, struct vpbe_device *vpbe_dev) { v4l2_device_unregister(&vpbe_dev->v4l2_dev); if (strcmp(vpbe_dev->cfg->module_name, "dm644x-vpbe-display") != 0) clk_put(vpbe_dev->dac_clk); kfree(vpbe_dev->amp); kfree(vpbe_dev->encoders); vpbe_dev->initialized = 0; /* disaable vpss clocks */ vpss_enable_clock(VPSS_VPBE_CLOCK, 0); }
/** * vpbe_initialize() - Initialize the vpbe display controller * @vpbe_dev - vpbe device ptr * * Master frame buffer device drivers calls this to initialize vpbe * display controller. This will then registers v4l2 device and the sub * devices and sets a current encoder sub device for display. v4l2 display * device driver is the master and frame buffer display device driver is * the slave. Frame buffer display driver checks the initialized during * probe and exit if not initialized. Returns status. */ static int vpbe_initialize(struct device *dev, struct vpbe_device *vpbe_dev) { struct encoder_config_info *enc_info; struct amp_config_info *amp_info; struct v4l2_subdev **enc_subdev; struct osd_state *osd_device; struct i2c_adapter *i2c_adap; int output_index; int num_encoders; int ret = 0; int err; int i; /* * v4l2 abd FBDev frame buffer devices will get the vpbe_dev pointer * from the platform device by iteration of platform drivers and * matching with device name */ if (NULL == vpbe_dev || NULL == dev) { printk(KERN_ERR "Null device pointers.\n"); return -ENODEV; } if (vpbe_dev->initialized) return 0; mutex_lock(&vpbe_dev->lock); if (strcmp(vpbe_dev->cfg->module_name, "dm644x-vpbe-display") != 0) { /* We have dac clock available for platform */ vpbe_dev->dac_clk = clk_get(vpbe_dev->pdev, "vpss_dac"); if (IS_ERR(vpbe_dev->dac_clk)) { ret = PTR_ERR(vpbe_dev->dac_clk); goto fail_mutex_unlock; } if (clk_prepare_enable(vpbe_dev->dac_clk)) { ret = -ENODEV; goto fail_mutex_unlock; } } /* first enable vpss clocks */ vpss_enable_clock(VPSS_VPBE_CLOCK, 1); /* First register a v4l2 device */ ret = v4l2_device_register(dev, &vpbe_dev->v4l2_dev); if (ret) { v4l2_err(dev->driver, "Unable to register v4l2 device.\n"); goto fail_clk_put; } v4l2_info(&vpbe_dev->v4l2_dev, "vpbe v4l2 device registered\n"); err = bus_for_each_dev(&platform_bus_type, NULL, vpbe_dev, platform_device_get); if (err < 0) return err; vpbe_dev->venc = venc_sub_dev_init(&vpbe_dev->v4l2_dev, vpbe_dev->cfg->venc.module_name); /* register venc sub device */ if (vpbe_dev->venc == NULL) { v4l2_err(&vpbe_dev->v4l2_dev, "vpbe unable to init venc sub device\n"); ret = -ENODEV; goto fail_dev_unregister; } /* initialize osd device */ osd_device = vpbe_dev->osd_device; if (NULL != osd_device->ops.initialize) { err = osd_device->ops.initialize(osd_device); if (err) { v4l2_err(&vpbe_dev->v4l2_dev, "unable to initialize the OSD device"); err = -ENOMEM; goto fail_dev_unregister; } } /* * Register any external encoders that are configured. At index 0 we * store venc sd index. */ num_encoders = vpbe_dev->cfg->num_ext_encoders + 1; vpbe_dev->encoders = kmalloc( sizeof(struct v4l2_subdev *)*num_encoders, GFP_KERNEL); if (NULL == vpbe_dev->encoders) { v4l2_err(&vpbe_dev->v4l2_dev, "unable to allocate memory for encoders sub devices"); ret = -ENOMEM; goto fail_dev_unregister; } i2c_adap = i2c_get_adapter(vpbe_dev->cfg->i2c_adapter_id); for (i = 0; i < (vpbe_dev->cfg->num_ext_encoders + 1); i++) { if (i == 0) { /* venc is at index 0 */ enc_subdev = &vpbe_dev->encoders[i]; *enc_subdev = vpbe_dev->venc; continue; } enc_info = &vpbe_dev->cfg->ext_encoders[i]; if (enc_info->is_i2c) { enc_subdev = &vpbe_dev->encoders[i]; *enc_subdev = v4l2_i2c_new_subdev_board( &vpbe_dev->v4l2_dev, i2c_adap, &enc_info->board_info, NULL); if (*enc_subdev) v4l2_info(&vpbe_dev->v4l2_dev, "v4l2 sub device %s registered\n", enc_info->module_name); else { v4l2_err(&vpbe_dev->v4l2_dev, "encoder %s" " failed to register", enc_info->module_name); ret = -ENODEV; goto fail_kfree_encoders; } } else v4l2_warn(&vpbe_dev->v4l2_dev, "non-i2c encoders" " currently not supported"); } /* Add amplifier subdevice for dm365 */ if ((strcmp(vpbe_dev->cfg->module_name, "dm365-vpbe-display") == 0) && vpbe_dev->cfg->amp != NULL) { amp_info = vpbe_dev->cfg->amp; if (amp_info->is_i2c) { vpbe_dev->amp = v4l2_i2c_new_subdev_board( &vpbe_dev->v4l2_dev, i2c_adap, &_info->board_info, NULL); if (!vpbe_dev->amp) { v4l2_err(&vpbe_dev->v4l2_dev, "amplifier %s failed to register", amp_info->module_name); ret = -ENODEV; goto fail_kfree_encoders; } v4l2_info(&vpbe_dev->v4l2_dev, "v4l2 sub device %s registered\n", amp_info->module_name); } else { vpbe_dev->amp = NULL; v4l2_warn(&vpbe_dev->v4l2_dev, "non-i2c amplifiers" " currently not supported"); } } else { vpbe_dev->amp = NULL; } /* set the current encoder and output to that of venc by default */ vpbe_dev->current_sd_index = 0; vpbe_dev->current_out_index = 0; output_index = 0; mutex_unlock(&vpbe_dev->lock); printk(KERN_NOTICE "Setting default output to %s\n", def_output); ret = vpbe_set_default_output(vpbe_dev); if (ret) { v4l2_err(&vpbe_dev->v4l2_dev, "Failed to set default output %s", def_output); return ret; } printk(KERN_NOTICE "Setting default mode to %s\n", def_mode); ret = vpbe_set_default_mode(vpbe_dev); if (ret) { v4l2_err(&vpbe_dev->v4l2_dev, "Failed to set default mode %s", def_mode); return ret; } vpbe_dev->initialized = 1; /* TBD handling of bootargs for default output and mode */ return 0; fail_kfree_encoders: kfree(vpbe_dev->encoders); fail_dev_unregister: v4l2_device_unregister(&vpbe_dev->v4l2_dev); fail_clk_put: if (strcmp(vpbe_dev->cfg->module_name, "dm644x-vpbe-display") != 0) { clk_disable_unprepare(vpbe_dev->dac_clk); clk_put(vpbe_dev->dac_clk); } fail_mutex_unlock: mutex_unlock(&vpbe_dev->lock); return ret; }