int msm_jpeg_platform_set_clk_rate(struct msm_jpeg_device *pgmn_dev, long clk_rate) { int rc = 0; struct clk *jpeg_clk; jpeg_clk = clk_get(&pgmn_dev->pdev->dev, "core_clk"); if (IS_ERR(jpeg_clk)) { JPEG_PR_ERR("%s get failed\n", "core_clk"); rc = PTR_ERR(jpeg_clk); goto error; } clk_rate = clk_round_rate(jpeg_clk, clk_rate); if (clk_rate < 0) { JPEG_PR_ERR("%s:%d] round rate failed", __func__, __LINE__); rc = -EINVAL; goto error; } JPEG_DBG("%s:%d] jpeg clk rate %ld", __func__, __LINE__, clk_rate); rc = clk_set_rate(jpeg_clk, clk_rate); error: return rc; }
int msm_jpeg_hw_exec_cmds(struct msm_jpeg_hw_cmd *hw_cmd_p, uint32_t m_cmds, uint32_t max_size, void *base) { int is_copy_to_user = 0; uint32_t data; while (m_cmds--) { if (hw_cmd_p->offset >= max_size) { JPEG_PR_ERR("%s:%d] %d exceed hw region %d\n", __func__, __LINE__, hw_cmd_p->offset, max_size); return -EFAULT; } if (hw_cmd_p->offset & 0x3) { JPEG_PR_ERR("%s:%d] %d Invalid alignment\n", __func__, __LINE__, hw_cmd_p->offset); return -EFAULT; } switch (hw_cmd_p->type) { case MSM_JPEG_HW_CMD_TYPE_READ: hw_cmd_p->data = msm_jpeg_hw_read(hw_cmd_p, base); is_copy_to_user = 1; break; case MSM_JPEG_HW_CMD_TYPE_WRITE: msm_jpeg_hw_write(hw_cmd_p, base); break; case MSM_JPEG_HW_CMD_TYPE_WRITE_OR: data = msm_jpeg_hw_read(hw_cmd_p, base); hw_cmd_p->data = (hw_cmd_p->data & hw_cmd_p->mask) | data; msm_jpeg_hw_write(hw_cmd_p, base); break; case MSM_JPEG_HW_CMD_TYPE_UWAIT: msm_jpeg_hw_wait(hw_cmd_p, 1, base); break; case MSM_JPEG_HW_CMD_TYPE_MWAIT: msm_jpeg_hw_wait(hw_cmd_p, 1000, base); break; case MSM_JPEG_HW_CMD_TYPE_UDELAY: msm_jpeg_hw_delay(hw_cmd_p, 1); break; case MSM_JPEG_HW_CMD_TYPE_MDELAY: msm_jpeg_hw_delay(hw_cmd_p, 1000); break; default: JPEG_PR_ERR("wrong hw command type\n"); break; } hw_cmd_p++; } return is_copy_to_user; }
uint32_t msm_jpeg_platform_v2p(struct msm_jpeg_device *pgmn_dev, int fd, uint32_t len, int iommu_hdl) { dma_addr_t paddr; size_t size; int rc; rc = cam_smmu_get_phy_addr(pgmn_dev->iommu_hdl, fd, CAM_SMMU_MAP_RW, &paddr, &size); JPEG_DBG("%s:%d] addr 0x%x size %zu", __func__, __LINE__, (uint32_t)paddr, size); if (rc < 0) { JPEG_PR_ERR("%s: fd %d got phy addr error %d\n", __func__, fd, rc); goto err_get_phy; } /* validate user input */ if (len > size) { JPEG_PR_ERR("%s: invalid offset + len\n", __func__); goto err_size; } return paddr; err_size: cam_smmu_put_phy_addr(pgmn_dev->iommu_hdl, fd); err_get_phy: return 0; }
void msm_jpeg_io_dump(int size) { char line_str[128], *p_str; void __iomem *addr = jpeg_region_base; int i; u32 *p = (u32 *) addr; u32 data; JPEG_PR_ERR("%s: %p %d reg_size %d\n", __func__, addr, size, jpeg_region_size); line_str[0] = '\0'; p_str = line_str; for (i = 0; i < size/4; i++) { if (i % 4 == 0) { snprintf(p_str, 12, "%08x: ", (u32) p); p_str += 10; } data = readl_relaxed(p++); snprintf(p_str, 12, "%08x ", data); p_str += 9; if ((i + 1) % 4 == 0) { JPEG_PR_ERR("%s\n", line_str); line_str[0] = '\0'; p_str = line_str; } } if (line_str[0] != '\0') JPEG_PR_ERR("%s\n", line_str); }
uint32_t msm_jpeg_platform_v2p(struct msm_jpeg_device *pgmn_dev, int fd, uint32_t len, struct file **file_p, struct ion_handle **ionhandle, int domain_num) { unsigned long paddr; unsigned long size; int rc; *ionhandle = ion_import_dma_buf(pgmn_dev->jpeg_client, fd); if (IS_ERR_OR_NULL(*ionhandle)) return 0; rc = ion_map_iommu(pgmn_dev->jpeg_client, *ionhandle, domain_num, 0, SZ_4K, 0, &paddr, (unsigned long *)&size, 0, 0); JPEG_DBG("%s:%d] addr 0x%x size %ld", __func__, __LINE__, (uint32_t)paddr, size); if (rc < 0) { JPEG_PR_ERR("%s: ion_map_iommu fd %d error %d\n", __func__, fd, rc); goto error1; } /* validate user input */ if (len > size) { JPEG_PR_ERR("%s: invalid offset + len\n", __func__); goto error1; } return paddr; error1: ion_free(pgmn_dev->jpeg_client, *ionhandle); return 0; }
/* * msm_jpeg_set_init_dt_parms() - get device tree config and write to registers. * @pgmn_dev: Pointer to jpeg device. * @dt_prop_name: Device tree property name. * @base: Base address. * * This function reads register offsets and values from dtsi based on * device tree property name and writes to jpeg registers. * * Return: 0 on success and negative error on failure. */ static int32_t msm_jpeg_set_init_dt_parms(struct msm_jpeg_device *pgmn_dev, const char *dt_prop_name, void *base) { struct device_node *of_node; int32_t i = 0 , rc = 0; uint32_t *dt_reg_settings = NULL; uint32_t dt_count = 0; of_node = pgmn_dev->pdev->dev.of_node; JPEG_DBG("%s:%d E\n", __func__, __LINE__); if (!of_get_property(of_node, dt_prop_name, &dt_count)) { JPEG_DBG("%s: Error property does not exist\n", __func__); return -ENOENT; } if (dt_count % 8) { JPEG_PR_ERR("%s: Error invalid entries\n", __func__); return -EINVAL; } dt_count /= 4; if (dt_count != 0) { dt_reg_settings = kcalloc(dt_count, sizeof(uint32_t), GFP_KERNEL); if (!dt_reg_settings) { JPEG_PR_ERR("%s:%d No memory\n", __func__, __LINE__); return -ENOMEM; } rc = of_property_read_u32_array(of_node, dt_prop_name, dt_reg_settings, dt_count); if (rc < 0) { JPEG_PR_ERR("%s: No reg info\n", __func__); kfree(dt_reg_settings); return -EINVAL; } for (i = 0; i < dt_count; i = i + 2) { JPEG_DBG("%s:%d] %p %08x\n", __func__, __LINE__, base + dt_reg_settings[i], dt_reg_settings[i + 1]); msm_camera_io_w(dt_reg_settings[i + 1], base + dt_reg_settings[i]); } kfree(dt_reg_settings); } return 0; }
static int msm_jpeg_release(struct inode *inode, struct file *filp) { int rc; struct msm_jpeg_device *pgmn_dev = filp->private_data; JPEG_PR_ERR("%s:%d]\n", __func__, __LINE__); rc = __msm_jpeg_release(pgmn_dev); JPEG_PR_ERR("%s:%d] %s open_count = %d\n", __func__, __LINE__, filp->f_path.dentry->d_name.name, pgmn_dev->open_count); return rc; }
int msm_jpeg_hw_pingpong_update(struct msm_jpeg_hw_pingpong *pingpong_hw, struct msm_jpeg_hw_buf *buf, void *base) { int buf_free_index = -1; if (!pingpong_hw->buf_status[0]) { buf_free_index = 0; } else if (!pingpong_hw->buf_status[1]) { buf_free_index = 1; } else { JPEG_PR_ERR("%s:%d: pingpong buffer busy\n", __func__, __LINE__); return -EBUSY; } pingpong_hw->buf[buf_free_index] = *buf; pingpong_hw->buf_status[buf_free_index] = 1; if (pingpong_hw->is_fe) { /* it is fe */ msm_jpeg_hw_fe_buffer_update( &pingpong_hw->buf[buf_free_index], buf_free_index, base); } else { /* it is we */ msm_jpeg_hw_we_buffer_update( &pingpong_hw->buf[buf_free_index], buf_free_index, base); } return 0; }
static int msm_jpeg_open(struct inode *inode, struct file *filp) { int rc = 0; struct msm_jpeg_device *pgmn_dev = container_of(inode->i_cdev, struct msm_jpeg_device, cdev); filp->private_data = pgmn_dev; JPEG_PR_ERR("%s:%d]\n", __func__, __LINE__); rc = __msm_jpeg_open(pgmn_dev); JPEG_PR_ERR("%s:%d] %s open_count = %d\n", __func__, __LINE__, filp->f_path.dentry->d_name.name, pgmn_dev->open_count); return rc; }
static int msm_jpeg_attach_iommu(struct msm_jpeg_device *pgmn_dev) { int rc; rc = cam_smmu_ops(pgmn_dev->iommu_hdl, CAM_SMMU_ATTACH); if (rc < 0) { JPEG_PR_ERR("%s: Device attach failed\n", __func__); return -ENODEV; } JPEG_DBG("%s:%d] handle %d attach\n", __func__, __LINE__, pgmn_dev->iommu_hdl); return 0; }
void msm_jpeg_hw_we_buffer_update(struct msm_jpeg_hw_buf *p_input, uint8_t pingpong_index, void *base) { struct msm_jpeg_hw_cmd *hw_cmd_p; if (pingpong_index == 0) { hw_cmd_p = &hw_cmd_we_ping_update[0]; hw_cmd_p->data = p_input->y_buffer_addr; JPEG_PR_ERR("%s Output pln0 buffer address is %x\n", __func__, p_input->y_buffer_addr); msm_jpeg_hw_write(hw_cmd_p++, base); hw_cmd_p->data = p_input->cbcr_buffer_addr; JPEG_PR_ERR("%s Output pln1 buffer address is %x\n", __func__, p_input->cbcr_buffer_addr); msm_jpeg_hw_write(hw_cmd_p++, base); hw_cmd_p->data = p_input->pln2_addr; JPEG_PR_ERR("%s Output pln2 buffer address is %x\n", __func__, p_input->pln2_addr); msm_jpeg_hw_write(hw_cmd_p++, base); } return; }
static int msm_jpeg_attach_iommu(struct msm_jpeg_device *pgmn_dev) { int i; for (i = 0; i < pgmn_dev->iommu_cnt; i++) { int rc = iommu_attach_device(pgmn_dev->domain, pgmn_dev->iommu_ctx_arr[i]); if (rc < 0) { JPEG_PR_ERR("%s: Device attach failed\n", __func__); return -ENODEV; } JPEG_DBG("%s:%d] dom 0x%lx ctx 0x%lx", __func__, __LINE__, (unsigned long)pgmn_dev->domain, (unsigned long)pgmn_dev->iommu_ctx_arr[i]); } return 0; }
int msm_jpeg_platform_set_clk_rate(struct msm_jpeg_device *pgmn_dev, long clk_rate) { int rc = 0; struct clk *jpeg_clk; jpeg_clk = clk_get(&pgmn_dev->pdev->dev, "core_clk"); if (IS_ERR(jpeg_clk)) { JPEG_PR_ERR("%s get failed\n", "core_clk"); rc = PTR_ERR(jpeg_clk); return rc; } rc = clk_set_rate(jpeg_clk, clk_rate); return rc; }
int msm_jpeg_platform_release(struct resource *mem, void *base, int irq, void *context) { int result = 0; int i = 0; struct msm_jpeg_device *pgmn_dev = (struct msm_jpeg_device *) context; free_irq(irq, context); #ifdef CONFIG_MSM_IOMMU for (i = 0; i < pgmn_dev->iommu_cnt; i++) { iommu_detach_device(pgmn_dev->domain, pgmn_dev->iommu_ctx_arr[i]); JPEG_DBG("%s:%d]", __func__, __LINE__); } #endif if (pgmn_dev->jpeg_bus_client) { msm_bus_scale_client_update_request( pgmn_dev->jpeg_bus_client, 0); msm_bus_scale_unregister_client(pgmn_dev->jpeg_bus_client); } msm_cam_clk_enable(&pgmn_dev->pdev->dev, jpeg_8x_clk_info, pgmn_dev->jpeg_clk, ARRAY_SIZE(jpeg_8x_clk_info), 0); JPEG_DBG("%s:%d] clock disbale done", __func__, __LINE__); if (pgmn_dev->jpeg_fs) { result = regulator_disable(pgmn_dev->jpeg_fs); if (!result) regulator_put(pgmn_dev->jpeg_fs); else JPEG_PR_ERR("%s:%d] regulator disable failed %d", __func__, __LINE__, result); pgmn_dev->jpeg_fs = NULL; } iounmap(pgmn_dev->jpeg_vbif); iounmap(base); release_mem_region(mem->start, resource_size(mem)); ion_client_destroy(pgmn_dev->jpeg_client); pgmn_dev->state = MSM_JPEG_IDLE; JPEG_DBG("%s:%d] success\n", __func__, __LINE__); return result; }
int msm_jpeg_platform_set_clk_rate(struct msm_jpeg_device *pgmn_dev, long clk_rate) { int rc = 0; uint32_t msm_jpeg_idx; /* retrieve clock index from list of clocks */ msm_jpeg_idx = msm_jpeg_get_clock_index(pgmn_dev, "core_clk"); if (msm_jpeg_idx < 0) { JPEG_PR_ERR("%s:Fail to get clock index\n", __func__); return -EINVAL; } /* set the rate */ msm_camera_clk_set_rate(&pgmn_dev->pdev->dev, pgmn_dev->jpeg_clk[msm_jpeg_idx], clk_rate); return rc; }
int msm_jpeg_platform_release(struct resource *mem, void *base, int irq, void *context) { int result = 0; struct msm_jpeg_device *pgmn_dev = (struct msm_jpeg_device *) context; free_irq(irq, context); msm_jpeg_detach_iommu(pgmn_dev); if (pgmn_dev->jpeg_bus_client) { msm_bus_scale_client_update_request( pgmn_dev->jpeg_bus_client, 0); msm_bus_scale_unregister_client(pgmn_dev->jpeg_bus_client); } msm_cam_clk_enable(&pgmn_dev->pdev->dev, pgmn_dev->jpeg_clk_info, pgmn_dev->jpeg_clk, pgmn_dev->num_clk, 0); JPEG_DBG("%s:%d] clock disbale done", __func__, __LINE__); if (pgmn_dev->jpeg_fs) { result = regulator_disable(pgmn_dev->jpeg_fs); if (!result) regulator_put(pgmn_dev->jpeg_fs); else JPEG_PR_ERR("%s:%d] regulator disable failed %d", __func__, __LINE__, result); pgmn_dev->jpeg_fs = NULL; } iounmap(pgmn_dev->jpeg_vbif); iounmap(base); release_mem_region(mem->start, resource_size(mem)); ion_client_destroy(pgmn_dev->jpeg_client); pgmn_dev->state = MSM_JPEG_IDLE; JPEG_DBG("%s:%d] success\n", __func__, __LINE__); return result; }
/* * msm_jpeg_platform_set_dt_config() - set jpeg device tree configuration. * @pgmn_dev: Pointer to jpeg device. * * This function holds an array of device tree property names and calls * msm_jpeg_set_init_dt_parms() for each property. * * Return: 0 on success and negative error on failure. */ int msm_jpeg_platform_set_dt_config(struct msm_jpeg_device *pgmn_dev) { int rc = 0; uint8_t dt_prop_cnt = JPEG_DT_PROP_CNT; char *dt_prop_name[JPEG_DT_PROP_CNT] = {"qcom,qos-reg-settings", "qcom,prefetch-reg-settings"}; while (dt_prop_cnt) { dt_prop_cnt--; rc = msm_jpeg_set_init_dt_parms(pgmn_dev, dt_prop_name[dt_prop_cnt], pgmn_dev->base); if (rc == -ENOENT) { JPEG_DBG("%s: No %s property\n", __func__, dt_prop_name[dt_prop_cnt]); } else if (rc < 0) { JPEG_PR_ERR("%s: %s params set fail\n", __func__, dt_prop_name[dt_prop_cnt]); return rc; } } return rc; }
int msm_jpeg_platform_init(irqreturn_t (*handler)(int, void *), void *context) { int rc = -1; struct msm_jpeg_device *pgmn_dev = (struct msm_jpeg_device *) context; struct platform_device *pdev = pgmn_dev->pdev; pgmn_dev->state = MSM_JPEG_IDLE; /* enable all regulators */ rc = msm_camera_regulator_enable(pgmn_dev->jpeg_vdd, pgmn_dev->num_reg, true); if (rc < 0) { JPEG_PR_ERR("%s: failed to enable regulators\n", __func__); goto err_reg_enable; } /* enable all clocks */ rc = msm_camera_clk_enable(&pgmn_dev->pdev->dev, pgmn_dev->jpeg_clk_info, pgmn_dev->jpeg_clk, pgmn_dev->num_clk, true); if (rc < 0) { JPEG_PR_ERR("%s: clk enable failed\n", __func__); goto err_clk_enable; } /* attach the smmu context banks */ rc = msm_jpeg_attach_iommu(pgmn_dev); if (rc < 0) { JPEG_PR_ERR("%s: iommu attach failed\n", __func__); goto err_fail_iommu; } rc = msm_jpeg_set_init_dt_parms(pgmn_dev, "qcom,vbif-reg-settings", pgmn_dev->vbif_base); if (rc == -ENOENT) { JPEG_DBG("%s: No qcom,vbif-reg-settings property\n", __func__); set_vbif_params(pgmn_dev, pgmn_dev->vbif_base); } else if (rc < 0) { JPEG_PR_ERR("%s: vbif params set fail\n", __func__); goto err_fail_set_vbif; } /* register the interrupt handler */ rc = msm_camera_register_irq(pgmn_dev->pdev, pgmn_dev->jpeg_irq_res, handler, IRQF_TRIGGER_RISING, "jpeg", context); if (rc < 0) { JPEG_PR_ERR("%s: irq request fail\n", __func__); goto err_reg_irq_fail; } pgmn_dev->hw_version = msm_camera_io_r(pgmn_dev->base + JPEG_HW_VERSION); JPEG_DBG_HIGH("%s:%d] jpeg HW version 0x%x", __func__, __LINE__, pgmn_dev->hw_version); pgmn_dev->state = MSM_JPEG_INIT; return 0; err_reg_irq_fail: err_fail_set_vbif: msm_jpeg_detach_iommu(pgmn_dev); err_fail_iommu: msm_camera_clk_enable(&pdev->dev, pgmn_dev->jpeg_clk_info, pgmn_dev->jpeg_clk, pgmn_dev->num_clk, false); err_clk_enable: msm_camera_regulator_enable(pgmn_dev->jpeg_vdd, pgmn_dev->num_reg, false); err_reg_enable: return rc; }
int msm_jpeg_platform_init(struct platform_device *pdev, struct resource **mem, void **base, int *irq, irqreturn_t (*handler) (int, void *), void *context) { int rc = -1; int i = 0; int jpeg_irq; struct resource *jpeg_mem, *jpeg_io, *jpeg_irq_res; void *jpeg_base; struct msm_jpeg_device *pgmn_dev = (struct msm_jpeg_device *) context; pgmn_dev->state = MSM_JPEG_IDLE; jpeg_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!jpeg_mem) { JPEG_PR_ERR("%s: no mem resource?\n", __func__); return -ENODEV; } jpeg_irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (!jpeg_irq_res) { JPEG_PR_ERR("no irq resource?\n"); return -ENODEV; } jpeg_irq = jpeg_irq_res->start; JPEG_DBG("%s base address: 0x%x, jpeg irq number: %d\n", __func__, jpeg_mem->start, jpeg_irq); pgmn_dev->jpeg_bus_client = msm_bus_scale_register_client(&msm_jpeg_bus_client_pdata); if (!pgmn_dev->jpeg_bus_client) { JPEG_PR_ERR("%s: Registration Failed!\n", __func__); pgmn_dev->jpeg_bus_client = 0; return -EINVAL; } msm_bus_scale_client_update_request( pgmn_dev->jpeg_bus_client, 1); jpeg_io = request_mem_region(jpeg_mem->start, resource_size(jpeg_mem), pdev->name); if (!jpeg_io) { JPEG_PR_ERR("%s: region already claimed\n", __func__); return -EBUSY; } jpeg_base = ioremap(jpeg_mem->start, resource_size(jpeg_mem)); if (!jpeg_base) { rc = -ENOMEM; JPEG_PR_ERR("%s: ioremap failed\n", __func__); goto fail_remap; } pgmn_dev->jpeg_fs = regulator_get(&pgmn_dev->pdev->dev, "vdd"); rc = regulator_enable(pgmn_dev->jpeg_fs); if (rc) { JPEG_PR_ERR("%s:%d]jpeg regulator get failed\n", __func__, __LINE__); goto fail_fs; } rc = msm_cam_clk_enable(&pgmn_dev->pdev->dev, jpeg_8x_clk_info, pgmn_dev->jpeg_clk, ARRAY_SIZE(jpeg_8x_clk_info), 1); if (rc < 0) { JPEG_PR_ERR("%s: clk failed rc = %d\n", __func__, rc); goto fail_clk; } pgmn_dev->hw_version = readl_relaxed(jpeg_base + JPEG_HW_VERSION); JPEG_DBG_HIGH("%s:%d] jpeg HW version 0x%x", __func__, __LINE__, pgmn_dev->hw_version); pgmn_dev->jpeg_vbif = ioremap(VBIF_BASE_ADDRESS, VBIF_REGION_SIZE); if (!pgmn_dev->jpeg_vbif) { rc = -ENOMEM; JPEG_PR_ERR("%s:%d] ioremap failed\n", __func__, __LINE__); goto fail_vbif; } JPEG_DBG("%s:%d] jpeg_vbif 0x%x", __func__, __LINE__, (uint32_t)pgmn_dev->jpeg_vbif); #ifdef CONFIG_MSM_IOMMU for (i = 0; i < pgmn_dev->iommu_cnt; i++) { rc = iommu_attach_device(pgmn_dev->domain, pgmn_dev->iommu_ctx_arr[i]); if (rc < 0) { rc = -ENODEV; JPEG_PR_ERR("%s: Device attach failed\n", __func__); goto fail_iommu; } JPEG_DBG("%s:%d] dom 0x%x ctx 0x%x", __func__, __LINE__, (uint32_t)pgmn_dev->domain, (uint32_t)pgmn_dev->iommu_ctx_arr[i]); } #endif set_vbif_params(pgmn_dev, pgmn_dev->jpeg_vbif); #ifdef CONFIG_MACH_LGE *mem = jpeg_mem; *base = jpeg_base; #endif rc = request_irq(jpeg_irq, handler, IRQF_TRIGGER_RISING, "jpeg", context); if (rc) { JPEG_PR_ERR("%s: request_irq failed, %d\n", __func__, jpeg_irq); goto fail_request_irq; } #ifndef CONFIG_MACH_LGE /* QCT origin */ *mem = jpeg_mem; *base = jpeg_base; #endif *irq = jpeg_irq; pgmn_dev->jpeg_client = msm_ion_client_create(-1, "camera/jpeg"); JPEG_DBG("%s:%d] success\n", __func__, __LINE__); pgmn_dev->state = MSM_JPEG_INIT; return rc; fail_request_irq: #ifdef CONFIG_MACH_LGE *mem = NULL; *base = NULL; #endif #ifdef CONFIG_MSM_IOMMU for (i = 0; i < pgmn_dev->iommu_cnt; i++) { JPEG_PR_ERR("%s:%d] dom 0x%x ctx 0x%x", __func__, __LINE__, (uint32_t)pgmn_dev->domain, (uint32_t)pgmn_dev->iommu_ctx_arr[i]); iommu_detach_device(pgmn_dev->domain, pgmn_dev->iommu_ctx_arr[i]); } #endif fail_iommu: iounmap(pgmn_dev->jpeg_vbif); fail_vbif: msm_cam_clk_enable(&pgmn_dev->pdev->dev, jpeg_8x_clk_info, pgmn_dev->jpeg_clk, ARRAY_SIZE(jpeg_8x_clk_info), 0); fail_clk: rc = regulator_disable(pgmn_dev->jpeg_fs); if (!rc) regulator_put(pgmn_dev->jpeg_fs); else JPEG_PR_ERR("%s:%d] regulator disable failed %d", __func__, __LINE__, rc); pgmn_dev->jpeg_fs = NULL; fail_fs: iounmap(jpeg_base); fail_remap: release_mem_region(jpeg_mem->start, resource_size(jpeg_mem)); JPEG_DBG("%s:%d] fail\n", __func__, __LINE__); return rc; }
static int msm_jpeg_init_dev(struct platform_device *pdev) { int rc = -1; struct device *dev; struct msm_jpeg_device *msm_jpeg_device_p; char devname[10]; msm_jpeg_device_p = kzalloc(sizeof(struct msm_jpeg_device), GFP_ATOMIC); if (!msm_jpeg_device_p) { JPEG_PR_ERR("%s: no mem\n", __func__); return -EFAULT; } msm_jpeg_device_p->pdev = pdev; if (pdev->dev.of_node) of_property_read_u32((&pdev->dev)->of_node, "cell-index", &pdev->id); snprintf(devname, sizeof(devname), "%s%d", MSM_JPEG_NAME, pdev->id); rc = __msm_jpeg_init(msm_jpeg_device_p); if (rc < -1) { JPEG_PR_ERR("%s: initialization failed\n", __func__); goto fail; } v4l2_subdev_init(&msm_jpeg_device_p->subdev, &msm_jpeg_subdev_ops); v4l2_set_subdev_hostdata(&msm_jpeg_device_p->subdev, msm_jpeg_device_p); JPEG_DBG("%s: msm_jpeg_device_p 0x%x", __func__, (uint32_t)msm_jpeg_device_p); rc = alloc_chrdev_region(&msm_jpeg_device_p->msm_jpeg_devno, 0, 1, devname); if (rc < 0) { JPEG_PR_ERR("%s: failed to allocate chrdev\n", __func__); goto fail_1; } if (!msm_jpeg_device_p->msm_jpeg_class) { msm_jpeg_device_p->msm_jpeg_class = class_create(THIS_MODULE, devname); if (IS_ERR(msm_jpeg_device_p->msm_jpeg_class)) { rc = PTR_ERR(msm_jpeg_device_p->msm_jpeg_class); JPEG_PR_ERR("%s: create device class failed\n", __func__); goto fail_2; } } dev = device_create(msm_jpeg_device_p->msm_jpeg_class, NULL, MKDEV(MAJOR(msm_jpeg_device_p->msm_jpeg_devno), MINOR(msm_jpeg_device_p->msm_jpeg_devno)), NULL, "%s%d", MSM_JPEG_NAME, pdev->id); if (IS_ERR(dev)) { JPEG_PR_ERR("%s: error creating device\n", __func__); rc = -ENODEV; goto fail_3; } cdev_init(&msm_jpeg_device_p->cdev, &msm_jpeg_fops); msm_jpeg_device_p->cdev.owner = THIS_MODULE; msm_jpeg_device_p->cdev.ops = (const struct file_operations *) &msm_jpeg_fops; rc = cdev_add(&msm_jpeg_device_p->cdev, msm_jpeg_device_p->msm_jpeg_devno, 1); if (rc < 0) { JPEG_PR_ERR("%s: error adding cdev\n", __func__); rc = -ENODEV; goto fail_4; } platform_set_drvdata(pdev, &msm_jpeg_device_p); JPEG_DBG("%s %s%d: success\n", __func__, MSM_JPEG_NAME, pdev->id); return rc; fail_4: device_destroy(msm_jpeg_device_p->msm_jpeg_class, msm_jpeg_device_p->msm_jpeg_devno); fail_3: class_destroy(msm_jpeg_device_p->msm_jpeg_class); fail_2: unregister_chrdev_region(msm_jpeg_device_p->msm_jpeg_devno, 1); fail_1: __msm_jpeg_exit(msm_jpeg_device_p); fail: kfree(msm_jpeg_device_p); return rc; }
int msm_jpeg_platform_init(struct platform_device *pdev, struct resource **mem, void **base, int *irq, irqreturn_t (*handler) (int, void *), void *context) { int rc = -1; int jpeg_irq; struct resource *jpeg_mem, *vbif_mem, *jpeg_io, *jpeg_irq_res; void *jpeg_base; struct msm_jpeg_device *pgmn_dev = (struct msm_jpeg_device *) context; pgmn_dev->state = MSM_JPEG_IDLE; jpeg_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!jpeg_mem) { JPEG_PR_ERR("%s: jpeg no mem resource?\n", __func__); return -ENODEV; } vbif_mem = platform_get_resource(pdev, IORESOURCE_MEM, 1); if (!vbif_mem) { JPEG_PR_ERR("%s: vbif no mem resource?\n", __func__); return -ENODEV; } jpeg_irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (!jpeg_irq_res) { JPEG_PR_ERR("no irq resource?\n"); return -ENODEV; } jpeg_irq = jpeg_irq_res->start; JPEG_DBG("%s base address: 0x%x, jpeg irq number: %d\n", __func__, jpeg_mem->start, jpeg_irq); pgmn_dev->jpeg_bus_client = msm_bus_scale_register_client(&msm_jpeg_bus_client_pdata); if (!pgmn_dev->jpeg_bus_client) { JPEG_PR_ERR("%s: Registration Failed!\n", __func__); pgmn_dev->jpeg_bus_client = 0; return -EINVAL; } msm_bus_scale_client_update_request( pgmn_dev->jpeg_bus_client, 1); jpeg_io = request_mem_region(jpeg_mem->start, resource_size(jpeg_mem), pdev->name); if (!jpeg_io) { JPEG_PR_ERR("%s: region already claimed\n", __func__); return -EBUSY; } jpeg_base = ioremap(jpeg_mem->start, resource_size(jpeg_mem)); if (!jpeg_base) { rc = -ENOMEM; JPEG_PR_ERR("%s: ioremap failed\n", __func__); goto fail_remap; } pgmn_dev->jpeg_fs = regulator_get(&pgmn_dev->pdev->dev, "vdd"); rc = regulator_enable(pgmn_dev->jpeg_fs); if (rc) { JPEG_PR_ERR("%s:%d]jpeg regulator get failed\n", __func__, __LINE__); goto fail_fs; } if (msm_jpeg_get_clk_info(pgmn_dev, pgmn_dev->pdev) < 0) { JPEG_PR_ERR("%s:%d]jpeg clock get failed\n", __func__, __LINE__); goto fail_fs; } rc = msm_cam_clk_enable(&pgmn_dev->pdev->dev, jpeg_8x_clk_info, pgmn_dev->jpeg_clk, pgmn_dev->num_clk, 1); if (rc < 0) { JPEG_PR_ERR("%s: clk failed rc = %d\n", __func__, rc); goto fail_clk; } pgmn_dev->hw_version = readl_relaxed(jpeg_base + JPEG_HW_VERSION); JPEG_DBG_HIGH("%s:%d] jpeg HW version 0x%x", __func__, __LINE__, pgmn_dev->hw_version); pgmn_dev->jpeg_vbif = ioremap(vbif_mem->start, resource_size(vbif_mem)); if (!pgmn_dev->jpeg_vbif) { rc = -ENOMEM; JPEG_PR_ERR("%s: ioremap failed\n", __func__); goto fail_vbif; } JPEG_DBG("%s:%d] jpeg_vbif 0x%x", __func__, __LINE__, (uint32_t)pgmn_dev->jpeg_vbif); rc = msm_jpeg_attach_iommu(pgmn_dev); if (rc < 0) goto fail_iommu; set_vbif_params(pgmn_dev, pgmn_dev->jpeg_vbif); if (pgmn_dev->hw_version == JPEG_8939) { writel_relaxed(0x0000550e, jpeg_base + JPEG_FE_QOS_CFG); writel_relaxed(0x00005555, jpeg_base + JPEG_WE_QOS_CFG); } rc = request_irq(jpeg_irq, handler, IRQF_TRIGGER_RISING, "jpeg", context); if (rc) { JPEG_PR_ERR("%s: request_irq failed, %d\n", __func__, jpeg_irq); goto fail_request_irq; } *mem = jpeg_mem; *base = jpeg_base; *irq = jpeg_irq; pgmn_dev->jpeg_client = msm_ion_client_create(-1, "camera/jpeg"); JPEG_DBG("%s:%d] success\n", __func__, __LINE__); pgmn_dev->state = MSM_JPEG_INIT; return rc; fail_request_irq: msm_jpeg_detach_iommu(pgmn_dev); fail_iommu: iounmap(pgmn_dev->jpeg_vbif); fail_vbif: msm_cam_clk_enable(&pgmn_dev->pdev->dev, jpeg_8x_clk_info, pgmn_dev->jpeg_clk, pgmn_dev->num_clk, 0); fail_clk: rc = regulator_disable(pgmn_dev->jpeg_fs); if (!rc) regulator_put(pgmn_dev->jpeg_fs); else JPEG_PR_ERR("%s:%d] regulator disable failed %d", __func__, __LINE__, rc); pgmn_dev->jpeg_fs = NULL; fail_fs: iounmap(jpeg_base); fail_remap: release_mem_region(jpeg_mem->start, resource_size(jpeg_mem)); JPEG_DBG("%s:%d] fail\n", __func__, __LINE__); return rc; }
int msm_jpeg_platform_setup(struct msm_jpeg_device *pgmn_dev) { int rc = -1; struct resource *jpeg_irq_res; void *jpeg_base, *vbif_base; struct platform_device *pdev = pgmn_dev->pdev; /* get the jpeg hardware device address */ jpeg_base = msm_camera_get_reg_base(pdev, "jpeg_hw", true); if (!jpeg_base) { JPEG_PR_ERR("%s: jpeg no mem resource?\n", __func__); rc = -ENXIO; goto out; } /* get the jpeg vbif device address */ vbif_base = msm_camera_get_reg_base(pdev, "jpeg_vbif", false); if (!vbif_base) { JPEG_PR_ERR("%s: vbif no mem resource?\n", __func__); rc = -ENXIO; goto err_vbif_base; } /* get the irq resource for the jpeg hardware */ jpeg_irq_res = msm_camera_get_irq(pdev, "jpeg"); if (!jpeg_irq_res) { JPEG_PR_ERR("%s: no irq resource?\n", __func__); rc = -ENXIO; goto err_jpeg_irq_res; } /* get all the clocks information */ rc = msm_camera_get_clk_info(pdev, &pgmn_dev->jpeg_clk_info, &pgmn_dev->jpeg_clk, &pgmn_dev->num_clk); if (rc < 0) { JPEG_PR_ERR("%s: failed to get the clocks\n", __func__); rc = -ENXIO; goto err_jpeg_clk; } /* get all the regulators information */ rc = msm_camera_get_regulator_info(pdev, &pgmn_dev->jpeg_vdd, &pgmn_dev->num_reg); if (rc < 0) { JPEG_PR_ERR("%s: failed to get the regulators\n", __func__); rc = -ENXIO; goto err_jpeg_get_reg; } /* map the dtsi cell id to bus client id */ switch (pgmn_dev->pdev->id) { case 0: pgmn_dev->bus_client = CAM_BUS_CLIENT_JPEG_ENC0; break; case 1: pgmn_dev->bus_client = CAM_BUS_CLIENT_JPEG_ENC1; break; case 2: pgmn_dev->bus_client = CAM_BUS_CLIENT_JPEG_DEC; break; case 3: pgmn_dev->bus_client = CAM_BUS_CLIENT_JPEG_DMA; break; default: JPEG_PR_ERR("%s: invalid cell id :%d\n", __func__, pgmn_dev->pdev->id); goto err_jpeg_get_reg; } /* register the bus client */ rc = msm_camera_register_bus_client(pgmn_dev->pdev, pgmn_dev->bus_client); if (rc < 0) { JPEG_PR_ERR("Fail to register bus client\n"); rc = -EINVAL; goto err_reg_bus; } /* get the resource size of jpeg hardware */ pgmn_dev->res_size = msm_camera_get_res_size(pdev, "jpeg_hw"); if (!pgmn_dev->res_size) { JPEG_PR_ERR("Fail to resource size\n"); rc = -EINVAL; goto err_res_size; } pgmn_dev->base = jpeg_base; pgmn_dev->vbif_base = vbif_base; pgmn_dev->jpeg_irq_res = jpeg_irq_res; return 0; err_res_size: msm_camera_unregister_bus_client(pgmn_dev->bus_client); err_reg_bus: msm_camera_put_regulators(pdev, &pgmn_dev->jpeg_vdd, pgmn_dev->num_reg); err_jpeg_get_reg: msm_camera_put_clk_info(pdev, &pgmn_dev->jpeg_clk_info, &pgmn_dev->jpeg_clk, pgmn_dev->num_clk); err_jpeg_clk: err_jpeg_irq_res: msm_camera_put_reg_base(pdev, vbif_base, "jpeg_vbif", false); err_vbif_base: msm_camera_put_reg_base(pdev, jpeg_base, "jpeg_hw", true); out: return rc; }