• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Driver for M-5MOLS 8M Pixel camera sensor with ISP
3  *
4  * Copyright (C) 2011 Samsung Electronics Co., Ltd.
5  * Author: HeungJun Kim <riverful.kim@samsung.com>
6  *
7  * Copyright (C) 2009 Samsung Electronics Co., Ltd.
8  * Author: Dongsoo Nathaniel Kim <dongsoo45.kim@samsung.com>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  */
15 
16 #include <linux/i2c.h>
17 #include <linux/slab.h>
18 #include <linux/irq.h>
19 #include <linux/interrupt.h>
20 #include <linux/delay.h>
21 #include <linux/gpio.h>
22 #include <linux/regulator/consumer.h>
23 #include <linux/videodev2.h>
24 #include <linux/module.h>
25 #include <media/v4l2-ctrls.h>
26 #include <media/v4l2-device.h>
27 #include <media/v4l2-subdev.h>
28 #include <media/i2c/m5mols.h>
29 
30 #include "m5mols.h"
31 #include "m5mols_reg.h"
32 
33 int m5mols_debug;
34 module_param(m5mols_debug, int, 0644);
35 
36 #define MODULE_NAME		"M5MOLS"
37 #define M5MOLS_I2C_CHECK_RETRY	500
38 
39 /* The regulator consumer names for external voltage regulators */
40 static struct regulator_bulk_data supplies[] = {
41 	{
42 		.supply = "core",	/* ARM core power, 1.2V */
43 	}, {
44 		.supply	= "dig_18",	/* digital power 1, 1.8V */
45 	}, {
46 		.supply	= "d_sensor",	/* sensor power 1, 1.8V */
47 	}, {
48 		.supply	= "dig_28",	/* digital power 2, 2.8V */
49 	}, {
50 		.supply	= "a_sensor",	/* analog power */
51 	}, {
52 		.supply	= "dig_12",	/* digital power 3, 1.2V */
53 	},
54 };
55 
56 static struct v4l2_mbus_framefmt m5mols_default_ffmt[M5MOLS_RESTYPE_MAX] = {
57 	[M5MOLS_RESTYPE_MONITOR] = {
58 		.width		= 1920,
59 		.height		= 1080,
60 		.code		= MEDIA_BUS_FMT_VYUY8_2X8,
61 		.field		= V4L2_FIELD_NONE,
62 		.colorspace	= V4L2_COLORSPACE_JPEG,
63 	},
64 	[M5MOLS_RESTYPE_CAPTURE] = {
65 		.width		= 1920,
66 		.height		= 1080,
67 		.code		= MEDIA_BUS_FMT_JPEG_1X8,
68 		.field		= V4L2_FIELD_NONE,
69 		.colorspace	= V4L2_COLORSPACE_JPEG,
70 	},
71 };
72 #define SIZE_DEFAULT_FFMT	ARRAY_SIZE(m5mols_default_ffmt)
73 
74 static const struct m5mols_resolution m5mols_reg_res[] = {
75 	{ 0x01, M5MOLS_RESTYPE_MONITOR, 128, 96 },	/* SUB-QCIF */
76 	{ 0x03, M5MOLS_RESTYPE_MONITOR, 160, 120 },	/* QQVGA */
77 	{ 0x05, M5MOLS_RESTYPE_MONITOR, 176, 144 },	/* QCIF */
78 	{ 0x06, M5MOLS_RESTYPE_MONITOR, 176, 176 },
79 	{ 0x08, M5MOLS_RESTYPE_MONITOR, 240, 320 },	/* QVGA */
80 	{ 0x09, M5MOLS_RESTYPE_MONITOR, 320, 240 },	/* QVGA */
81 	{ 0x0c, M5MOLS_RESTYPE_MONITOR, 240, 400 },	/* WQVGA */
82 	{ 0x0d, M5MOLS_RESTYPE_MONITOR, 400, 240 },	/* WQVGA */
83 	{ 0x0e, M5MOLS_RESTYPE_MONITOR, 352, 288 },	/* CIF */
84 	{ 0x13, M5MOLS_RESTYPE_MONITOR, 480, 360 },
85 	{ 0x15, M5MOLS_RESTYPE_MONITOR, 640, 360 },	/* qHD */
86 	{ 0x17, M5MOLS_RESTYPE_MONITOR, 640, 480 },	/* VGA */
87 	{ 0x18, M5MOLS_RESTYPE_MONITOR, 720, 480 },
88 	{ 0x1a, M5MOLS_RESTYPE_MONITOR, 800, 480 },	/* WVGA */
89 	{ 0x1f, M5MOLS_RESTYPE_MONITOR, 800, 600 },	/* SVGA */
90 	{ 0x21, M5MOLS_RESTYPE_MONITOR, 1280, 720 },	/* HD */
91 	{ 0x25, M5MOLS_RESTYPE_MONITOR, 1920, 1080 },	/* 1080p */
92 	{ 0x29, M5MOLS_RESTYPE_MONITOR, 3264, 2448 },	/* 2.63fps 8M */
93 	{ 0x39, M5MOLS_RESTYPE_MONITOR, 800, 602 },	/* AHS_MON debug */
94 
95 	{ 0x02, M5MOLS_RESTYPE_CAPTURE, 320, 240 },	/* QVGA */
96 	{ 0x04, M5MOLS_RESTYPE_CAPTURE, 400, 240 },	/* WQVGA */
97 	{ 0x07, M5MOLS_RESTYPE_CAPTURE, 480, 360 },
98 	{ 0x08, M5MOLS_RESTYPE_CAPTURE, 640, 360 },	/* qHD */
99 	{ 0x09, M5MOLS_RESTYPE_CAPTURE, 640, 480 },	/* VGA */
100 	{ 0x0a, M5MOLS_RESTYPE_CAPTURE, 800, 480 },	/* WVGA */
101 	{ 0x10, M5MOLS_RESTYPE_CAPTURE, 1280, 720 },	/* HD */
102 	{ 0x14, M5MOLS_RESTYPE_CAPTURE, 1280, 960 },	/* 1M */
103 	{ 0x17, M5MOLS_RESTYPE_CAPTURE, 1600, 1200 },	/* 2M */
104 	{ 0x19, M5MOLS_RESTYPE_CAPTURE, 1920, 1080 },	/* Full-HD */
105 	{ 0x1a, M5MOLS_RESTYPE_CAPTURE, 2048, 1152 },	/* 3Mega */
106 	{ 0x1b, M5MOLS_RESTYPE_CAPTURE, 2048, 1536 },
107 	{ 0x1c, M5MOLS_RESTYPE_CAPTURE, 2560, 1440 },	/* 4Mega */
108 	{ 0x1d, M5MOLS_RESTYPE_CAPTURE, 2560, 1536 },
109 	{ 0x1f, M5MOLS_RESTYPE_CAPTURE, 2560, 1920 },	/* 5Mega */
110 	{ 0x21, M5MOLS_RESTYPE_CAPTURE, 3264, 1836 },	/* 6Mega */
111 	{ 0x22, M5MOLS_RESTYPE_CAPTURE, 3264, 1960 },
112 	{ 0x25, M5MOLS_RESTYPE_CAPTURE, 3264, 2448 },	/* 8Mega */
113 };
114 
115 /**
116  * m5mols_swap_byte - an byte array to integer conversion function
117  * @size: size in bytes of I2C packet defined in the M-5MOLS datasheet
118  *
119  * Convert I2C data byte array with performing any required byte
120  * reordering to assure proper values for each data type, regardless
121  * of the architecture endianness.
122  */
m5mols_swap_byte(u8 * data,u8 length)123 static u32 m5mols_swap_byte(u8 *data, u8 length)
124 {
125 	if (length == 1)
126 		return *data;
127 	else if (length == 2)
128 		return be16_to_cpu(*((__be16 *)data));
129 	else
130 		return be32_to_cpu(*((__be32 *)data));
131 }
132 
133 /**
134  * m5mols_read -  I2C read function
135  * @reg: combination of size, category and command for the I2C packet
136  * @size: desired size of I2C packet
137  * @val: read value
138  *
139  * Returns 0 on success, or else negative errno.
140  */
m5mols_read(struct v4l2_subdev * sd,u32 size,u32 reg,u32 * val)141 static int m5mols_read(struct v4l2_subdev *sd, u32 size, u32 reg, u32 *val)
142 {
143 	struct i2c_client *client = v4l2_get_subdevdata(sd);
144 	struct m5mols_info *info = to_m5mols(sd);
145 	u8 rbuf[M5MOLS_I2C_MAX_SIZE + 1];
146 	u8 category = I2C_CATEGORY(reg);
147 	u8 cmd = I2C_COMMAND(reg);
148 	struct i2c_msg msg[2];
149 	u8 wbuf[5];
150 	int ret;
151 
152 	if (!client->adapter)
153 		return -ENODEV;
154 
155 	msg[0].addr = client->addr;
156 	msg[0].flags = 0;
157 	msg[0].len = 5;
158 	msg[0].buf = wbuf;
159 	wbuf[0] = 5;
160 	wbuf[1] = M5MOLS_BYTE_READ;
161 	wbuf[2] = category;
162 	wbuf[3] = cmd;
163 	wbuf[4] = size;
164 
165 	msg[1].addr = client->addr;
166 	msg[1].flags = I2C_M_RD;
167 	msg[1].len = size + 1;
168 	msg[1].buf = rbuf;
169 
170 	/* minimum stabilization time */
171 	usleep_range(200, 200);
172 
173 	ret = i2c_transfer(client->adapter, msg, 2);
174 
175 	if (ret == 2) {
176 		*val = m5mols_swap_byte(&rbuf[1], size);
177 		return 0;
178 	}
179 
180 	if (info->isp_ready)
181 		v4l2_err(sd, "read failed: size:%d cat:%02x cmd:%02x. %d\n",
182 			 size, category, cmd, ret);
183 
184 	return ret < 0 ? ret : -EIO;
185 }
186 
m5mols_read_u8(struct v4l2_subdev * sd,u32 reg,u8 * val)187 int m5mols_read_u8(struct v4l2_subdev *sd, u32 reg, u8 *val)
188 {
189 	u32 val_32;
190 	int ret;
191 
192 	if (I2C_SIZE(reg) != 1) {
193 		v4l2_err(sd, "Wrong data size\n");
194 		return -EINVAL;
195 	}
196 
197 	ret = m5mols_read(sd, I2C_SIZE(reg), reg, &val_32);
198 	if (ret)
199 		return ret;
200 
201 	*val = (u8)val_32;
202 	return ret;
203 }
204 
m5mols_read_u16(struct v4l2_subdev * sd,u32 reg,u16 * val)205 int m5mols_read_u16(struct v4l2_subdev *sd, u32 reg, u16 *val)
206 {
207 	u32 val_32;
208 	int ret;
209 
210 	if (I2C_SIZE(reg) != 2) {
211 		v4l2_err(sd, "Wrong data size\n");
212 		return -EINVAL;
213 	}
214 
215 	ret = m5mols_read(sd, I2C_SIZE(reg), reg, &val_32);
216 	if (ret)
217 		return ret;
218 
219 	*val = (u16)val_32;
220 	return ret;
221 }
222 
m5mols_read_u32(struct v4l2_subdev * sd,u32 reg,u32 * val)223 int m5mols_read_u32(struct v4l2_subdev *sd, u32 reg, u32 *val)
224 {
225 	if (I2C_SIZE(reg) != 4) {
226 		v4l2_err(sd, "Wrong data size\n");
227 		return -EINVAL;
228 	}
229 
230 	return m5mols_read(sd, I2C_SIZE(reg), reg, val);
231 }
232 
233 /**
234  * m5mols_write - I2C command write function
235  * @reg: combination of size, category and command for the I2C packet
236  * @val: value to write
237  *
238  * Returns 0 on success, or else negative errno.
239  */
m5mols_write(struct v4l2_subdev * sd,u32 reg,u32 val)240 int m5mols_write(struct v4l2_subdev *sd, u32 reg, u32 val)
241 {
242 	struct i2c_client *client = v4l2_get_subdevdata(sd);
243 	struct m5mols_info *info = to_m5mols(sd);
244 	u8 wbuf[M5MOLS_I2C_MAX_SIZE + 4];
245 	u8 category = I2C_CATEGORY(reg);
246 	u8 cmd = I2C_COMMAND(reg);
247 	u8 size	= I2C_SIZE(reg);
248 	u32 *buf = (u32 *)&wbuf[4];
249 	struct i2c_msg msg[1];
250 	int ret;
251 
252 	if (!client->adapter)
253 		return -ENODEV;
254 
255 	if (size != 1 && size != 2 && size != 4) {
256 		v4l2_err(sd, "Wrong data size\n");
257 		return -EINVAL;
258 	}
259 
260 	msg->addr = client->addr;
261 	msg->flags = 0;
262 	msg->len = (u16)size + 4;
263 	msg->buf = wbuf;
264 	wbuf[0] = size + 4;
265 	wbuf[1] = M5MOLS_BYTE_WRITE;
266 	wbuf[2] = category;
267 	wbuf[3] = cmd;
268 
269 	*buf = m5mols_swap_byte((u8 *)&val, size);
270 
271 	usleep_range(200, 200);
272 
273 	ret = i2c_transfer(client->adapter, msg, 1);
274 	if (ret == 1)
275 		return 0;
276 
277 	if (info->isp_ready)
278 		v4l2_err(sd, "write failed: cat:%02x cmd:%02x ret:%d\n",
279 			 category, cmd, ret);
280 
281 	return ret < 0 ? ret : -EIO;
282 }
283 
284 /**
285  * m5mols_busy_wait - Busy waiting with I2C register polling
286  * @reg: the I2C_REG() address of an 8-bit status register to check
287  * @value: expected status register value
288  * @mask: bit mask for the read status register value
289  * @timeout: timeout in miliseconds, or -1 for default timeout
290  *
291  * The @reg register value is ORed with @mask before comparing with @value.
292  *
293  * Return: 0 if the requested condition became true within less than
294  *         @timeout ms, or else negative errno.
295  */
m5mols_busy_wait(struct v4l2_subdev * sd,u32 reg,u32 value,u32 mask,int timeout)296 int m5mols_busy_wait(struct v4l2_subdev *sd, u32 reg, u32 value, u32 mask,
297 		     int timeout)
298 {
299 	int ms = timeout < 0 ? M5MOLS_BUSY_WAIT_DEF_TIMEOUT : timeout;
300 	unsigned long end = jiffies + msecs_to_jiffies(ms);
301 	u8 status;
302 
303 	do {
304 		int ret = m5mols_read_u8(sd, reg, &status);
305 
306 		if (ret < 0 && !(mask & M5MOLS_I2C_RDY_WAIT_FL))
307 			return ret;
308 		if (!ret && (status & mask & 0xff) == (value & 0xff))
309 			return 0;
310 		usleep_range(100, 250);
311 	} while (ms > 0 && time_is_after_jiffies(end));
312 
313 	return -EBUSY;
314 }
315 
316 /**
317  * m5mols_enable_interrupt - Clear interrupt pending bits and unmask interrupts
318  *
319  * Before writing desired interrupt value the INT_FACTOR register should
320  * be read to clear pending interrupts.
321  */
m5mols_enable_interrupt(struct v4l2_subdev * sd,u8 reg)322 int m5mols_enable_interrupt(struct v4l2_subdev *sd, u8 reg)
323 {
324 	struct m5mols_info *info = to_m5mols(sd);
325 	u8 mask = is_available_af(info) ? REG_INT_AF : 0;
326 	u8 dummy;
327 	int ret;
328 
329 	ret = m5mols_read_u8(sd, SYSTEM_INT_FACTOR, &dummy);
330 	if (!ret)
331 		ret = m5mols_write(sd, SYSTEM_INT_ENABLE, reg & ~mask);
332 	return ret;
333 }
334 
m5mols_wait_interrupt(struct v4l2_subdev * sd,u8 irq_mask,u32 timeout)335 int m5mols_wait_interrupt(struct v4l2_subdev *sd, u8 irq_mask, u32 timeout)
336 {
337 	struct m5mols_info *info = to_m5mols(sd);
338 
339 	int ret = wait_event_interruptible_timeout(info->irq_waitq,
340 				atomic_add_unless(&info->irq_done, -1, 0),
341 				msecs_to_jiffies(timeout));
342 	if (ret <= 0)
343 		return ret ? ret : -ETIMEDOUT;
344 
345 	return m5mols_busy_wait(sd, SYSTEM_INT_FACTOR, irq_mask,
346 				M5MOLS_I2C_RDY_WAIT_FL | irq_mask, -1);
347 }
348 
349 /**
350  * m5mols_reg_mode - Write the mode and check busy status
351  *
352  * It always accompanies a little delay changing the M-5MOLS mode, so it is
353  * needed checking current busy status to guarantee right mode.
354  */
m5mols_reg_mode(struct v4l2_subdev * sd,u8 mode)355 static int m5mols_reg_mode(struct v4l2_subdev *sd, u8 mode)
356 {
357 	int ret = m5mols_write(sd, SYSTEM_SYSMODE, mode);
358 	if (ret < 0)
359 		return ret;
360 	return m5mols_busy_wait(sd, SYSTEM_SYSMODE, mode, 0xff,
361 				M5MOLS_MODE_CHANGE_TIMEOUT);
362 }
363 
364 /**
365  * m5mols_set_mode - set the M-5MOLS controller mode
366  * @mode: the required operation mode
367  *
368  * The commands of M-5MOLS are grouped into specific modes. Each functionality
369  * can be guaranteed only when the sensor is operating in mode which a command
370  * belongs to.
371  */
m5mols_set_mode(struct m5mols_info * info,u8 mode)372 int m5mols_set_mode(struct m5mols_info *info, u8 mode)
373 {
374 	struct v4l2_subdev *sd = &info->sd;
375 	int ret = -EINVAL;
376 	u8 reg;
377 
378 	if (mode < REG_PARAMETER || mode > REG_CAPTURE)
379 		return ret;
380 
381 	ret = m5mols_read_u8(sd, SYSTEM_SYSMODE, &reg);
382 	if (ret || reg == mode)
383 		return ret;
384 
385 	switch (reg) {
386 	case REG_PARAMETER:
387 		ret = m5mols_reg_mode(sd, REG_MONITOR);
388 		if (mode == REG_MONITOR)
389 			break;
390 		if (!ret)
391 			ret = m5mols_reg_mode(sd, REG_CAPTURE);
392 		break;
393 
394 	case REG_MONITOR:
395 		if (mode == REG_PARAMETER) {
396 			ret = m5mols_reg_mode(sd, REG_PARAMETER);
397 			break;
398 		}
399 
400 		ret = m5mols_reg_mode(sd, REG_CAPTURE);
401 		break;
402 
403 	case REG_CAPTURE:
404 		ret = m5mols_reg_mode(sd, REG_MONITOR);
405 		if (mode == REG_MONITOR)
406 			break;
407 		if (!ret)
408 			ret = m5mols_reg_mode(sd, REG_PARAMETER);
409 		break;
410 
411 	default:
412 		v4l2_warn(sd, "Wrong mode: %d\n", mode);
413 	}
414 
415 	if (!ret)
416 		info->mode = mode;
417 
418 	return ret;
419 }
420 
421 /**
422  * m5mols_get_version - retrieve full revisions information of M-5MOLS
423  *
424  * The version information includes revisions of hardware and firmware,
425  * AutoFocus alghorithm version and the version string.
426  */
m5mols_get_version(struct v4l2_subdev * sd)427 static int m5mols_get_version(struct v4l2_subdev *sd)
428 {
429 	struct m5mols_info *info = to_m5mols(sd);
430 	struct m5mols_version *ver = &info->ver;
431 	u8 *str = ver->str;
432 	int i;
433 	int ret;
434 
435 	ret = m5mols_read_u8(sd, SYSTEM_VER_CUSTOMER, &ver->customer);
436 	if (!ret)
437 		ret = m5mols_read_u8(sd, SYSTEM_VER_PROJECT, &ver->project);
438 	if (!ret)
439 		ret = m5mols_read_u16(sd, SYSTEM_VER_FIRMWARE, &ver->fw);
440 	if (!ret)
441 		ret = m5mols_read_u16(sd, SYSTEM_VER_HARDWARE, &ver->hw);
442 	if (!ret)
443 		ret = m5mols_read_u16(sd, SYSTEM_VER_PARAMETER, &ver->param);
444 	if (!ret)
445 		ret = m5mols_read_u16(sd, SYSTEM_VER_AWB, &ver->awb);
446 	if (!ret)
447 		ret = m5mols_read_u8(sd, AF_VERSION, &ver->af);
448 	if (ret)
449 		return ret;
450 
451 	for (i = 0; i < VERSION_STRING_SIZE; i++) {
452 		ret = m5mols_read_u8(sd, SYSTEM_VER_STRING, &str[i]);
453 		if (ret)
454 			return ret;
455 	}
456 
457 	v4l2_info(sd, "Manufacturer\t[%s]\n",
458 			is_manufacturer(info, REG_SAMSUNG_ELECTRO) ?
459 			"Samsung Electro-Machanics" :
460 			is_manufacturer(info, REG_SAMSUNG_OPTICS) ?
461 			"Samsung Fiber-Optics" :
462 			is_manufacturer(info, REG_SAMSUNG_TECHWIN) ?
463 			"Samsung Techwin" : "None");
464 	v4l2_info(sd, "Customer/Project\t[0x%02x/0x%02x]\n",
465 			info->ver.customer, info->ver.project);
466 
467 	if (!is_available_af(info))
468 		v4l2_info(sd, "No support Auto Focus on this firmware\n");
469 
470 	return ret;
471 }
472 
473 /**
474  * __find_restype - Lookup M-5MOLS resolution type according to pixel code
475  * @code: pixel code
476  */
__find_restype(u32 code)477 static enum m5mols_restype __find_restype(u32 code)
478 {
479 	enum m5mols_restype type = M5MOLS_RESTYPE_MONITOR;
480 
481 	do {
482 		if (code == m5mols_default_ffmt[type].code)
483 			return type;
484 	} while (type++ != SIZE_DEFAULT_FFMT);
485 
486 	return 0;
487 }
488 
489 /**
490  * __find_resolution - Lookup preset and type of M-5MOLS's resolution
491  * @mf: pixel format to find/negotiate the resolution preset for
492  * @type: M-5MOLS resolution type
493  * @resolution:	M-5MOLS resolution preset register value
494  *
495  * Find nearest resolution matching resolution preset and adjust mf
496  * to supported values.
497  */
__find_resolution(struct v4l2_subdev * sd,struct v4l2_mbus_framefmt * mf,enum m5mols_restype * type,u32 * resolution)498 static int __find_resolution(struct v4l2_subdev *sd,
499 			     struct v4l2_mbus_framefmt *mf,
500 			     enum m5mols_restype *type,
501 			     u32 *resolution)
502 {
503 	const struct m5mols_resolution *fsize = &m5mols_reg_res[0];
504 	const struct m5mols_resolution *match = NULL;
505 	enum m5mols_restype stype = __find_restype(mf->code);
506 	int i = ARRAY_SIZE(m5mols_reg_res);
507 	unsigned int min_err = ~0;
508 
509 	while (i--) {
510 		int err;
511 		if (stype == fsize->type) {
512 			err = abs(fsize->width - mf->width)
513 				+ abs(fsize->height - mf->height);
514 
515 			if (err < min_err) {
516 				min_err = err;
517 				match = fsize;
518 			}
519 		}
520 		fsize++;
521 	}
522 	if (match) {
523 		mf->width  = match->width;
524 		mf->height = match->height;
525 		*resolution = match->reg;
526 		*type = stype;
527 		return 0;
528 	}
529 
530 	return -EINVAL;
531 }
532 
__find_format(struct m5mols_info * info,struct v4l2_subdev_pad_config * cfg,enum v4l2_subdev_format_whence which,enum m5mols_restype type)533 static struct v4l2_mbus_framefmt *__find_format(struct m5mols_info *info,
534 				struct v4l2_subdev_pad_config *cfg,
535 				enum v4l2_subdev_format_whence which,
536 				enum m5mols_restype type)
537 {
538 	if (which == V4L2_SUBDEV_FORMAT_TRY)
539 		return cfg ? v4l2_subdev_get_try_format(&info->sd, cfg, 0) : NULL;
540 
541 	return &info->ffmt[type];
542 }
543 
m5mols_get_fmt(struct v4l2_subdev * sd,struct v4l2_subdev_pad_config * cfg,struct v4l2_subdev_format * fmt)544 static int m5mols_get_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg,
545 			  struct v4l2_subdev_format *fmt)
546 {
547 	struct m5mols_info *info = to_m5mols(sd);
548 	struct v4l2_mbus_framefmt *format;
549 	int ret = 0;
550 
551 	mutex_lock(&info->lock);
552 
553 	format = __find_format(info, cfg, fmt->which, info->res_type);
554 	if (format)
555 		fmt->format = *format;
556 	else
557 		ret = -EINVAL;
558 
559 	mutex_unlock(&info->lock);
560 	return ret;
561 }
562 
m5mols_set_fmt(struct v4l2_subdev * sd,struct v4l2_subdev_pad_config * cfg,struct v4l2_subdev_format * fmt)563 static int m5mols_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg,
564 			  struct v4l2_subdev_format *fmt)
565 {
566 	struct m5mols_info *info = to_m5mols(sd);
567 	struct v4l2_mbus_framefmt *format = &fmt->format;
568 	struct v4l2_mbus_framefmt *sfmt;
569 	enum m5mols_restype type;
570 	u32 resolution = 0;
571 	int ret;
572 
573 	ret = __find_resolution(sd, format, &type, &resolution);
574 	if (ret < 0)
575 		return ret;
576 
577 	sfmt = __find_format(info, cfg, fmt->which, type);
578 	if (!sfmt)
579 		return 0;
580 
581 	mutex_lock(&info->lock);
582 
583 	format->code = m5mols_default_ffmt[type].code;
584 	format->colorspace = V4L2_COLORSPACE_JPEG;
585 	format->field = V4L2_FIELD_NONE;
586 
587 	if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
588 		*sfmt = *format;
589 		info->resolution = resolution;
590 		info->res_type = type;
591 	}
592 
593 	mutex_unlock(&info->lock);
594 	return ret;
595 }
596 
m5mols_get_frame_desc(struct v4l2_subdev * sd,unsigned int pad,struct v4l2_mbus_frame_desc * fd)597 static int m5mols_get_frame_desc(struct v4l2_subdev *sd, unsigned int pad,
598 				 struct v4l2_mbus_frame_desc *fd)
599 {
600 	struct m5mols_info *info = to_m5mols(sd);
601 
602 	if (pad != 0 || fd == NULL)
603 		return -EINVAL;
604 
605 	mutex_lock(&info->lock);
606 	/*
607 	 * .get_frame_desc is only used for compressed formats,
608 	 * thus we always return the capture frame parameters here.
609 	 */
610 	fd->entry[0].length = info->cap.buf_size;
611 	fd->entry[0].pixelcode = info->ffmt[M5MOLS_RESTYPE_CAPTURE].code;
612 	mutex_unlock(&info->lock);
613 
614 	fd->entry[0].flags = V4L2_MBUS_FRAME_DESC_FL_LEN_MAX;
615 	fd->num_entries = 1;
616 
617 	return 0;
618 }
619 
m5mols_set_frame_desc(struct v4l2_subdev * sd,unsigned int pad,struct v4l2_mbus_frame_desc * fd)620 static int m5mols_set_frame_desc(struct v4l2_subdev *sd, unsigned int pad,
621 				 struct v4l2_mbus_frame_desc *fd)
622 {
623 	struct m5mols_info *info = to_m5mols(sd);
624 	struct v4l2_mbus_framefmt *mf = &info->ffmt[M5MOLS_RESTYPE_CAPTURE];
625 
626 	if (pad != 0 || fd == NULL)
627 		return -EINVAL;
628 
629 	fd->entry[0].flags = V4L2_MBUS_FRAME_DESC_FL_LEN_MAX;
630 	fd->num_entries = 1;
631 	fd->entry[0].length = clamp_t(u32, fd->entry[0].length,
632 				      mf->width * mf->height,
633 				      M5MOLS_MAIN_JPEG_SIZE_MAX);
634 	mutex_lock(&info->lock);
635 	info->cap.buf_size = fd->entry[0].length;
636 	mutex_unlock(&info->lock);
637 
638 	return 0;
639 }
640 
641 
m5mols_enum_mbus_code(struct v4l2_subdev * sd,struct v4l2_subdev_pad_config * cfg,struct v4l2_subdev_mbus_code_enum * code)642 static int m5mols_enum_mbus_code(struct v4l2_subdev *sd,
643 				 struct v4l2_subdev_pad_config *cfg,
644 				 struct v4l2_subdev_mbus_code_enum *code)
645 {
646 	if (!code || code->index >= SIZE_DEFAULT_FFMT)
647 		return -EINVAL;
648 
649 	code->code = m5mols_default_ffmt[code->index].code;
650 
651 	return 0;
652 }
653 
654 static struct v4l2_subdev_pad_ops m5mols_pad_ops = {
655 	.enum_mbus_code	= m5mols_enum_mbus_code,
656 	.get_fmt	= m5mols_get_fmt,
657 	.set_fmt	= m5mols_set_fmt,
658 	.get_frame_desc	= m5mols_get_frame_desc,
659 	.set_frame_desc	= m5mols_set_frame_desc,
660 };
661 
662 /**
663  * m5mols_restore_controls - Apply current control values to the registers
664  *
665  * m5mols_do_scenemode() handles all parameters for which there is yet no
666  * individual control. It should be replaced at some point by setting each
667  * control individually, in required register set up order.
668  */
m5mols_restore_controls(struct m5mols_info * info)669 int m5mols_restore_controls(struct m5mols_info *info)
670 {
671 	int ret;
672 
673 	if (info->ctrl_sync)
674 		return 0;
675 
676 	ret = m5mols_do_scenemode(info, REG_SCENE_NORMAL);
677 	if (ret)
678 		return ret;
679 
680 	ret = v4l2_ctrl_handler_setup(&info->handle);
681 	info->ctrl_sync = !ret;
682 
683 	return ret;
684 }
685 
686 /**
687  * m5mols_start_monitor - Start the monitor mode
688  *
689  * Before applying the controls setup the resolution and frame rate
690  * in PARAMETER mode, and then switch over to MONITOR mode.
691  */
m5mols_start_monitor(struct m5mols_info * info)692 static int m5mols_start_monitor(struct m5mols_info *info)
693 {
694 	struct v4l2_subdev *sd = &info->sd;
695 	int ret;
696 
697 	ret = m5mols_set_mode(info, REG_PARAMETER);
698 	if (!ret)
699 		ret = m5mols_write(sd, PARM_MON_SIZE, info->resolution);
700 	if (!ret)
701 		ret = m5mols_write(sd, PARM_MON_FPS, REG_FPS_30);
702 	if (!ret)
703 		ret = m5mols_set_mode(info, REG_MONITOR);
704 	if (!ret)
705 		ret = m5mols_restore_controls(info);
706 
707 	return ret;
708 }
709 
m5mols_s_stream(struct v4l2_subdev * sd,int enable)710 static int m5mols_s_stream(struct v4l2_subdev *sd, int enable)
711 {
712 	struct m5mols_info *info = to_m5mols(sd);
713 	u32 code;
714 	int ret;
715 
716 	mutex_lock(&info->lock);
717 	code = info->ffmt[info->res_type].code;
718 
719 	if (enable) {
720 		if (is_code(code, M5MOLS_RESTYPE_MONITOR))
721 			ret = m5mols_start_monitor(info);
722 		else if (is_code(code, M5MOLS_RESTYPE_CAPTURE))
723 			ret = m5mols_start_capture(info);
724 		else
725 			ret = -EINVAL;
726 	} else {
727 		ret = m5mols_set_mode(info, REG_PARAMETER);
728 	}
729 
730 	mutex_unlock(&info->lock);
731 	return ret;
732 }
733 
734 static const struct v4l2_subdev_video_ops m5mols_video_ops = {
735 	.s_stream	= m5mols_s_stream,
736 };
737 
m5mols_sensor_power(struct m5mols_info * info,bool enable)738 static int m5mols_sensor_power(struct m5mols_info *info, bool enable)
739 {
740 	struct v4l2_subdev *sd = &info->sd;
741 	struct i2c_client *client = v4l2_get_subdevdata(sd);
742 	const struct m5mols_platform_data *pdata = info->pdata;
743 	int ret;
744 
745 	if (info->power == enable)
746 		return 0;
747 
748 	if (enable) {
749 		if (info->set_power) {
750 			ret = info->set_power(&client->dev, 1);
751 			if (ret)
752 				return ret;
753 		}
754 
755 		ret = regulator_bulk_enable(ARRAY_SIZE(supplies), supplies);
756 		if (ret) {
757 			info->set_power(&client->dev, 0);
758 			return ret;
759 		}
760 
761 		gpio_set_value(pdata->gpio_reset, !pdata->reset_polarity);
762 		info->power = 1;
763 
764 		return ret;
765 	}
766 
767 	ret = regulator_bulk_disable(ARRAY_SIZE(supplies), supplies);
768 	if (ret)
769 		return ret;
770 
771 	if (info->set_power)
772 		info->set_power(&client->dev, 0);
773 
774 	gpio_set_value(pdata->gpio_reset, pdata->reset_polarity);
775 
776 	info->isp_ready = 0;
777 	info->power = 0;
778 
779 	return ret;
780 }
781 
782 /* m5mols_update_fw - optional firmware update routine */
m5mols_update_fw(struct v4l2_subdev * sd,int (* set_power)(struct m5mols_info *,bool))783 int __attribute__ ((weak)) m5mols_update_fw(struct v4l2_subdev *sd,
784 		int (*set_power)(struct m5mols_info *, bool))
785 {
786 	return 0;
787 }
788 
789 /**
790  * m5mols_fw_start - M-5MOLS internal ARM controller initialization
791  *
792  * Execute the M-5MOLS internal ARM controller initialization sequence.
793  * This function should be called after the supply voltage has been
794  * applied and before any requests to the device are made.
795  */
m5mols_fw_start(struct v4l2_subdev * sd)796 static int m5mols_fw_start(struct v4l2_subdev *sd)
797 {
798 	struct m5mols_info *info = to_m5mols(sd);
799 	int ret;
800 
801 	atomic_set(&info->irq_done, 0);
802 	/* Wait until I2C slave is initialized in Flash Writer mode */
803 	ret = m5mols_busy_wait(sd, FLASH_CAM_START, REG_IN_FLASH_MODE,
804 			       M5MOLS_I2C_RDY_WAIT_FL | 0xff, -1);
805 	if (!ret)
806 		ret = m5mols_write(sd, FLASH_CAM_START, REG_START_ARM_BOOT);
807 	if (!ret)
808 		ret = m5mols_wait_interrupt(sd, REG_INT_MODE, 2000);
809 	if (ret < 0)
810 		return ret;
811 
812 	info->isp_ready = 1;
813 
814 	ret = m5mols_get_version(sd);
815 	if (!ret)
816 		ret = m5mols_update_fw(sd, m5mols_sensor_power);
817 	if (ret)
818 		return ret;
819 
820 	v4l2_dbg(1, m5mols_debug, sd, "Success ARM Booting\n");
821 
822 	ret = m5mols_write(sd, PARM_INTERFACE, REG_INTERFACE_MIPI);
823 	if (!ret)
824 		ret = m5mols_enable_interrupt(sd,
825 				REG_INT_AF | REG_INT_CAPTURE);
826 
827 	return ret;
828 }
829 
830 /* Execute the lens soft-landing algorithm */
m5mols_auto_focus_stop(struct m5mols_info * info)831 static int m5mols_auto_focus_stop(struct m5mols_info *info)
832 {
833 	int ret;
834 
835 	ret = m5mols_write(&info->sd, AF_EXECUTE, REG_AF_STOP);
836 	if (!ret)
837 		ret = m5mols_write(&info->sd, AF_MODE, REG_AF_POWEROFF);
838 	if (!ret)
839 		ret = m5mols_busy_wait(&info->sd, SYSTEM_STATUS, REG_AF_IDLE,
840 				       0xff, -1);
841 	return ret;
842 }
843 
844 /**
845  * m5mols_s_power - Main sensor power control function
846  *
847  * To prevent breaking the lens when the sensor is powered off the Soft-Landing
848  * algorithm is called where available. The Soft-Landing algorithm availability
849  * dependends on the firmware provider.
850  */
m5mols_s_power(struct v4l2_subdev * sd,int on)851 static int m5mols_s_power(struct v4l2_subdev *sd, int on)
852 {
853 	struct m5mols_info *info = to_m5mols(sd);
854 	int ret;
855 
856 	mutex_lock(&info->lock);
857 
858 	if (on) {
859 		ret = m5mols_sensor_power(info, true);
860 		if (!ret)
861 			ret = m5mols_fw_start(sd);
862 	} else {
863 		if (is_manufacturer(info, REG_SAMSUNG_TECHWIN)) {
864 			ret = m5mols_set_mode(info, REG_MONITOR);
865 			if (!ret)
866 				ret = m5mols_auto_focus_stop(info);
867 			if (ret < 0)
868 				v4l2_warn(sd, "Soft landing lens failed\n");
869 		}
870 		ret = m5mols_sensor_power(info, false);
871 
872 		info->ctrl_sync = 0;
873 	}
874 
875 	mutex_unlock(&info->lock);
876 	return ret;
877 }
878 
m5mols_log_status(struct v4l2_subdev * sd)879 static int m5mols_log_status(struct v4l2_subdev *sd)
880 {
881 	struct m5mols_info *info = to_m5mols(sd);
882 
883 	v4l2_ctrl_handler_log_status(&info->handle, sd->name);
884 
885 	return 0;
886 }
887 
888 static const struct v4l2_subdev_core_ops m5mols_core_ops = {
889 	.s_power	= m5mols_s_power,
890 	.log_status	= m5mols_log_status,
891 };
892 
893 /*
894  * V4L2 subdev internal operations
895  */
m5mols_open(struct v4l2_subdev * sd,struct v4l2_subdev_fh * fh)896 static int m5mols_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
897 {
898 	struct v4l2_mbus_framefmt *format = v4l2_subdev_get_try_format(sd, fh->pad, 0);
899 
900 	*format = m5mols_default_ffmt[0];
901 	return 0;
902 }
903 
904 static const struct v4l2_subdev_internal_ops m5mols_subdev_internal_ops = {
905 	.open		= m5mols_open,
906 };
907 
908 static const struct v4l2_subdev_ops m5mols_ops = {
909 	.core		= &m5mols_core_ops,
910 	.pad		= &m5mols_pad_ops,
911 	.video		= &m5mols_video_ops,
912 };
913 
m5mols_irq_handler(int irq,void * data)914 static irqreturn_t m5mols_irq_handler(int irq, void *data)
915 {
916 	struct m5mols_info *info = to_m5mols(data);
917 
918 	atomic_set(&info->irq_done, 1);
919 	wake_up_interruptible(&info->irq_waitq);
920 
921 	return IRQ_HANDLED;
922 }
923 
m5mols_probe(struct i2c_client * client,const struct i2c_device_id * id)924 static int m5mols_probe(struct i2c_client *client,
925 			const struct i2c_device_id *id)
926 {
927 	const struct m5mols_platform_data *pdata = client->dev.platform_data;
928 	unsigned long gpio_flags;
929 	struct m5mols_info *info;
930 	struct v4l2_subdev *sd;
931 	int ret;
932 
933 	if (pdata == NULL) {
934 		dev_err(&client->dev, "No platform data\n");
935 		return -EINVAL;
936 	}
937 
938 	if (!gpio_is_valid(pdata->gpio_reset)) {
939 		dev_err(&client->dev, "No valid RESET GPIO specified\n");
940 		return -EINVAL;
941 	}
942 
943 	if (!client->irq) {
944 		dev_err(&client->dev, "Interrupt not assigned\n");
945 		return -EINVAL;
946 	}
947 
948 	info = devm_kzalloc(&client->dev, sizeof(*info), GFP_KERNEL);
949 	if (!info)
950 		return -ENOMEM;
951 
952 	info->pdata = pdata;
953 	info->set_power	= pdata->set_power;
954 
955 	gpio_flags = pdata->reset_polarity
956 		   ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW;
957 	ret = devm_gpio_request_one(&client->dev, pdata->gpio_reset, gpio_flags,
958 				    "M5MOLS_NRST");
959 	if (ret) {
960 		dev_err(&client->dev, "Failed to request gpio: %d\n", ret);
961 		return ret;
962 	}
963 
964 	ret = devm_regulator_bulk_get(&client->dev, ARRAY_SIZE(supplies),
965 				      supplies);
966 	if (ret) {
967 		dev_err(&client->dev, "Failed to get regulators: %d\n", ret);
968 		return ret;
969 	}
970 
971 	sd = &info->sd;
972 	v4l2_i2c_subdev_init(sd, client, &m5mols_ops);
973 	strlcpy(sd->name, MODULE_NAME, sizeof(sd->name));
974 	sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
975 
976 	sd->internal_ops = &m5mols_subdev_internal_ops;
977 	info->pad.flags = MEDIA_PAD_FL_SOURCE;
978 	ret = media_entity_pads_init(&sd->entity, 1, &info->pad);
979 	if (ret < 0)
980 		return ret;
981 	sd->entity.function = MEDIA_ENT_F_CAM_SENSOR;
982 
983 	init_waitqueue_head(&info->irq_waitq);
984 	mutex_init(&info->lock);
985 
986 	ret = devm_request_irq(&client->dev, client->irq, m5mols_irq_handler,
987 			       IRQF_TRIGGER_RISING, MODULE_NAME, sd);
988 	if (ret) {
989 		dev_err(&client->dev, "Interrupt request failed: %d\n", ret);
990 		goto error;
991 	}
992 	info->res_type = M5MOLS_RESTYPE_MONITOR;
993 	info->ffmt[0] = m5mols_default_ffmt[0];
994 	info->ffmt[1] =	m5mols_default_ffmt[1];
995 
996 	ret = m5mols_sensor_power(info, true);
997 	if (ret)
998 		goto error;
999 
1000 	ret = m5mols_fw_start(sd);
1001 	if (!ret)
1002 		ret = m5mols_init_controls(sd);
1003 
1004 	ret = m5mols_sensor_power(info, false);
1005 	if (!ret)
1006 		return 0;
1007 error:
1008 	media_entity_cleanup(&sd->entity);
1009 	return ret;
1010 }
1011 
m5mols_remove(struct i2c_client * client)1012 static int m5mols_remove(struct i2c_client *client)
1013 {
1014 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
1015 
1016 	v4l2_device_unregister_subdev(sd);
1017 	v4l2_ctrl_handler_free(sd->ctrl_handler);
1018 	media_entity_cleanup(&sd->entity);
1019 
1020 	return 0;
1021 }
1022 
1023 static const struct i2c_device_id m5mols_id[] = {
1024 	{ MODULE_NAME, 0 },
1025 	{ },
1026 };
1027 MODULE_DEVICE_TABLE(i2c, m5mols_id);
1028 
1029 static struct i2c_driver m5mols_i2c_driver = {
1030 	.driver = {
1031 		.name	= MODULE_NAME,
1032 	},
1033 	.probe		= m5mols_probe,
1034 	.remove		= m5mols_remove,
1035 	.id_table	= m5mols_id,
1036 };
1037 
1038 module_i2c_driver(m5mols_i2c_driver);
1039 
1040 MODULE_AUTHOR("HeungJun Kim <riverful.kim@samsung.com>");
1041 MODULE_AUTHOR("Dongsoo Kim <dongsoo45.kim@samsung.com>");
1042 MODULE_DESCRIPTION("Fujitsu M-5MOLS 8M Pixel camera driver");
1043 MODULE_LICENSE("GPL");
1044