]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/blame - drivers/media/i2c/mt9m111.c
treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 500
[mirror_ubuntu-jammy-kernel.git] / drivers / media / i2c / mt9m111.c
CommitLineData
d2912cb1 1// SPDX-License-Identifier: GPL-2.0-only
77110abb 2/*
c8cf078e 3 * Driver for MT9M111/MT9M112/MT9M131 CMOS Image Sensor from Micron/Aptina
77110abb
RJ
4 *
5 * Copyright (C) 2008, Robert Jarzmik <robert.jarzmik@free.fr>
77110abb
RJ
6 */
7#include <linux/videodev2.h>
8#include <linux/slab.h>
9#include <linux/i2c.h>
10#include <linux/log2.h>
11#include <linux/gpio.h>
12#include <linux/delay.h>
95d20109 13#include <linux/v4l2-mediabus.h>
7a707b89 14#include <linux/module.h>
98480d65 15#include <linux/property.h>
77110abb 16
5d7cc01b 17#include <media/v4l2-async.h>
9aea470b 18#include <media/v4l2-clk.h>
77110abb 19#include <media/v4l2-common.h>
af8425c5 20#include <media/v4l2-ctrls.h>
5d7cc01b 21#include <media/v4l2-device.h>
329d9e35 22#include <media/v4l2-event.h>
98480d65 23#include <media/v4l2-fwnode.h>
77110abb
RJ
24
25/*
c8cf078e
PW
26 * MT9M111, MT9M112 and MT9M131:
27 * i2c address is 0x48 or 0x5d (depending on SADDR pin)
25a34811
GL
28 * The platform has to define struct i2c_board_info objects and link to them
29 * from struct soc_camera_host_desc
77110abb
RJ
30 */
31
c8cf078e
PW
32/*
33 * Sensor core register addresses (0x000..0x0ff)
34 */
77110abb
RJ
35#define MT9M111_CHIP_VERSION 0x000
36#define MT9M111_ROW_START 0x001
37#define MT9M111_COLUMN_START 0x002
38#define MT9M111_WINDOW_HEIGHT 0x003
39#define MT9M111_WINDOW_WIDTH 0x004
40#define MT9M111_HORIZONTAL_BLANKING_B 0x005
41#define MT9M111_VERTICAL_BLANKING_B 0x006
42#define MT9M111_HORIZONTAL_BLANKING_A 0x007
43#define MT9M111_VERTICAL_BLANKING_A 0x008
44#define MT9M111_SHUTTER_WIDTH 0x009
45#define MT9M111_ROW_SPEED 0x00a
46#define MT9M111_EXTRA_DELAY 0x00b
47#define MT9M111_SHUTTER_DELAY 0x00c
48#define MT9M111_RESET 0x00d
49#define MT9M111_READ_MODE_B 0x020
50#define MT9M111_READ_MODE_A 0x021
51#define MT9M111_FLASH_CONTROL 0x023
52#define MT9M111_GREEN1_GAIN 0x02b
53#define MT9M111_BLUE_GAIN 0x02c
54#define MT9M111_RED_GAIN 0x02d
55#define MT9M111_GREEN2_GAIN 0x02e
56#define MT9M111_GLOBAL_GAIN 0x02f
57#define MT9M111_CONTEXT_CONTROL 0x0c8
58#define MT9M111_PAGE_MAP 0x0f0
59#define MT9M111_BYTE_WISE_ADDR 0x0f1
60
61#define MT9M111_RESET_SYNC_CHANGES (1 << 15)
62#define MT9M111_RESET_RESTART_BAD_FRAME (1 << 9)
63#define MT9M111_RESET_SHOW_BAD_FRAMES (1 << 8)
64#define MT9M111_RESET_RESET_SOC (1 << 5)
65#define MT9M111_RESET_OUTPUT_DISABLE (1 << 4)
66#define MT9M111_RESET_CHIP_ENABLE (1 << 3)
67#define MT9M111_RESET_ANALOG_STANDBY (1 << 2)
68#define MT9M111_RESET_RESTART_FRAME (1 << 1)
69#define MT9M111_RESET_RESET_MODE (1 << 0)
70
7c58e7d0
MG
71#define MT9M111_RM_FULL_POWER_RD (0 << 10)
72#define MT9M111_RM_LOW_POWER_RD (1 << 10)
73#define MT9M111_RM_COL_SKIP_4X (1 << 5)
74#define MT9M111_RM_ROW_SKIP_4X (1 << 4)
75#define MT9M111_RM_COL_SKIP_2X (1 << 3)
76#define MT9M111_RM_ROW_SKIP_2X (1 << 2)
77110abb
RJ
77#define MT9M111_RMB_MIRROR_COLS (1 << 1)
78#define MT9M111_RMB_MIRROR_ROWS (1 << 0)
79#define MT9M111_CTXT_CTRL_RESTART (1 << 15)
80#define MT9M111_CTXT_CTRL_DEFECTCOR_B (1 << 12)
81#define MT9M111_CTXT_CTRL_RESIZE_B (1 << 10)
82#define MT9M111_CTXT_CTRL_CTRL2_B (1 << 9)
83#define MT9M111_CTXT_CTRL_GAMMA_B (1 << 8)
84#define MT9M111_CTXT_CTRL_XENON_EN (1 << 7)
85#define MT9M111_CTXT_CTRL_READ_MODE_B (1 << 3)
86#define MT9M111_CTXT_CTRL_LED_FLASH_EN (1 << 2)
87#define MT9M111_CTXT_CTRL_VBLANK_SEL_B (1 << 1)
88#define MT9M111_CTXT_CTRL_HBLANK_SEL_B (1 << 0)
c8cf078e 89
77110abb 90/*
c8cf078e 91 * Colorpipe register addresses (0x100..0x1ff)
77110abb
RJ
92 */
93#define MT9M111_OPER_MODE_CTRL 0x106
94#define MT9M111_OUTPUT_FORMAT_CTRL 0x108
74e08739 95#define MT9M111_TPG_CTRL 0x148
77110abb
RJ
96#define MT9M111_REDUCER_XZOOM_B 0x1a0
97#define MT9M111_REDUCER_XSIZE_B 0x1a1
98#define MT9M111_REDUCER_YZOOM_B 0x1a3
99#define MT9M111_REDUCER_YSIZE_B 0x1a4
100#define MT9M111_REDUCER_XZOOM_A 0x1a6
101#define MT9M111_REDUCER_XSIZE_A 0x1a7
102#define MT9M111_REDUCER_YZOOM_A 0x1a9
103#define MT9M111_REDUCER_YSIZE_A 0x1aa
dde64f72 104#define MT9M111_EFFECTS_MODE 0x1e2
77110abb
RJ
105
106#define MT9M111_OUTPUT_FORMAT_CTRL2_A 0x13a
107#define MT9M111_OUTPUT_FORMAT_CTRL2_B 0x19b
108
109#define MT9M111_OPMODE_AUTOEXPO_EN (1 << 14)
39bf372f 110#define MT9M111_OPMODE_AUTOWHITEBAL_EN (1 << 1)
7c58e7d0
MG
111#define MT9M111_OUTFMT_FLIP_BAYER_COL (1 << 9)
112#define MT9M111_OUTFMT_FLIP_BAYER_ROW (1 << 8)
77110abb
RJ
113#define MT9M111_OUTFMT_PROCESSED_BAYER (1 << 14)
114#define MT9M111_OUTFMT_BYPASS_IFP (1 << 10)
115#define MT9M111_OUTFMT_INV_PIX_CLOCK (1 << 9)
116#define MT9M111_OUTFMT_RGB (1 << 8)
ec73365b
MG
117#define MT9M111_OUTFMT_RGB565 (0 << 6)
118#define MT9M111_OUTFMT_RGB555 (1 << 6)
119#define MT9M111_OUTFMT_RGB444x (2 << 6)
120#define MT9M111_OUTFMT_RGBx444 (3 << 6)
121#define MT9M111_OUTFMT_TST_RAMP_OFF (0 << 4)
122#define MT9M111_OUTFMT_TST_RAMP_COL (1 << 4)
123#define MT9M111_OUTFMT_TST_RAMP_ROW (2 << 4)
124#define MT9M111_OUTFMT_TST_RAMP_FRAME (3 << 4)
77110abb
RJ
125#define MT9M111_OUTFMT_SHIFT_3_UP (1 << 3)
126#define MT9M111_OUTFMT_AVG_CHROMA (1 << 2)
7c58e7d0
MG
127#define MT9M111_OUTFMT_SWAP_YCbCr_C_Y_RGB_EVEN (1 << 1)
128#define MT9M111_OUTFMT_SWAP_YCbCr_Cb_Cr_RGB_R_B (1 << 0)
74e08739 129#define MT9M111_TPG_SEL_MASK GENMASK(2, 0)
dde64f72 130#define MT9M111_EFFECTS_MODE_MASK GENMASK(2, 0)
937bb425
MG
131#define MT9M111_RM_PWR_MASK BIT(10)
132#define MT9M111_RM_SKIP2_MASK GENMASK(3, 2)
c8cf078e 133
77110abb 134/*
c8cf078e 135 * Camera control register addresses (0x200..0x2ff not implemented)
77110abb
RJ
136 */
137
9538e1c2
GL
138#define reg_read(reg) mt9m111_reg_read(client, MT9M111_##reg)
139#define reg_write(reg, val) mt9m111_reg_write(client, MT9M111_##reg, (val))
140#define reg_set(reg, val) mt9m111_reg_set(client, MT9M111_##reg, (val))
141#define reg_clear(reg, val) mt9m111_reg_clear(client, MT9M111_##reg, (val))
7c58e7d0
MG
142#define reg_mask(reg, val, mask) mt9m111_reg_mask(client, MT9M111_##reg, \
143 (val), (mask))
77110abb
RJ
144
145#define MT9M111_MIN_DARK_ROWS 8
669470a8 146#define MT9M111_MIN_DARK_COLS 26
77110abb
RJ
147#define MT9M111_MAX_HEIGHT 1024
148#define MT9M111_MAX_WIDTH 1280
149
47921932
GL
150struct mt9m111_context {
151 u16 read_mode;
152 u16 blanking_h;
153 u16 blanking_v;
154 u16 reducer_xzoom;
155 u16 reducer_yzoom;
156 u16 reducer_xsize;
157 u16 reducer_ysize;
158 u16 output_fmt_ctrl2;
159 u16 control;
160};
161
162static struct mt9m111_context context_a = {
163 .read_mode = MT9M111_READ_MODE_A,
164 .blanking_h = MT9M111_HORIZONTAL_BLANKING_A,
165 .blanking_v = MT9M111_VERTICAL_BLANKING_A,
166 .reducer_xzoom = MT9M111_REDUCER_XZOOM_A,
167 .reducer_yzoom = MT9M111_REDUCER_YZOOM_A,
168 .reducer_xsize = MT9M111_REDUCER_XSIZE_A,
169 .reducer_ysize = MT9M111_REDUCER_YSIZE_A,
170 .output_fmt_ctrl2 = MT9M111_OUTPUT_FORMAT_CTRL2_A,
171 .control = MT9M111_CTXT_CTRL_RESTART,
172};
173
174static struct mt9m111_context context_b = {
175 .read_mode = MT9M111_READ_MODE_B,
176 .blanking_h = MT9M111_HORIZONTAL_BLANKING_B,
177 .blanking_v = MT9M111_VERTICAL_BLANKING_B,
178 .reducer_xzoom = MT9M111_REDUCER_XZOOM_B,
179 .reducer_yzoom = MT9M111_REDUCER_YZOOM_B,
180 .reducer_xsize = MT9M111_REDUCER_XSIZE_B,
181 .reducer_ysize = MT9M111_REDUCER_YSIZE_B,
182 .output_fmt_ctrl2 = MT9M111_OUTPUT_FORMAT_CTRL2_B,
183 .control = MT9M111_CTXT_CTRL_RESTART |
184 MT9M111_CTXT_CTRL_DEFECTCOR_B | MT9M111_CTXT_CTRL_RESIZE_B |
185 MT9M111_CTXT_CTRL_CTRL2_B | MT9M111_CTXT_CTRL_GAMMA_B |
186 MT9M111_CTXT_CTRL_READ_MODE_B | MT9M111_CTXT_CTRL_VBLANK_SEL_B |
187 MT9M111_CTXT_CTRL_HBLANK_SEL_B,
188};
189
760697be
GL
190/* MT9M111 has only one fixed colorspace per pixelcode */
191struct mt9m111_datafmt {
f5fe58fd 192 u32 code;
760697be
GL
193 enum v4l2_colorspace colorspace;
194};
195
760697be 196static const struct mt9m111_datafmt mt9m111_colour_fmts[] = {
1a412faa
RJ
197 {MEDIA_BUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_SRGB},
198 {MEDIA_BUS_FMT_YVYU8_2X8, V4L2_COLORSPACE_SRGB},
199 {MEDIA_BUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_SRGB},
200 {MEDIA_BUS_FMT_VYUY8_2X8, V4L2_COLORSPACE_SRGB},
f5fe58fd
BB
201 {MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE, V4L2_COLORSPACE_SRGB},
202 {MEDIA_BUS_FMT_RGB555_2X8_PADHI_BE, V4L2_COLORSPACE_SRGB},
203 {MEDIA_BUS_FMT_RGB565_2X8_LE, V4L2_COLORSPACE_SRGB},
204 {MEDIA_BUS_FMT_RGB565_2X8_BE, V4L2_COLORSPACE_SRGB},
205 {MEDIA_BUS_FMT_BGR565_2X8_LE, V4L2_COLORSPACE_SRGB},
206 {MEDIA_BUS_FMT_BGR565_2X8_BE, V4L2_COLORSPACE_SRGB},
207 {MEDIA_BUS_FMT_SBGGR8_1X8, V4L2_COLORSPACE_SRGB},
208 {MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE, V4L2_COLORSPACE_SRGB},
77110abb
RJ
209};
210
937bb425
MG
211enum mt9m111_mode_id {
212 MT9M111_MODE_SXGA_8FPS,
213 MT9M111_MODE_SXGA_15FPS,
214 MT9M111_MODE_QSXGA_30FPS,
215 MT9M111_NUM_MODES,
216};
217
218struct mt9m111_mode_info {
219 unsigned int sensor_w;
220 unsigned int sensor_h;
221 unsigned int max_image_w;
222 unsigned int max_image_h;
223 unsigned int max_fps;
224 unsigned int reg_val;
225 unsigned int reg_mask;
226};
227
77110abb 228struct mt9m111 {
979ea1dd 229 struct v4l2_subdev subdev;
af8425c5
HV
230 struct v4l2_ctrl_handler hdl;
231 struct v4l2_ctrl *gain;
47921932 232 struct mt9m111_context *ctx;
da673e60 233 struct v4l2_rect rect; /* cropping rectangle */
9aea470b 234 struct v4l2_clk *clk;
f90580ca
RR
235 unsigned int width; /* output */
236 unsigned int height; /* sizes */
937bb425
MG
237 struct v4l2_fract frame_interval;
238 const struct mt9m111_mode_info *current_mode;
14c5ea9b
GL
239 struct mutex power_lock; /* lock to protect power_count */
240 int power_count;
760697be 241 const struct mt9m111_datafmt *fmt;
096b703f 242 int lastpage; /* PageMap cache value */
7784b1d2 243 bool is_streaming;
98480d65
ES
244 /* user point of view - 0: falling 1: rising edge */
245 unsigned int pclk_sample:1;
90411ce4
AM
246#ifdef CONFIG_MEDIA_CONTROLLER
247 struct media_pad pad;
248#endif
77110abb
RJ
249};
250
937bb425
MG
251static const struct mt9m111_mode_info mt9m111_mode_data[MT9M111_NUM_MODES] = {
252 [MT9M111_MODE_SXGA_8FPS] = {
253 .sensor_w = 1280,
254 .sensor_h = 1024,
255 .max_image_w = 1280,
256 .max_image_h = 1024,
257 .max_fps = 8,
258 .reg_val = MT9M111_RM_LOW_POWER_RD,
259 .reg_mask = MT9M111_RM_PWR_MASK | MT9M111_RM_SKIP2_MASK,
260 },
261 [MT9M111_MODE_SXGA_15FPS] = {
262 .sensor_w = 1280,
263 .sensor_h = 1024,
264 .max_image_w = 1280,
265 .max_image_h = 1024,
266 .max_fps = 15,
267 .reg_val = MT9M111_RM_FULL_POWER_RD,
268 .reg_mask = MT9M111_RM_PWR_MASK | MT9M111_RM_SKIP2_MASK,
269 },
270 [MT9M111_MODE_QSXGA_30FPS] = {
271 .sensor_w = 1280,
272 .sensor_h = 1024,
273 .max_image_w = 640,
274 .max_image_h = 512,
275 .max_fps = 30,
276 .reg_val = MT9M111_RM_LOW_POWER_RD | MT9M111_RM_COL_SKIP_2X |
277 MT9M111_RM_ROW_SKIP_2X,
278 .reg_mask = MT9M111_RM_PWR_MASK | MT9M111_RM_SKIP2_MASK,
279 },
280};
281
da673e60
GL
282/* Find a data format by a pixel code */
283static const struct mt9m111_datafmt *mt9m111_find_datafmt(struct mt9m111 *mt9m111,
f5fe58fd 284 u32 code)
da673e60
GL
285{
286 int i;
287 for (i = 0; i < ARRAY_SIZE(mt9m111_colour_fmts); i++)
288 if (mt9m111_colour_fmts[i].code == code)
289 return mt9m111_colour_fmts + i;
290
291 return mt9m111->fmt;
292}
293
979ea1dd
GL
294static struct mt9m111 *to_mt9m111(const struct i2c_client *client)
295{
296 return container_of(i2c_get_clientdata(client), struct mt9m111, subdev);
297}
298
77110abb
RJ
299static int reg_page_map_set(struct i2c_client *client, const u16 reg)
300{
301 int ret;
302 u16 page;
096b703f 303 struct mt9m111 *mt9m111 = to_mt9m111(client);
77110abb
RJ
304
305 page = (reg >> 8);
096b703f 306 if (page == mt9m111->lastpage)
77110abb
RJ
307 return 0;
308 if (page > 2)
309 return -EINVAL;
310
3f877045 311 ret = i2c_smbus_write_word_swapped(client, MT9M111_PAGE_MAP, page);
506c629a 312 if (!ret)
096b703f 313 mt9m111->lastpage = page;
77110abb
RJ
314 return ret;
315}
316
9538e1c2 317static int mt9m111_reg_read(struct i2c_client *client, const u16 reg)
77110abb 318{
77110abb
RJ
319 int ret;
320
321 ret = reg_page_map_set(client, reg);
322 if (!ret)
3f877045 323 ret = i2c_smbus_read_word_swapped(client, reg & 0xff);
77110abb 324
9538e1c2 325 dev_dbg(&client->dev, "read reg.%03x -> %04x\n", reg, ret);
77110abb
RJ
326 return ret;
327}
328
9538e1c2 329static int mt9m111_reg_write(struct i2c_client *client, const u16 reg,
77110abb
RJ
330 const u16 data)
331{
77110abb
RJ
332 int ret;
333
334 ret = reg_page_map_set(client, reg);
506c629a 335 if (!ret)
3f877045 336 ret = i2c_smbus_write_word_swapped(client, reg & 0xff, data);
9538e1c2 337 dev_dbg(&client->dev, "write reg.%03x = %04x -> %d\n", reg, data, ret);
77110abb
RJ
338 return ret;
339}
340
9538e1c2 341static int mt9m111_reg_set(struct i2c_client *client, const u16 reg,
77110abb
RJ
342 const u16 data)
343{
344 int ret;
345
9538e1c2 346 ret = mt9m111_reg_read(client, reg);
77110abb 347 if (ret >= 0)
9538e1c2 348 ret = mt9m111_reg_write(client, reg, ret | data);
77110abb
RJ
349 return ret;
350}
351
9538e1c2 352static int mt9m111_reg_clear(struct i2c_client *client, const u16 reg,
77110abb
RJ
353 const u16 data)
354{
355 int ret;
356
9538e1c2 357 ret = mt9m111_reg_read(client, reg);
9c56cbf9
MG
358 if (ret >= 0)
359 ret = mt9m111_reg_write(client, reg, ret & ~data);
360 return ret;
77110abb
RJ
361}
362
7c58e7d0
MG
363static int mt9m111_reg_mask(struct i2c_client *client, const u16 reg,
364 const u16 data, const u16 mask)
365{
366 int ret;
367
368 ret = mt9m111_reg_read(client, reg);
369 if (ret >= 0)
370 ret = mt9m111_reg_write(client, reg, (ret & ~mask) | data);
371 return ret;
372}
373
2768cbbb 374static int mt9m111_set_context(struct mt9m111 *mt9m111,
47921932 375 struct mt9m111_context *ctx)
77110abb 376{
2768cbbb 377 struct i2c_client *client = v4l2_get_subdevdata(&mt9m111->subdev);
47921932
GL
378 return reg_write(CONTEXT_CONTROL, ctx->control);
379}
380
381static int mt9m111_setup_rect_ctx(struct mt9m111 *mt9m111,
da673e60
GL
382 struct mt9m111_context *ctx, struct v4l2_rect *rect,
383 unsigned int width, unsigned int height)
47921932
GL
384{
385 struct i2c_client *client = v4l2_get_subdevdata(&mt9m111->subdev);
da673e60 386 int ret = mt9m111_reg_write(client, ctx->reducer_xzoom, rect->width);
47921932 387 if (!ret)
da673e60 388 ret = mt9m111_reg_write(client, ctx->reducer_yzoom, rect->height);
47921932 389 if (!ret)
da673e60 390 ret = mt9m111_reg_write(client, ctx->reducer_xsize, width);
47921932 391 if (!ret)
da673e60 392 ret = mt9m111_reg_write(client, ctx->reducer_ysize, height);
47921932 393 return ret;
77110abb
RJ
394}
395
da673e60 396static int mt9m111_setup_geometry(struct mt9m111 *mt9m111, struct v4l2_rect *rect,
f5fe58fd 397 int width, int height, u32 code)
77110abb 398{
2768cbbb 399 struct i2c_client *client = v4l2_get_subdevdata(&mt9m111->subdev);
47921932 400 int ret;
77110abb 401
09e231b3 402 ret = reg_write(COLUMN_START, rect->left);
506c629a 403 if (!ret)
09e231b3 404 ret = reg_write(ROW_START, rect->top);
77110abb 405
da673e60
GL
406 if (!ret)
407 ret = reg_write(WINDOW_WIDTH, rect->width);
408 if (!ret)
409 ret = reg_write(WINDOW_HEIGHT, rect->height);
410
f5fe58fd 411 if (code != MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE) {
da673e60 412 /* IFP in use, down-scaling possible */
506c629a 413 if (!ret)
da673e60
GL
414 ret = mt9m111_setup_rect_ctx(mt9m111, &context_b,
415 rect, width, height);
506c629a 416 if (!ret)
da673e60
GL
417 ret = mt9m111_setup_rect_ctx(mt9m111, &context_a,
418 rect, width, height);
77110abb
RJ
419 }
420
da673e60
GL
421 dev_dbg(&client->dev, "%s(%x): %ux%u@%u:%u -> %ux%u = %d\n",
422 __func__, code, rect->width, rect->height, rect->left, rect->top,
423 width, height, ret);
424
77110abb
RJ
425 return ret;
426}
427
2768cbbb 428static int mt9m111_enable(struct mt9m111 *mt9m111)
77110abb 429{
2768cbbb 430 struct i2c_client *client = v4l2_get_subdevdata(&mt9m111->subdev);
a650bf1e 431 return reg_write(RESET, MT9M111_RESET_CHIP_ENABLE);
77110abb
RJ
432}
433
2768cbbb 434static int mt9m111_reset(struct mt9m111 *mt9m111)
77110abb 435{
2768cbbb 436 struct i2c_client *client = v4l2_get_subdevdata(&mt9m111->subdev);
77110abb
RJ
437 int ret;
438
439 ret = reg_set(RESET, MT9M111_RESET_RESET_MODE);
506c629a 440 if (!ret)
77110abb 441 ret = reg_set(RESET, MT9M111_RESET_RESET_SOC);
506c629a 442 if (!ret)
77110abb
RJ
443 ret = reg_clear(RESET, MT9M111_RESET_RESET_MODE
444 | MT9M111_RESET_RESET_SOC);
afb13683 445
77110abb
RJ
446 return ret;
447}
448
10d5509c
HV
449static int mt9m111_set_selection(struct v4l2_subdev *sd,
450 struct v4l2_subdev_pad_config *cfg,
451 struct v4l2_subdev_selection *sel)
6a6c8786 452{
10d5509c
HV
453 struct i2c_client *client = v4l2_get_subdevdata(sd);
454 struct mt9m111 *mt9m111 = to_mt9m111(client);
455 struct v4l2_rect rect = sel->r;
da673e60 456 int width, height;
5d7cc01b 457 int ret, align = 0;
da673e60 458
10d5509c
HV
459 if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE ||
460 sel->target != V4L2_SEL_TGT_CROP)
da673e60
GL
461 return -EINVAL;
462
f5fe58fd
BB
463 if (mt9m111->fmt->code == MEDIA_BUS_FMT_SBGGR8_1X8 ||
464 mt9m111->fmt->code == MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE) {
6a6c8786 465 /* Bayer format - even size lengths */
5d7cc01b 466 align = 1;
6a6c8786
GL
467 /* Let the user play with the starting pixel */
468 }
469
470 /* FIXME: the datasheet doesn't specify minimum sizes */
5d7cc01b
RJ
471 v4l_bound_align_image(&rect.width, 2, MT9M111_MAX_WIDTH, align,
472 &rect.height, 2, MT9M111_MAX_HEIGHT, align, 0);
473 rect.left = clamp(rect.left, MT9M111_MIN_DARK_COLS,
474 MT9M111_MIN_DARK_COLS + MT9M111_MAX_WIDTH -
475 (__s32)rect.width);
476 rect.top = clamp(rect.top, MT9M111_MIN_DARK_ROWS,
477 MT9M111_MIN_DARK_ROWS + MT9M111_MAX_HEIGHT -
478 (__s32)rect.height);
6a6c8786 479
da673e60
GL
480 width = min(mt9m111->width, rect.width);
481 height = min(mt9m111->height, rect.height);
09e231b3 482
da673e60
GL
483 ret = mt9m111_setup_geometry(mt9m111, &rect, width, height, mt9m111->fmt->code);
484 if (!ret) {
6a6c8786 485 mt9m111->rect = rect;
da673e60
GL
486 mt9m111->width = width;
487 mt9m111->height = height;
488 }
489
09e231b3
GL
490 return ret;
491}
492
10d5509c
HV
493static int mt9m111_get_selection(struct v4l2_subdev *sd,
494 struct v4l2_subdev_pad_config *cfg,
495 struct v4l2_subdev_selection *sel)
6a6c8786 496{
10d5509c
HV
497 struct i2c_client *client = v4l2_get_subdevdata(sd);
498 struct mt9m111 *mt9m111 = to_mt9m111(client);
6a6c8786 499
10d5509c 500 if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
6b6d33c7
MG
501 return -EINVAL;
502
10d5509c
HV
503 switch (sel->target) {
504 case V4L2_SEL_TGT_CROP_BOUNDS:
10d5509c
HV
505 sel->r.left = MT9M111_MIN_DARK_COLS;
506 sel->r.top = MT9M111_MIN_DARK_ROWS;
507 sel->r.width = MT9M111_MAX_WIDTH;
508 sel->r.height = MT9M111_MAX_HEIGHT;
509 return 0;
510 case V4L2_SEL_TGT_CROP:
511 sel->r = mt9m111->rect;
512 return 0;
513 default:
514 return -EINVAL;
515 }
6a6c8786
GL
516}
517
da298c6d
HV
518static int mt9m111_get_fmt(struct v4l2_subdev *sd,
519 struct v4l2_subdev_pad_config *cfg,
520 struct v4l2_subdev_format *format)
6a6c8786 521{
da298c6d 522 struct v4l2_mbus_framefmt *mf = &format->format;
2768cbbb 523 struct mt9m111 *mt9m111 = container_of(sd, struct mt9m111, subdev);
6a6c8786 524
da298c6d
HV
525 if (format->pad)
526 return -EINVAL;
527
49410d3a
AM
528 if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
529#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
530 mf = v4l2_subdev_get_try_format(sd, cfg, format->pad);
531 format->format = *mf;
532 return 0;
533#else
534 return -ENOTTY;
535#endif
536 }
537
da673e60
GL
538 mf->width = mt9m111->width;
539 mf->height = mt9m111->height;
760697be 540 mf->code = mt9m111->fmt->code;
01f5a394 541 mf->colorspace = mt9m111->fmt->colorspace;
760697be 542 mf->field = V4L2_FIELD_NONE;
2e1566ab
AM
543 mf->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
544 mf->quantization = V4L2_QUANTIZATION_DEFAULT;
545 mf->xfer_func = V4L2_XFER_FUNC_DEFAULT;
6a6c8786
GL
546
547 return 0;
548}
549
2768cbbb 550static int mt9m111_set_pixfmt(struct mt9m111 *mt9m111,
f5fe58fd 551 u32 code)
77110abb 552{
7c58e7d0
MG
553 struct i2c_client *client = v4l2_get_subdevdata(&mt9m111->subdev);
554 u16 data_outfmt2, mask_outfmt2 = MT9M111_OUTFMT_PROCESSED_BAYER |
555 MT9M111_OUTFMT_BYPASS_IFP | MT9M111_OUTFMT_RGB |
556 MT9M111_OUTFMT_RGB565 | MT9M111_OUTFMT_RGB555 |
557 MT9M111_OUTFMT_RGB444x | MT9M111_OUTFMT_RGBx444 |
558 MT9M111_OUTFMT_SWAP_YCbCr_C_Y_RGB_EVEN |
559 MT9M111_OUTFMT_SWAP_YCbCr_Cb_Cr_RGB_R_B;
506c629a 560 int ret;
77110abb 561
760697be 562 switch (code) {
f5fe58fd 563 case MEDIA_BUS_FMT_SBGGR8_1X8:
7c58e7d0
MG
564 data_outfmt2 = MT9M111_OUTFMT_PROCESSED_BAYER |
565 MT9M111_OUTFMT_RGB;
77110abb 566 break;
f5fe58fd 567 case MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE:
7c58e7d0 568 data_outfmt2 = MT9M111_OUTFMT_BYPASS_IFP | MT9M111_OUTFMT_RGB;
77110abb 569 break;
f5fe58fd 570 case MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE:
7c58e7d0
MG
571 data_outfmt2 = MT9M111_OUTFMT_RGB | MT9M111_OUTFMT_RGB555 |
572 MT9M111_OUTFMT_SWAP_YCbCr_C_Y_RGB_EVEN;
573 break;
f5fe58fd 574 case MEDIA_BUS_FMT_RGB555_2X8_PADHI_BE:
7c58e7d0 575 data_outfmt2 = MT9M111_OUTFMT_RGB | MT9M111_OUTFMT_RGB555;
77110abb 576 break;
f5fe58fd 577 case MEDIA_BUS_FMT_RGB565_2X8_LE:
7c58e7d0
MG
578 data_outfmt2 = MT9M111_OUTFMT_RGB | MT9M111_OUTFMT_RGB565 |
579 MT9M111_OUTFMT_SWAP_YCbCr_C_Y_RGB_EVEN;
580 break;
f5fe58fd 581 case MEDIA_BUS_FMT_RGB565_2X8_BE:
7c58e7d0
MG
582 data_outfmt2 = MT9M111_OUTFMT_RGB | MT9M111_OUTFMT_RGB565;
583 break;
f5fe58fd 584 case MEDIA_BUS_FMT_BGR565_2X8_BE:
7c58e7d0
MG
585 data_outfmt2 = MT9M111_OUTFMT_RGB | MT9M111_OUTFMT_RGB565 |
586 MT9M111_OUTFMT_SWAP_YCbCr_Cb_Cr_RGB_R_B;
587 break;
f5fe58fd 588 case MEDIA_BUS_FMT_BGR565_2X8_LE:
7c58e7d0
MG
589 data_outfmt2 = MT9M111_OUTFMT_RGB | MT9M111_OUTFMT_RGB565 |
590 MT9M111_OUTFMT_SWAP_YCbCr_C_Y_RGB_EVEN |
591 MT9M111_OUTFMT_SWAP_YCbCr_Cb_Cr_RGB_R_B;
77110abb 592 break;
f5fe58fd 593 case MEDIA_BUS_FMT_UYVY8_2X8:
7c58e7d0 594 data_outfmt2 = 0;
88f4b899 595 break;
f5fe58fd 596 case MEDIA_BUS_FMT_VYUY8_2X8:
7c58e7d0 597 data_outfmt2 = MT9M111_OUTFMT_SWAP_YCbCr_Cb_Cr_RGB_R_B;
88f4b899 598 break;
f5fe58fd 599 case MEDIA_BUS_FMT_YUYV8_2X8:
7c58e7d0 600 data_outfmt2 = MT9M111_OUTFMT_SWAP_YCbCr_C_Y_RGB_EVEN;
88f4b899 601 break;
f5fe58fd 602 case MEDIA_BUS_FMT_YVYU8_2X8:
7c58e7d0
MG
603 data_outfmt2 = MT9M111_OUTFMT_SWAP_YCbCr_C_Y_RGB_EVEN |
604 MT9M111_OUTFMT_SWAP_YCbCr_Cb_Cr_RGB_R_B;
77110abb
RJ
605 break;
606 default:
7c58e7d0
MG
607 dev_err(&client->dev, "Pixel format not handled: %x\n", code);
608 return -EINVAL;
77110abb
RJ
609 }
610
98480d65
ES
611 /* receiver samples on falling edge, chip-hw default is rising */
612 if (mt9m111->pclk_sample == 0)
613 mask_outfmt2 |= MT9M111_OUTFMT_INV_PIX_CLOCK;
614
47921932
GL
615 ret = mt9m111_reg_mask(client, context_a.output_fmt_ctrl2,
616 data_outfmt2, mask_outfmt2);
7c58e7d0 617 if (!ret)
47921932
GL
618 ret = mt9m111_reg_mask(client, context_b.output_fmt_ctrl2,
619 data_outfmt2, mask_outfmt2);
7c58e7d0 620
77110abb
RJ
621 return ret;
622}
623
717fd5b4
HV
624static int mt9m111_set_fmt(struct v4l2_subdev *sd,
625 struct v4l2_subdev_pad_config *cfg,
626 struct v4l2_subdev_format *format)
77110abb 627{
717fd5b4 628 struct v4l2_mbus_framefmt *mf = &format->format;
da673e60 629 struct i2c_client *client = v4l2_get_subdevdata(sd);
2768cbbb 630 struct mt9m111 *mt9m111 = container_of(sd, struct mt9m111, subdev);
760697be 631 const struct mt9m111_datafmt *fmt;
da673e60
GL
632 struct v4l2_rect *rect = &mt9m111->rect;
633 bool bayer;
717fd5b4
HV
634 int ret;
635
3c437901
MG
636 if (mt9m111->is_streaming)
637 return -EBUSY;
638
717fd5b4
HV
639 if (format->pad)
640 return -EINVAL;
da673e60
GL
641
642 fmt = mt9m111_find_datafmt(mt9m111, mf->code);
643
f5fe58fd
BB
644 bayer = fmt->code == MEDIA_BUS_FMT_SBGGR8_1X8 ||
645 fmt->code == MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE;
6a6c8786
GL
646
647 /*
648 * With Bayer format enforce even side lengths, but let the user play
649 * with the starting pixel
650 */
da673e60
GL
651 if (bayer) {
652 rect->width = ALIGN(rect->width, 2);
653 rect->height = ALIGN(rect->height, 2);
654 }
64f5905e 655
f5fe58fd 656 if (fmt->code == MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE) {
da673e60
GL
657 /* IFP bypass mode, no scaling */
658 mf->width = rect->width;
659 mf->height = rect->height;
660 } else {
661 /* No upscaling */
662 if (mf->width > rect->width)
663 mf->width = rect->width;
664 if (mf->height > rect->height)
665 mf->height = rect->height;
666 }
6a6c8786 667
da673e60
GL
668 dev_dbg(&client->dev, "%s(): %ux%u, code=%x\n", __func__,
669 mf->width, mf->height, fmt->code);
760697be 670
da673e60 671 mf->code = fmt->code;
760697be 672 mf->colorspace = fmt->colorspace;
2e1566ab
AM
673 mf->field = V4L2_FIELD_NONE;
674 mf->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
675 mf->quantization = V4L2_QUANTIZATION_DEFAULT;
676 mf->xfer_func = V4L2_XFER_FUNC_DEFAULT;
77110abb 677
717fd5b4
HV
678 if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
679 cfg->try_fmt = *mf;
680 return 0;
681 }
da673e60
GL
682
683 ret = mt9m111_setup_geometry(mt9m111, rect, mf->width, mf->height, mf->code);
684 if (!ret)
685 ret = mt9m111_set_pixfmt(mt9m111, mf->code);
686 if (!ret) {
687 mt9m111->width = mf->width;
688 mt9m111->height = mf->height;
689 mt9m111->fmt = fmt;
690 }
691
692 return ret;
693}
694
937bb425
MG
695static const struct mt9m111_mode_info *
696mt9m111_find_mode(struct mt9m111 *mt9m111, unsigned int req_fps,
697 unsigned int width, unsigned int height)
698{
699 const struct mt9m111_mode_info *mode;
700 struct v4l2_rect *sensor_rect = &mt9m111->rect;
701 unsigned int gap, gap_best = (unsigned int) -1;
702 int i, best_gap_idx = MT9M111_MODE_SXGA_15FPS;
703 bool skip_30fps = false;
704
705 /*
706 * The fps selection is based on the row, column skipping mechanism.
707 * So ensure that the sensor window is set to default else the fps
708 * aren't calculated correctly within the sensor hw.
709 */
710 if (sensor_rect->width != MT9M111_MAX_WIDTH ||
711 sensor_rect->height != MT9M111_MAX_HEIGHT) {
712 dev_info(mt9m111->subdev.dev,
713 "Framerate selection is not supported for cropped "
714 "images\n");
715 return NULL;
716 }
717
718 /* 30fps only supported for images not exceeding 640x512 */
719 if (width > MT9M111_MAX_WIDTH / 2 || height > MT9M111_MAX_HEIGHT / 2) {
720 dev_dbg(mt9m111->subdev.dev,
721 "Framerates > 15fps are supported only for images "
722 "not exceeding 640x512\n");
723 skip_30fps = true;
724 }
725
726 /* find best matched fps */
727 for (i = 0; i < MT9M111_NUM_MODES; i++) {
728 unsigned int fps = mt9m111_mode_data[i].max_fps;
729
730 if (fps == 30 && skip_30fps)
731 continue;
732
733 gap = abs(fps - req_fps);
734 if (gap < gap_best) {
735 best_gap_idx = i;
736 gap_best = gap;
737 }
738 }
739
740 /*
741 * Use context a/b default timing values instead of calculate blanking
742 * timing values.
743 */
744 mode = &mt9m111_mode_data[best_gap_idx];
745 mt9m111->ctx = (best_gap_idx == MT9M111_MODE_QSXGA_30FPS) ? &context_a :
746 &context_b;
747 return mode;
748}
749
77110abb 750#ifdef CONFIG_VIDEO_ADV_DEBUG
979ea1dd
GL
751static int mt9m111_g_register(struct v4l2_subdev *sd,
752 struct v4l2_dbg_register *reg)
77110abb 753{
c4ce6d14 754 struct i2c_client *client = v4l2_get_subdevdata(sd);
77110abb 755 int val;
77110abb 756
6be89daa 757 if (reg->reg > 0x2ff)
77110abb 758 return -EINVAL;
77110abb 759
9538e1c2 760 val = mt9m111_reg_read(client, reg->reg);
aecde8b5 761 reg->size = 2;
77110abb
RJ
762 reg->val = (u64)val;
763
764 if (reg->val > 0xffff)
765 return -EIO;
766
767 return 0;
768}
769
979ea1dd 770static int mt9m111_s_register(struct v4l2_subdev *sd,
977ba3b1 771 const struct v4l2_dbg_register *reg)
77110abb 772{
c4ce6d14 773 struct i2c_client *client = v4l2_get_subdevdata(sd);
77110abb 774
6be89daa 775 if (reg->reg > 0x2ff)
77110abb
RJ
776 return -EINVAL;
777
9538e1c2 778 if (mt9m111_reg_write(client, reg->reg, reg->val) < 0)
77110abb
RJ
779 return -EIO;
780
781 return 0;
782}
783#endif
784
2768cbbb 785static int mt9m111_set_flip(struct mt9m111 *mt9m111, int flip, int mask)
77110abb 786{
2768cbbb 787 struct i2c_client *client = v4l2_get_subdevdata(&mt9m111->subdev);
77110abb
RJ
788 int ret;
789
47921932
GL
790 if (flip)
791 ret = mt9m111_reg_set(client, mt9m111->ctx->read_mode, mask);
792 else
793 ret = mt9m111_reg_clear(client, mt9m111->ctx->read_mode, mask);
77110abb
RJ
794
795 return ret;
796}
797
2768cbbb 798static int mt9m111_get_global_gain(struct mt9m111 *mt9m111)
77110abb 799{
2768cbbb 800 struct i2c_client *client = v4l2_get_subdevdata(&mt9m111->subdev);
0f28b793 801 int data;
77110abb
RJ
802
803 data = reg_read(GLOBAL_GAIN);
804 if (data >= 0)
0f28b793 805 return (data & 0x2f) * (1 << ((data >> 10) & 1)) *
806 (1 << ((data >> 9) & 1));
807 return data;
77110abb 808}
0f28b793 809
2768cbbb 810static int mt9m111_set_global_gain(struct mt9m111 *mt9m111, int gain)
77110abb 811{
2768cbbb 812 struct i2c_client *client = v4l2_get_subdevdata(&mt9m111->subdev);
77110abb
RJ
813 u16 val;
814
815 if (gain > 63 * 2 * 2)
816 return -EINVAL;
817
77110abb
RJ
818 if ((gain >= 64 * 2) && (gain < 63 * 2 * 2))
819 val = (1 << 10) | (1 << 9) | (gain / 4);
820 else if ((gain >= 64) && (gain < 64 * 2))
506c629a 821 val = (1 << 9) | (gain / 2);
77110abb
RJ
822 else
823 val = gain;
824
825 return reg_write(GLOBAL_GAIN, val);
826}
827
cbaa5c54 828static int mt9m111_set_autoexposure(struct mt9m111 *mt9m111, int val)
77110abb 829{
2768cbbb 830 struct i2c_client *client = v4l2_get_subdevdata(&mt9m111->subdev);
77110abb 831
cbaa5c54 832 if (val == V4L2_EXPOSURE_AUTO)
af8425c5
HV
833 return reg_set(OPER_MODE_CTRL, MT9M111_OPMODE_AUTOEXPO_EN);
834 return reg_clear(OPER_MODE_CTRL, MT9M111_OPMODE_AUTOEXPO_EN);
77110abb 835}
39bf372f 836
2768cbbb 837static int mt9m111_set_autowhitebalance(struct mt9m111 *mt9m111, int on)
39bf372f 838{
2768cbbb 839 struct i2c_client *client = v4l2_get_subdevdata(&mt9m111->subdev);
39bf372f
RJ
840
841 if (on)
af8425c5
HV
842 return reg_set(OPER_MODE_CTRL, MT9M111_OPMODE_AUTOWHITEBAL_EN);
843 return reg_clear(OPER_MODE_CTRL, MT9M111_OPMODE_AUTOWHITEBAL_EN);
39bf372f
RJ
844}
845
74e08739
AM
846static const char * const mt9m111_test_pattern_menu[] = {
847 "Disabled",
848 "Vertical monochrome gradient",
849 "Flat color type 1",
850 "Flat color type 2",
851 "Flat color type 3",
852 "Flat color type 4",
853 "Flat color type 5",
854 "Color bar",
855};
856
857static int mt9m111_set_test_pattern(struct mt9m111 *mt9m111, int val)
858{
859 struct i2c_client *client = v4l2_get_subdevdata(&mt9m111->subdev);
860
861 return mt9m111_reg_mask(client, MT9M111_TPG_CTRL, val,
862 MT9M111_TPG_SEL_MASK);
863}
864
dde64f72
AM
865static int mt9m111_set_colorfx(struct mt9m111 *mt9m111, int val)
866{
867 struct i2c_client *client = v4l2_get_subdevdata(&mt9m111->subdev);
868 static const struct v4l2_control colorfx[] = {
869 { V4L2_COLORFX_NONE, 0 },
870 { V4L2_COLORFX_BW, 1 },
871 { V4L2_COLORFX_SEPIA, 2 },
872 { V4L2_COLORFX_NEGATIVE, 3 },
873 { V4L2_COLORFX_SOLARIZATION, 4 },
874 };
875 int i;
876
877 for (i = 0; i < ARRAY_SIZE(colorfx); i++) {
878 if (colorfx[i].id == val) {
879 return mt9m111_reg_mask(client, MT9M111_EFFECTS_MODE,
880 colorfx[i].value,
881 MT9M111_EFFECTS_MODE_MASK);
882 }
883 }
884
885 return -EINVAL;
886}
887
af8425c5 888static int mt9m111_s_ctrl(struct v4l2_ctrl *ctrl)
77110abb 889{
af8425c5
HV
890 struct mt9m111 *mt9m111 = container_of(ctrl->handler,
891 struct mt9m111, hdl);
77110abb
RJ
892
893 switch (ctrl->id) {
894 case V4L2_CID_VFLIP:
af8425c5 895 return mt9m111_set_flip(mt9m111, ctrl->val,
77110abb 896 MT9M111_RMB_MIRROR_ROWS);
77110abb 897 case V4L2_CID_HFLIP:
af8425c5 898 return mt9m111_set_flip(mt9m111, ctrl->val,
77110abb 899 MT9M111_RMB_MIRROR_COLS);
77110abb 900 case V4L2_CID_GAIN:
af8425c5 901 return mt9m111_set_global_gain(mt9m111, ctrl->val);
77110abb 902 case V4L2_CID_EXPOSURE_AUTO:
af8425c5 903 return mt9m111_set_autoexposure(mt9m111, ctrl->val);
39bf372f 904 case V4L2_CID_AUTO_WHITE_BALANCE:
af8425c5 905 return mt9m111_set_autowhitebalance(mt9m111, ctrl->val);
74e08739
AM
906 case V4L2_CID_TEST_PATTERN:
907 return mt9m111_set_test_pattern(mt9m111, ctrl->val);
dde64f72
AM
908 case V4L2_CID_COLORFX:
909 return mt9m111_set_colorfx(mt9m111, ctrl->val);
77110abb
RJ
910 }
911
af8425c5 912 return -EINVAL;
77110abb
RJ
913}
914
14c5ea9b 915static int mt9m111_suspend(struct mt9m111 *mt9m111)
96c75399 916{
a650bf1e
GL
917 struct i2c_client *client = v4l2_get_subdevdata(&mt9m111->subdev);
918 int ret;
919
af8425c5 920 v4l2_ctrl_s_ctrl(mt9m111->gain, mt9m111_get_global_gain(mt9m111));
96c75399 921
a650bf1e
GL
922 ret = reg_set(RESET, MT9M111_RESET_RESET_MODE);
923 if (!ret)
924 ret = reg_set(RESET, MT9M111_RESET_RESET_SOC |
925 MT9M111_RESET_OUTPUT_DISABLE |
926 MT9M111_RESET_ANALOG_STANDBY);
927 if (!ret)
928 ret = reg_clear(RESET, MT9M111_RESET_CHIP_ENABLE);
929
930 return ret;
96c75399
GL
931}
932
2768cbbb 933static void mt9m111_restore_state(struct mt9m111 *mt9m111)
77110abb 934{
937bb425
MG
935 struct i2c_client *client = v4l2_get_subdevdata(&mt9m111->subdev);
936
47921932 937 mt9m111_set_context(mt9m111, mt9m111->ctx);
2768cbbb 938 mt9m111_set_pixfmt(mt9m111, mt9m111->fmt->code);
da673e60
GL
939 mt9m111_setup_geometry(mt9m111, &mt9m111->rect,
940 mt9m111->width, mt9m111->height, mt9m111->fmt->code);
af8425c5 941 v4l2_ctrl_handler_setup(&mt9m111->hdl);
937bb425
MG
942 mt9m111_reg_mask(client, mt9m111->ctx->read_mode,
943 mt9m111->current_mode->reg_val,
944 mt9m111->current_mode->reg_mask);
77110abb
RJ
945}
946
14c5ea9b 947static int mt9m111_resume(struct mt9m111 *mt9m111)
77110abb 948{
a650bf1e
GL
949 int ret = mt9m111_enable(mt9m111);
950 if (!ret)
951 ret = mt9m111_reset(mt9m111);
952 if (!ret)
953 mt9m111_restore_state(mt9m111);
77110abb 954
77110abb
RJ
955 return ret;
956}
957
2768cbbb 958static int mt9m111_init(struct mt9m111 *mt9m111)
77110abb 959{
2768cbbb 960 struct i2c_client *client = v4l2_get_subdevdata(&mt9m111->subdev);
77110abb
RJ
961 int ret;
962
2768cbbb 963 ret = mt9m111_enable(mt9m111);
506c629a 964 if (!ret)
2768cbbb 965 ret = mt9m111_reset(mt9m111);
506c629a 966 if (!ret)
47921932 967 ret = mt9m111_set_context(mt9m111, mt9m111->ctx);
506c629a 968 if (ret)
c8cf078e 969 dev_err(&client->dev, "mt9m111 init failed: %d\n", ret);
506c629a 970 return ret;
77110abb
RJ
971}
972
4ec10bac
LP
973static int mt9m111_power_on(struct mt9m111 *mt9m111)
974{
975 struct i2c_client *client = v4l2_get_subdevdata(&mt9m111->subdev);
4ec10bac
LP
976 int ret;
977
5d7cc01b 978 ret = v4l2_clk_enable(mt9m111->clk);
4ec10bac
LP
979 if (ret < 0)
980 return ret;
981
982 ret = mt9m111_resume(mt9m111);
983 if (ret < 0) {
984 dev_err(&client->dev, "Failed to resume the sensor: %d\n", ret);
5d7cc01b 985 v4l2_clk_disable(mt9m111->clk);
4ec10bac
LP
986 }
987
988 return ret;
989}
990
991static void mt9m111_power_off(struct mt9m111 *mt9m111)
992{
4ec10bac 993 mt9m111_suspend(mt9m111);
5d7cc01b 994 v4l2_clk_disable(mt9m111->clk);
4ec10bac
LP
995}
996
14c5ea9b
GL
997static int mt9m111_s_power(struct v4l2_subdev *sd, int on)
998{
999 struct mt9m111 *mt9m111 = container_of(sd, struct mt9m111, subdev);
14c5ea9b
GL
1000 int ret = 0;
1001
1002 mutex_lock(&mt9m111->power_lock);
1003
1004 /*
1005 * If the power count is modified from 0 to != 0 or from != 0 to 0,
1006 * update the power state.
1007 */
1008 if (mt9m111->power_count == !on) {
4ec10bac
LP
1009 if (on)
1010 ret = mt9m111_power_on(mt9m111);
1011 else
1012 mt9m111_power_off(mt9m111);
14c5ea9b
GL
1013 }
1014
4ec10bac
LP
1015 if (!ret) {
1016 /* Update the power count. */
1017 mt9m111->power_count += on ? 1 : -1;
1018 WARN_ON(mt9m111->power_count < 0);
1019 }
14c5ea9b 1020
14c5ea9b
GL
1021 mutex_unlock(&mt9m111->power_lock);
1022 return ret;
1023}
1024
af8425c5
HV
1025static const struct v4l2_ctrl_ops mt9m111_ctrl_ops = {
1026 .s_ctrl = mt9m111_s_ctrl,
1027};
1028
39229620 1029static const struct v4l2_subdev_core_ops mt9m111_subdev_core_ops = {
14c5ea9b 1030 .s_power = mt9m111_s_power,
329d9e35
AM
1031 .log_status = v4l2_ctrl_subdev_log_status,
1032 .subscribe_event = v4l2_ctrl_subdev_subscribe_event,
1033 .unsubscribe_event = v4l2_event_subdev_unsubscribe,
979ea1dd
GL
1034#ifdef CONFIG_VIDEO_ADV_DEBUG
1035 .g_register = mt9m111_g_register,
1036 .s_register = mt9m111_s_register,
1037#endif
1038};
1039
937bb425
MG
1040static int mt9m111_g_frame_interval(struct v4l2_subdev *sd,
1041 struct v4l2_subdev_frame_interval *fi)
1042{
1043 struct mt9m111 *mt9m111 = container_of(sd, struct mt9m111, subdev);
1044
1045 fi->interval = mt9m111->frame_interval;
1046
1047 return 0;
1048}
1049
1050static int mt9m111_s_frame_interval(struct v4l2_subdev *sd,
1051 struct v4l2_subdev_frame_interval *fi)
1052{
1053 struct mt9m111 *mt9m111 = container_of(sd, struct mt9m111, subdev);
1054 const struct mt9m111_mode_info *mode;
1055 struct v4l2_fract *fract = &fi->interval;
1056 int fps;
1057
1058 if (mt9m111->is_streaming)
1059 return -EBUSY;
1060
1061 if (fi->pad != 0)
1062 return -EINVAL;
1063
1064 if (fract->numerator == 0) {
1065 fract->denominator = 30;
1066 fract->numerator = 1;
1067 }
1068
1069 fps = DIV_ROUND_CLOSEST(fract->denominator, fract->numerator);
1070
1071 /* Find best fitting mode. Do not update the mode if no one was found. */
1072 mode = mt9m111_find_mode(mt9m111, fps, mt9m111->width, mt9m111->height);
1073 if (!mode)
1074 return 0;
1075
1076 if (mode->max_fps != fps) {
1077 fract->denominator = mode->max_fps;
1078 fract->numerator = 1;
1079 }
1080
1081 mt9m111->current_mode = mode;
1082 mt9m111->frame_interval = fi->interval;
1083
1084 return 0;
1085}
1086
ebcff5fc
HV
1087static int mt9m111_enum_mbus_code(struct v4l2_subdev *sd,
1088 struct v4l2_subdev_pad_config *cfg,
1089 struct v4l2_subdev_mbus_code_enum *code)
760697be 1090{
ebcff5fc 1091 if (code->pad || code->index >= ARRAY_SIZE(mt9m111_colour_fmts))
760697be
GL
1092 return -EINVAL;
1093
ebcff5fc 1094 code->code = mt9m111_colour_fmts[code->index].code;
760697be
GL
1095 return 0;
1096}
1097
7784b1d2
MF
1098static int mt9m111_s_stream(struct v4l2_subdev *sd, int enable)
1099{
1100 struct mt9m111 *mt9m111 = container_of(sd, struct mt9m111, subdev);
1101
1102 mt9m111->is_streaming = !!enable;
1103 return 0;
1104}
1105
49410d3a
AM
1106static int mt9m111_init_cfg(struct v4l2_subdev *sd,
1107 struct v4l2_subdev_pad_config *cfg)
1108{
1109#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
1110 struct v4l2_mbus_framefmt *format =
1111 v4l2_subdev_get_try_format(sd, cfg, 0);
1112
1113 format->width = MT9M111_MAX_WIDTH;
1114 format->height = MT9M111_MAX_HEIGHT;
1115 format->code = mt9m111_colour_fmts[0].code;
1116 format->colorspace = mt9m111_colour_fmts[0].colorspace;
1117 format->field = V4L2_FIELD_NONE;
1118 format->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
1119 format->quantization = V4L2_QUANTIZATION_DEFAULT;
1120 format->xfer_func = V4L2_XFER_FUNC_DEFAULT;
1121#endif
1122 return 0;
1123}
1124
0c0b446d
GL
1125static int mt9m111_g_mbus_config(struct v4l2_subdev *sd,
1126 struct v4l2_mbus_config *cfg)
1127{
98480d65
ES
1128 struct mt9m111 *mt9m111 = container_of(sd, struct mt9m111, subdev);
1129
1130 cfg->flags = V4L2_MBUS_MASTER |
0c0b446d
GL
1131 V4L2_MBUS_HSYNC_ACTIVE_HIGH | V4L2_MBUS_VSYNC_ACTIVE_HIGH |
1132 V4L2_MBUS_DATA_ACTIVE_HIGH;
98480d65
ES
1133
1134 cfg->flags |= mt9m111->pclk_sample ? V4L2_MBUS_PCLK_SAMPLE_RISING :
1135 V4L2_MBUS_PCLK_SAMPLE_FALLING;
1136
0c0b446d 1137 cfg->type = V4L2_MBUS_PARALLEL;
0c0b446d
GL
1138
1139 return 0;
1140}
1141
39229620 1142static const struct v4l2_subdev_video_ops mt9m111_subdev_video_ops = {
0c0b446d 1143 .g_mbus_config = mt9m111_g_mbus_config,
7784b1d2 1144 .s_stream = mt9m111_s_stream,
937bb425
MG
1145 .g_frame_interval = mt9m111_g_frame_interval,
1146 .s_frame_interval = mt9m111_s_frame_interval,
979ea1dd
GL
1147};
1148
ebcff5fc 1149static const struct v4l2_subdev_pad_ops mt9m111_subdev_pad_ops = {
49410d3a 1150 .init_cfg = mt9m111_init_cfg,
ebcff5fc 1151 .enum_mbus_code = mt9m111_enum_mbus_code,
10d5509c
HV
1152 .get_selection = mt9m111_get_selection,
1153 .set_selection = mt9m111_set_selection,
da298c6d 1154 .get_fmt = mt9m111_get_fmt,
717fd5b4 1155 .set_fmt = mt9m111_set_fmt,
ebcff5fc
HV
1156};
1157
39229620 1158static const struct v4l2_subdev_ops mt9m111_subdev_ops = {
979ea1dd
GL
1159 .core = &mt9m111_subdev_core_ops,
1160 .video = &mt9m111_subdev_video_ops,
ebcff5fc 1161 .pad = &mt9m111_subdev_pad_ops,
979ea1dd
GL
1162};
1163
4bbc6d52
LP
1164/*
1165 * Interface active, can use i2c. If it fails, it can indeed mean, that
1166 * this wasn't our capture interface, so, we wait for the right one
1167 */
1168static int mt9m111_video_probe(struct i2c_client *client)
1169{
1170 struct mt9m111 *mt9m111 = to_mt9m111(client);
1171 s32 data;
1172 int ret;
1173
1174 ret = mt9m111_s_power(&mt9m111->subdev, 1);
1175 if (ret < 0)
1176 return ret;
1177
1178 data = reg_read(CHIP_VERSION);
1179
1180 switch (data) {
1181 case 0x143a: /* MT9M111 or MT9M131 */
4bbc6d52
LP
1182 dev_info(&client->dev,
1183 "Detected a MT9M111/MT9M131 chip ID %x\n", data);
1184 break;
1185 case 0x148c: /* MT9M112 */
4bbc6d52
LP
1186 dev_info(&client->dev, "Detected a MT9M112 chip ID %x\n", data);
1187 break;
1188 default:
1189 dev_err(&client->dev,
1190 "No MT9M111/MT9M112/MT9M131 chip detected register read %x\n",
1191 data);
1192 ret = -ENODEV;
1193 goto done;
1194 }
1195
1196 ret = mt9m111_init(mt9m111);
1197 if (ret)
1198 goto done;
1199
1200 ret = v4l2_ctrl_handler_setup(&mt9m111->hdl);
1201
1202done:
1203 mt9m111_s_power(&mt9m111->subdev, 0);
1204 return ret;
1205}
1206
98480d65
ES
1207static int mt9m111_probe_fw(struct i2c_client *client, struct mt9m111 *mt9m111)
1208{
1209 struct v4l2_fwnode_endpoint bus_cfg = {
1210 .bus_type = V4L2_MBUS_PARALLEL
1211 };
1212 struct fwnode_handle *np;
1213 int ret;
1214
1215 np = fwnode_graph_get_next_endpoint(dev_fwnode(&client->dev), NULL);
1216 if (!np)
1217 return -EINVAL;
1218
1219 ret = v4l2_fwnode_endpoint_parse(np, &bus_cfg);
1220 if (ret)
1221 goto out_put_fw;
1222
1223 mt9m111->pclk_sample = !!(bus_cfg.bus.parallel.flags &
1224 V4L2_MBUS_PCLK_SAMPLE_RISING);
1225
1226out_put_fw:
1227 fwnode_handle_put(np);
1228 return ret;
1229}
1230
77110abb
RJ
1231static int mt9m111_probe(struct i2c_client *client,
1232 const struct i2c_device_id *did)
1233{
1234 struct mt9m111 *mt9m111;
77110abb 1235 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
77110abb
RJ
1236 int ret;
1237
77110abb
RJ
1238 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA)) {
1239 dev_warn(&adapter->dev,
1240 "I2C-Adapter doesn't support I2C_FUNC_SMBUS_WORD\n");
1241 return -EIO;
1242 }
1243
70e176a5 1244 mt9m111 = devm_kzalloc(&client->dev, sizeof(struct mt9m111), GFP_KERNEL);
77110abb
RJ
1245 if (!mt9m111)
1246 return -ENOMEM;
1247
98480d65
ES
1248 ret = mt9m111_probe_fw(client, mt9m111);
1249 if (ret)
1250 return ret;
1251
ef6672ea
GL
1252 mt9m111->clk = v4l2_clk_get(&client->dev, "mclk");
1253 if (IS_ERR(mt9m111->clk))
bddb4b53 1254 return PTR_ERR(mt9m111->clk);
ef6672ea 1255
4a1313c4
GL
1256 /* Default HIGHPOWER context */
1257 mt9m111->ctx = &context_b;
1258
979ea1dd 1259 v4l2_i2c_subdev_init(&mt9m111->subdev, client, &mt9m111_subdev_ops);
329d9e35
AM
1260 mt9m111->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
1261 V4L2_SUBDEV_FL_HAS_EVENTS;
5ed8c224 1262
dde64f72 1263 v4l2_ctrl_handler_init(&mt9m111->hdl, 7);
af8425c5
HV
1264 v4l2_ctrl_new_std(&mt9m111->hdl, &mt9m111_ctrl_ops,
1265 V4L2_CID_VFLIP, 0, 1, 1, 0);
1266 v4l2_ctrl_new_std(&mt9m111->hdl, &mt9m111_ctrl_ops,
1267 V4L2_CID_HFLIP, 0, 1, 1, 0);
1268 v4l2_ctrl_new_std(&mt9m111->hdl, &mt9m111_ctrl_ops,
1269 V4L2_CID_AUTO_WHITE_BALANCE, 0, 1, 1, 1);
1270 mt9m111->gain = v4l2_ctrl_new_std(&mt9m111->hdl, &mt9m111_ctrl_ops,
1271 V4L2_CID_GAIN, 0, 63 * 2 * 2, 1, 32);
1272 v4l2_ctrl_new_std_menu(&mt9m111->hdl,
1273 &mt9m111_ctrl_ops, V4L2_CID_EXPOSURE_AUTO, 1, 0,
1274 V4L2_EXPOSURE_AUTO);
74e08739
AM
1275 v4l2_ctrl_new_std_menu_items(&mt9m111->hdl,
1276 &mt9m111_ctrl_ops, V4L2_CID_TEST_PATTERN,
1277 ARRAY_SIZE(mt9m111_test_pattern_menu) - 1, 0, 0,
1278 mt9m111_test_pattern_menu);
dde64f72
AM
1279 v4l2_ctrl_new_std_menu(&mt9m111->hdl, &mt9m111_ctrl_ops,
1280 V4L2_CID_COLORFX, V4L2_COLORFX_SOLARIZATION,
1281 ~(BIT(V4L2_COLORFX_NONE) |
1282 BIT(V4L2_COLORFX_BW) |
1283 BIT(V4L2_COLORFX_SEPIA) |
1284 BIT(V4L2_COLORFX_NEGATIVE) |
1285 BIT(V4L2_COLORFX_SOLARIZATION)),
1286 V4L2_COLORFX_NONE);
af8425c5 1287 mt9m111->subdev.ctrl_handler = &mt9m111->hdl;
ef6672ea
GL
1288 if (mt9m111->hdl.error) {
1289 ret = mt9m111->hdl.error;
1290 goto out_clkput;
1291 }
77110abb 1292
90411ce4
AM
1293#ifdef CONFIG_MEDIA_CONTROLLER
1294 mt9m111->pad.flags = MEDIA_PAD_FL_SOURCE;
1295 mt9m111->subdev.entity.function = MEDIA_ENT_F_CAM_SENSOR;
1296 ret = media_entity_pads_init(&mt9m111->subdev.entity, 1, &mt9m111->pad);
1297 if (ret < 0)
1298 goto out_hdlfree;
1299#endif
1300
937bb425
MG
1301 mt9m111->current_mode = &mt9m111_mode_data[MT9M111_MODE_SXGA_15FPS];
1302 mt9m111->frame_interval.numerator = 1;
1303 mt9m111->frame_interval.denominator = mt9m111->current_mode->max_fps;
1304
af8425c5 1305 /* Second stage probe - when a capture adapter is there */
6a6c8786
GL
1306 mt9m111->rect.left = MT9M111_MIN_DARK_COLS;
1307 mt9m111->rect.top = MT9M111_MIN_DARK_ROWS;
1308 mt9m111->rect.width = MT9M111_MAX_WIDTH;
1309 mt9m111->rect.height = MT9M111_MAX_HEIGHT;
29856308
AM
1310 mt9m111->width = mt9m111->rect.width;
1311 mt9m111->height = mt9m111->rect.height;
760697be 1312 mt9m111->fmt = &mt9m111_colour_fmts[0];
14178aa5 1313 mt9m111->lastpage = -1;
6b806e30 1314 mutex_init(&mt9m111->power_lock);
6a6c8786 1315
14178aa5 1316 ret = mt9m111_video_probe(client);
ef6672ea 1317 if (ret < 0)
90411ce4 1318 goto out_entityclean;
ef6672ea
GL
1319
1320 mt9m111->subdev.dev = &client->dev;
1321 ret = v4l2_async_register_subdev(&mt9m111->subdev);
1322 if (ret < 0)
90411ce4 1323 goto out_entityclean;
ef6672ea
GL
1324
1325 return 0;
1326
90411ce4
AM
1327out_entityclean:
1328#ifdef CONFIG_MEDIA_CONTROLLER
1329 media_entity_cleanup(&mt9m111->subdev.entity);
ef6672ea 1330out_hdlfree:
90411ce4 1331#endif
ef6672ea
GL
1332 v4l2_ctrl_handler_free(&mt9m111->hdl);
1333out_clkput:
1334 v4l2_clk_put(mt9m111->clk);
77110abb 1335
77110abb
RJ
1336 return ret;
1337}
1338
1339static int mt9m111_remove(struct i2c_client *client)
1340{
979ea1dd 1341 struct mt9m111 *mt9m111 = to_mt9m111(client);
40e2e092 1342
ef6672ea 1343 v4l2_async_unregister_subdev(&mt9m111->subdev);
90411ce4 1344 media_entity_cleanup(&mt9m111->subdev.entity);
9aea470b 1345 v4l2_clk_put(mt9m111->clk);
af8425c5 1346 v4l2_ctrl_handler_free(&mt9m111->hdl);
77110abb
RJ
1347
1348 return 0;
1349}
c5f176dc
RJ
1350static const struct of_device_id mt9m111_of_match[] = {
1351 { .compatible = "micron,mt9m111", },
1352 {},
1353};
1354MODULE_DEVICE_TABLE(of, mt9m111_of_match);
77110abb
RJ
1355
1356static const struct i2c_device_id mt9m111_id[] = {
1357 { "mt9m111", 0 },
1358 { }
1359};
1360MODULE_DEVICE_TABLE(i2c, mt9m111_id);
1361
1362static struct i2c_driver mt9m111_i2c_driver = {
1363 .driver = {
1364 .name = "mt9m111",
c5f176dc 1365 .of_match_table = of_match_ptr(mt9m111_of_match),
77110abb
RJ
1366 },
1367 .probe = mt9m111_probe,
1368 .remove = mt9m111_remove,
1369 .id_table = mt9m111_id,
1370};
1371
c6e8d86f 1372module_i2c_driver(mt9m111_i2c_driver);
77110abb 1373
c8cf078e 1374MODULE_DESCRIPTION("Micron/Aptina MT9M111/MT9M112/MT9M131 Camera driver");
77110abb
RJ
1375MODULE_AUTHOR("Robert Jarzmik");
1376MODULE_LICENSE("GPL");