feat(camera): add bananarchy-photo CLI, Sxmo menu integration, and multi-capture ISPIF/VFE0 reset
This commit is contained in:
@@ -320,6 +320,9 @@ static int msm8905_cam_hw_init(struct msm8905_cam_dev *cam)
|
||||
u16 chip_id;
|
||||
u32 r;
|
||||
|
||||
if (cam->hw_initialized)
|
||||
return 0;
|
||||
|
||||
/* 1. Ensure PM8909 LDO6 (1.8V) and LDO17 (2.85V) are enabled */
|
||||
if (cam->usid1_regmap) {
|
||||
regmap_update_bits(cam->usid1_regmap, PM8909_LDO6_EN_CTL,
|
||||
@@ -497,6 +500,29 @@ static int msm8905_cam_capture_rgb(struct msm8905_cam_dev *cam, u8 *dst_rgb)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Ensure GC2395 stream and VFE0 WM0/RDI0 are idle before resetting ISPIF */
|
||||
gc2395_write_reg(cam, 0xfeU, 0x00U);
|
||||
gc2395_write_reg(cam, 0xedU, 0x00U);
|
||||
cam_w32(cam->camss_base, VFE0_BASE + 0x04cU, 0x00000000U);
|
||||
cam_w32(cam->camss_base, VFE0_BASE + 0x6fcU, 0x00000000U);
|
||||
wmb();
|
||||
|
||||
/* Reset ISPIF cleanly for this frame */
|
||||
cam_w32(cam->camss_base, ISPIF_BASE + 0x008U, 0x00001ff9U);
|
||||
usleep_range(1000, 1500);
|
||||
cam_w32(cam->camss_base, ISPIF_BASE + 0x008U, 0x00000000U);
|
||||
usleep_range(1000, 1500);
|
||||
cam_w32(cam->camss_base, ISPIF_BASE + 0x200U, 0x00000040U);
|
||||
cam_w32(cam->camss_base, ISPIF_BASE + 0x230U, 0xffffffffU);
|
||||
cam_w32(cam->camss_base, ISPIF_BASE + 0x234U, 0xffffffffU);
|
||||
cam_w32(cam->camss_base, ISPIF_BASE + 0x238U, 0xffffffffU);
|
||||
cam_w32(cam->camss_base, ISPIF_BASE + 0x01cU, 0x00000001U);
|
||||
cam_w32(cam->camss_base, ISPIF_BASE + 0x208U, 0xffffffffU);
|
||||
cam_w32(cam->camss_base, ISPIF_BASE + 0x20cU, 0xffffffffU);
|
||||
cam_w32(cam->camss_base, ISPIF_BASE + 0x210U, 0xffffffffU);
|
||||
cam_w32(cam->camss_base, ISPIF_BASE + 0x244U, 0x00000000U);
|
||||
cam_w32(cam->camss_base, ISPIF_BASE + 0x264U, 0x00000001U);
|
||||
|
||||
/* Program WM0 PING & PONG to raw_dma_phys and arm single frame */
|
||||
cam_w32(cam->camss_base, VFE0_BASE + 0x050U, (u32)cam->raw_dma_phys);
|
||||
cam_w32(cam->camss_base, VFE0_BASE + 0x054U, (u32)cam->raw_dma_phys);
|
||||
@@ -529,21 +555,21 @@ static int msm8905_cam_capture_rgb(struct msm8905_cam_dev *cam, u8 *dst_rgb)
|
||||
usleep_range(2000, 3000);
|
||||
}
|
||||
|
||||
/* Immediately stop WM0, ISPIF RDI0, and GC2395 stream to prevent overflow */
|
||||
cam_w32(cam->camss_base, ISPIF_BASE + 0x248U, 0xaaaaaaaaU);
|
||||
/* Stop GC2395 stream, WM0, and RDI0 cleanly */
|
||||
gc2395_write_reg(cam, 0xfeU, 0x00U);
|
||||
gc2395_write_reg(cam, 0xedU, 0x00U);
|
||||
cam_w32(cam->camss_base, VFE0_BASE + 0x04cU, 0x00000000U);
|
||||
cam_w32(cam->camss_base, VFE0_BASE + 0x6fcU, 0x00000000U);
|
||||
cam_w32(cam->camss_base, VFE0_BASE + 0x024U, 0xffffffffU);
|
||||
cam_w32(cam->camss_base, VFE0_BASE + 0x028U, 0xffffffffU);
|
||||
cam_w32(cam->camss_base, VFE0_BASE + 0x018U, 0x00000001U);
|
||||
cam_w32(cam->camss_base, ISPIF_BASE + 0x008U, 0x00001ff9U);
|
||||
usleep_range(500, 1000);
|
||||
cam_w32(cam->camss_base, ISPIF_BASE + 0x008U, 0x00000000U);
|
||||
wmb();
|
||||
|
||||
gc2395_write_reg(cam, 0xfeU, 0x00U);
|
||||
gc2395_write_reg(cam, 0xedU, 0x00U);
|
||||
|
||||
if (!(irq0 & 0x00000040U)) {
|
||||
cam->hw_initialized = false;
|
||||
if (!(irq0 & 0x00000040U))
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
msm8905_cam_demosaic(cam->raw_dma_buf, dst_rgb);
|
||||
cam->sequence++;
|
||||
@@ -751,8 +777,9 @@ static int msm8905_cam_dqbuf(struct file *file, void *priv,
|
||||
b->field = V4L2_FIELD_NONE;
|
||||
b->sequence = cam->sequence;
|
||||
b->memory = V4L2_MEMORY_MMAP;
|
||||
b->m.offset = idx * PAGE_ALIGN(CAM_OUT_FRAME_BYTES);
|
||||
b->length = CAM_OUT_FRAME_BYTES;
|
||||
ktime_get_ts64((struct timespec64 *)&b->timestamp);
|
||||
v4l2_buffer_set_timestamp(b, ktime_get_ns());
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user