/** * m5mols_do_scenemode() - Change current scenemode * @mode: Desired mode of the scenemode * * WARNING: The execution order is important. Do not change the order. */ int m5mols_do_scenemode(struct m5mols_info *info, u8 mode) { struct v4l2_subdev *sd = &info->sd; struct m5mols_scenemode scenemode = m5mols_default_scenemode[mode]; int ret; if (mode > REG_SCENE_CANDLE) return -EINVAL; ret = v4l2_ctrl_s_ctrl(info->lock_3a, 0); if (!ret) ret = m5mols_write(sd, AE_EV_PRESET_MONITOR, mode); if (!ret) ret = m5mols_write(sd, AE_EV_PRESET_CAPTURE, mode); if (!ret) ret = m5mols_write(sd, AE_MODE, scenemode.metering); if (!ret) ret = m5mols_write(sd, AE_INDEX, scenemode.ev_bias); if (!ret) ret = m5mols_write(sd, AWB_MODE, scenemode.wb_mode); if (!ret) ret = m5mols_write(sd, AWB_MANUAL, scenemode.wb_preset); if (!ret) ret = m5mols_write(sd, MON_CHROMA_EN, scenemode.chroma_en); if (!ret) ret = m5mols_write(sd, MON_CHROMA_LVL, scenemode.chroma_lvl); if (!ret) ret = m5mols_write(sd, MON_EDGE_EN, scenemode.edge_en); if (!ret) ret = m5mols_write(sd, MON_EDGE_LVL, scenemode.edge_lvl); if (!ret && is_available_af(info)) ret = m5mols_write(sd, AF_MODE, scenemode.af_range); if (!ret && is_available_af(info)) ret = m5mols_write(sd, FD_CTL, scenemode.fd_mode); if (!ret) ret = m5mols_write(sd, MON_TONE_CTL, scenemode.tone); if (!ret) ret = m5mols_write(sd, AE_ISO, scenemode.iso); if (!ret) ret = m5mols_set_mode(info, REG_CAPTURE); if (!ret) ret = m5mols_write(sd, CAPP_WDR_EN, scenemode.wdr); if (!ret) ret = m5mols_write(sd, CAPP_MCC_MODE, scenemode.mcc); if (!ret) ret = m5mols_write(sd, CAPP_LIGHT_CTRL, scenemode.light); if (!ret) ret = m5mols_write(sd, CAPP_FLASH_CTRL, scenemode.flash); if (!ret) ret = m5mols_write(sd, CAPC_MODE, scenemode.capt_mode); if (!ret) ret = m5mols_set_mode(info, REG_MONITOR); return ret; }
static void m5mols_irq_work(struct work_struct *work) { struct m5mols_info *info = container_of(work, struct m5mols_info, work_irq); struct v4l2_subdev *sd = &info->sd; u8 reg; int ret; if (!is_powered(info) || m5mols_read_u8(sd, SYSTEM_INT_FACTOR, &info->interrupt)) return; switch (info->interrupt & REG_INT_MASK) { case REG_INT_AF: if (!is_available_af(info)) break; ret = m5mols_read_u8(sd, AF_STATUS, ®); v4l2_dbg(2, m5mols_debug, sd, "AF %s\n", reg == REG_AF_FAIL ? "Failed" : reg == REG_AF_SUCCESS ? "Success" : reg == REG_AF_IDLE ? "Idle" : "Busy"); break; case REG_INT_CAPTURE: if (!test_and_set_bit(ST_CAPT_IRQ, &info->flags)) wake_up_interruptible(&info->irq_waitq); v4l2_dbg(2, m5mols_debug, sd, "CAPTURE\n"); break; default: v4l2_dbg(2, m5mols_debug, sd, "Undefined: %02x\n", reg); break; }; }
/** * m5mols_enable_interrupt - Clear interrupt pending bits and unmask interrupts * * Before writing desired interrupt value the INT_FACTOR register should * be read to clear pending interrupts. */ int m5mols_enable_interrupt(struct v4l2_subdev *sd, u8 reg) { struct m5mols_info *info = to_m5mols(sd); u8 mask = is_available_af(info) ? REG_INT_AF : 0; u8 dummy; int ret; ret = m5mols_read_u8(sd, SYSTEM_INT_FACTOR, &dummy); if (!ret) ret = m5mols_write(sd, SYSTEM_INT_ENABLE, reg & ~mask); return ret; }
/** * m5mols_get_version - retrieve full revisions information of M-5MOLS * * The version information includes revisions of hardware and firmware, * AutoFocus alghorithm version and the version string. */ static int m5mols_get_version(struct v4l2_subdev *sd) { struct m5mols_info *info = to_m5mols(sd); struct m5mols_version *ver = &info->ver; u8 *str = ver->str; int i; int ret; ret = m5mols_read_u8(sd, SYSTEM_VER_CUSTOMER, &ver->customer); if (!ret) ret = m5mols_read_u8(sd, SYSTEM_VER_PROJECT, &ver->project); if (!ret) ret = m5mols_read_u16(sd, SYSTEM_VER_FIRMWARE, &ver->fw); if (!ret) ret = m5mols_read_u16(sd, SYSTEM_VER_HARDWARE, &ver->hw); if (!ret) ret = m5mols_read_u16(sd, SYSTEM_VER_PARAMETER, &ver->param); if (!ret) ret = m5mols_read_u16(sd, SYSTEM_VER_AWB, &ver->awb); if (!ret) ret = m5mols_read_u8(sd, AF_VERSION, &ver->af); if (ret) return ret; for (i = 0; i < VERSION_STRING_SIZE; i++) { ret = m5mols_read_u8(sd, SYSTEM_VER_STRING, &str[i]); if (ret) return ret; } ver->fw = be16_to_cpu(ver->fw); ver->hw = be16_to_cpu(ver->hw); ver->param = be16_to_cpu(ver->param); ver->awb = be16_to_cpu(ver->awb); v4l2_info(sd, "Manufacturer\t[%s]\n", is_manufacturer(info, REG_SAMSUNG_ELECTRO) ? "Samsung Electro-Machanics" : is_manufacturer(info, REG_SAMSUNG_OPTICS) ? "Samsung Fiber-Optics" : is_manufacturer(info, REG_SAMSUNG_TECHWIN) ? "Samsung Techwin" : "None"); v4l2_info(sd, "Customer/Project\t[0x%02x/0x%02x]\n", info->ver.customer, info->ver.project); if (!is_available_af(info)) v4l2_info(sd, "No support Auto Focus on this firmware\n"); return ret; }