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-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * Driver for MT9M032 CMOS Image Sensor from Micron
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * Copyright (C) 2010-2011 Lund Engineering
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  * Contact: Gil Lund <gwlund@lundeng.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  * Author: Martin Hostettler <martin@neutronstar.dyndns.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/i2c.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/math64.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include <linux/v4l2-mediabus.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include <media/media-entity.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #include <media/i2c/mt9m032.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #include <media/v4l2-ctrls.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #include <media/v4l2-device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #include <media/v4l2-subdev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) #include "aptina-pll.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29)  * width and height include active boundary and black parts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31)  * column    0-  15 active boundary
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32)  * column   16-1455 image
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33)  * column 1456-1471 active boundary
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34)  * column 1472-1599 black
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36)  * row       0-  51 black
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37)  * row      53-  59 active boundary
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38)  * row      60-1139 image
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39)  * row    1140-1147 active boundary
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40)  * row    1148-1151 black
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) #define MT9M032_PIXEL_ARRAY_WIDTH			1600
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) #define MT9M032_PIXEL_ARRAY_HEIGHT			1152
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) #define MT9M032_CHIP_VERSION				0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) #define		MT9M032_CHIP_VERSION_VALUE		0x1402
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) #define MT9M032_ROW_START				0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) #define		MT9M032_ROW_START_MIN			0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) #define		MT9M032_ROW_START_MAX			1152
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) #define		MT9M032_ROW_START_DEF			60
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) #define MT9M032_COLUMN_START				0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) #define		MT9M032_COLUMN_START_MIN		0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) #define		MT9M032_COLUMN_START_MAX		1600
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) #define		MT9M032_COLUMN_START_DEF		16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) #define MT9M032_ROW_SIZE				0x03
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) #define		MT9M032_ROW_SIZE_MIN			32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) #define		MT9M032_ROW_SIZE_MAX			1152
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) #define		MT9M032_ROW_SIZE_DEF			1080
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) #define MT9M032_COLUMN_SIZE				0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) #define		MT9M032_COLUMN_SIZE_MIN			32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) #define		MT9M032_COLUMN_SIZE_MAX			1600
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) #define		MT9M032_COLUMN_SIZE_DEF			1440
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) #define MT9M032_HBLANK					0x05
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) #define MT9M032_VBLANK					0x06
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) #define		MT9M032_VBLANK_MAX			0x7ff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) #define MT9M032_SHUTTER_WIDTH_HIGH			0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) #define MT9M032_SHUTTER_WIDTH_LOW			0x09
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) #define		MT9M032_SHUTTER_WIDTH_MIN		1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) #define		MT9M032_SHUTTER_WIDTH_MAX		1048575
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) #define		MT9M032_SHUTTER_WIDTH_DEF		1943
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) #define MT9M032_PIX_CLK_CTRL				0x0a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) #define		MT9M032_PIX_CLK_CTRL_INV_PIXCLK		0x8000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) #define MT9M032_RESTART					0x0b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) #define MT9M032_RESET					0x0d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) #define MT9M032_PLL_CONFIG1				0x11
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) #define		MT9M032_PLL_CONFIG1_PREDIV_MASK		0x3f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) #define		MT9M032_PLL_CONFIG1_MUL_SHIFT		8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) #define MT9M032_READ_MODE1				0x1e
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) #define		MT9M032_READ_MODE1_OUTPUT_BAD_FRAMES	(1 << 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) #define		MT9M032_READ_MODE1_MAINTAIN_FRAME_RATE	(1 << 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) #define		MT9M032_READ_MODE1_XOR_LINE_VALID	(1 << 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) #define		MT9M032_READ_MODE1_CONT_LINE_VALID	(1 << 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) #define		MT9M032_READ_MODE1_INVERT_TRIGGER	(1 << 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) #define		MT9M032_READ_MODE1_SNAPSHOT		(1 << 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) #define		MT9M032_READ_MODE1_GLOBAL_RESET		(1 << 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) #define		MT9M032_READ_MODE1_BULB_EXPOSURE	(1 << 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) #define		MT9M032_READ_MODE1_INVERT_STROBE	(1 << 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) #define		MT9M032_READ_MODE1_STROBE_ENABLE	(1 << 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) #define		MT9M032_READ_MODE1_STROBE_START_TRIG1	(0 << 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) #define		MT9M032_READ_MODE1_STROBE_START_EXP	(1 << 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) #define		MT9M032_READ_MODE1_STROBE_START_SHUTTER	(2 << 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) #define		MT9M032_READ_MODE1_STROBE_START_TRIG2	(3 << 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) #define		MT9M032_READ_MODE1_STROBE_END_TRIG1	(0 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) #define		MT9M032_READ_MODE1_STROBE_END_EXP	(1 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) #define		MT9M032_READ_MODE1_STROBE_END_SHUTTER	(2 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) #define		MT9M032_READ_MODE1_STROBE_END_TRIG2	(3 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) #define MT9M032_READ_MODE2				0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) #define		MT9M032_READ_MODE2_VFLIP_SHIFT		15
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) #define		MT9M032_READ_MODE2_HFLIP_SHIFT		14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) #define		MT9M032_READ_MODE2_ROW_BLC		0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) #define MT9M032_GAIN_GREEN1				0x2b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) #define MT9M032_GAIN_BLUE				0x2c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) #define MT9M032_GAIN_RED				0x2d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) #define MT9M032_GAIN_GREEN2				0x2e
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) /* write only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) #define MT9M032_GAIN_ALL				0x35
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) #define		MT9M032_GAIN_DIGITAL_MASK		0x7f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) #define		MT9M032_GAIN_DIGITAL_SHIFT		8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) #define		MT9M032_GAIN_AMUL_SHIFT			6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) #define		MT9M032_GAIN_ANALOG_MASK		0x3f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) #define MT9M032_FORMATTER1				0x9e
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) #define		MT9M032_FORMATTER1_PLL_P1_6		(1 << 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) #define		MT9M032_FORMATTER1_PARALLEL		(1 << 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) #define MT9M032_FORMATTER2				0x9f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) #define		MT9M032_FORMATTER2_DOUT_EN		0x1000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) #define		MT9M032_FORMATTER2_PIXCLK_EN		0x2000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)  * The available MT9M032 datasheet is missing documentation for register 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)  * MT9P031 seems to be close enough, so use constants from that datasheet for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)  * now.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)  * But keep the name MT9P031 to remind us, that this isn't really confirmed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)  * for this sensor.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) #define MT9P031_PLL_CONTROL				0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) #define		MT9P031_PLL_CONTROL_PWROFF		0x0050
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) #define		MT9P031_PLL_CONTROL_PWRON		0x0051
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) #define		MT9P031_PLL_CONTROL_USEPLL		0x0052
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) struct mt9m032 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	struct v4l2_subdev subdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 	struct media_pad pad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	struct mt9m032_platform_data *pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 	unsigned int pix_clock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	struct v4l2_ctrl_handler ctrls;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 	struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 		struct v4l2_ctrl *hflip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 		struct v4l2_ctrl *vflip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	struct mutex lock; /* Protects streaming, format, interval and crop */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	bool streaming;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 	struct v4l2_mbus_framefmt format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	struct v4l2_rect crop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	struct v4l2_fract frame_interval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) #define to_mt9m032(sd)	container_of(sd, struct mt9m032, subdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) #define to_dev(sensor) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	(&((struct i2c_client *)v4l2_get_subdevdata(&(sensor)->subdev))->dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) static int mt9m032_read(struct i2c_client *client, u8 reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 	return i2c_smbus_read_word_swapped(client, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) static int mt9m032_write(struct i2c_client *client, u8 reg, const u16 data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 	return i2c_smbus_write_word_swapped(client, reg, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) static u32 mt9m032_row_time(struct mt9m032 *sensor, unsigned int width)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	unsigned int effective_width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 	u32 ns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 	effective_width = width + 716; /* empirical value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 	ns = div_u64(1000000000ULL * effective_width, sensor->pix_clock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	dev_dbg(to_dev(sensor),	"MT9M032 line time: %u ns\n", ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 	return ns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) static int mt9m032_update_timing(struct mt9m032 *sensor,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 				 struct v4l2_fract *interval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 	struct i2c_client *client = v4l2_get_subdevdata(&sensor->subdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 	struct v4l2_rect *crop = &sensor->crop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 	unsigned int min_vblank;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 	unsigned int vblank;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	u32 row_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 	if (!interval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 		interval = &sensor->frame_interval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 	row_time = mt9m032_row_time(sensor, crop->width);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 	vblank = div_u64(1000000000ULL * interval->numerator,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 			 (u64)row_time * interval->denominator)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 	       - crop->height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 	if (vblank > MT9M032_VBLANK_MAX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 		/* hardware limits to 11 bit values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 		interval->denominator = 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 		interval->numerator =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 			div_u64((crop->height + MT9M032_VBLANK_MAX) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 				(u64)row_time * interval->denominator,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 				1000000000ULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 		vblank = div_u64(1000000000ULL * interval->numerator,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 				 (u64)row_time * interval->denominator)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 		       - crop->height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 	/* enforce minimal 1.6ms blanking time. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 	min_vblank = 1600000 / row_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 	vblank = clamp_t(unsigned int, vblank, min_vblank, MT9M032_VBLANK_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 	return mt9m032_write(client, MT9M032_VBLANK, vblank);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) static int mt9m032_update_geom_timing(struct mt9m032 *sensor)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 	struct i2c_client *client = v4l2_get_subdevdata(&sensor->subdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 	ret = mt9m032_write(client, MT9M032_COLUMN_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 			    sensor->crop.width - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 	if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 		ret = mt9m032_write(client, MT9M032_ROW_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 				    sensor->crop.height - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 	if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 		ret = mt9m032_write(client, MT9M032_COLUMN_START,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 				    sensor->crop.left);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 	if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 		ret = mt9m032_write(client, MT9M032_ROW_START,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 				    sensor->crop.top);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 	if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 		ret = mt9m032_update_timing(sensor, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) static int update_formatter2(struct mt9m032 *sensor, bool streaming)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 	struct i2c_client *client = v4l2_get_subdevdata(&sensor->subdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 	u16 reg_val =   MT9M032_FORMATTER2_DOUT_EN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 		      | 0x0070;  /* parts reserved! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 				 /* possibly for changing to 14-bit mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 	if (streaming)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 		reg_val |= MT9M032_FORMATTER2_PIXCLK_EN;   /* pixclock enable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 	return mt9m032_write(client, MT9M032_FORMATTER2, reg_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) static int mt9m032_setup_pll(struct mt9m032 *sensor)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 	static const struct aptina_pll_limits limits = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 		.ext_clock_min = 8000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 		.ext_clock_max = 16500000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 		.int_clock_min = 2000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 		.int_clock_max = 24000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 		.out_clock_min = 322000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 		.out_clock_max = 693000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 		.pix_clock_max = 99000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 		.n_min = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 		.n_max = 64,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 		.m_min = 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 		.m_max = 255,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 		.p1_min = 6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 		.p1_max = 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 	struct i2c_client *client = v4l2_get_subdevdata(&sensor->subdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 	struct mt9m032_platform_data *pdata = sensor->pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 	struct aptina_pll pll;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 	u16 reg_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 	pll.ext_clock = pdata->ext_clock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 	pll.pix_clock = pdata->pix_clock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 	ret = aptina_pll_calculate(&client->dev, &limits, &pll);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 	sensor->pix_clock = pdata->pix_clock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 	ret = mt9m032_write(client, MT9M032_PLL_CONFIG1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 			    (pll.m << MT9M032_PLL_CONFIG1_MUL_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 			    ((pll.n - 1) & MT9M032_PLL_CONFIG1_PREDIV_MASK));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 	if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 		ret = mt9m032_write(client, MT9P031_PLL_CONTROL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 				    MT9P031_PLL_CONTROL_PWRON |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 				    MT9P031_PLL_CONTROL_USEPLL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 	if (!ret)		/* more reserved, Continuous, Master Mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 		ret = mt9m032_write(client, MT9M032_READ_MODE1, 0x8000 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 				    MT9M032_READ_MODE1_STROBE_START_EXP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 				    MT9M032_READ_MODE1_STROBE_END_SHUTTER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 	if (!ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 		reg_val = (pll.p1 == 6 ? MT9M032_FORMATTER1_PLL_P1_6 : 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 			| MT9M032_FORMATTER1_PARALLEL | 0x001e; /* 14-bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 		ret = mt9m032_write(client, MT9M032_FORMATTER1, reg_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) /* -----------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)  * Subdev pad operations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) static int mt9m032_enum_mbus_code(struct v4l2_subdev *subdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 				  struct v4l2_subdev_pad_config *cfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 				  struct v4l2_subdev_mbus_code_enum *code)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 	if (code->index != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 	code->code = MEDIA_BUS_FMT_Y8_1X8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) static int mt9m032_enum_frame_size(struct v4l2_subdev *subdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 				   struct v4l2_subdev_pad_config *cfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 				   struct v4l2_subdev_frame_size_enum *fse)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 	if (fse->index != 0 || fse->code != MEDIA_BUS_FMT_Y8_1X8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 	fse->min_width = MT9M032_COLUMN_SIZE_DEF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 	fse->max_width = MT9M032_COLUMN_SIZE_DEF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 	fse->min_height = MT9M032_ROW_SIZE_DEF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 	fse->max_height = MT9M032_ROW_SIZE_DEF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)  * __mt9m032_get_pad_crop() - get crop rect
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)  * @sensor: pointer to the sensor struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)  * @cfg: v4l2_subdev_pad_config for getting the try crop rect from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)  * @which: select try or active crop rect
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)  * Returns a pointer the current active or fh relative try crop rect
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) static struct v4l2_rect *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) __mt9m032_get_pad_crop(struct mt9m032 *sensor, struct v4l2_subdev_pad_config *cfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 		       enum v4l2_subdev_format_whence which)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 	switch (which) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 	case V4L2_SUBDEV_FORMAT_TRY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 		return v4l2_subdev_get_try_crop(&sensor->subdev, cfg, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 	case V4L2_SUBDEV_FORMAT_ACTIVE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 		return &sensor->crop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)  * __mt9m032_get_pad_format() - get format
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)  * @sensor: pointer to the sensor struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)  * @cfg: v4l2_subdev_pad_config for getting the try format from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)  * @which: select try or active format
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)  * Returns a pointer the current active or fh relative try format
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) static struct v4l2_mbus_framefmt *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) __mt9m032_get_pad_format(struct mt9m032 *sensor, struct v4l2_subdev_pad_config *cfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 			 enum v4l2_subdev_format_whence which)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 	switch (which) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 	case V4L2_SUBDEV_FORMAT_TRY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 		return v4l2_subdev_get_try_format(&sensor->subdev, cfg, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 	case V4L2_SUBDEV_FORMAT_ACTIVE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 		return &sensor->format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) static int mt9m032_get_pad_format(struct v4l2_subdev *subdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 				  struct v4l2_subdev_pad_config *cfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 				  struct v4l2_subdev_format *fmt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 	struct mt9m032 *sensor = to_mt9m032(subdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 	mutex_lock(&sensor->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 	fmt->format = *__mt9m032_get_pad_format(sensor, cfg, fmt->which);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 	mutex_unlock(&sensor->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) static int mt9m032_set_pad_format(struct v4l2_subdev *subdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 				  struct v4l2_subdev_pad_config *cfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 				  struct v4l2_subdev_format *fmt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 	struct mt9m032 *sensor = to_mt9m032(subdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 	mutex_lock(&sensor->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 	if (sensor->streaming && fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 		ret = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 		goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 	/* Scaling is not supported, the format is thus fixed. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 	fmt->format = *__mt9m032_get_pad_format(sensor, cfg, fmt->which);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 	ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 	mutex_unlock(&sensor->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) static int mt9m032_get_pad_selection(struct v4l2_subdev *subdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 				     struct v4l2_subdev_pad_config *cfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 				     struct v4l2_subdev_selection *sel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 	struct mt9m032 *sensor = to_mt9m032(subdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 	if (sel->target != V4L2_SEL_TGT_CROP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 	mutex_lock(&sensor->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 	sel->r = *__mt9m032_get_pad_crop(sensor, cfg, sel->which);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 	mutex_unlock(&sensor->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) static int mt9m032_set_pad_selection(struct v4l2_subdev *subdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 				     struct v4l2_subdev_pad_config *cfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 				     struct v4l2_subdev_selection *sel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 	struct mt9m032 *sensor = to_mt9m032(subdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 	struct v4l2_mbus_framefmt *format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 	struct v4l2_rect *__crop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 	struct v4l2_rect rect;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 	if (sel->target != V4L2_SEL_TGT_CROP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 	mutex_lock(&sensor->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 	if (sensor->streaming && sel->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 		ret = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 		goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 	/* Clamp the crop rectangle boundaries and align them to a multiple of 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 	 * pixels to ensure a GRBG Bayer pattern.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 	rect.left = clamp(ALIGN(sel->r.left, 2), MT9M032_COLUMN_START_MIN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 			  MT9M032_COLUMN_START_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 	rect.top = clamp(ALIGN(sel->r.top, 2), MT9M032_ROW_START_MIN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 			 MT9M032_ROW_START_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 	rect.width = clamp_t(unsigned int, ALIGN(sel->r.width, 2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 			     MT9M032_COLUMN_SIZE_MIN, MT9M032_COLUMN_SIZE_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 	rect.height = clamp_t(unsigned int, ALIGN(sel->r.height, 2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 			      MT9M032_ROW_SIZE_MIN, MT9M032_ROW_SIZE_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 	rect.width = min_t(unsigned int, rect.width,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 			   MT9M032_PIXEL_ARRAY_WIDTH - rect.left);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 	rect.height = min_t(unsigned int, rect.height,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 			    MT9M032_PIXEL_ARRAY_HEIGHT - rect.top);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 	__crop = __mt9m032_get_pad_crop(sensor, cfg, sel->which);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 	if (rect.width != __crop->width || rect.height != __crop->height) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 		/* Reset the output image size if the crop rectangle size has
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 		 * been modified.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 		format = __mt9m032_get_pad_format(sensor, cfg, sel->which);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 		format->width = rect.width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 		format->height = rect.height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 	*__crop = rect;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 	sel->r = rect;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 	if (sel->which == V4L2_SUBDEV_FORMAT_ACTIVE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 		ret = mt9m032_update_geom_timing(sensor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 	mutex_unlock(&sensor->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) static int mt9m032_get_frame_interval(struct v4l2_subdev *subdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 				      struct v4l2_subdev_frame_interval *fi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 	struct mt9m032 *sensor = to_mt9m032(subdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 	mutex_lock(&sensor->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 	memset(fi, 0, sizeof(*fi));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 	fi->interval = sensor->frame_interval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 	mutex_unlock(&sensor->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) static int mt9m032_set_frame_interval(struct v4l2_subdev *subdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 				      struct v4l2_subdev_frame_interval *fi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 	struct mt9m032 *sensor = to_mt9m032(subdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 	mutex_lock(&sensor->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 	if (sensor->streaming) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 		ret = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 		goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 	/* Avoid divisions by 0. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 	if (fi->interval.denominator == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 		fi->interval.denominator = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 	ret = mt9m032_update_timing(sensor, &fi->interval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 	if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 		sensor->frame_interval = fi->interval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 	mutex_unlock(&sensor->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) static int mt9m032_s_stream(struct v4l2_subdev *subdev, int streaming)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 	struct mt9m032 *sensor = to_mt9m032(subdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) 	mutex_lock(&sensor->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) 	ret = update_formatter2(sensor, streaming);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) 	if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) 		sensor->streaming = streaming;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) 	mutex_unlock(&sensor->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) /* -----------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541)  * V4L2 subdev core operations
^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) #ifdef CONFIG_VIDEO_ADV_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) static int mt9m032_g_register(struct v4l2_subdev *sd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) 			      struct v4l2_dbg_register *reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) 	struct mt9m032 *sensor = to_mt9m032(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) 	struct i2c_client *client = v4l2_get_subdevdata(&sensor->subdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) 	int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) 	if (reg->reg > 0xff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) 	val = mt9m032_read(client, reg->reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) 	if (val < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) 		return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) 	reg->size = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) 	reg->val = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) static int mt9m032_s_register(struct v4l2_subdev *sd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) 			      const struct v4l2_dbg_register *reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) 	struct mt9m032 *sensor = to_mt9m032(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) 	struct i2c_client *client = v4l2_get_subdevdata(&sensor->subdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) 	if (reg->reg > 0xff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) 	return mt9m032_write(client, reg->reg, reg->val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) /* -----------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579)  * V4L2 subdev control operations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) static int update_read_mode2(struct mt9m032 *sensor, bool vflip, bool hflip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) 	struct i2c_client *client = v4l2_get_subdevdata(&sensor->subdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) 	int reg_val = (vflip << MT9M032_READ_MODE2_VFLIP_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) 		    | (hflip << MT9M032_READ_MODE2_HFLIP_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) 		    | MT9M032_READ_MODE2_ROW_BLC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) 		    | 0x0007;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) 	return mt9m032_write(client, MT9M032_READ_MODE2, reg_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) static int mt9m032_set_gain(struct mt9m032 *sensor, s32 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) 	struct i2c_client *client = v4l2_get_subdevdata(&sensor->subdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) 	int digital_gain_val;	/* in 1/8th (0..127) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) 	int analog_mul;		/* 0 or 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) 	int analog_gain_val;	/* in 1/16th. (0..63) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) 	u16 reg_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) 	digital_gain_val = 51; /* from setup example */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) 	if (val < 63) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) 		analog_mul = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) 		analog_gain_val = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) 		analog_mul = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) 		analog_gain_val = val / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) 	/* a_gain = (1 + analog_mul) + (analog_gain_val + 1) / 16 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) 	/* overall_gain = a_gain * (1 + digital_gain_val / 8) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) 	reg_val = ((digital_gain_val & MT9M032_GAIN_DIGITAL_MASK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) 		   << MT9M032_GAIN_DIGITAL_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) 		| ((analog_mul & 1) << MT9M032_GAIN_AMUL_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) 		| (analog_gain_val & MT9M032_GAIN_ANALOG_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) 	return mt9m032_write(client, MT9M032_GAIN_ALL, reg_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) static int mt9m032_try_ctrl(struct v4l2_ctrl *ctrl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) 	if (ctrl->id == V4L2_CID_GAIN && ctrl->val >= 63) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) 		/* round because of multiplier used for values >= 63 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) 		ctrl->val &= ~1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) static int mt9m032_set_ctrl(struct v4l2_ctrl *ctrl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) 	struct mt9m032 *sensor =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) 		container_of(ctrl->handler, struct mt9m032, ctrls);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) 	struct i2c_client *client = v4l2_get_subdevdata(&sensor->subdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) 	switch (ctrl->id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) 	case V4L2_CID_GAIN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) 		return mt9m032_set_gain(sensor, ctrl->val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) 	case V4L2_CID_HFLIP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) 	/* case V4L2_CID_VFLIP: -- In the same cluster */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) 		return update_read_mode2(sensor, sensor->vflip->val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) 					 sensor->hflip->val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) 	case V4L2_CID_EXPOSURE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) 		ret = mt9m032_write(client, MT9M032_SHUTTER_WIDTH_HIGH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) 				    (ctrl->val >> 16) & 0xffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) 		return mt9m032_write(client, MT9M032_SHUTTER_WIDTH_LOW,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) 				     ctrl->val & 0xffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) 	return 0;
^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 const struct v4l2_ctrl_ops mt9m032_ctrl_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) 	.s_ctrl = mt9m032_set_ctrl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) 	.try_ctrl = mt9m032_try_ctrl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) /* -------------------------------------------------------------------------- */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) static const struct v4l2_subdev_core_ops mt9m032_core_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) #ifdef CONFIG_VIDEO_ADV_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) 	.g_register = mt9m032_g_register,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) 	.s_register = mt9m032_s_register,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) static const struct v4l2_subdev_video_ops mt9m032_video_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) 	.s_stream = mt9m032_s_stream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) 	.g_frame_interval = mt9m032_get_frame_interval,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) 	.s_frame_interval = mt9m032_set_frame_interval,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) static const struct v4l2_subdev_pad_ops mt9m032_pad_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) 	.enum_mbus_code = mt9m032_enum_mbus_code,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) 	.enum_frame_size = mt9m032_enum_frame_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) 	.get_fmt = mt9m032_get_pad_format,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) 	.set_fmt = mt9m032_set_pad_format,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) 	.set_selection = mt9m032_set_pad_selection,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) 	.get_selection = mt9m032_get_pad_selection,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) static const struct v4l2_subdev_ops mt9m032_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) 	.core = &mt9m032_core_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) 	.video = &mt9m032_video_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) 	.pad = &mt9m032_pad_ops,
^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) /* -----------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697)  * Driver initialization and probing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) static int mt9m032_probe(struct i2c_client *client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) 			 const struct i2c_device_id *devid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) 	struct mt9m032_platform_data *pdata = client->dev.platform_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) 	struct i2c_adapter *adapter = client->adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) 	struct mt9m032 *sensor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) 	int chip_version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) 	if (pdata == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) 		dev_err(&client->dev, "No platform data\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) 		dev_warn(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) 			 "I2C-Adapter doesn't support I2C_FUNC_SMBUS_WORD\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) 		return -EIO;
^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) 	if (!client->dev.platform_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) 	sensor = devm_kzalloc(&client->dev, sizeof(*sensor), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) 	if (sensor == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) 	mutex_init(&sensor->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) 	sensor->pdata = pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) 	v4l2_i2c_subdev_init(&sensor->subdev, client, &mt9m032_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) 	sensor->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) 	chip_version = mt9m032_read(client, MT9M032_CHIP_VERSION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) 	if (chip_version != MT9M032_CHIP_VERSION_VALUE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) 		dev_err(&client->dev, "MT9M032 not detected, wrong version "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) 			"0x%04x\n", chip_version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) 		ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) 		goto error_sensor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) 	dev_info(&client->dev, "MT9M032 detected at address 0x%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) 		 client->addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) 	sensor->frame_interval.numerator = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) 	sensor->frame_interval.denominator = 30;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) 	sensor->crop.left = MT9M032_COLUMN_START_DEF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) 	sensor->crop.top = MT9M032_ROW_START_DEF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) 	sensor->crop.width = MT9M032_COLUMN_SIZE_DEF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) 	sensor->crop.height = MT9M032_ROW_SIZE_DEF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) 	sensor->format.width = sensor->crop.width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) 	sensor->format.height = sensor->crop.height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) 	sensor->format.code = MEDIA_BUS_FMT_Y8_1X8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) 	sensor->format.field = V4L2_FIELD_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) 	sensor->format.colorspace = V4L2_COLORSPACE_SRGB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) 	v4l2_ctrl_handler_init(&sensor->ctrls, 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) 	v4l2_ctrl_new_std(&sensor->ctrls, &mt9m032_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) 			  V4L2_CID_GAIN, 0, 127, 1, 64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) 	sensor->hflip = v4l2_ctrl_new_std(&sensor->ctrls,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) 					  &mt9m032_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) 					  V4L2_CID_HFLIP, 0, 1, 1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) 	sensor->vflip = v4l2_ctrl_new_std(&sensor->ctrls,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) 					  &mt9m032_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) 					  V4L2_CID_VFLIP, 0, 1, 1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) 	v4l2_ctrl_new_std(&sensor->ctrls, &mt9m032_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) 			  V4L2_CID_EXPOSURE, MT9M032_SHUTTER_WIDTH_MIN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) 			  MT9M032_SHUTTER_WIDTH_MAX, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) 			  MT9M032_SHUTTER_WIDTH_DEF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) 	v4l2_ctrl_new_std(&sensor->ctrls, &mt9m032_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) 			  V4L2_CID_PIXEL_RATE, pdata->pix_clock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) 			  pdata->pix_clock, 1, pdata->pix_clock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) 	if (sensor->ctrls.error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) 		ret = sensor->ctrls.error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) 		dev_err(&client->dev, "control initialization error %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) 		goto error_ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) 	v4l2_ctrl_cluster(2, &sensor->hflip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) 	sensor->subdev.ctrl_handler = &sensor->ctrls;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) 	sensor->subdev.entity.function = MEDIA_ENT_F_CAM_SENSOR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) 	sensor->pad.flags = MEDIA_PAD_FL_SOURCE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) 	ret = media_entity_pads_init(&sensor->subdev.entity, 1, &sensor->pad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) 		goto error_ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) 	ret = mt9m032_write(client, MT9M032_RESET, 1);	/* reset on */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) 		goto error_entity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) 	ret = mt9m032_write(client, MT9M032_RESET, 0);	/* reset off */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) 		goto error_entity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) 	ret = mt9m032_setup_pll(sensor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) 		goto error_entity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) 	usleep_range(10000, 11000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) 	ret = v4l2_ctrl_handler_setup(&sensor->ctrls);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) 		goto error_entity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) 	/* SIZE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) 	ret = mt9m032_update_geom_timing(sensor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) 		goto error_entity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) 	ret = mt9m032_write(client, 0x41, 0x0000);	/* reserved !!! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) 		goto error_entity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) 	ret = mt9m032_write(client, 0x42, 0x0003);	/* reserved !!! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) 		goto error_entity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) 	ret = mt9m032_write(client, 0x43, 0x0003);	/* reserved !!! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) 		goto error_entity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) 	ret = mt9m032_write(client, 0x7f, 0x0000);	/* reserved !!! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) 		goto error_entity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) 	if (sensor->pdata->invert_pixclock) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) 		ret = mt9m032_write(client, MT9M032_PIX_CLK_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) 				    MT9M032_PIX_CLK_CTRL_INV_PIXCLK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) 			goto error_entity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) 	ret = mt9m032_write(client, MT9M032_RESTART, 1); /* Restart on */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) 		goto error_entity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) 	msleep(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) 	ret = mt9m032_write(client, MT9M032_RESTART, 0); /* Restart off */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) 		goto error_entity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) 	msleep(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) 	ret = update_formatter2(sensor, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) 		goto error_entity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) error_entity:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) 	media_entity_cleanup(&sensor->subdev.entity);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) error_ctrl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) 	v4l2_ctrl_handler_free(&sensor->ctrls);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) error_sensor:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) 	mutex_destroy(&sensor->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) static int mt9m032_remove(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) 	struct v4l2_subdev *subdev = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) 	struct mt9m032 *sensor = to_mt9m032(subdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) 	v4l2_device_unregister_subdev(subdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) 	v4l2_ctrl_handler_free(&sensor->ctrls);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) 	media_entity_cleanup(&subdev->entity);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) 	mutex_destroy(&sensor->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) static const struct i2c_device_id mt9m032_id_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) 	{ MT9M032_NAME, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) 	{ }
^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) MODULE_DEVICE_TABLE(i2c, mt9m032_id_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) static struct i2c_driver mt9m032_i2c_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) 	.driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) 		.name = MT9M032_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) 	.probe = mt9m032_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) 	.remove = mt9m032_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) 	.id_table = mt9m032_id_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) module_i2c_driver(mt9m032_i2c_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) MODULE_AUTHOR("Martin Hostettler <martin@neutronstar.dyndns.org>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) MODULE_DESCRIPTION("MT9M032 camera sensor driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) MODULE_LICENSE("GPL v2");