static int fimc_init_global(struct platform_device *pdev) { struct fimc_control *ctrl; struct s3c_platform_fimc *pdata; struct s3c_platform_camera *cam; struct clk *srclk; int id, i; pdata = to_fimc_plat(&pdev->dev); id = pdev->id; ctrl = get_fimc_ctrl(id); /* Registering external camera modules. re-arrange order to be sure */ for (i = 0; i < FIMC_MAXCAMS; i++) { cam = pdata->camera[i]; if (!cam) break; /* WriteBack doesn't need clock setting */ if(cam->id == CAMERA_WB) { fimc_dev->camera[cam->id] = cam; break; } srclk = clk_get(&pdev->dev, cam->srclk_name); if (IS_ERR(srclk)) { fimc_err("%s: failed to get mclk source\n", __func__); return -EINVAL; } /* mclk */ cam->clk = clk_get(&pdev->dev, cam->clk_name); if (IS_ERR(cam->clk)) { fimc_err("%s: failed to get mclk source\n", __func__); return -EINVAL; } if (cam->clk->set_parent) { cam->clk->parent = srclk; cam->clk->set_parent(cam->clk, srclk); } /* Assign camera device to fimc */ fimc_dev->camera[cam->id] = cam; } fimc_dev->initialized = 1; return 0; }
static int fimc_show_log_level(struct device *dev, struct device_attribute *attr, char *buf) { struct fimc_control *ctrl; struct platform_device *pdev; int id = -1; char temp[150]; pdev = to_platform_device(dev); id = pdev->id; ctrl = get_fimc_ctrl(id); sprintf(temp, "\t"); strcat(buf, temp); if (ctrl->log & FIMC_LOG_DEBUG) { sprintf(temp, "FIMC_LOG_DEBUG | "); strcat(buf, temp); } if (ctrl->log & FIMC_LOG_INFO_L2) { sprintf(temp, "FIMC_LOG_INFO_L2 | "); strcat(buf, temp); } if (ctrl->log & FIMC_LOG_INFO_L1) { sprintf(temp, "FIMC_LOG_INFO_L1 | "); strcat(buf, temp); } if (ctrl->log & FIMC_LOG_WARN) { sprintf(temp, "FIMC_LOG_WARN | "); strcat(buf, temp); } if (ctrl->log & FIMC_LOG_ERR) { sprintf(temp, "FIMC_LOG_ERR\n"); strcat(buf, temp); } return strlen(buf); }
static int fimc_unregister_controller(struct platform_device *pdev) { struct s3c_platform_fimc *pdata; struct fimc_control *ctrl; int id = pdev->id; #ifdef VIEW_FUNCTION_CALL printk("[FIMC_DEV] %s(%d)\n", __func__, __LINE__); #endif pdata = to_fimc_plat(&pdev->dev); ctrl = get_fimc_ctrl(id); if (pdata->clk_off) pdata->clk_off(pdev, ctrl->clk); iounmap(ctrl->regs); memset(ctrl, 0, sizeof(*ctrl)); return 0; }
int fimc_resume(struct platform_device *pdev) { struct fimc_control *ctrl; struct s3c_platform_fimc *pdata; int id = pdev->id; ctrl = get_fimc_ctrl(id); pdata = to_fimc_plat(ctrl->dev); if (pdata->clk_on) pdata->clk_on(pdev, ctrl->clk); if (ctrl->out) fimc_resume_out(ctrl); else if (ctrl->cap) fimc_resume_cap(ctrl); else ctrl->status = FIMC_STREAMOFF; return 0; }
static int fimc_unregister_controller(struct platform_device *pdev) { struct s3c_platform_fimc *pdata; struct fimc_control *ctrl; int id = pdev->id; pdata = to_fimc_plat(&pdev->dev); ctrl = get_fimc_ctrl(id); free_irq(ctrl->irq, ctrl); mutex_destroy(&ctrl->lock); mutex_destroy(&ctrl->v4l2_lock); kfree(&ctrl->wq); if (pdata->clk_off) pdata->clk_off(pdev, ctrl->clk); iounmap(ctrl->regs); memset(ctrl, 0, sizeof(*ctrl)); return 0; }
int fimc_suspend(struct platform_device *pdev, pm_message_t state) { struct fimc_control *ctrl; struct s3c_platform_fimc *pdata; int id; id = pdev->id; ctrl = get_fimc_ctrl(id); pdata = to_fimc_plat(ctrl->dev); if (ctrl->out) fimc_suspend_out(ctrl); else if (ctrl->cap) fimc_suspend_cap(ctrl); else ctrl->status = FIMC_OFF_SLEEP; if (pdata->clk_off) pdata->clk_off(pdev, ctrl->clk); return 0; }
static int fimc_store_log_level(struct device *dev, struct device_attribute *attr, const char *buf, size_t len) { struct fimc_control *ctrl; struct platform_device *pdev; const char *p = buf; char msg[150] = {0, }; int id = -1; u32 match = 0; pdev = to_platform_device(dev); id = pdev->id; ctrl = get_fimc_ctrl(id); while (*p != '\0') { if (!isspace(*p)) strncat(msg, p, 1); p++; } ctrl->log = 0; printk(KERN_INFO "FIMC.%d log level is set as below.\n", id); if (strstr(msg, "FIMC_LOG_ERR") != NULL) { ctrl->log |= FIMC_LOG_ERR; match = 1; printk(KERN_INFO "\tFIMC_LOG_ERR\n"); } if (strstr(msg, "FIMC_LOG_WARN") != NULL) { ctrl->log |= FIMC_LOG_WARN; match = 1; printk(KERN_INFO "\tFIMC_LOG_WARN\n"); } if (strstr(msg, "FIMC_LOG_INFO_L1") != NULL) { ctrl->log |= FIMC_LOG_INFO_L1; match = 1; printk(KERN_INFO "\tFIMC_LOG_INFO_L1\n"); } if (strstr(msg, "FIMC_LOG_INFO_L2") != NULL) { ctrl->log |= FIMC_LOG_INFO_L2; match = 1; printk(KERN_INFO "\tFIMC_LOG_INFO_L2\n"); } if (strstr(msg, "FIMC_LOG_DEBUG") != NULL) { ctrl->log |= FIMC_LOG_DEBUG; match = 1; printk(KERN_INFO "\tFIMC_LOG_DEBUG\n"); } if (!match) { printk(KERN_INFO "FIMC_LOG_ERR \t: Error condition.\n"); printk(KERN_INFO "FIMC_LOG_WARN \t: WARNING condition.\n"); printk(KERN_INFO "FIMC_LOG_INFO_L1 \t: V4L2 API without QBUF, DQBUF.\n"); printk(KERN_INFO "FIMC_LOG_INFO_L2 \t: V4L2 API QBUF, DQBUF.\n"); printk(KERN_INFO "FIMC_LOG_DEBUG \t: Queue status report.\n"); } return len; }
/* * Assign v4l2 device and subdev to fimc * it is called per every fimc ctrl registering */ static int fimc_configure_subdev(struct platform_device *pdev, int id) { struct s3c_platform_fimc *pdata; struct s3c_platform_camera *cam; struct i2c_adapter *i2c_adap; struct i2c_board_info *i2c_info; struct v4l2_subdev *sd; struct fimc_control *ctrl; unsigned short addr; char *name; ctrl = get_fimc_ctrl(id); pdata = to_fimc_plat(&pdev->dev); cam = pdata->camera[id]; /* Subdev registration */ if (cam) { i2c_adap = i2c_get_adapter(cam->i2c_busnum); if (!i2c_adap) { fimc_info1("subdev i2c_adapter missing-skip " "registration\n"); } i2c_info = cam->info; if (!i2c_info) { fimc_err("%s: subdev i2c board info missing\n", __func__); return -ENODEV; } name = i2c_info->type; if (!name) { fimc_info1("subdev i2c dirver name missing-skip " "registration\n"); return -ENODEV; } addr = i2c_info->addr; if (!addr) { fimc_info1("subdev i2c address missing-skip " "registration\n"); return -ENODEV; } /* * NOTE: first time subdev being registered, * s_config is called and try to initialize subdev device * but in this point, we are not giving MCLK and power to subdev * so nothing happens but pass platform data through */ sd = v4l2_i2c_new_subdev_board(&ctrl->v4l2_dev, i2c_adap, name, i2c_info, &addr); if (!sd) { fimc_err("%s: v4l2 subdev board registering failed\n", __func__); } /* Assign camera device to fimc */ fimc_dev->camera[cam->id] = cam; /* Assign subdev to proper camera device pointer */ fimc_dev->camera[cam->id]->sd = sd; } return 0; }
static struct fimc_control *fimc_register_controller(struct platform_device *pdev) { struct s3c_platform_fimc *pdata; struct fimc_control *ctrl; struct resource *res; int id, mdev_id; id = pdev->id; mdev_id = S3C_MDEV_FIMC0 + id; pdata = to_fimc_plat(&pdev->dev); ctrl = get_fimc_ctrl(id); ctrl->id = id; ctrl->dev = &pdev->dev; ctrl->vd = &fimc_video_device[id]; ctrl->vd->minor = id; /* alloc from bank1 as default */ ctrl->mem.base = s3c_get_media_memory_bank(mdev_id, 1); ctrl->mem.size = s3c_get_media_memsize_bank(mdev_id, 1); ctrl->mem.curr = ctrl->mem.base; ctrl->status = FIMC_STREAMOFF; ctrl->limit = &fimc_limits[id]; ctrl->log = FIMC_LOG_DEFAULT; sprintf(ctrl->name, "%s%d", FIMC_NAME, id); strcpy(ctrl->vd->name, ctrl->name); atomic_set(&ctrl->in_use, 0); mutex_init(&ctrl->lock); mutex_init(&ctrl->v4l2_lock); spin_lock_init(&ctrl->lock_in); spin_lock_init(&ctrl->lock_out); init_waitqueue_head(&ctrl->wq); /* get resource for io memory */ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { fimc_err("%s: failed to get io memory region\n", __func__); return NULL; } /* request mem region */ res = request_mem_region(res->start, res->end - res->start + 1, pdev->name); if (!res) { fimc_err("%s: failed to request io memory region\n", __func__); return NULL; } /* ioremap for register block */ ctrl->regs = ioremap(res->start, res->end - res->start + 1); if (!ctrl->regs) { fimc_err("%s: failed to remap io region\n", __func__); return NULL; } /* irq */ ctrl->irq = platform_get_irq(pdev, 0); if (request_irq(ctrl->irq, fimc_irq, IRQF_DISABLED, ctrl->name, ctrl)) fimc_err("%s: request_irq failed\n", __func__); fimc_hwset_reset(ctrl); return ctrl; }
static struct fimc_control *fimc_register_controller(struct platform_device *pdev) { struct s3c_platform_fimc *pdata; struct fimc_control *ctrl; struct resource *res; int id, mdev_id, irq; #ifdef VIEW_FUNCTION_CALL printk("[FIMC_DEV] %s(%d)\n", __func__, __LINE__); #endif id = pdev->id; mdev_id = S3C_MDEV_FIMC0 + id; pdata = to_fimc_plat(&pdev->dev); ctrl = get_fimc_ctrl(id); ctrl->id = id; ctrl->dev = &pdev->dev; ctrl->vd = &fimc_video_device[id]; ctrl->vd->minor = id; /* alloc from bank1 as default */ #if 0 ctrl->mem.base = s3c_get_media_memory_node(mdev_id, 1); ctrl->mem.size = s3c_get_media_memsize_node(mdev_id, 1); #else if(id == 0){ ctrl->mem.base = FIMC0_RESERVED_MEM_START; ctrl->mem.size = RESERVED_MEM_FIMC0; } else if(id == 1){ ctrl->mem.base = FIMC1_RESERVED_MEM_START; ctrl->mem.size = RESERVED_MEM_FIMC1; } else if(id == 2){ ctrl->mem.base = FIMC2_RESERVED_MEM_START; ctrl->mem.size = RESERVED_MEM_FIMC2; } #endif ctrl->mem.curr = ctrl->mem.base; ctrl->status = FIMC_STREAMOFF; ctrl->limit = &fimc_limits[id]; sprintf(ctrl->name, "%s%d", FIMC_NAME, id); strcpy(ctrl->vd->name, ctrl->name); atomic_set(&ctrl->in_use, 0); mutex_init(&ctrl->lock); mutex_init(&ctrl->v4l2_lock); spin_lock_init(&ctrl->lock_in); spin_lock_init(&ctrl->lock_out); init_waitqueue_head(&ctrl->wq); /* get resource for io memory */ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { dev_err(ctrl->dev, "%s: failed to get io memory region\n", __func__); return NULL; } /* request mem region */ res = request_mem_region(res->start, res->end - res->start + 1, pdev->name); if (!res) { dev_err(ctrl->dev, "%s: failed to request io memory region\n", __func__); return NULL; } /* ioremap for register block */ ctrl->regs = ioremap(res->start, res->end - res->start + 1); if (!ctrl->regs) { dev_err(ctrl->dev, "%s: failed to remap io region\n", __func__); return NULL; } /* irq */ irq = platform_get_irq(pdev, 0); if (request_irq(irq, fimc_irq, IRQF_DISABLED, ctrl->name, ctrl)) dev_err(ctrl->dev, "%s: request_irq failed\n", __func__); fimc_hwset_reset(ctrl); return ctrl; }