/** * isph3a_aewb_configure - Configure AEWB regs, enable/disable H3A engine. * @aewbcfg: Pointer to AEWB config structure. * * Returns 0 if successful, -EINVAL if aewbcfg pointer is NULL, -ENOMEM if * was unable to allocate memory for the buffer, of other errors if H3A * callback is not set or the parameters for AEWB are invalid. **/ int isph3a_aewb_configure(struct isp_h3a_device *isp_h3a, struct isph3a_aewb_config *aewbcfg) { int ret = 0; int win_count = 0; unsigned int buf_size; unsigned long irqflags; struct ispstat_buffer *buf; if (NULL == aewbcfg) { dev_info(isp_h3a->dev, "h3a: Null argument in configuration\n"); return -EINVAL; } ret = isph3a_aewb_validate_params(isp_h3a, aewbcfg); if (ret) return ret; /* FIXME: This win_count handling looks really fishy. */ win_count = aewbcfg->ver_win_count * aewbcfg->hor_win_count; win_count += aewbcfg->hor_win_count; ret = win_count / 8; win_count += win_count % 8 ? 1 : 0; win_count += ret; buf_size = win_count * AEWB_PACKET_SIZE; ret = ispstat_bufs_alloc(&isp_h3a->stat, buf_size); if (ret) return ret; buf = ispstat_buf_next(&isp_h3a->stat); spin_lock_irqsave(isp_h3a->lock, irqflags); isp_h3a->win_count = win_count; isph3a_aewb_set_params(isp_h3a, aewbcfg); isp_reg_writel(isp_h3a->dev, buf->iommu_addr, OMAP3_ISP_IOMEM_H3A, ISPH3A_AEWBUFST); spin_unlock_irqrestore(isp_h3a->lock, irqflags); isph3a_aewb_enable(isp_h3a, aewbcfg->aewb_enable); isph3a_print_status(isp_h3a); return 0; }
/** * isph3a_aewb_config - Configure AEWB regs, enable/disable H3A engine. * @aewbcfg: Pointer to AEWB config structure. * * Returns 0 if successful, -EINVAL if aewbcfg pointer is NULL, -ENOMEM if * was unable to allocate memory for the buffer, of other errors if H3A * callback is not set or the parameters for AEWB are invalid. **/ int isph3a_aewb_config(struct isp_h3a_device *isp_h3a, struct isph3a_aewb_config *aewbcfg) { struct device *dev = to_device(isp_h3a); int ret = 0; int win_count = 0; unsigned int buf_size; unsigned long irqflags; if (NULL == aewbcfg) { dev_dbg(dev, "h3a: Null argument in configuration\n"); return -EINVAL; } ret = isph3a_aewb_validate_params(isp_h3a, aewbcfg); if (ret) return ret; /* FIXME: This win_count handling looks really fishy. */ win_count = aewbcfg->ver_win_count * aewbcfg->hor_win_count; win_count += aewbcfg->hor_win_count; ret = win_count / 8; win_count += win_count % 8 ? 1 : 0; win_count += ret; buf_size = win_count * AEWB_PACKET_SIZE; ret = ispstat_bufs_alloc(&isp_h3a->stat, buf_size, 0); if (ret) return ret; spin_lock_irqsave(isp_h3a->lock, irqflags); isp_h3a->win_count = win_count; isph3a_aewb_set_params(isp_h3a, aewbcfg); spin_unlock_irqrestore(isp_h3a->lock, irqflags); return 0; }
/* Function to perform hardware set up */ int isp_af_config(struct isp_af_device *isp_af, struct af_configuration *afconfig) { struct device *dev = to_device(isp_af); int result; int buf_size; unsigned long irqflags; if (!afconfig) { dev_dbg(dev, "af: Null argument in configuration.\n"); return -EINVAL; } /* Check Parameters */ spin_lock_irqsave(isp_af->lock, irqflags); result = isp_af_check_params(isp_af, afconfig); spin_unlock_irqrestore(isp_af->lock, irqflags); if (result) { dev_dbg(dev, "af: wrong configure params received.\n"); return result; } /* Compute buffer size */ buf_size = (afconfig->paxel_config.hz_cnt + 1) * (afconfig->paxel_config.vt_cnt + 1) * AF_PAXEL_SIZE; result = ispstat_bufs_alloc(&isp_af->stat, buf_size, 0); if (result) return result; spin_lock_irqsave(isp_af->lock, irqflags); isp_af->buf_size = buf_size; isp_af_update_params(isp_af, afconfig); spin_unlock_irqrestore(isp_af->lock, irqflags); /* Success */ return 0; }
/* * ispstat_config - Receives new statistic engine configuration. * @new_conf: Pointer to config structure. * * Returns 0 if successful, -EINVAL if new_conf pointer is NULL, -ENOMEM if * was unable to allocate memory for the buffer, or other errors if parameters * are invalid. */ int ispstat_config(struct ispstat *stat, void *new_conf) { int ret; unsigned long irqflags; struct ispstat_generic_config *user_cfg = new_conf; u32 buf_size = user_cfg->buf_size; if (!new_conf) { dev_dbg(stat->isp->dev, "%s: configuration is NULL\n", stat->subdev.name); return -EINVAL; } mutex_lock(&stat->ioctl_lock); dev_dbg(stat->isp->dev, "%s: configuring module with buffer " "size=0x%08lx\n", stat->subdev.name, (unsigned long)buf_size); ret = stat->ops->validate_params(stat, new_conf); if (ret) { mutex_unlock(&stat->ioctl_lock); dev_dbg(stat->isp->dev, "%s: configuration values are " "invalid.\n", stat->subdev.name); return ret; } if (buf_size != user_cfg->buf_size) dev_dbg(stat->isp->dev, "%s: driver has corrected buffer size " "request to 0x%08lx\n", stat->subdev.name, (unsigned long)user_cfg->buf_size); /* * Hack: H3A modules may need a doubled buffer size to avoid access * to a invalid memory address after a SBL overflow. * The buffer size is always PAGE_ALIGNED. * Hack 2: MAGIC_SIZE is added to buf_size so a magic word can be * inserted at the end to data integrity check purpose. * Hack 3: AF module writes one paxel data more than it should, so * the buffer allocation must consider it to avoid invalid memory * access. */ if (IS_H3A_AEWB(stat)) buf_size = PAGE_ALIGN(user_cfg->buf_size * 2 + MAGIC_SIZE); else if (IS_H3A_AF(stat)) buf_size = PAGE_ALIGN(user_cfg->buf_size * 2 + MAGIC_SIZE + AF_EXTRA_DATA); else buf_size = PAGE_ALIGN(user_cfg->buf_size + MAGIC_SIZE); ret = ispstat_bufs_alloc(stat, buf_size); if (ret) { mutex_unlock(&stat->ioctl_lock); return ret; } spin_lock_irqsave(&stat->isp->stat_lock, irqflags); stat->ops->set_params(stat, new_conf); spin_unlock_irqrestore(&stat->isp->stat_lock, irqflags); /* * Returning the right future config_counter for this setup, so * userspace can *know* when it has been applied. */ user_cfg->config_counter = stat->config_counter + stat->inc_config; /* Module has a valid configuration. */ stat->configured = 1; dev_dbg(stat->isp->dev, "%s: module has been successfully " "configured.\n", stat->subdev.name); mutex_unlock(&stat->ioctl_lock); return 0; }