cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

m5mols_capture.c (4332B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2
      3/*
      4 * The Capture code for Fujitsu M-5MOLS ISP
      5 *
      6 * Copyright (C) 2011 Samsung Electronics Co., Ltd.
      7 * Author: HeungJun Kim <riverful.kim@samsung.com>
      8 *
      9 * Copyright (C) 2009 Samsung Electronics Co., Ltd.
     10 * Author: Dongsoo Nathaniel Kim <dongsoo45.kim@samsung.com>
     11 */
     12
     13#include <linux/i2c.h>
     14#include <linux/slab.h>
     15#include <linux/irq.h>
     16#include <linux/interrupt.h>
     17#include <linux/delay.h>
     18#include <linux/regulator/consumer.h>
     19#include <linux/videodev2.h>
     20#include <media/v4l2-ctrls.h>
     21#include <media/v4l2-device.h>
     22#include <media/v4l2-subdev.h>
     23#include <media/i2c/m5mols.h>
     24#include <media/drv-intf/exynos-fimc.h>
     25
     26#include "m5mols.h"
     27#include "m5mols_reg.h"
     28
     29/**
     30 * m5mols_read_rational - I2C read of a rational number
     31 * @sd: sub-device, as pointed by struct v4l2_subdev
     32 * @addr_num: numerator register
     33 * @addr_den: denominator register
     34 * @val: place to store the division result
     35 *
     36 * Read numerator and denominator from registers @addr_num and @addr_den
     37 * respectively and return the division result in @val.
     38 */
     39static int m5mols_read_rational(struct v4l2_subdev *sd, u32 addr_num,
     40				u32 addr_den, u32 *val)
     41{
     42	u32 num, den;
     43
     44	int ret = m5mols_read_u32(sd, addr_num, &num);
     45	if (!ret)
     46		ret = m5mols_read_u32(sd, addr_den, &den);
     47	if (ret)
     48		return ret;
     49	*val = den == 0 ? 0 : num / den;
     50	return ret;
     51}
     52
     53/**
     54 * m5mols_capture_info - Gather captured image information
     55 * @info: M-5MOLS driver data structure
     56 *
     57 * For now it gathers only EXIF information and file size.
     58 */
     59static int m5mols_capture_info(struct m5mols_info *info)
     60{
     61	struct m5mols_exif *exif = &info->cap.exif;
     62	struct v4l2_subdev *sd = &info->sd;
     63	int ret;
     64
     65	ret = m5mols_read_rational(sd, EXIF_INFO_EXPTIME_NU,
     66				   EXIF_INFO_EXPTIME_DE, &exif->exposure_time);
     67	if (ret)
     68		return ret;
     69	ret = m5mols_read_rational(sd, EXIF_INFO_TV_NU, EXIF_INFO_TV_DE,
     70				   &exif->shutter_speed);
     71	if (ret)
     72		return ret;
     73	ret = m5mols_read_rational(sd, EXIF_INFO_AV_NU, EXIF_INFO_AV_DE,
     74				   &exif->aperture);
     75	if (ret)
     76		return ret;
     77	ret = m5mols_read_rational(sd, EXIF_INFO_BV_NU, EXIF_INFO_BV_DE,
     78				   &exif->brightness);
     79	if (ret)
     80		return ret;
     81	ret = m5mols_read_rational(sd, EXIF_INFO_EBV_NU, EXIF_INFO_EBV_DE,
     82				   &exif->exposure_bias);
     83	if (ret)
     84		return ret;
     85
     86	ret = m5mols_read_u16(sd, EXIF_INFO_ISO, &exif->iso_speed);
     87	if (!ret)
     88		ret = m5mols_read_u16(sd, EXIF_INFO_FLASH, &exif->flash);
     89	if (!ret)
     90		ret = m5mols_read_u16(sd, EXIF_INFO_SDR, &exif->sdr);
     91	if (!ret)
     92		ret = m5mols_read_u16(sd, EXIF_INFO_QVAL, &exif->qval);
     93	if (ret)
     94		return ret;
     95
     96	if (!ret)
     97		ret = m5mols_read_u32(sd, CAPC_IMAGE_SIZE, &info->cap.main);
     98	if (!ret)
     99		ret = m5mols_read_u32(sd, CAPC_THUMB_SIZE, &info->cap.thumb);
    100	if (!ret)
    101		info->cap.total = info->cap.main + info->cap.thumb;
    102
    103	return ret;
    104}
    105
    106int m5mols_start_capture(struct m5mols_info *info)
    107{
    108	unsigned int framesize = info->cap.buf_size - M5MOLS_JPEG_TAGS_SIZE;
    109	struct v4l2_subdev *sd = &info->sd;
    110	int ret;
    111
    112	/*
    113	 * Synchronize the controls, set the capture frame resolution and color
    114	 * format. The frame capture is initiated during switching from Monitor
    115	 * to Capture mode.
    116	 */
    117	ret = m5mols_set_mode(info, REG_MONITOR);
    118	if (!ret)
    119		ret = m5mols_restore_controls(info);
    120	if (!ret)
    121		ret = m5mols_write(sd, CAPP_YUVOUT_MAIN, REG_JPEG);
    122	if (!ret)
    123		ret = m5mols_write(sd, CAPP_MAIN_IMAGE_SIZE, info->resolution);
    124	if (!ret)
    125		ret = m5mols_write(sd, CAPP_JPEG_SIZE_MAX, framesize);
    126	if (!ret)
    127		ret = m5mols_set_mode(info, REG_CAPTURE);
    128	if (!ret)
    129		/* Wait until a frame is captured to ISP internal memory */
    130		ret = m5mols_wait_interrupt(sd, REG_INT_CAPTURE, 2000);
    131	if (ret)
    132		return ret;
    133
    134	/*
    135	 * Initiate the captured data transfer to a MIPI-CSI receiver.
    136	 */
    137	ret = m5mols_write(sd, CAPC_SEL_FRAME, 1);
    138	if (!ret)
    139		ret = m5mols_write(sd, CAPC_START, REG_CAP_START_MAIN);
    140	if (!ret) {
    141		bool captured = false;
    142		unsigned int size;
    143
    144		/* Wait for the capture completion interrupt */
    145		ret = m5mols_wait_interrupt(sd, REG_INT_CAPTURE, 2000);
    146		if (!ret) {
    147			captured = true;
    148			ret = m5mols_capture_info(info);
    149		}
    150		size = captured ? info->cap.main : 0;
    151		v4l2_dbg(1, m5mols_debug, sd, "%s: size: %d, thumb.: %d B\n",
    152			 __func__, size, info->cap.thumb);
    153
    154		v4l2_subdev_notify(sd, S5P_FIMC_TX_END_NOTIFY, &size);
    155	}
    156
    157	return ret;
    158}