1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * Driver for MT9M001 CMOS Image Sensor from Micron |
4 | * |
5 | * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de> |
6 | */ |
7 | |
8 | #include <linux/clk.h> |
9 | #include <linux/delay.h> |
10 | #include <linux/gpio/consumer.h> |
11 | #include <linux/i2c.h> |
12 | #include <linux/log2.h> |
13 | #include <linux/module.h> |
14 | #include <linux/pm_runtime.h> |
15 | #include <linux/slab.h> |
16 | #include <linux/videodev2.h> |
17 | |
18 | #include <media/v4l2-ctrls.h> |
19 | #include <media/v4l2-device.h> |
20 | #include <media/v4l2-event.h> |
21 | #include <media/v4l2-subdev.h> |
22 | |
23 | /* |
24 | * mt9m001 i2c address 0x5d |
25 | */ |
26 | |
27 | /* mt9m001 selected register addresses */ |
28 | #define MT9M001_CHIP_VERSION 0x00 |
29 | #define MT9M001_ROW_START 0x01 |
30 | #define MT9M001_COLUMN_START 0x02 |
31 | #define MT9M001_WINDOW_HEIGHT 0x03 |
32 | #define MT9M001_WINDOW_WIDTH 0x04 |
33 | #define MT9M001_HORIZONTAL_BLANKING 0x05 |
34 | #define MT9M001_VERTICAL_BLANKING 0x06 |
35 | #define MT9M001_OUTPUT_CONTROL 0x07 |
36 | #define MT9M001_SHUTTER_WIDTH 0x09 |
37 | #define MT9M001_FRAME_RESTART 0x0b |
38 | #define MT9M001_SHUTTER_DELAY 0x0c |
39 | #define MT9M001_RESET 0x0d |
40 | #define MT9M001_READ_OPTIONS1 0x1e |
41 | #define MT9M001_READ_OPTIONS2 0x20 |
42 | #define MT9M001_GLOBAL_GAIN 0x35 |
43 | #define MT9M001_CHIP_ENABLE 0xF1 |
44 | |
45 | #define MT9M001_MAX_WIDTH 1280 |
46 | #define MT9M001_MAX_HEIGHT 1024 |
47 | #define MT9M001_MIN_WIDTH 48 |
48 | #define MT9M001_MIN_HEIGHT 32 |
49 | #define MT9M001_COLUMN_SKIP 20 |
50 | #define MT9M001_ROW_SKIP 12 |
51 | #define MT9M001_DEFAULT_HBLANK 9 |
52 | #define MT9M001_DEFAULT_VBLANK 25 |
53 | |
54 | /* MT9M001 has only one fixed colorspace per pixelcode */ |
55 | struct mt9m001_datafmt { |
56 | u32 code; |
57 | enum v4l2_colorspace colorspace; |
58 | }; |
59 | |
60 | /* Find a data format by a pixel code in an array */ |
61 | static const struct mt9m001_datafmt *mt9m001_find_datafmt( |
62 | u32 code, const struct mt9m001_datafmt *fmt, |
63 | int n) |
64 | { |
65 | int i; |
66 | for (i = 0; i < n; i++) |
67 | if (fmt[i].code == code) |
68 | return fmt + i; |
69 | |
70 | return NULL; |
71 | } |
72 | |
73 | static const struct mt9m001_datafmt mt9m001_colour_fmts[] = { |
74 | /* |
75 | * Order important: first natively supported, |
76 | * second supported with a GPIO extender |
77 | */ |
78 | {MEDIA_BUS_FMT_SBGGR10_1X10, V4L2_COLORSPACE_SRGB}, |
79 | {MEDIA_BUS_FMT_SBGGR8_1X8, V4L2_COLORSPACE_SRGB}, |
80 | }; |
81 | |
82 | static const struct mt9m001_datafmt mt9m001_monochrome_fmts[] = { |
83 | /* Order important - see above */ |
84 | {MEDIA_BUS_FMT_Y10_1X10, V4L2_COLORSPACE_JPEG}, |
85 | {MEDIA_BUS_FMT_Y8_1X8, V4L2_COLORSPACE_JPEG}, |
86 | }; |
87 | |
88 | struct mt9m001 { |
89 | struct v4l2_subdev subdev; |
90 | struct v4l2_ctrl_handler hdl; |
91 | struct { |
92 | /* exposure/auto-exposure cluster */ |
93 | struct v4l2_ctrl *autoexposure; |
94 | struct v4l2_ctrl *exposure; |
95 | }; |
96 | struct mutex mutex; |
97 | struct v4l2_rect rect; /* Sensor window */ |
98 | struct clk *clk; |
99 | struct gpio_desc *standby_gpio; |
100 | struct gpio_desc *reset_gpio; |
101 | const struct mt9m001_datafmt *fmt; |
102 | const struct mt9m001_datafmt *fmts; |
103 | int num_fmts; |
104 | unsigned int total_h; |
105 | unsigned short y_skip_top; /* Lines to skip at the top */ |
106 | struct media_pad pad; |
107 | }; |
108 | |
109 | static struct mt9m001 *to_mt9m001(const struct i2c_client *client) |
110 | { |
111 | return container_of(i2c_get_clientdata(client), struct mt9m001, subdev); |
112 | } |
113 | |
114 | static int reg_read(struct i2c_client *client, const u8 reg) |
115 | { |
116 | return i2c_smbus_read_word_swapped(client, command: reg); |
117 | } |
118 | |
119 | static int reg_write(struct i2c_client *client, const u8 reg, |
120 | const u16 data) |
121 | { |
122 | return i2c_smbus_write_word_swapped(client, command: reg, value: data); |
123 | } |
124 | |
125 | static int reg_set(struct i2c_client *client, const u8 reg, |
126 | const u16 data) |
127 | { |
128 | int ret; |
129 | |
130 | ret = reg_read(client, reg); |
131 | if (ret < 0) |
132 | return ret; |
133 | return reg_write(client, reg, data: ret | data); |
134 | } |
135 | |
136 | static int reg_clear(struct i2c_client *client, const u8 reg, |
137 | const u16 data) |
138 | { |
139 | int ret; |
140 | |
141 | ret = reg_read(client, reg); |
142 | if (ret < 0) |
143 | return ret; |
144 | return reg_write(client, reg, data: ret & ~data); |
145 | } |
146 | |
147 | struct mt9m001_reg { |
148 | u8 reg; |
149 | u16 data; |
150 | }; |
151 | |
152 | static int multi_reg_write(struct i2c_client *client, |
153 | const struct mt9m001_reg *regs, int num) |
154 | { |
155 | int i; |
156 | |
157 | for (i = 0; i < num; i++) { |
158 | int ret = reg_write(client, reg: regs[i].reg, data: regs[i].data); |
159 | |
160 | if (ret) |
161 | return ret; |
162 | } |
163 | |
164 | return 0; |
165 | } |
166 | |
167 | static int mt9m001_init(struct i2c_client *client) |
168 | { |
169 | static const struct mt9m001_reg init_regs[] = { |
170 | /* |
171 | * Issue a soft reset. This returns all registers to their |
172 | * default values. |
173 | */ |
174 | { MT9M001_RESET, 1 }, |
175 | { MT9M001_RESET, 0 }, |
176 | /* Disable chip, synchronous option update */ |
177 | { MT9M001_OUTPUT_CONTROL, 0 } |
178 | }; |
179 | |
180 | dev_dbg(&client->dev, "%s\n" , __func__); |
181 | |
182 | return multi_reg_write(client, regs: init_regs, ARRAY_SIZE(init_regs)); |
183 | } |
184 | |
185 | static int mt9m001_apply_selection(struct v4l2_subdev *sd) |
186 | { |
187 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
188 | struct mt9m001 *mt9m001 = to_mt9m001(client); |
189 | const struct mt9m001_reg regs[] = { |
190 | /* Blanking and start values - default... */ |
191 | { MT9M001_HORIZONTAL_BLANKING, MT9M001_DEFAULT_HBLANK }, |
192 | { MT9M001_VERTICAL_BLANKING, MT9M001_DEFAULT_VBLANK }, |
193 | /* |
194 | * The caller provides a supported format, as verified per |
195 | * call to .set_fmt(FORMAT_TRY). |
196 | */ |
197 | { MT9M001_COLUMN_START, mt9m001->rect.left }, |
198 | { MT9M001_ROW_START, mt9m001->rect.top }, |
199 | { MT9M001_WINDOW_WIDTH, mt9m001->rect.width - 1 }, |
200 | { MT9M001_WINDOW_HEIGHT, |
201 | mt9m001->rect.height + mt9m001->y_skip_top - 1 }, |
202 | }; |
203 | |
204 | return multi_reg_write(client, regs, ARRAY_SIZE(regs)); |
205 | } |
206 | |
207 | static int mt9m001_s_stream(struct v4l2_subdev *sd, int enable) |
208 | { |
209 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
210 | struct mt9m001 *mt9m001 = to_mt9m001(client); |
211 | int ret = 0; |
212 | |
213 | mutex_lock(&mt9m001->mutex); |
214 | |
215 | if (enable) { |
216 | ret = pm_runtime_resume_and_get(dev: &client->dev); |
217 | if (ret < 0) |
218 | goto unlock; |
219 | |
220 | ret = mt9m001_apply_selection(sd); |
221 | if (ret) |
222 | goto put_unlock; |
223 | |
224 | ret = __v4l2_ctrl_handler_setup(hdl: &mt9m001->hdl); |
225 | if (ret) |
226 | goto put_unlock; |
227 | |
228 | /* Switch to master "normal" mode */ |
229 | ret = reg_write(client, MT9M001_OUTPUT_CONTROL, data: 2); |
230 | if (ret < 0) |
231 | goto put_unlock; |
232 | } else { |
233 | /* Switch to master stop sensor readout */ |
234 | reg_write(client, MT9M001_OUTPUT_CONTROL, data: 0); |
235 | pm_runtime_put(dev: &client->dev); |
236 | } |
237 | |
238 | mutex_unlock(lock: &mt9m001->mutex); |
239 | |
240 | return 0; |
241 | |
242 | put_unlock: |
243 | pm_runtime_put(dev: &client->dev); |
244 | unlock: |
245 | mutex_unlock(lock: &mt9m001->mutex); |
246 | |
247 | return ret; |
248 | } |
249 | |
250 | static int mt9m001_set_selection(struct v4l2_subdev *sd, |
251 | struct v4l2_subdev_state *sd_state, |
252 | struct v4l2_subdev_selection *sel) |
253 | { |
254 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
255 | struct mt9m001 *mt9m001 = to_mt9m001(client); |
256 | struct v4l2_rect rect = sel->r; |
257 | |
258 | if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE || |
259 | sel->target != V4L2_SEL_TGT_CROP) |
260 | return -EINVAL; |
261 | |
262 | if (mt9m001->fmts == mt9m001_colour_fmts) |
263 | /* |
264 | * Bayer format - even number of rows for simplicity, |
265 | * but let the user play with the top row. |
266 | */ |
267 | rect.height = ALIGN(rect.height, 2); |
268 | |
269 | /* Datasheet requirement: see register description */ |
270 | rect.width = ALIGN(rect.width, 2); |
271 | rect.left = ALIGN(rect.left, 2); |
272 | |
273 | rect.width = clamp_t(u32, rect.width, MT9M001_MIN_WIDTH, |
274 | MT9M001_MAX_WIDTH); |
275 | rect.left = clamp_t(u32, rect.left, MT9M001_COLUMN_SKIP, |
276 | MT9M001_COLUMN_SKIP + MT9M001_MAX_WIDTH - rect.width); |
277 | |
278 | rect.height = clamp_t(u32, rect.height, MT9M001_MIN_HEIGHT, |
279 | MT9M001_MAX_HEIGHT); |
280 | rect.top = clamp_t(u32, rect.top, MT9M001_ROW_SKIP, |
281 | MT9M001_ROW_SKIP + MT9M001_MAX_HEIGHT - rect.height); |
282 | |
283 | mt9m001->total_h = rect.height + mt9m001->y_skip_top + |
284 | MT9M001_DEFAULT_VBLANK; |
285 | |
286 | mt9m001->rect = rect; |
287 | |
288 | return 0; |
289 | } |
290 | |
291 | static int mt9m001_get_selection(struct v4l2_subdev *sd, |
292 | struct v4l2_subdev_state *sd_state, |
293 | struct v4l2_subdev_selection *sel) |
294 | { |
295 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
296 | struct mt9m001 *mt9m001 = to_mt9m001(client); |
297 | |
298 | if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE) |
299 | return -EINVAL; |
300 | |
301 | switch (sel->target) { |
302 | case V4L2_SEL_TGT_CROP_BOUNDS: |
303 | sel->r.left = MT9M001_COLUMN_SKIP; |
304 | sel->r.top = MT9M001_ROW_SKIP; |
305 | sel->r.width = MT9M001_MAX_WIDTH; |
306 | sel->r.height = MT9M001_MAX_HEIGHT; |
307 | return 0; |
308 | case V4L2_SEL_TGT_CROP: |
309 | sel->r = mt9m001->rect; |
310 | return 0; |
311 | default: |
312 | return -EINVAL; |
313 | } |
314 | } |
315 | |
316 | static int mt9m001_get_fmt(struct v4l2_subdev *sd, |
317 | struct v4l2_subdev_state *sd_state, |
318 | struct v4l2_subdev_format *format) |
319 | { |
320 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
321 | struct mt9m001 *mt9m001 = to_mt9m001(client); |
322 | struct v4l2_mbus_framefmt *mf = &format->format; |
323 | |
324 | if (format->pad) |
325 | return -EINVAL; |
326 | |
327 | if (format->which == V4L2_SUBDEV_FORMAT_TRY) { |
328 | mf = v4l2_subdev_state_get_format(sd_state, 0); |
329 | format->format = *mf; |
330 | return 0; |
331 | } |
332 | |
333 | mf->width = mt9m001->rect.width; |
334 | mf->height = mt9m001->rect.height; |
335 | mf->code = mt9m001->fmt->code; |
336 | mf->colorspace = mt9m001->fmt->colorspace; |
337 | mf->field = V4L2_FIELD_NONE; |
338 | mf->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT; |
339 | mf->quantization = V4L2_QUANTIZATION_DEFAULT; |
340 | mf->xfer_func = V4L2_XFER_FUNC_DEFAULT; |
341 | |
342 | return 0; |
343 | } |
344 | |
345 | static int mt9m001_s_fmt(struct v4l2_subdev *sd, |
346 | const struct mt9m001_datafmt *fmt, |
347 | struct v4l2_mbus_framefmt *mf) |
348 | { |
349 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
350 | struct mt9m001 *mt9m001 = to_mt9m001(client); |
351 | struct v4l2_subdev_selection sel = { |
352 | .which = V4L2_SUBDEV_FORMAT_ACTIVE, |
353 | .target = V4L2_SEL_TGT_CROP, |
354 | .r.left = mt9m001->rect.left, |
355 | .r.top = mt9m001->rect.top, |
356 | .r.width = mf->width, |
357 | .r.height = mf->height, |
358 | }; |
359 | int ret; |
360 | |
361 | /* No support for scaling so far, just crop. TODO: use skipping */ |
362 | ret = mt9m001_set_selection(sd, NULL, sel: &sel); |
363 | if (!ret) { |
364 | mf->width = mt9m001->rect.width; |
365 | mf->height = mt9m001->rect.height; |
366 | mt9m001->fmt = fmt; |
367 | mf->colorspace = fmt->colorspace; |
368 | } |
369 | |
370 | return ret; |
371 | } |
372 | |
373 | static int mt9m001_set_fmt(struct v4l2_subdev *sd, |
374 | struct v4l2_subdev_state *sd_state, |
375 | struct v4l2_subdev_format *format) |
376 | { |
377 | struct v4l2_mbus_framefmt *mf = &format->format; |
378 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
379 | struct mt9m001 *mt9m001 = to_mt9m001(client); |
380 | const struct mt9m001_datafmt *fmt; |
381 | |
382 | if (format->pad) |
383 | return -EINVAL; |
384 | |
385 | v4l_bound_align_image(width: &mf->width, MT9M001_MIN_WIDTH, |
386 | MT9M001_MAX_WIDTH, walign: 1, |
387 | height: &mf->height, MT9M001_MIN_HEIGHT + mt9m001->y_skip_top, |
388 | MT9M001_MAX_HEIGHT + mt9m001->y_skip_top, halign: 0, salign: 0); |
389 | |
390 | if (mt9m001->fmts == mt9m001_colour_fmts) |
391 | mf->height = ALIGN(mf->height - 1, 2); |
392 | |
393 | fmt = mt9m001_find_datafmt(code: mf->code, fmt: mt9m001->fmts, |
394 | n: mt9m001->num_fmts); |
395 | if (!fmt) { |
396 | fmt = mt9m001->fmt; |
397 | mf->code = fmt->code; |
398 | } |
399 | |
400 | mf->colorspace = fmt->colorspace; |
401 | mf->field = V4L2_FIELD_NONE; |
402 | mf->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT; |
403 | mf->quantization = V4L2_QUANTIZATION_DEFAULT; |
404 | mf->xfer_func = V4L2_XFER_FUNC_DEFAULT; |
405 | |
406 | if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE) |
407 | return mt9m001_s_fmt(sd, fmt, mf); |
408 | *v4l2_subdev_state_get_format(sd_state, 0) = *mf; |
409 | return 0; |
410 | } |
411 | |
412 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
413 | static int mt9m001_g_register(struct v4l2_subdev *sd, |
414 | struct v4l2_dbg_register *reg) |
415 | { |
416 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
417 | |
418 | if (reg->reg > 0xff) |
419 | return -EINVAL; |
420 | |
421 | reg->size = 2; |
422 | reg->val = reg_read(client, reg: reg->reg); |
423 | |
424 | if (reg->val > 0xffff) |
425 | return -EIO; |
426 | |
427 | return 0; |
428 | } |
429 | |
430 | static int mt9m001_s_register(struct v4l2_subdev *sd, |
431 | const struct v4l2_dbg_register *reg) |
432 | { |
433 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
434 | |
435 | if (reg->reg > 0xff) |
436 | return -EINVAL; |
437 | |
438 | if (reg_write(client, reg: reg->reg, data: reg->val) < 0) |
439 | return -EIO; |
440 | |
441 | return 0; |
442 | } |
443 | #endif |
444 | |
445 | static int mt9m001_power_on(struct device *dev) |
446 | { |
447 | struct i2c_client *client = to_i2c_client(dev); |
448 | struct mt9m001 *mt9m001 = to_mt9m001(client); |
449 | int ret; |
450 | |
451 | ret = clk_prepare_enable(clk: mt9m001->clk); |
452 | if (ret) |
453 | return ret; |
454 | |
455 | if (mt9m001->standby_gpio) { |
456 | gpiod_set_value_cansleep(desc: mt9m001->standby_gpio, value: 0); |
457 | usleep_range(min: 1000, max: 2000); |
458 | } |
459 | |
460 | if (mt9m001->reset_gpio) { |
461 | gpiod_set_value_cansleep(desc: mt9m001->reset_gpio, value: 1); |
462 | usleep_range(min: 1000, max: 2000); |
463 | gpiod_set_value_cansleep(desc: mt9m001->reset_gpio, value: 0); |
464 | usleep_range(min: 1000, max: 2000); |
465 | } |
466 | |
467 | return 0; |
468 | } |
469 | |
470 | static int mt9m001_power_off(struct device *dev) |
471 | { |
472 | struct i2c_client *client = to_i2c_client(dev); |
473 | struct mt9m001 *mt9m001 = to_mt9m001(client); |
474 | |
475 | gpiod_set_value_cansleep(desc: mt9m001->standby_gpio, value: 1); |
476 | clk_disable_unprepare(clk: mt9m001->clk); |
477 | |
478 | return 0; |
479 | } |
480 | |
481 | static int mt9m001_g_volatile_ctrl(struct v4l2_ctrl *ctrl) |
482 | { |
483 | struct mt9m001 *mt9m001 = container_of(ctrl->handler, |
484 | struct mt9m001, hdl); |
485 | s32 min, max; |
486 | |
487 | switch (ctrl->id) { |
488 | case V4L2_CID_EXPOSURE_AUTO: |
489 | min = mt9m001->exposure->minimum; |
490 | max = mt9m001->exposure->maximum; |
491 | mt9m001->exposure->val = |
492 | (524 + (mt9m001->total_h - 1) * (max - min)) / 1048 + min; |
493 | break; |
494 | } |
495 | return 0; |
496 | } |
497 | |
498 | static int mt9m001_s_ctrl(struct v4l2_ctrl *ctrl) |
499 | { |
500 | struct mt9m001 *mt9m001 = container_of(ctrl->handler, |
501 | struct mt9m001, hdl); |
502 | struct v4l2_subdev *sd = &mt9m001->subdev; |
503 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
504 | struct v4l2_ctrl *exp = mt9m001->exposure; |
505 | int data; |
506 | int ret; |
507 | |
508 | if (!pm_runtime_get_if_in_use(dev: &client->dev)) |
509 | return 0; |
510 | |
511 | switch (ctrl->id) { |
512 | case V4L2_CID_VFLIP: |
513 | if (ctrl->val) |
514 | ret = reg_set(client, MT9M001_READ_OPTIONS2, data: 0x8000); |
515 | else |
516 | ret = reg_clear(client, MT9M001_READ_OPTIONS2, data: 0x8000); |
517 | break; |
518 | |
519 | case V4L2_CID_GAIN: |
520 | /* See Datasheet Table 7, Gain settings. */ |
521 | if (ctrl->val <= ctrl->default_value) { |
522 | /* Pack it into 0..1 step 0.125, register values 0..8 */ |
523 | unsigned long range = ctrl->default_value - ctrl->minimum; |
524 | data = ((ctrl->val - (s32)ctrl->minimum) * 8 + range / 2) / range; |
525 | |
526 | dev_dbg(&client->dev, "Setting gain %d\n" , data); |
527 | ret = reg_write(client, MT9M001_GLOBAL_GAIN, data); |
528 | } else { |
529 | /* Pack it into 1.125..15 variable step, register values 9..67 */ |
530 | /* We assume qctrl->maximum - qctrl->default_value - 1 > 0 */ |
531 | unsigned long range = ctrl->maximum - ctrl->default_value - 1; |
532 | unsigned long gain = ((ctrl->val - (s32)ctrl->default_value - 1) * |
533 | 111 + range / 2) / range + 9; |
534 | |
535 | if (gain <= 32) |
536 | data = gain; |
537 | else if (gain <= 64) |
538 | data = ((gain - 32) * 16 + 16) / 32 + 80; |
539 | else |
540 | data = ((gain - 64) * 7 + 28) / 56 + 96; |
541 | |
542 | dev_dbg(&client->dev, "Setting gain from %d to %d\n" , |
543 | reg_read(client, MT9M001_GLOBAL_GAIN), data); |
544 | ret = reg_write(client, MT9M001_GLOBAL_GAIN, data); |
545 | } |
546 | break; |
547 | |
548 | case V4L2_CID_EXPOSURE_AUTO: |
549 | if (ctrl->val == V4L2_EXPOSURE_MANUAL) { |
550 | unsigned long range = exp->maximum - exp->minimum; |
551 | unsigned long shutter = ((exp->val - (s32)exp->minimum) * 1048 + |
552 | range / 2) / range + 1; |
553 | |
554 | dev_dbg(&client->dev, |
555 | "Setting shutter width from %d to %lu\n" , |
556 | reg_read(client, MT9M001_SHUTTER_WIDTH), shutter); |
557 | ret = reg_write(client, MT9M001_SHUTTER_WIDTH, data: shutter); |
558 | } else { |
559 | mt9m001->total_h = mt9m001->rect.height + |
560 | mt9m001->y_skip_top + MT9M001_DEFAULT_VBLANK; |
561 | ret = reg_write(client, MT9M001_SHUTTER_WIDTH, |
562 | data: mt9m001->total_h); |
563 | } |
564 | break; |
565 | default: |
566 | ret = -EINVAL; |
567 | break; |
568 | } |
569 | |
570 | pm_runtime_put(dev: &client->dev); |
571 | |
572 | return ret; |
573 | } |
574 | |
575 | /* |
576 | * Interface active, can use i2c. If it fails, it can indeed mean, that |
577 | * this wasn't our capture interface, so, we wait for the right one |
578 | */ |
579 | static int mt9m001_video_probe(struct i2c_client *client) |
580 | { |
581 | struct mt9m001 *mt9m001 = to_mt9m001(client); |
582 | s32 data; |
583 | int ret; |
584 | |
585 | /* Enable the chip */ |
586 | data = reg_write(client, MT9M001_CHIP_ENABLE, data: 1); |
587 | dev_dbg(&client->dev, "write: %d\n" , data); |
588 | |
589 | /* Read out the chip version register */ |
590 | data = reg_read(client, MT9M001_CHIP_VERSION); |
591 | |
592 | /* must be 0x8411 or 0x8421 for colour sensor and 8431 for bw */ |
593 | switch (data) { |
594 | case 0x8411: |
595 | case 0x8421: |
596 | mt9m001->fmts = mt9m001_colour_fmts; |
597 | mt9m001->num_fmts = ARRAY_SIZE(mt9m001_colour_fmts); |
598 | break; |
599 | case 0x8431: |
600 | mt9m001->fmts = mt9m001_monochrome_fmts; |
601 | mt9m001->num_fmts = ARRAY_SIZE(mt9m001_monochrome_fmts); |
602 | break; |
603 | default: |
604 | dev_err(&client->dev, |
605 | "No MT9M001 chip detected, register read %x\n" , data); |
606 | ret = -ENODEV; |
607 | goto done; |
608 | } |
609 | |
610 | mt9m001->fmt = &mt9m001->fmts[0]; |
611 | |
612 | dev_info(&client->dev, "Detected a MT9M001 chip ID %x (%s)\n" , data, |
613 | data == 0x8431 ? "C12STM" : "C12ST" ); |
614 | |
615 | ret = mt9m001_init(client); |
616 | if (ret < 0) { |
617 | dev_err(&client->dev, "Failed to initialise the camera\n" ); |
618 | goto done; |
619 | } |
620 | |
621 | /* mt9m001_init() has reset the chip, returning registers to defaults */ |
622 | ret = v4l2_ctrl_handler_setup(hdl: &mt9m001->hdl); |
623 | |
624 | done: |
625 | return ret; |
626 | } |
627 | |
628 | static int mt9m001_g_skip_top_lines(struct v4l2_subdev *sd, u32 *lines) |
629 | { |
630 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
631 | struct mt9m001 *mt9m001 = to_mt9m001(client); |
632 | |
633 | *lines = mt9m001->y_skip_top; |
634 | |
635 | return 0; |
636 | } |
637 | |
638 | static const struct v4l2_ctrl_ops mt9m001_ctrl_ops = { |
639 | .g_volatile_ctrl = mt9m001_g_volatile_ctrl, |
640 | .s_ctrl = mt9m001_s_ctrl, |
641 | }; |
642 | |
643 | static const struct v4l2_subdev_core_ops mt9m001_subdev_core_ops = { |
644 | .log_status = v4l2_ctrl_subdev_log_status, |
645 | .subscribe_event = v4l2_ctrl_subdev_subscribe_event, |
646 | .unsubscribe_event = v4l2_event_subdev_unsubscribe, |
647 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
648 | .g_register = mt9m001_g_register, |
649 | .s_register = mt9m001_s_register, |
650 | #endif |
651 | }; |
652 | |
653 | static int mt9m001_init_state(struct v4l2_subdev *sd, |
654 | struct v4l2_subdev_state *sd_state) |
655 | { |
656 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
657 | struct mt9m001 *mt9m001 = to_mt9m001(client); |
658 | struct v4l2_mbus_framefmt *try_fmt = |
659 | v4l2_subdev_state_get_format(sd_state, 0); |
660 | |
661 | try_fmt->width = MT9M001_MAX_WIDTH; |
662 | try_fmt->height = MT9M001_MAX_HEIGHT; |
663 | try_fmt->code = mt9m001->fmts[0].code; |
664 | try_fmt->colorspace = mt9m001->fmts[0].colorspace; |
665 | try_fmt->field = V4L2_FIELD_NONE; |
666 | try_fmt->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT; |
667 | try_fmt->quantization = V4L2_QUANTIZATION_DEFAULT; |
668 | try_fmt->xfer_func = V4L2_XFER_FUNC_DEFAULT; |
669 | |
670 | return 0; |
671 | } |
672 | |
673 | static int mt9m001_enum_mbus_code(struct v4l2_subdev *sd, |
674 | struct v4l2_subdev_state *sd_state, |
675 | struct v4l2_subdev_mbus_code_enum *code) |
676 | { |
677 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
678 | struct mt9m001 *mt9m001 = to_mt9m001(client); |
679 | |
680 | if (code->pad || code->index >= mt9m001->num_fmts) |
681 | return -EINVAL; |
682 | |
683 | code->code = mt9m001->fmts[code->index].code; |
684 | return 0; |
685 | } |
686 | |
687 | static int mt9m001_get_mbus_config(struct v4l2_subdev *sd, |
688 | unsigned int pad, |
689 | struct v4l2_mbus_config *cfg) |
690 | { |
691 | /* MT9M001 has all capture_format parameters fixed */ |
692 | cfg->type = V4L2_MBUS_PARALLEL; |
693 | cfg->bus.parallel.flags = V4L2_MBUS_PCLK_SAMPLE_FALLING | |
694 | V4L2_MBUS_HSYNC_ACTIVE_HIGH | |
695 | V4L2_MBUS_VSYNC_ACTIVE_HIGH | |
696 | V4L2_MBUS_DATA_ACTIVE_HIGH | |
697 | V4L2_MBUS_MASTER; |
698 | |
699 | return 0; |
700 | } |
701 | |
702 | static const struct v4l2_subdev_video_ops mt9m001_subdev_video_ops = { |
703 | .s_stream = mt9m001_s_stream, |
704 | }; |
705 | |
706 | static const struct v4l2_subdev_sensor_ops mt9m001_subdev_sensor_ops = { |
707 | .g_skip_top_lines = mt9m001_g_skip_top_lines, |
708 | }; |
709 | |
710 | static const struct v4l2_subdev_pad_ops mt9m001_subdev_pad_ops = { |
711 | .enum_mbus_code = mt9m001_enum_mbus_code, |
712 | .get_selection = mt9m001_get_selection, |
713 | .set_selection = mt9m001_set_selection, |
714 | .get_fmt = mt9m001_get_fmt, |
715 | .set_fmt = mt9m001_set_fmt, |
716 | .get_mbus_config = mt9m001_get_mbus_config, |
717 | }; |
718 | |
719 | static const struct v4l2_subdev_ops mt9m001_subdev_ops = { |
720 | .core = &mt9m001_subdev_core_ops, |
721 | .video = &mt9m001_subdev_video_ops, |
722 | .sensor = &mt9m001_subdev_sensor_ops, |
723 | .pad = &mt9m001_subdev_pad_ops, |
724 | }; |
725 | |
726 | static const struct v4l2_subdev_internal_ops mt9m001_internal_ops = { |
727 | .init_state = mt9m001_init_state, |
728 | }; |
729 | |
730 | static int mt9m001_probe(struct i2c_client *client) |
731 | { |
732 | struct mt9m001 *mt9m001; |
733 | struct i2c_adapter *adapter = client->adapter; |
734 | int ret; |
735 | |
736 | if (!i2c_check_functionality(adap: adapter, I2C_FUNC_SMBUS_WORD_DATA)) { |
737 | dev_warn(&adapter->dev, |
738 | "I2C-Adapter doesn't support I2C_FUNC_SMBUS_WORD\n" ); |
739 | return -EIO; |
740 | } |
741 | |
742 | mt9m001 = devm_kzalloc(dev: &client->dev, size: sizeof(*mt9m001), GFP_KERNEL); |
743 | if (!mt9m001) |
744 | return -ENOMEM; |
745 | |
746 | mt9m001->clk = devm_clk_get(dev: &client->dev, NULL); |
747 | if (IS_ERR(ptr: mt9m001->clk)) |
748 | return PTR_ERR(ptr: mt9m001->clk); |
749 | |
750 | mt9m001->standby_gpio = devm_gpiod_get_optional(dev: &client->dev, con_id: "standby" , |
751 | flags: GPIOD_OUT_LOW); |
752 | if (IS_ERR(ptr: mt9m001->standby_gpio)) |
753 | return PTR_ERR(ptr: mt9m001->standby_gpio); |
754 | |
755 | mt9m001->reset_gpio = devm_gpiod_get_optional(dev: &client->dev, con_id: "reset" , |
756 | flags: GPIOD_OUT_LOW); |
757 | if (IS_ERR(ptr: mt9m001->reset_gpio)) |
758 | return PTR_ERR(ptr: mt9m001->reset_gpio); |
759 | |
760 | v4l2_i2c_subdev_init(sd: &mt9m001->subdev, client, ops: &mt9m001_subdev_ops); |
761 | mt9m001->subdev.internal_ops = &mt9m001_internal_ops; |
762 | mt9m001->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | |
763 | V4L2_SUBDEV_FL_HAS_EVENTS; |
764 | v4l2_ctrl_handler_init(&mt9m001->hdl, 4); |
765 | v4l2_ctrl_new_std(hdl: &mt9m001->hdl, ops: &mt9m001_ctrl_ops, |
766 | V4L2_CID_VFLIP, min: 0, max: 1, step: 1, def: 0); |
767 | v4l2_ctrl_new_std(hdl: &mt9m001->hdl, ops: &mt9m001_ctrl_ops, |
768 | V4L2_CID_GAIN, min: 0, max: 127, step: 1, def: 64); |
769 | mt9m001->exposure = v4l2_ctrl_new_std(hdl: &mt9m001->hdl, ops: &mt9m001_ctrl_ops, |
770 | V4L2_CID_EXPOSURE, min: 1, max: 255, step: 1, def: 255); |
771 | /* |
772 | * Simulated autoexposure. If enabled, we calculate shutter width |
773 | * ourselves in the driver based on vertical blanking and frame width |
774 | */ |
775 | mt9m001->autoexposure = v4l2_ctrl_new_std_menu(hdl: &mt9m001->hdl, |
776 | ops: &mt9m001_ctrl_ops, V4L2_CID_EXPOSURE_AUTO, max: 1, mask: 0, |
777 | def: V4L2_EXPOSURE_AUTO); |
778 | mt9m001->subdev.ctrl_handler = &mt9m001->hdl; |
779 | if (mt9m001->hdl.error) |
780 | return mt9m001->hdl.error; |
781 | |
782 | v4l2_ctrl_auto_cluster(ncontrols: 2, controls: &mt9m001->autoexposure, |
783 | manual_val: V4L2_EXPOSURE_MANUAL, set_volatile: true); |
784 | |
785 | mutex_init(&mt9m001->mutex); |
786 | mt9m001->hdl.lock = &mt9m001->mutex; |
787 | |
788 | /* Second stage probe - when a capture adapter is there */ |
789 | mt9m001->y_skip_top = 0; |
790 | mt9m001->rect.left = MT9M001_COLUMN_SKIP; |
791 | mt9m001->rect.top = MT9M001_ROW_SKIP; |
792 | mt9m001->rect.width = MT9M001_MAX_WIDTH; |
793 | mt9m001->rect.height = MT9M001_MAX_HEIGHT; |
794 | |
795 | ret = mt9m001_power_on(dev: &client->dev); |
796 | if (ret) |
797 | goto error_hdl_free; |
798 | |
799 | pm_runtime_set_active(dev: &client->dev); |
800 | pm_runtime_enable(dev: &client->dev); |
801 | |
802 | ret = mt9m001_video_probe(client); |
803 | if (ret) |
804 | goto error_power_off; |
805 | |
806 | mt9m001->pad.flags = MEDIA_PAD_FL_SOURCE; |
807 | mt9m001->subdev.entity.function = MEDIA_ENT_F_CAM_SENSOR; |
808 | ret = media_entity_pads_init(entity: &mt9m001->subdev.entity, num_pads: 1, pads: &mt9m001->pad); |
809 | if (ret) |
810 | goto error_power_off; |
811 | |
812 | ret = v4l2_async_register_subdev(sd: &mt9m001->subdev); |
813 | if (ret) |
814 | goto error_entity_cleanup; |
815 | |
816 | pm_runtime_idle(dev: &client->dev); |
817 | |
818 | return 0; |
819 | |
820 | error_entity_cleanup: |
821 | media_entity_cleanup(entity: &mt9m001->subdev.entity); |
822 | error_power_off: |
823 | pm_runtime_disable(dev: &client->dev); |
824 | pm_runtime_set_suspended(dev: &client->dev); |
825 | mt9m001_power_off(dev: &client->dev); |
826 | |
827 | error_hdl_free: |
828 | v4l2_ctrl_handler_free(hdl: &mt9m001->hdl); |
829 | mutex_destroy(lock: &mt9m001->mutex); |
830 | |
831 | return ret; |
832 | } |
833 | |
834 | static void mt9m001_remove(struct i2c_client *client) |
835 | { |
836 | struct mt9m001 *mt9m001 = to_mt9m001(client); |
837 | |
838 | /* |
839 | * As it increments RPM usage_count even on errors, we don't need to |
840 | * check the returned code here. |
841 | */ |
842 | pm_runtime_get_sync(dev: &client->dev); |
843 | |
844 | v4l2_async_unregister_subdev(sd: &mt9m001->subdev); |
845 | media_entity_cleanup(entity: &mt9m001->subdev.entity); |
846 | |
847 | pm_runtime_disable(dev: &client->dev); |
848 | pm_runtime_set_suspended(dev: &client->dev); |
849 | pm_runtime_put_noidle(dev: &client->dev); |
850 | mt9m001_power_off(dev: &client->dev); |
851 | |
852 | v4l2_ctrl_handler_free(hdl: &mt9m001->hdl); |
853 | mutex_destroy(lock: &mt9m001->mutex); |
854 | } |
855 | |
856 | static const struct i2c_device_id mt9m001_id[] = { |
857 | { "mt9m001" , 0 }, |
858 | { } |
859 | }; |
860 | MODULE_DEVICE_TABLE(i2c, mt9m001_id); |
861 | |
862 | static const struct dev_pm_ops mt9m001_pm_ops = { |
863 | SET_RUNTIME_PM_OPS(mt9m001_power_off, mt9m001_power_on, NULL) |
864 | }; |
865 | |
866 | static const struct of_device_id mt9m001_of_match[] = { |
867 | { .compatible = "onnn,mt9m001" , }, |
868 | { /* sentinel */ }, |
869 | }; |
870 | MODULE_DEVICE_TABLE(of, mt9m001_of_match); |
871 | |
872 | static struct i2c_driver mt9m001_i2c_driver = { |
873 | .driver = { |
874 | .name = "mt9m001" , |
875 | .pm = &mt9m001_pm_ops, |
876 | .of_match_table = mt9m001_of_match, |
877 | }, |
878 | .probe = mt9m001_probe, |
879 | .remove = mt9m001_remove, |
880 | .id_table = mt9m001_id, |
881 | }; |
882 | |
883 | module_i2c_driver(mt9m001_i2c_driver); |
884 | |
885 | MODULE_DESCRIPTION("Micron MT9M001 Camera driver" ); |
886 | MODULE_AUTHOR("Guennadi Liakhovetski <kernel@pengutronix.de>" ); |
887 | MODULE_LICENSE("GPL v2" ); |
888 | |