Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    3)  * mt9t112 Camera Driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    5)  * Copyright (C) 2018 Jacopo Mondi <jacopo+renesas@jmondi.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    6)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    7)  * Copyright (C) 2009 Renesas Solutions Corp.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    8)  * Kuninori Morimoto <morimoto.kuninori@renesas.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    9)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   10)  * Based on ov772x driver, mt9m111 driver,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   11)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   12)  * Copyright (C) 2008 Kuninori Morimoto <morimoto.kuninori@renesas.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   13)  * Copyright (C) 2008, Robert Jarzmik <robert.jarzmik@free.fr>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   14)  * Copyright 2006-7 Jonathan Corbet <corbet@lwn.net>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   15)  * Copyright (C) 2008 Magnus Damm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   16)  * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   17)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   18)  * TODO: This driver lacks support for frame rate control due to missing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   19)  *	 register level documentation and suitable hardware for testing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   20)  *	 v4l-utils compliance tools will report errors.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   21)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   22) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   23) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   24) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   25) #include <linux/gpio/consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   26) #include <linux/i2c.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   27) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   28) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   29) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   30) #include <linux/v4l2-mediabus.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   31) #include <linux/videodev2.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   32) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   33) #include <media/i2c/mt9t112.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   34) #include <media/v4l2-common.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   35) #include <media/v4l2-image-sizes.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   36) #include <media/v4l2-subdev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   37) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   38) /* you can check PLL/clock info */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   39) /* #define EXT_CLOCK 24000000 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   40) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   41) /************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   42)  *			macro
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   43)  ***********************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   44) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   45)  * frame size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   46)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   47) #define MAX_WIDTH   2048
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   48) #define MAX_HEIGHT  1536
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   49) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   50) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   51)  * macro of read/write
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   52)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   53) #define ECHECKER(ret, x)		\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   54) 	do {				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   55) 		(ret) = (x);		\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   56) 		if ((ret) < 0)		\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   57) 			return (ret);	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   58) 	} while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   59) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   60) #define mt9t112_reg_write(ret, client, a, b) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   61) 	ECHECKER(ret, __mt9t112_reg_write(client, a, b))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   62) #define mt9t112_mcu_write(ret, client, a, b) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   63) 	ECHECKER(ret, __mt9t112_mcu_write(client, a, b))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   64) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   65) #define mt9t112_reg_mask_set(ret, client, a, b, c) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   66) 	ECHECKER(ret, __mt9t112_reg_mask_set(client, a, b, c))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   67) #define mt9t112_mcu_mask_set(ret, client, a, b, c) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   68) 	ECHECKER(ret, __mt9t112_mcu_mask_set(client, a, b, c))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   69) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   70) #define mt9t112_reg_read(ret, client, a) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   71) 	ECHECKER(ret, __mt9t112_reg_read(client, a))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   72) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74)  * Logical address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76) #define _VAR(id, offset, base)	(base | (id & 0x1f) << 10 | (offset & 0x3ff))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77) #define VAR(id, offset)  _VAR(id, offset, 0x0000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78) #define VAR8(id, offset) _VAR(id, offset, 0x8000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   80) /************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   81)  *			struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   82)  ***********************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   83) struct mt9t112_format {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84) 	u32 code;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85) 	enum v4l2_colorspace colorspace;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86) 	u16 fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87) 	u16 order;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90) struct mt9t112_priv {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91) 	struct v4l2_subdev		 subdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92) 	struct mt9t112_platform_data	*info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93) 	struct i2c_client		*client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94) 	struct v4l2_rect		 frame;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   95) 	struct clk			*clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   96) 	struct gpio_desc		*standby_gpio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   97) 	const struct mt9t112_format	*format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98) 	int				 num_formats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99) 	bool				 init_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102) /************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  103)  *			supported format
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  104)  ***********************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  106) static const struct mt9t112_format mt9t112_cfmts[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  107) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  108) 		.code		= MEDIA_BUS_FMT_UYVY8_2X8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  109) 		.colorspace	= V4L2_COLORSPACE_SRGB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  110) 		.fmt		= 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  111) 		.order		= 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  112) 	}, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113) 		.code		= MEDIA_BUS_FMT_VYUY8_2X8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114) 		.colorspace	= V4L2_COLORSPACE_SRGB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115) 		.fmt		= 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116) 		.order		= 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  117) 	}, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  118) 		.code		= MEDIA_BUS_FMT_YUYV8_2X8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  119) 		.colorspace	= V4L2_COLORSPACE_SRGB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120) 		.fmt		= 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121) 		.order		= 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122) 	}, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123) 		.code		= MEDIA_BUS_FMT_YVYU8_2X8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124) 		.colorspace	= V4L2_COLORSPACE_SRGB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125) 		.fmt		= 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  126) 		.order		= 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  127) 	}, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  128) 		.code		= MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129) 		.colorspace	= V4L2_COLORSPACE_SRGB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130) 		.fmt		= 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131) 		.order		= 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132) 	}, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133) 		.code		= MEDIA_BUS_FMT_RGB565_2X8_LE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134) 		.colorspace	= V4L2_COLORSPACE_SRGB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135) 		.fmt		= 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  136) 		.order		= 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  137) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  138) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  139) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  140) /************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  141)  *			general function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  142)  ***********************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143) static struct mt9t112_priv *to_mt9t112(const struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145) 	return container_of(i2c_get_clientdata(client),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146) 			    struct mt9t112_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147) 			    subdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  148) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  149) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  150) static int __mt9t112_reg_read(const struct i2c_client *client, u16 command)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  152) 	struct i2c_msg msg[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  153) 	u8 buf[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  154) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  155) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  156) 	command = swab16(command);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  157) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  158) 	msg[0].addr  = client->addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  159) 	msg[0].flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  160) 	msg[0].len   = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  161) 	msg[0].buf   = (u8 *)&command;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  162) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  163) 	msg[1].addr  = client->addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  164) 	msg[1].flags = I2C_M_RD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  165) 	msg[1].len   = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  166) 	msg[1].buf   = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  167) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  168) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  169) 	 * If return value of this function is < 0, it means error, else,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  170) 	 * below 16bit is valid data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  171) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  172) 	ret = i2c_transfer(client->adapter, msg, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  173) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  176) 	memcpy(&ret, buf, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  177) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  178) 	return swab16(ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  179) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  181) static int __mt9t112_reg_write(const struct i2c_client *client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  182) 			       u16 command, u16 data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  183) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184) 	struct i2c_msg msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  185) 	u8 buf[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  186) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  187) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  188) 	command = swab16(command);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  189) 	data = swab16(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  191) 	memcpy(buf + 0, &command, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  192) 	memcpy(buf + 2, &data,    2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  193) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194) 	msg.addr  = client->addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195) 	msg.flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196) 	msg.len   = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197) 	msg.buf   = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  200) 	 * i2c_transfer return message length, but this function should
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  201) 	 * return 0 if correct case.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  202) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  203) 	ret = i2c_transfer(client->adapter, &msg, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  204) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  205) 	return ret >= 0 ? 0 : ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208) static int __mt9t112_reg_mask_set(const struct i2c_client *client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209) 				  u16  command, u16  mask, u16  set)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211) 	int val = __mt9t112_reg_read(client, command);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213) 	if (val < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214) 		return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  215) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  216) 	val &= ~mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  217) 	val |= set & mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219) 	return __mt9t112_reg_write(client, command, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  220) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  221) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  222) /* mcu access */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223) static int __mt9t112_mcu_read(const struct i2c_client *client, u16 command)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  226) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  227) 	ret = __mt9t112_reg_write(client, 0x098E, command);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  228) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231) 	return __mt9t112_reg_read(client, 0x0990);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  234) static int __mt9t112_mcu_write(const struct i2c_client *client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  235) 			       u16 command, u16 data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  236) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  237) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  238) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  239) 	ret = __mt9t112_reg_write(client, 0x098E, command);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  240) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  241) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  242) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  243) 	return __mt9t112_reg_write(client, 0x0990, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246) static int __mt9t112_mcu_mask_set(const struct i2c_client *client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247) 				  u16  command, u16  mask, u16  set)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249) 	int val = __mt9t112_mcu_read(client, command);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  250) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  251) 	if (val < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  252) 		return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254) 	val &= ~mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255) 	val |= set & mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  256) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  257) 	return __mt9t112_mcu_write(client, command, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  258) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260) static int mt9t112_reset(const struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  262) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  263) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  264) 	mt9t112_reg_mask_set(ret, client, 0x001a, 0x0001, 0x0001);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  265) 	usleep_range(1000, 5000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  266) 	mt9t112_reg_mask_set(ret, client, 0x001a, 0x0001, 0x0000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  269) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  270) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  271) #ifndef EXT_CLOCK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  272) #define CLOCK_INFO(a, b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  273) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  274) #define CLOCK_INFO(a, b) mt9t112_clock_info(a, b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  275) static int mt9t112_clock_info(const struct i2c_client *client, u32 ext)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  276) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  277) 	int m, n, p1, p2, p3, p4, p5, p6, p7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  278) 	u32 vco, clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  279) 	char *enable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  280) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281) 	ext /= 1000; /* kbyte order */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283) 	mt9t112_reg_read(n, client, 0x0012);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284) 	p1 = n & 0x000f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285) 	n = n >> 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  286) 	p2 = n & 0x000f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  287) 	n = n >> 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  288) 	p3 = n & 0x000f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  289) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  290) 	mt9t112_reg_read(n, client, 0x002a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291) 	p4 = n & 0x000f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  292) 	n = n >> 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  293) 	p5 = n & 0x000f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  294) 	n = n >> 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  295) 	p6 = n & 0x000f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  296) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  297) 	mt9t112_reg_read(n, client, 0x002c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  298) 	p7 = n & 0x000f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300) 	mt9t112_reg_read(n, client, 0x0010);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301) 	m = n & 0x00ff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  302) 	n = (n >> 8) & 0x003f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  303) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  304) 	enable = ((ext < 6000) || (ext > 54000)) ? "X" : "";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  305) 	dev_dbg(&client->dev, "EXTCLK          : %10u K %s\n", ext, enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  306) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  307) 	vco = 2 * m * ext / (n + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308) 	enable = ((vco < 384000) || (vco > 768000)) ? "X" : "";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309) 	dev_dbg(&client->dev, "VCO             : %10u K %s\n", vco, enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311) 	clk = vco / (p1 + 1) / (p2 + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312) 	enable = (clk > 96000) ? "X" : "";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  313) 	dev_dbg(&client->dev, "PIXCLK          : %10u K %s\n", clk, enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  314) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  315) 	clk = vco / (p3 + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  316) 	enable = (clk > 768000) ? "X" : "";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  317) 	dev_dbg(&client->dev, "MIPICLK         : %10u K %s\n", clk, enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  318) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319) 	clk = vco / (p6 + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  320) 	enable = (clk > 96000) ? "X" : "";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  321) 	dev_dbg(&client->dev, "MCU CLK         : %10u K %s\n", clk, enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  322) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  323) 	clk = vco / (p5 + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324) 	enable = (clk > 54000) ? "X" : "";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325) 	dev_dbg(&client->dev, "SOC CLK         : %10u K %s\n", clk, enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327) 	clk = vco / (p4 + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  328) 	enable = (clk > 70000) ? "X" : "";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  329) 	dev_dbg(&client->dev, "Sensor CLK      : %10u K %s\n", clk, enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  330) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  331) 	clk = vco / (p7 + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  332) 	dev_dbg(&client->dev, "External sensor : %10u K\n", clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  333) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  334) 	clk = ext / (n + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  335) 	enable = ((clk < 2000) || (clk > 24000)) ? "X" : "";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  336) 	dev_dbg(&client->dev, "PFD             : %10u K %s\n", clk, enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342) static int mt9t112_set_a_frame_size(const struct i2c_client *client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343) 				    u16 width, u16 height)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  345) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  346) 	u16 wstart = (MAX_WIDTH - width) / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  347) 	u16 hstart = (MAX_HEIGHT - height) / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  348) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  349) 	/* (Context A) Image Width/Height. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  350) 	mt9t112_mcu_write(ret, client, VAR(26, 0), width);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  351) 	mt9t112_mcu_write(ret, client, VAR(26, 2), height);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  352) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  353) 	/* (Context A) Output Width/Height. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354) 	mt9t112_mcu_write(ret, client, VAR(18, 43), 8 + width);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355) 	mt9t112_mcu_write(ret, client, VAR(18, 45), 8 + height);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  357) 	/* (Context A) Start Row/Column. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  358) 	mt9t112_mcu_write(ret, client, VAR(18, 2), 4 + hstart);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  359) 	mt9t112_mcu_write(ret, client, VAR(18, 4), 4 + wstart);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  360) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  361) 	/* (Context A) End Row/Column. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  362) 	mt9t112_mcu_write(ret, client, VAR(18, 6), 11 + height + hstart);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  363) 	mt9t112_mcu_write(ret, client, VAR(18, 8), 11 + width  + wstart);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  364) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  365) 	mt9t112_mcu_write(ret, client, VAR8(1, 0), 0x06);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  366) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  369) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  370) static int mt9t112_set_pll_dividers(const struct i2c_client *client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  371) 				    u8 m, u8 n, u8 p1, u8 p2, u8 p3, u8 p4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  372) 				    u8 p5, u8 p6, u8 p7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375) 	u16 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  377) 	/* N/M */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  378) 	val = (n << 8) | (m << 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  379) 	mt9t112_reg_mask_set(ret, client, 0x0010, 0x3fff, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381) 	/* P1/P2/P3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382) 	val = ((p3 & 0x0F) << 8) | ((p2 & 0x0F) << 4) | ((p1 & 0x0F) << 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383) 	mt9t112_reg_mask_set(ret, client, 0x0012, 0x0fff, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385) 	/* P4/P5/P6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386) 	val = (0x7 << 12) | ((p6 & 0x0F) <<  8) | ((p5 & 0x0F) <<  4) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387) 	      ((p4 & 0x0F) <<  0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388) 	mt9t112_reg_mask_set(ret, client, 0x002A, 0x7fff, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390) 	/* P7 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391) 	val = (0x1 << 12) | ((p7 & 0x0F) <<  0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392) 	mt9t112_reg_mask_set(ret, client, 0x002C, 0x100f, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397) static int mt9t112_init_pll(const struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  398) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  399) 	struct mt9t112_priv *priv = to_mt9t112(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  400) 	int data, i, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  401) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  402) 	mt9t112_reg_mask_set(ret, client, 0x0014, 0x003, 0x0001);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  403) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  404) 	/* PLL control: BYPASS PLL = 8517. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405) 	mt9t112_reg_write(ret, client, 0x0014, 0x2145);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407) 	/* Replace these registers when new timing parameters are generated. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  408) 	mt9t112_set_pll_dividers(client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  409) 				 priv->info->divider.m, priv->info->divider.n,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  410) 				 priv->info->divider.p1, priv->info->divider.p2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  411) 				 priv->info->divider.p3, priv->info->divider.p4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  412) 				 priv->info->divider.p5, priv->info->divider.p6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413) 				 priv->info->divider.p7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  414) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  415) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  416) 	 * TEST_BYPASS  on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  417) 	 * PLL_ENABLE   on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  418) 	 * SEL_LOCK_DET on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  419) 	 * TEST_BYPASS  off
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  420) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421) 	mt9t112_reg_write(ret, client, 0x0014, 0x2525);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422) 	mt9t112_reg_write(ret, client, 0x0014, 0x2527);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423) 	mt9t112_reg_write(ret, client, 0x0014, 0x3427);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424) 	mt9t112_reg_write(ret, client, 0x0014, 0x3027);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426) 	mdelay(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429) 	 * PLL_BYPASS off
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430) 	 * Reference clock count
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431) 	 * I2C Master Clock Divider
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433) 	mt9t112_reg_write(ret, client, 0x0014, 0x3046);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434) 	/* JPEG initialization workaround */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  435) 	mt9t112_reg_write(ret, client, 0x0016, 0x0400);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  436) 	mt9t112_reg_write(ret, client, 0x0022, 0x0190);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  437) 	mt9t112_reg_write(ret, client, 0x3B84, 0x0212);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  438) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  439) 	/* External sensor clock is PLL bypass. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  440) 	mt9t112_reg_write(ret, client, 0x002E, 0x0500);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  441) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  442) 	mt9t112_reg_mask_set(ret, client, 0x0018, 0x0002, 0x0002);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  443) 	mt9t112_reg_mask_set(ret, client, 0x3B82, 0x0004, 0x0004);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  444) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  445) 	/* MCU disabled. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  446) 	mt9t112_reg_mask_set(ret, client, 0x0018, 0x0004, 0x0004);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  447) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  448) 	/* Out of standby. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  449) 	mt9t112_reg_mask_set(ret, client, 0x0018, 0x0001, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  450) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451) 	mdelay(50);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  454) 	 * Standby Workaround
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  455) 	 * Disable Secondary I2C Pads
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  456) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  457) 	mt9t112_reg_write(ret, client, 0x0614, 0x0001);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  458) 	mdelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  459) 	mt9t112_reg_write(ret, client, 0x0614, 0x0001);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  460) 	mdelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461) 	mt9t112_reg_write(ret, client, 0x0614, 0x0001);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462) 	mdelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463) 	mt9t112_reg_write(ret, client, 0x0614, 0x0001);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464) 	mdelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465) 	mt9t112_reg_write(ret, client, 0x0614, 0x0001);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466) 	mdelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467) 	mt9t112_reg_write(ret, client, 0x0614, 0x0001);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468) 	mdelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  470) 	/* Poll to verify out of standby. Must Poll this bit. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  471) 	for (i = 0; i < 100; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  472) 		mt9t112_reg_read(data, client, 0x0018);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473) 		if (!(data & 0x4000))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476) 		mdelay(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  479) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  480) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  481) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482) static int mt9t112_init_setting(const struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  484) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  485) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  486) 	/* Adaptive Output Clock (A) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  487) 	mt9t112_mcu_mask_set(ret, client, VAR(26, 160), 0x0040, 0x0000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  488) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  489) 	/* Read Mode (A) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  490) 	mt9t112_mcu_write(ret, client, VAR(18, 12), 0x0024);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  491) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  492) 	/* Fine Correction (A) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  493) 	mt9t112_mcu_write(ret, client, VAR(18, 15), 0x00CC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  495) 	/* Fine IT Min (A) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  496) 	mt9t112_mcu_write(ret, client, VAR(18, 17), 0x01f1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  497) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  498) 	/* Fine IT Max Margin (A) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499) 	mt9t112_mcu_write(ret, client, VAR(18, 19), 0x00fF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501) 	/* Base Frame Lines (A) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502) 	mt9t112_mcu_write(ret, client, VAR(18, 29), 0x032D);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504) 	/* Min Line Length (A) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505) 	mt9t112_mcu_write(ret, client, VAR(18, 31), 0x073a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  506) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  507) 	/* Line Length (A) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  508) 	mt9t112_mcu_write(ret, client, VAR(18, 37), 0x07d0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  509) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  510) 	/* Adaptive Output Clock (B) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511) 	mt9t112_mcu_mask_set(ret, client, VAR(27, 160), 0x0040, 0x0000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513) 	/* Row Start (B) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514) 	mt9t112_mcu_write(ret, client, VAR(18, 74), 0x004);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516) 	/* Column Start (B) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517) 	mt9t112_mcu_write(ret, client, VAR(18, 76), 0x004);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519) 	/* Row End (B) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  520) 	mt9t112_mcu_write(ret, client, VAR(18, 78), 0x60B);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  521) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  522) 	/* Column End (B) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523) 	mt9t112_mcu_write(ret, client, VAR(18, 80), 0x80B);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  525) 	/* Fine Correction (B) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  526) 	mt9t112_mcu_write(ret, client, VAR(18, 87), 0x008C);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  527) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  528) 	/* Fine IT Min (B) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  529) 	mt9t112_mcu_write(ret, client, VAR(18, 89), 0x01F1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  530) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  531) 	/* Fine IT Max Margin (B) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  532) 	mt9t112_mcu_write(ret, client, VAR(18, 91), 0x00FF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  533) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  534) 	/* Base Frame Lines (B) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535) 	mt9t112_mcu_write(ret, client, VAR(18, 101), 0x0668);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537) 	/* Min Line Length (B) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  538) 	mt9t112_mcu_write(ret, client, VAR(18, 103), 0x0AF0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  539) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  540) 	/* Line Length (B) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541) 	mt9t112_mcu_write(ret, client, VAR(18, 109), 0x0AF0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544) 	 * Flicker Detection registers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545) 	 * This section should be replaced whenever new timing file is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  546) 	 * generated. All the following registers need to be replaced.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  547) 	 * Following registers are generated from Register Wizard but user can
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  548) 	 * modify them. For detail see auto flicker detection tuning.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  550) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  551) 	/* FD_FDPERIOD_SELECT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  552) 	mt9t112_mcu_write(ret, client, VAR8(8, 5), 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554) 	/* PRI_B_CONFIG_FD_ALGO_RUN */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555) 	mt9t112_mcu_write(ret, client, VAR(27, 17), 0x0003);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  556) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  557) 	/* PRI_A_CONFIG_FD_ALGO_RUN */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  558) 	mt9t112_mcu_write(ret, client, VAR(26, 17), 0x0003);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  560) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  561) 	 * AFD range detection tuning registers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  562) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564) 	/* Search_f1_50 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565) 	mt9t112_mcu_write(ret, client, VAR8(18, 165), 0x25);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567) 	/* Search_f2_50 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568) 	mt9t112_mcu_write(ret, client, VAR8(18, 166), 0x28);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  569) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  570) 	/* Search_f1_60 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  571) 	mt9t112_mcu_write(ret, client, VAR8(18, 167), 0x2C);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  572) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  573) 	/* Search_f2_60 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574) 	mt9t112_mcu_write(ret, client, VAR8(18, 168), 0x2F);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  575) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  576) 	/* Period_50Hz (A) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  577) 	mt9t112_mcu_write(ret, client, VAR8(18, 68), 0xBA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579) 	/* Secret register by Aptina. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  580) 	/* Period_50Hz (A MSB) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  581) 	mt9t112_mcu_write(ret, client, VAR8(18, 303), 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  582) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583) 	/* Period_60Hz (A) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584) 	mt9t112_mcu_write(ret, client, VAR8(18, 69), 0x9B);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586) 	/* Secret register by Aptina. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587) 	/* Period_60Hz (A MSB) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588) 	mt9t112_mcu_write(ret, client, VAR8(18, 301), 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  590) 	/* Period_50Hz (B) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  591) 	mt9t112_mcu_write(ret, client, VAR8(18, 140), 0x82);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  592) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  593) 	/* Secret register by Aptina. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  594) 	/* Period_50Hz (B) MSB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595) 	mt9t112_mcu_write(ret, client, VAR8(18, 304), 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  596) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  597) 	/* Period_60Hz (B) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  598) 	mt9t112_mcu_write(ret, client, VAR8(18, 141), 0x6D);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  599) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  600) 	/* Secret register by Aptina. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  601) 	/* Period_60Hz (B) MSB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602) 	mt9t112_mcu_write(ret, client, VAR8(18, 302), 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604) 	/* FD Mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605) 	mt9t112_mcu_write(ret, client, VAR8(8, 2), 0x10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  606) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  607) 	/* Stat_min */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  608) 	mt9t112_mcu_write(ret, client, VAR8(8, 9), 0x02);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  609) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  610) 	/* Stat_max */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  611) 	mt9t112_mcu_write(ret, client, VAR8(8, 10), 0x03);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  613) 	/* Min_amplitude */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  614) 	mt9t112_mcu_write(ret, client, VAR8(8, 12), 0x0A);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  615) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616) 	/* RX FIFO Watermark (A) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617) 	mt9t112_mcu_write(ret, client, VAR(18, 70), 0x0014);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  619) 	/* RX FIFO Watermark (B) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  620) 	mt9t112_mcu_write(ret, client, VAR(18, 142), 0x0014);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  621) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  622) 	/* MCLK: 16MHz
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  623) 	 * PCLK: 73MHz
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  624) 	 * CorePixCLK: 36.5 MHz
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  625) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  626) 	mt9t112_mcu_write(ret, client, VAR8(18, 0x0044), 133);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  627) 	mt9t112_mcu_write(ret, client, VAR8(18, 0x0045), 110);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  628) 	mt9t112_mcu_write(ret, client, VAR8(18, 0x008c), 130);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  629) 	mt9t112_mcu_write(ret, client, VAR8(18, 0x008d), 108);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631) 	mt9t112_mcu_write(ret, client, VAR8(18, 0x00A5), 27);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632) 	mt9t112_mcu_write(ret, client, VAR8(18, 0x00a6), 30);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633) 	mt9t112_mcu_write(ret, client, VAR8(18, 0x00a7), 32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634) 	mt9t112_mcu_write(ret, client, VAR8(18, 0x00a8), 35);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  638) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  639) static int mt9t112_auto_focus_setting(const struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  640) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  641) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  643) 	mt9t112_mcu_write(ret, client, VAR(12, 13),	0x000F);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  644) 	mt9t112_mcu_write(ret, client, VAR(12, 23),	0x0F0F);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  645) 	mt9t112_mcu_write(ret, client, VAR8(1, 0),	0x06);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  646) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  647) 	mt9t112_reg_write(ret, client, 0x0614, 0x0000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  648) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649) 	mt9t112_mcu_write(ret, client, VAR8(1, 0),	0x05);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650) 	mt9t112_mcu_write(ret, client, VAR8(12, 2),	0x02);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651) 	mt9t112_mcu_write(ret, client, VAR(12, 3),	0x0002);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652) 	mt9t112_mcu_write(ret, client, VAR(17, 3),	0x8001);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653) 	mt9t112_mcu_write(ret, client, VAR(17, 11),	0x0025);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654) 	mt9t112_mcu_write(ret, client, VAR(17, 13),	0x0193);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655) 	mt9t112_mcu_write(ret, client, VAR8(17, 33),	0x18);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656) 	mt9t112_mcu_write(ret, client, VAR8(1, 0),	0x05);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  657) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  658) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  659) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661) static int mt9t112_auto_focus_trigger(const struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665) 	mt9t112_mcu_write(ret, client, VAR8(12, 25), 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  666) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  667) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  668) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  670) static int mt9t112_init_camera(const struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  671) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  672) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674) 	ECHECKER(ret, mt9t112_reset(client));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675) 	ECHECKER(ret, mt9t112_init_pll(client));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676) 	ECHECKER(ret, mt9t112_init_setting(client));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677) 	ECHECKER(ret, mt9t112_auto_focus_setting(client));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679) 	mt9t112_reg_mask_set(ret, client, 0x0018, 0x0004, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681) 	/* Analog setting B.*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682) 	mt9t112_reg_write(ret, client, 0x3084, 0x2409);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683) 	mt9t112_reg_write(ret, client, 0x3092, 0x0A49);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684) 	mt9t112_reg_write(ret, client, 0x3094, 0x4949);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685) 	mt9t112_reg_write(ret, client, 0x3096, 0x4950);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688) 	 * Disable adaptive clock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689) 	 * PRI_A_CONFIG_JPEG_OB_TX_CONTROL_VAR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690) 	 * PRI_B_CONFIG_JPEG_OB_TX_CONTROL_VAR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692) 	mt9t112_mcu_write(ret, client, VAR(26, 160), 0x0A2E);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693) 	mt9t112_mcu_write(ret, client, VAR(27, 160), 0x0A2E);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696) 	 * Configure Status in Status_before_length Format and enable header.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697) 	 * PRI_B_CONFIG_JPEG_OB_TX_CONTROL_VAR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699) 	mt9t112_mcu_write(ret, client, VAR(27, 144), 0x0CB4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  702) 	 * Enable JPEG in context B.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  703) 	 * PRI_B_CONFIG_JPEG_OB_TX_CONTROL_VAR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  704) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705) 	mt9t112_mcu_write(ret, client, VAR8(27, 142), 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707) 	/* Disable Dac_TXLO. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708) 	mt9t112_reg_write(ret, client, 0x316C, 0x350F);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710) 	/* Set max slew rates. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711) 	mt9t112_reg_write(ret, client, 0x1E, 0x777);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  712) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  713) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  714) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  715) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716) /************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717)  *			v4l2_subdev_core_ops
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718)  ***********************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  719) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  720) #ifdef CONFIG_VIDEO_ADV_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  721) static int mt9t112_g_register(struct v4l2_subdev *sd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722) 			      struct v4l2_dbg_register *reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  724) 	struct i2c_client *client = v4l2_get_subdevdata(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  725) 	int                ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  726) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727) 	reg->size = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728) 	mt9t112_reg_read(ret, client, reg->reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730) 	reg->val = (__u64)ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  735) static int mt9t112_s_register(struct v4l2_subdev *sd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  736) 			      const struct v4l2_dbg_register *reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  737) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738) 	struct i2c_client *client = v4l2_get_subdevdata(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  740) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  741) 	mt9t112_reg_write(ret, client, reg->reg, reg->val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  742) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747) static int mt9t112_power_on(struct mt9t112_priv *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751) 	ret = clk_prepare_enable(priv->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755) 	if (priv->standby_gpio) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756) 		gpiod_set_value(priv->standby_gpio, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757) 		msleep(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763) static int mt9t112_power_off(struct mt9t112_priv *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765) 	clk_disable_unprepare(priv->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766) 	if (priv->standby_gpio) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767) 		gpiod_set_value(priv->standby_gpio, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768) 		msleep(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774) static int mt9t112_s_power(struct v4l2_subdev *sd, int on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  775) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  776) 	struct i2c_client *client = v4l2_get_subdevdata(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  777) 	struct mt9t112_priv *priv = to_mt9t112(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  778) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  779) 	return on ? mt9t112_power_on(priv) :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  780) 		    mt9t112_power_off(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  781) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  782) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783) static const struct v4l2_subdev_core_ops mt9t112_subdev_core_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784) #ifdef CONFIG_VIDEO_ADV_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  785) 	.g_register	= mt9t112_g_register,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  786) 	.s_register	= mt9t112_s_register,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  787) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  788) 	.s_power	= mt9t112_s_power,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  789) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791) /************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792)  *			v4l2_subdev_video_ops
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793)  **********************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794) static int mt9t112_s_stream(struct v4l2_subdev *sd, int enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796) 	struct i2c_client *client = v4l2_get_subdevdata(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  797) 	struct mt9t112_priv *priv = to_mt9t112(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  798) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  799) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  800) 	if (!enable) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  801) 		/* FIXME
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802) 		 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803) 		 * If user selected large output size, and used it long time,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804) 		 * mt9t112 camera will be very warm.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805) 		 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806) 		 * But current driver can not stop mt9t112 camera.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807) 		 * So, set small size here to solve this problem.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  808) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  809) 		mt9t112_set_a_frame_size(client, VGA_WIDTH, VGA_HEIGHT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  810) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813) 	if (!priv->init_done) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814) 		u16 param = MT9T112_FLAG_PCLK_RISING_EDGE & priv->info->flags ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  815) 			    0x0001 : 0x0000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  816) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  817) 		ECHECKER(ret, mt9t112_init_camera(client));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819) 		/* Invert PCLK (Data sampled on falling edge of pixclk). */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820) 		mt9t112_reg_write(ret, client, 0x3C20, param);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  821) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  822) 		mdelay(5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  823) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  824) 		priv->init_done = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  825) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  826) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  827) 	mt9t112_mcu_write(ret, client, VAR(26, 7), priv->format->fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  828) 	mt9t112_mcu_write(ret, client, VAR(26, 9), priv->format->order);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829) 	mt9t112_mcu_write(ret, client, VAR8(1, 0), 0x06);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831) 	mt9t112_set_a_frame_size(client, priv->frame.width, priv->frame.height);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833) 	ECHECKER(ret, mt9t112_auto_focus_trigger(client));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835) 	dev_dbg(&client->dev, "format : %d\n", priv->format->code);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836) 	dev_dbg(&client->dev, "size   : %d x %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837) 		priv->frame.width,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838) 		priv->frame.height);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840) 	CLOCK_INFO(client, EXT_CLOCK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845) static int mt9t112_set_params(struct mt9t112_priv *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846) 			      const struct v4l2_rect *rect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  847) 			      u32 code)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  848) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  849) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852) 	 * get color format
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  853) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  854) 	for (i = 0; i < priv->num_formats; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  855) 		if (mt9t112_cfmts[i].code == code)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  856) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  857) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  858) 	if (i == priv->num_formats)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  859) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861) 	priv->frame = *rect;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864) 	 * frame size check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866) 	v4l_bound_align_image(&priv->frame.width, 0, MAX_WIDTH, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867) 			      &priv->frame.height, 0, MAX_HEIGHT, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869) 	priv->format = mt9t112_cfmts + i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  872) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  873) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  874) static int mt9t112_get_selection(struct v4l2_subdev *sd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  875) 				 struct v4l2_subdev_pad_config *cfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  876) 		struct v4l2_subdev_selection *sel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  877) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  878) 	struct i2c_client *client = v4l2_get_subdevdata(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  879) 	struct mt9t112_priv *priv = to_mt9t112(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  880) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  881) 	if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884) 	switch (sel->target) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885) 	case V4L2_SEL_TGT_CROP_BOUNDS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886) 		sel->r.left = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887) 		sel->r.top = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888) 		sel->r.width = MAX_WIDTH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889) 		sel->r.height = MAX_HEIGHT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891) 	case V4L2_SEL_TGT_CROP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892) 		sel->r = priv->frame;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  893) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  894) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  895) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  899) static int mt9t112_set_selection(struct v4l2_subdev *sd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  900) 				 struct v4l2_subdev_pad_config *cfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  901) 				 struct v4l2_subdev_selection *sel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  902) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  903) 	struct i2c_client *client = v4l2_get_subdevdata(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  904) 	struct mt9t112_priv *priv = to_mt9t112(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  905) 	const struct v4l2_rect *rect = &sel->r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907) 	if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908) 	    sel->target != V4L2_SEL_TGT_CROP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  911) 	return mt9t112_set_params(priv, rect, priv->format->code);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  912) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  913) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914) static int mt9t112_get_fmt(struct v4l2_subdev *sd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915) 			   struct v4l2_subdev_pad_config *cfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  916) 			   struct v4l2_subdev_format *format)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  917) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  918) 	struct v4l2_mbus_framefmt *mf = &format->format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  919) 	struct i2c_client *client = v4l2_get_subdevdata(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  920) 	struct mt9t112_priv *priv = to_mt9t112(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922) 	if (format->pad)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925) 	mf->width	= priv->frame.width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926) 	mf->height	= priv->frame.height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927) 	mf->colorspace	= priv->format->colorspace;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928) 	mf->code	= priv->format->code;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929) 	mf->field	= V4L2_FIELD_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  931) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  932) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  933) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934) static int mt9t112_s_fmt(struct v4l2_subdev *sd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935) 			 struct v4l2_mbus_framefmt *mf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937) 	struct i2c_client *client = v4l2_get_subdevdata(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938) 	struct mt9t112_priv *priv = to_mt9t112(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939) 	struct v4l2_rect rect = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940) 		.width = mf->width,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941) 		.height = mf->height,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942) 		.left = priv->frame.left,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943) 		.top = priv->frame.top,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  945) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  946) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  947) 	ret = mt9t112_set_params(priv, &rect, mf->code);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949) 	if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  950) 		mf->colorspace = priv->format->colorspace;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  951) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  952) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  953) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  954) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  955) static int mt9t112_set_fmt(struct v4l2_subdev *sd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956) 			   struct v4l2_subdev_pad_config *cfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957) 			   struct v4l2_subdev_format *format)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959) 	struct i2c_client *client = v4l2_get_subdevdata(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960) 	struct v4l2_mbus_framefmt *mf = &format->format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961) 	struct mt9t112_priv *priv = to_mt9t112(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964) 	if (format->pad)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967) 	for (i = 0; i < priv->num_formats; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968) 		if (mt9t112_cfmts[i].code == mf->code)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  969) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  970) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  971) 	if (i == priv->num_formats) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972) 		mf->code = MEDIA_BUS_FMT_UYVY8_2X8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973) 		mf->colorspace = V4L2_COLORSPACE_JPEG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975) 		mf->colorspace = mt9t112_cfmts[i].colorspace;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  977) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  978) 	v4l_bound_align_image(&mf->width, 0, MAX_WIDTH, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  979) 			      &mf->height, 0, MAX_HEIGHT, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981) 	mf->field = V4L2_FIELD_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983) 	if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984) 		return mt9t112_s_fmt(sd, mf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985) 	cfg->try_fmt = *mf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990) static int mt9t112_enum_mbus_code(struct v4l2_subdev *sd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991) 				  struct v4l2_subdev_pad_config *cfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992) 				  struct v4l2_subdev_mbus_code_enum *code)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994) 	struct i2c_client *client = v4l2_get_subdevdata(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995) 	struct mt9t112_priv *priv = to_mt9t112(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997) 	if (code->pad || code->index >= priv->num_formats)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  999) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) 	code->code = mt9t112_cfmts[code->index].code;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) static const struct v4l2_subdev_video_ops mt9t112_subdev_video_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) 	.s_stream	= mt9t112_s_stream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) static const struct v4l2_subdev_pad_ops mt9t112_subdev_pad_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) 	.enum_mbus_code	= mt9t112_enum_mbus_code,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) 	.get_selection	= mt9t112_get_selection,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) 	.set_selection	= mt9t112_set_selection,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) 	.get_fmt	= mt9t112_get_fmt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) 	.set_fmt	= mt9t112_set_fmt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) /************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018)  *			i2c driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019)  ***********************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) static const struct v4l2_subdev_ops mt9t112_subdev_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) 	.core	= &mt9t112_subdev_core_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) 	.video	= &mt9t112_subdev_video_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) 	.pad	= &mt9t112_subdev_pad_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) static int mt9t112_camera_probe(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) 	struct mt9t112_priv *priv = to_mt9t112(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) 	const char          *devname;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) 	int                  chipid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) 	int		     ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) 	ret = mt9t112_s_power(&priv->subdev, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) 	/* Check and show chip ID. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) 	mt9t112_reg_read(chipid, client, 0x0000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) 	switch (chipid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) 	case 0x2680:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) 		devname = "mt9t111";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) 		priv->num_formats = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) 	case 0x2682:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) 		devname = "mt9t112";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) 		priv->num_formats = ARRAY_SIZE(mt9t112_cfmts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) 		dev_err(&client->dev, "Product ID error %04x\n", chipid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) 		ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) 		goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) 	dev_info(&client->dev, "%s chip ID %04x\n", devname, chipid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) 	mt9t112_s_power(&priv->subdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) static int mt9t112_probe(struct i2c_client *client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) 			 const struct i2c_device_id *did)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) 	struct mt9t112_priv *priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) 	if (!client->dev.platform_data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) 		dev_err(&client->dev, "mt9t112: missing platform data!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) 	priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) 	if (!priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) 	priv->info = client->dev.platform_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) 	priv->init_done = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) 	v4l2_i2c_subdev_init(&priv->subdev, client, &mt9t112_subdev_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) 	priv->clk = devm_clk_get(&client->dev, "extclk");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) 	if (PTR_ERR(priv->clk) == -ENOENT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) 		priv->clk = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) 	} else if (IS_ERR(priv->clk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) 		dev_err(&client->dev, "Unable to get clock \"extclk\"\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) 		return PTR_ERR(priv->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) 	priv->standby_gpio = devm_gpiod_get_optional(&client->dev, "standby",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) 						     GPIOD_OUT_HIGH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) 	if (IS_ERR(priv->standby_gpio)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) 		dev_err(&client->dev, "Unable to get gpio \"standby\"\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) 		return PTR_ERR(priv->standby_gpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) 	ret = mt9t112_camera_probe(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) 	return v4l2_async_register_subdev(&priv->subdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) static int mt9t112_remove(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) 	struct mt9t112_priv *priv = to_mt9t112(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) 	clk_disable_unprepare(priv->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) 	v4l2_async_unregister_subdev(&priv->subdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) static const struct i2c_device_id mt9t112_id[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) 	{ "mt9t112", 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) 	{ }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) MODULE_DEVICE_TABLE(i2c, mt9t112_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) static struct i2c_driver mt9t112_i2c_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) 	.driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) 		.name = "mt9t112",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) 	.probe    = mt9t112_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) 	.remove   = mt9t112_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) 	.id_table = mt9t112_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) module_i2c_driver(mt9t112_i2c_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) MODULE_DESCRIPTION("V4L2 driver for MT9T111/MT9T112 camera sensor");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) MODULE_AUTHOR("Kuninori Morimoto");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) MODULE_LICENSE("GPL v2");