2 * The Capture code for Fujitsu M-5MOLS ISP
4 * Copyright (C) 2011 Samsung Electronics Co., Ltd.
5 * Author: HeungJun Kim, riverful.kim@samsung.com
7 * Copyright (C) 2009 Samsung Electronics Co., Ltd.
8 * Author: Dongsoo Nathaniel Kim, dongsoo45.kim@samsung.com
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
16 #include <linux/i2c.h>
17 #include <linux/slab.h>
18 #include <linux/irq.h>
19 #include <linux/interrupt.h>
20 #include <linux/delay.h>
21 #include <linux/version.h>
22 #include <linux/gpio.h>
23 #include <linux/regulator/consumer.h>
24 #include <linux/videodev2.h>
25 #include <linux/version.h>
26 #include <media/v4l2-ctrls.h>
27 #include <media/v4l2-device.h>
28 #include <media/v4l2-subdev.h>
29 #include <media/m5mols.h>
32 #include "m5mols_reg.h"
34 static int m5mols_capture_handler_error(struct m5mols_info *info,
39 /* Disable all interrupt & clear desired interrupt */
40 ret = i2c_w8_system(&info->sd, CAT0_INT_ENABLE,
41 info->interrupt & ~(REG_INT_CAPTURE));
45 /* If all timeout exhausted, return error. */
51 info->capture = false;
56 /* m5mols_capture_info() - Gather captured image informations. For now,
57 * it gathers only EXIF information and file size. */
58 static int m5mols_capture_info(struct m5mols_info *info, bool msgon)
60 struct v4l2_subdev *sd = &info->sd;
61 struct m5mols_exif *exif = &info->cap.exif;
62 int denominator, numerator;
65 ret = i2c_r32_exif(sd, CAT7_INFO_EXPTIME_NU, &numerator);
67 ret = i2c_r32_exif(sd, CAT7_INFO_EXPTIME_DE, &denominator);
69 exif->exposure_time = (u32)(numerator / denominator);
73 ret = i2c_r32_exif(sd, CAT7_INFO_TV_NU, &numerator);
75 ret = i2c_r32_exif(sd, CAT7_INFO_TV_DE, &denominator);
77 exif->shutter_speed = (u32)(numerator / denominator);
81 ret = i2c_r32_exif(sd, CAT7_INFO_AV_NU, &numerator);
83 ret = i2c_r32_exif(sd, CAT7_INFO_AV_DE, &denominator);
85 exif->aperture = (u32)(numerator / denominator);
89 ret = i2c_r32_exif(sd, CAT7_INFO_BV_NU, &numerator);
91 ret = i2c_r32_exif(sd, CAT7_INFO_BV_DE, &denominator);
93 exif->brightness = (u32)(numerator / denominator);
97 ret = i2c_r32_exif(sd, CAT7_INFO_EBV_NU, &numerator);
99 ret = i2c_r32_exif(sd, CAT7_INFO_EBV_DE, &denominator);
101 exif->exposure_bias = (u32)(numerator / denominator);
105 ret = i2c_r16_exif(sd, CAT7_INFO_ISO, (u32 *)&exif->iso_speed);
107 ret = i2c_r16_exif(sd, CAT7_INFO_FLASH, (u32 *)&exif->flash);
109 ret = i2c_r16_exif(sd, CAT7_INFO_SDR, (u32 *)&exif->sdr);
111 ret = i2c_r16_exif(sd, CAT7_INFO_QVAL, (u32 *)&exif->qval);
116 ret = i2c_r32_capt_ctrl(sd, CATC_CAP_IMAGE_SIZE,
119 ret = i2c_r32_capt_ctrl(sd, CATC_CAP_THUMB_SIZE,
124 info->cap.total = info->cap.main + info->cap.thumb;
127 struct i2c_client *client = v4l2_get_subdevdata(sd);
128 struct device *cdev = &client->dev;
130 dev_info(cdev, "capture: total size\t%d\n", info->cap.total);
131 dev_info(cdev, "capture: main size\t%d\n", info->cap.main);
132 dev_info(cdev, "capture: thumb size\t%d\n", info->cap.thumb);
133 dev_info(cdev, "capture: exposure_time\t%d\n",
134 exif->exposure_time);
135 dev_info(cdev, "capture: shutter_speed\t%d\n",
136 exif->shutter_speed);
137 dev_info(cdev, "capture: aperture\t%d\n", exif->aperture);
138 dev_info(cdev, "capture: brightness\t%d\n", exif->brightness);
139 dev_info(cdev, "capture: exposure_bias\t%d\n",
140 exif->exposure_bias);
141 dev_info(cdev, "capture: iso_speed\t%d\n", exif->iso_speed);
142 dev_info(cdev, "capture: flash\t%d\n", exif->flash);
143 dev_info(cdev, "capture: sdr\t%d\n", exif->sdr);
144 dev_info(cdev, "capture: qval\t%d\n", exif->qval);
150 int m5mols_start_capture(struct m5mols_info *info)
152 struct v4l2_subdev *sd = &info->sd;
153 u32 resolution = info->resolution;
158 * Preparing capture. Setting control & interrupt before entering
161 * 1) change to MONITOR mode for operating control & interrupt
162 * 2) set controls (considering v4l2_control value & lock 3A)
164 * 4) change to CAPTURE mode
166 ret = m5mols_change_mode(info, REG_MODE_MONITOR);
168 ret = m5mols_sync_control(info);
170 ret = m5mols_lock_3a(info, true);
172 ret = m5mols_enable_interrupt(sd, REG_INT_CAPTURE);
174 ret = m5mols_change_mode(info, REG_MODE_CAPTURE);
176 /* Wait for capture interrupt, after changing capture mode */
177 timeout = wait_event_interruptible_timeout(info->wait_capture,
178 is_captured(info), msecs_to_jiffies(2000));
179 if (!ret && is_captured(info))
180 ret = m5mols_capture_handler_error(info, timeout);
182 ret = m5mols_lock_3a(info, false);
187 * Starting capture. Setting capture frame count and resolution and
188 * the format(available format: JPEG, Bayer RAW, YUV).
190 * 1) select single or multi(enable to 25), format, size
192 * 3) start capture(for main image, now)
194 * 5) notify file size to v4l2 device(e.g, to s5p-fimc v4l2 device)
196 ret = i2c_w8_capt_ctrl(sd, CATC_CAP_SEL_FRAME, 1);
198 ret = i2c_w8_capt_param(sd, CATB_YUVOUT_MAIN, REG_JPEG);
200 ret = i2c_w8_capt_param(sd, CATB_MAIN_IMAGE_SIZE, resolution);
202 ret = m5mols_enable_interrupt(sd, REG_INT_CAPTURE);
204 ret = i2c_w8_capt_ctrl(sd, CATC_CAP_START, REG_CAP_START_MAIN);
206 /* Wait for capture interrupt, after starting capture */
207 timeout = wait_event_interruptible_timeout(info->wait_capture,
208 is_captured(info), msecs_to_jiffies(2000));
209 if (!ret && is_captured(info))
210 ret = m5mols_capture_info(info, false);
212 v4l2_subdev_notify(sd, 0, &info->cap.total);
214 ret = m5mols_capture_handler_error(info, timeout);