/** * ispccdc_allocate_lsc - Allocate space for Lens Shading Compensation table * @table_size: LSC gain table size. * * Returns 0 if successful, -ENOMEM of its no memory available, or -EINVAL if * table_size is zero. **/ static int ispccdc_allocate_lsc(u32 table_size) { if (table_size == 0) return -EINVAL; if ((lsc_config.size >= table_size) && lsc_gain_table) return 0; ispccdc_free_lsc(); lsc_gain_table = kmalloc(table_size, GFP_KERNEL | GFP_DMA); if (!lsc_gain_table) { printk(KERN_ERR "Cannot allocate memory for gain tables \n"); return -ENOMEM; } lsc_ispmmu_addr = ispmmu_kmap(virt_to_phys(lsc_gain_table), table_size); if (lsc_ispmmu_addr <= 0) { printk(KERN_ERR "Cannot map memory for gain tables \n"); kfree(lsc_gain_table); return -ENOMEM; } return 0; }
/** * omap34xx_isp_ccdc_config - Sets CCDC configuration from userspace * @userspace_add: Structure containing CCDC configuration sent from userspace. * * Returns 0 if successful, -EINVAL if the pointer to the configuration * structure is null, or the copy_from_user function fails to copy user space * memory to kernel space memory. **/ int omap34xx_isp_ccdc_config(void *userspace_add) { struct ispccdc_bclamp bclamp_t; struct ispccdc_blcomp blcomp_t; struct ispccdc_fpc fpc_t; struct ispccdc_culling cull_t; struct ispccdc_update_config *ccdc_struct; if (userspace_add == NULL) return -EINVAL; ccdc_struct = userspace_add; if (ISP_ABS_CCDC_ALAW & ccdc_struct->flag) { if (ISP_ABS_CCDC_ALAW & ccdc_struct->update) ispccdc_config_alaw(ccdc_struct->alawip); ispccdc_enable_alaw(1); } else if (ISP_ABS_CCDC_ALAW & ccdc_struct->update) ispccdc_enable_alaw(0); if (ISP_ABS_CCDC_LPF & ccdc_struct->flag) ispccdc_enable_lpf(1); else ispccdc_enable_lpf(0); if (ISP_ABS_CCDC_BLCLAMP & ccdc_struct->flag) { if (ISP_ABS_CCDC_BLCLAMP & ccdc_struct->update) { if (copy_from_user(&bclamp_t, (struct ispccdc_bclamp *) ccdc_struct->bclamp, sizeof(struct ispccdc_bclamp))) goto copy_from_user_err; ispccdc_enable_black_clamp(1); ispccdc_config_black_clamp(bclamp_t); } else ispccdc_enable_black_clamp(1); } else { if (ISP_ABS_CCDC_BLCLAMP & ccdc_struct->update) { if (copy_from_user(&bclamp_t, (struct ispccdc_bclamp *) ccdc_struct->bclamp, sizeof(struct ispccdc_bclamp))) goto copy_from_user_err; ispccdc_enable_black_clamp(0); ispccdc_config_black_clamp(bclamp_t); } } if (ISP_ABS_CCDC_BCOMP & ccdc_struct->update) { if (copy_from_user(&blcomp_t, (struct ispccdc_blcomp *) ccdc_struct->blcomp, sizeof(blcomp_t))) goto copy_from_user_err; ispccdc_config_black_comp(blcomp_t); } if (ISP_ABS_CCDC_FPC & ccdc_struct->flag) { if (ISP_ABS_CCDC_FPC & ccdc_struct->update) { if (copy_from_user(&fpc_t, (struct ispccdc_fpc *) ccdc_struct->fpc, sizeof(fpc_t))) goto copy_from_user_err; fpc_table_add = kmalloc(64 + fpc_t.fpnum * 4, GFP_KERNEL | GFP_DMA); if (!fpc_table_add) { printk(KERN_ERR "Cannot allocate memory for" " FPC table"); return -ENOMEM; } while (((unsigned long)fpc_table_add & 0xFFFFFFC0) != (unsigned long)fpc_table_add) fpc_table_add++; fpc_table_add_m = ispmmu_kmap(virt_to_phys (fpc_table_add), fpc_t.fpnum * 4); if (copy_from_user(fpc_table_add, (u32 *)fpc_t.fpcaddr, fpc_t.fpnum * 4)) goto copy_from_user_err; fpc_t.fpcaddr = fpc_table_add_m; ispccdc_config_fpc(fpc_t); } ispccdc_enable_fpc(1); } else if (ISP_ABS_CCDC_FPC & ccdc_struct->update) ispccdc_enable_fpc(0); if (ISP_ABS_CCDC_CULL & ccdc_struct->update) { if (copy_from_user(&cull_t, (struct ispccdc_culling *) ccdc_struct->cull, sizeof(cull_t))) goto copy_from_user_err; ispccdc_config_culling(cull_t); } if (is_isplsc_activated()) { if (ISP_ABS_CCDC_CONFIG_LSC & ccdc_struct->flag) { if (ISP_ABS_CCDC_CONFIG_LSC & ccdc_struct->update) { if (copy_from_user( &lsc_config, (struct ispccdc_lsc_config *) ccdc_struct->lsc_cfg, sizeof(struct ispccdc_lsc_config))) goto copy_from_user_err; ispccdc_config_lsc(&lsc_config); } ispccdc_enable_lsc(1); } else if (ISP_ABS_CCDC_CONFIG_LSC & ccdc_struct->update) { ispccdc_enable_lsc(0); } if (ISP_ABS_TBL_LSC & ccdc_struct->update) { if (copy_from_user(lsc_gain_table, ccdc_struct->lsc, lsc_config.size)) goto copy_from_user_err; ispccdc_load_lsc(lsc_gain_table, lsc_config.size); } } if (ISP_ABS_CCDC_COLPTN & ccdc_struct->update) ispccdc_config_imgattr(ccdc_struct->colptn); return 0; copy_from_user_err: printk(KERN_ERR "CCDC Config:Copy From User Error"); return -EINVAL ; }
/* Function to perform hardware set up */ int isp_af_configure(struct af_configuration *afconfig) { int result; int buff_size, i; unsigned int busyaf; struct af_configuration *af_curr_cfg = af_dev_configptr->config; if (NULL == afconfig) { printk(KERN_ERR "Null argument in configuration. \n"); return -EINVAL; } memcpy(af_curr_cfg, afconfig, sizeof(struct af_configuration)); /* Get the value of PCR register */ busyaf = isp_reg_readl(OMAP3_ISP_IOMEM_H3A, ISPH3A_PCR); if ((busyaf & AF_BUSYAF) == AF_BUSYAF) { DPRINTK_ISP_AF("AF_register_setup_ERROR : Engine Busy"); DPRINTK_ISP_AF("\n Configuration cannot be done "); return -AF_ERR_ENGINE_BUSY; } /* Check IIR Coefficient and start Values */ result = isp_af_check_iir(); if (result < 0) return result; /* Check Paxel Values */ result = isp_af_check_paxel(); if (result < 0) return result; /* Check HMF Threshold Values */ if (af_curr_cfg->hmf_config.threshold > AF_THRESHOLD_MAX) { DPRINTK_ISP_AF("Error : HMF Threshold is incorrect"); return -AF_ERR_THRESHOLD; } /* Compute buffer size */ buff_size = (af_curr_cfg->paxel_config.hz_cnt + 1) * (af_curr_cfg->paxel_config.vt_cnt + 1) * AF_PAXEL_SIZE; afstat.curr_cfg_buf_size = buff_size; /* Deallocate the previous buffers */ if (afstat.stats_buf_size && buff_size > afstat.stats_buf_size) { isp_af_enable(0); for (i = 0; i < H3A_MAX_BUFF; i++) { ispmmu_kunmap(afstat.af_buff[i].ispmmu_addr); free_pages_exact((void *)afstat.af_buff[i].virt_addr, afstat.min_buf_size); afstat.af_buff[i].virt_addr = 0; } afstat.stats_buf_size = 0; } if (!afstat.af_buff[0].virt_addr) { afstat.stats_buf_size = buff_size; afstat.min_buf_size = PAGE_ALIGN(afstat.stats_buf_size); for (i = 0; i < H3A_MAX_BUFF; i++) { afstat.af_buff[i].virt_addr = (unsigned long)alloc_pages_exact( afstat.min_buf_size, GFP_KERNEL | GFP_DMA); if (afstat.af_buff[i].virt_addr == 0) { printk(KERN_ERR "Can't acquire memory for " "buffer[%d]\n", i); return -ENOMEM; } afstat.af_buff[i].phy_addr = dma_map_single(NULL, (void *)afstat.af_buff[i].virt_addr, afstat.min_buf_size, DMA_FROM_DEVICE); afstat.af_buff[i].addr_align = afstat.af_buff[i].virt_addr; while ((afstat.af_buff[i].addr_align & 0xFFFFFFC0) != afstat.af_buff[i].addr_align) afstat.af_buff[i].addr_align++; afstat.af_buff[i].ispmmu_addr = ispmmu_kmap(afstat.af_buff[i].phy_addr, afstat.min_buf_size); } isp_af_unlock_buffers(); isp_af_link_buffers(); /* First active buffer */ if (active_buff == NULL) active_buff = &afstat.af_buff[0]; isp_af_set_address(active_buff->ispmmu_addr); } result = isp_af_register_setup(af_dev_configptr); if (result < 0) return result; af_dev_configptr->size_paxel = buff_size; atomic_inc(&afstat.config_counter); afstat.initialized = 1; afstat.frame_count = 1; active_buff->frame_num = 1; /* Set configuration flag to indicate HW setup done */ if (af_curr_cfg->af_config) isp_af_enable(1); else isp_af_enable(0); /* Success */ return 0; }