/** * m5mols_fw_start - M-5MOLS internal ARM controller initialization * * Execute the M-5MOLS internal ARM controller initialization sequence. * This function should be called after the supply voltage has been * applied and before any requests to the device are made. */ static int m5mols_fw_start(struct v4l2_subdev *sd) { struct m5mols_info *info = to_m5mols(sd); int ret; atomic_set(&info->irq_done, 0); /* Wait until I2C slave is initialized in Flash Writer mode */ ret = m5mols_busy_wait(sd, FLASH_CAM_START, REG_IN_FLASH_MODE, M5MOLS_I2C_RDY_WAIT_FL | 0xff, -1); if (!ret) ret = m5mols_write(sd, FLASH_CAM_START, REG_START_ARM_BOOT); if (!ret) ret = m5mols_wait_interrupt(sd, REG_INT_MODE, 2000); if (ret < 0) return ret; info->isp_ready = 1; ret = m5mols_get_version(sd); if (!ret) ret = m5mols_update_fw(sd, m5mols_sensor_power); if (ret) return ret; v4l2_dbg(1, m5mols_debug, sd, "Success ARM Booting\n"); ret = m5mols_write(sd, PARM_INTERFACE, REG_INTERFACE_MIPI); if (!ret) ret = m5mols_enable_interrupt(sd, REG_INT_AF | REG_INT_CAPTURE); return ret; }
/** * m5mols_sensor_armboot - Booting M-5MOLS internal ARM core. * * Booting internal ARM core makes the M-5MOLS is ready for getting commands * with I2C. It's the first thing to be done after it powered up. It must wait * at least 520ms recommended by M-5MOLS datasheet, after executing arm booting. */ static int m5mols_sensor_armboot(struct v4l2_subdev *sd) { int ret; ret = m5mols_write(sd, FLASH_CAM_START, REG_START_ARM_BOOT); if (ret < 0) return ret; msleep(520); ret = m5mols_get_version(sd); if (!ret) ret = m5mols_update_fw(sd, m5mols_sensor_power); if (ret) return ret; v4l2_dbg(1, m5mols_debug, sd, "Success ARM Booting\n"); ret = m5mols_write(sd, PARM_INTERFACE, REG_INTERFACE_MIPI); if (!ret) ret = m5mols_enable_interrupt(sd, REG_INT_AF); return ret; }
int m5mols_start_capture(struct m5mols_info *info) { struct v4l2_subdev *sd = &info->sd; u8 resolution = info->resolution; int timeout; int ret; /* * Preparing capture. Setting control & interrupt before entering * capture mode * * 1) change to MONITOR mode for operating control & interrupt * 2) set controls (considering v4l2_control value & lock 3A) * 3) set interrupt * 4) change to CAPTURE mode */ ret = m5mols_mode(info, REG_MONITOR); if (!ret) ret = m5mols_sync_controls(info); if (!ret) ret = m5mols_lock_3a(info, true); if (!ret) ret = m5mols_enable_interrupt(sd, REG_INT_CAPTURE); if (!ret) ret = m5mols_mode(info, REG_CAPTURE); if (!ret) { /* Wait for capture interrupt, after changing capture mode */ timeout = wait_event_interruptible_timeout(info->irq_waitq, test_bit(ST_CAPT_IRQ, &info->flags), msecs_to_jiffies(2000)); if (test_and_clear_bit(ST_CAPT_IRQ, &info->flags)) ret = m5mols_capture_error_handler(info, timeout); } if (!ret) ret = m5mols_lock_3a(info, false); if (ret) return ret; /* * Starting capture. Setting capture frame count and resolution and * the format(available format: JPEG, Bayer RAW, YUV). * * 1) select single or multi(enable to 25), format, size * 2) set interrupt * 3) start capture(for main image, now) * 4) get information * 5) notify file size to v4l2 device(e.g, to s5p-fimc v4l2 device) */ ret = m5mols_write(sd, CAPC_SEL_FRAME, 1); if (!ret) ret = m5mols_write(sd, CAPP_YUVOUT_MAIN, REG_JPEG); if (!ret) ret = m5mols_write(sd, CAPP_MAIN_IMAGE_SIZE, resolution); if (!ret) ret = m5mols_enable_interrupt(sd, REG_INT_CAPTURE); if (!ret) ret = m5mols_write(sd, CAPC_START, REG_CAP_START_MAIN); if (!ret) { /* Wait for the capture completion interrupt */ timeout = wait_event_interruptible_timeout(info->irq_waitq, test_bit(ST_CAPT_IRQ, &info->flags), msecs_to_jiffies(2000)); if (test_and_clear_bit(ST_CAPT_IRQ, &info->flags)) { ret = m5mols_capture_info(info); if (!ret) v4l2_subdev_notify(sd, 0, &info->cap.total); } } return m5mols_capture_error_handler(info, timeout); }