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