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)  * IMI RDACM20 GMSL Camera Driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * Copyright (C) 2017-2020 Jacopo Mondi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  * Copyright (C) 2017-2020 Kieran Bingham
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  * Copyright (C) 2017-2019 Laurent Pinchart
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  * Copyright (C) 2017-2019 Niklas Söderlund
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  * Copyright (C) 2016 Renesas Electronics Corporation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  * Copyright (C) 2015 Cogent Embedded, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14)  * The camera is made of an Omnivision OV10635 sensor connected to a Maxim
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15)  * MAX9271 GMSL serializer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include <linux/fwnode.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #include <linux/i2c.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #include <linux/videodev2.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) #include <media/v4l2-async.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) #include <media/v4l2-ctrls.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) #include <media/v4l2-subdev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) #include "max9271.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) #define OV10635_I2C_ADDRESS		0x30
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) #define OV10635_SOFTWARE_RESET		0x0103
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) #define OV10635_PID			0x300a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) #define OV10635_VER			0x300b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) #define OV10635_SC_CMMN_SCCB_ID		0x300c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) #define OV10635_SC_CMMN_SCCB_ID_SELECT	BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) #define OV10635_VERSION			0xa635
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) #define OV10635_WIDTH			1280
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) #define OV10635_HEIGHT			800
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) /* VTS = PCLK / FPS / HTS / 2 (= 88MHz / 1572 / 30 / 2) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) #define OV10635_HTS			1572
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) /* FPS = 29,9998 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) #define OV10635_VTS			933
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50)  * As the drivers supports a single MEDIA_BUS_FMT_UYVY8_2X8 format we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51)  * can harcode the pixel rate.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53)  * PCLK is fed through the system clock, programmed @88MHz.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54)  * MEDIA_BUS_FMT_UYVY8_2X8 format = 2 samples per pixel.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56)  * Pixelrate = PCLK / 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57)  * FPS = (OV10635_VTS * OV10635_HTS) / PixelRate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58)  *     = 29,9998
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) #define OV10635_PIXEL_RATE		(44000000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) static const struct ov10635_reg {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	u16	reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	u8	val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) } ov10635_regs_wizard[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	{ 0x301b, 0xff }, { 0x301c, 0xff }, { 0x301a, 0xff }, { 0x3011, 0x42 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	{ 0x6900, 0x0c }, { 0x6901, 0x19 }, { 0x3503, 0x10 }, { 0x3025, 0x03 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	{ 0x3003, 0x16 }, { 0x3004, 0x30 }, { 0x3005, 0x40 }, { 0x3006, 0x91 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	{ 0x3600, 0x74 }, { 0x3601, 0x2b }, { 0x3612, 0x00 }, { 0x3611, 0x67 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	{ 0x3633, 0xca }, { 0x3602, 0xaf }, { 0x3603, 0x04 }, { 0x3630, 0x28 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	{ 0x3631, 0x16 }, { 0x3714, 0x10 }, { 0x371d, 0x01 }, { 0x4300, 0x3a },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	{ 0x3007, 0x01 }, { 0x3024, 0x03 }, { 0x3020, 0x0a }, { 0x3702, 0x0d },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	{ 0x3703, 0x20 }, { 0x3704, 0x15 }, { 0x3709, 0xa8 }, { 0x370c, 0xc7 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	{ 0x370d, 0x80 }, { 0x3712, 0x00 }, { 0x3713, 0x20 }, { 0x3715, 0x04 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	{ 0x381d, 0x40 }, { 0x381c, 0x00 }, { 0x3822, 0x50 }, { 0x3824, 0x10 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	{ 0x3815, 0x8c }, { 0x3804, 0x05 }, { 0x3805, 0x1f }, { 0x3800, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	{ 0x3801, 0x00 }, { 0x3806, 0x03 }, { 0x3807, 0x28 }, { 0x3802, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	{ 0x3803, 0x07 }, { 0x3808, 0x05 }, { 0x3809, 0x00 }, { 0x380a, 0x03 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	{ 0x380b, 0x20 }, { 0x380c, OV10635_HTS >> 8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	{ 0x380d, OV10635_HTS & 0xff }, { 0x380e, OV10635_VTS >> 8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	{ 0x380f, OV10635_VTS & 0xff },	{ 0x3813, 0x02 }, { 0x3811, 0x08 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	{ 0x381f, 0x0c }, { 0x3819, 0x04 }, { 0x3804, 0x01 }, { 0x3805, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	{ 0x3828, 0x03 }, { 0x3829, 0x10 }, { 0x382a, 0x10 }, { 0x3621, 0x63 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	{ 0x5005, 0x08 }, { 0x56d5, 0x00 }, { 0x56d6, 0x80 }, { 0x56d7, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	{ 0x56d8, 0x00 }, { 0x56d9, 0x00 }, { 0x56da, 0x80 }, { 0x56db, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	{ 0x56dc, 0x00 }, { 0x56e8, 0x00 }, { 0x56e9, 0x7f }, { 0x56ea, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	{ 0x56eb, 0x7f }, { 0x5100, 0x00 }, { 0x5101, 0x80 }, { 0x5102, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	{ 0x5103, 0x80 }, { 0x5104, 0x00 }, { 0x5105, 0x80 }, { 0x5106, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	{ 0x5107, 0x80 }, { 0x5108, 0x00 }, { 0x5109, 0x00 }, { 0x510a, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	{ 0x510b, 0x00 }, { 0x510c, 0x00 }, { 0x510d, 0x00 }, { 0x510e, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	{ 0x510f, 0x00 }, { 0x5110, 0x00 }, { 0x5111, 0x80 }, { 0x5112, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	{ 0x5113, 0x80 }, { 0x5114, 0x00 }, { 0x5115, 0x80 }, { 0x5116, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	{ 0x5117, 0x80 }, { 0x5118, 0x00 }, { 0x5119, 0x00 }, { 0x511a, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	{ 0x511b, 0x00 }, { 0x511c, 0x00 }, { 0x511d, 0x00 }, { 0x511e, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	{ 0x511f, 0x00 }, { 0x56d0, 0x00 }, { 0x5006, 0x04 }, { 0x5608, 0x05 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	{ 0x52d7, 0x06 }, { 0x528d, 0x08 }, { 0x5293, 0x12 }, { 0x52d3, 0x12 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	{ 0x5288, 0x06 }, { 0x5289, 0x20 }, { 0x52c8, 0x06 }, { 0x52c9, 0x20 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	{ 0x52cd, 0x04 }, { 0x5381, 0x00 }, { 0x5382, 0xff }, { 0x5589, 0x76 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	{ 0x558a, 0x47 }, { 0x558b, 0xef }, { 0x558c, 0xc9 }, { 0x558d, 0x49 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	{ 0x558e, 0x30 }, { 0x558f, 0x67 }, { 0x5590, 0x3f }, { 0x5591, 0xf0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	{ 0x5592, 0x10 }, { 0x55a2, 0x6d }, { 0x55a3, 0x55 }, { 0x55a4, 0xc3 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	{ 0x55a5, 0xb5 }, { 0x55a6, 0x43 }, { 0x55a7, 0x38 }, { 0x55a8, 0x5f },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	{ 0x55a9, 0x4b }, { 0x55aa, 0xf0 }, { 0x55ab, 0x10 }, { 0x5581, 0x52 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 	{ 0x5300, 0x01 }, { 0x5301, 0x00 }, { 0x5302, 0x00 }, { 0x5303, 0x0e },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	{ 0x5304, 0x00 }, { 0x5305, 0x0e }, { 0x5306, 0x00 }, { 0x5307, 0x36 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	{ 0x5308, 0x00 }, { 0x5309, 0xd9 }, { 0x530a, 0x00 }, { 0x530b, 0x0f },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	{ 0x530c, 0x00 }, { 0x530d, 0x2c }, { 0x530e, 0x00 }, { 0x530f, 0x59 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	{ 0x5310, 0x00 }, { 0x5311, 0x7b }, { 0x5312, 0x00 }, { 0x5313, 0x22 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	{ 0x5314, 0x00 }, { 0x5315, 0xd5 }, { 0x5316, 0x00 }, { 0x5317, 0x13 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	{ 0x5318, 0x00 }, { 0x5319, 0x18 }, { 0x531a, 0x00 }, { 0x531b, 0x26 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	{ 0x531c, 0x00 }, { 0x531d, 0xdc }, { 0x531e, 0x00 }, { 0x531f, 0x02 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	{ 0x5320, 0x00 }, { 0x5321, 0x24 }, { 0x5322, 0x00 }, { 0x5323, 0x56 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 	{ 0x5324, 0x00 }, { 0x5325, 0x85 }, { 0x5326, 0x00 }, { 0x5327, 0x20 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	{ 0x5609, 0x01 }, { 0x560a, 0x40 }, { 0x560b, 0x01 }, { 0x560c, 0x40 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	{ 0x560d, 0x00 }, { 0x560e, 0xfa }, { 0x560f, 0x00 }, { 0x5610, 0xfa },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	{ 0x5611, 0x02 }, { 0x5612, 0x80 }, { 0x5613, 0x02 }, { 0x5614, 0x80 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	{ 0x5615, 0x01 }, { 0x5616, 0x2c }, { 0x5617, 0x01 }, { 0x5618, 0x2c },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	{ 0x563b, 0x01 }, { 0x563c, 0x01 }, { 0x563d, 0x01 }, { 0x563e, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	{ 0x563f, 0x03 }, { 0x5640, 0x03 }, { 0x5641, 0x03 }, { 0x5642, 0x05 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	{ 0x5643, 0x09 }, { 0x5644, 0x05 }, { 0x5645, 0x05 }, { 0x5646, 0x05 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	{ 0x5647, 0x05 }, { 0x5651, 0x00 }, { 0x5652, 0x80 }, { 0x521a, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	{ 0x521b, 0x03 }, { 0x521c, 0x06 }, { 0x521d, 0x0a }, { 0x521e, 0x0e },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 	{ 0x521f, 0x12 }, { 0x5220, 0x16 }, { 0x5223, 0x02 }, { 0x5225, 0x04 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 	{ 0x5227, 0x08 }, { 0x5229, 0x0c }, { 0x522b, 0x12 }, { 0x522d, 0x18 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	{ 0x522f, 0x1e }, { 0x5241, 0x04 }, { 0x5242, 0x01 }, { 0x5243, 0x03 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	{ 0x5244, 0x06 }, { 0x5245, 0x0a }, { 0x5246, 0x0e }, { 0x5247, 0x12 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	{ 0x5248, 0x16 }, { 0x524a, 0x03 }, { 0x524c, 0x04 }, { 0x524e, 0x08 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 	{ 0x5250, 0x0c }, { 0x5252, 0x12 }, { 0x5254, 0x18 }, { 0x5256, 0x1e },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	/* fifo_line_length = 2*hts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	{ 0x4606, (2 * OV10635_HTS) >> 8 }, { 0x4607, (2 * OV10635_HTS) & 0xff },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	/* fifo_hsync_start = 2*(hts - xres) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	{ 0x460a, (2 * (OV10635_HTS - OV10635_WIDTH)) >> 8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	{ 0x460b, (2 * (OV10635_HTS - OV10635_WIDTH)) & 0xff },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 	{ 0x460c, 0x00 }, { 0x4620, 0x0e },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	/* BT601: 0x08 is also acceptable as HS/VS mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	{ 0x4700, 0x04 }, { 0x4701, 0x00 }, { 0x4702, 0x01 }, { 0x4004, 0x04 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 	{ 0x4005, 0x18 }, { 0x4001, 0x06 }, { 0x4050, 0x22 }, { 0x4051, 0x24 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 	{ 0x4052, 0x02 }, { 0x4057, 0x9c }, { 0x405a, 0x00 }, { 0x4202, 0x02 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	{ 0x3023, 0x10 }, { 0x0100, 0x01 }, { 0x0100, 0x01 }, { 0x6f10, 0x07 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 	{ 0x6f11, 0x82 }, { 0x6f12, 0x04 }, { 0x6f13, 0x00 }, { 0xd000, 0x19 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 	{ 0xd001, 0xa0 }, { 0xd002, 0x00 }, { 0xd003, 0x01 }, { 0xd004, 0xa9 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 	{ 0xd005, 0xad }, { 0xd006, 0x10 }, { 0xd007, 0x40 }, { 0xd008, 0x44 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	{ 0xd009, 0x00 }, { 0xd00a, 0x68 }, { 0xd00b, 0x00 }, { 0xd00c, 0x15 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 	{ 0xd00d, 0x00 }, { 0xd00e, 0x00 }, { 0xd00f, 0x00 }, { 0xd040, 0x9c },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	{ 0xd041, 0x21 }, { 0xd042, 0xff }, { 0xd043, 0xf8 }, { 0xd044, 0xd4 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 	{ 0xd045, 0x01 }, { 0xd046, 0x48 }, { 0xd047, 0x00 }, { 0xd048, 0xd4 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	{ 0xd049, 0x01 }, { 0xd04a, 0x50 }, { 0xd04b, 0x04 }, { 0xd04c, 0x18 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 	{ 0xd04d, 0x60 }, { 0xd04e, 0x00 }, { 0xd04f, 0x01 }, { 0xd050, 0xa8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 	{ 0xd051, 0x63 }, { 0xd052, 0x02 }, { 0xd053, 0xa4 }, { 0xd054, 0x85 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	{ 0xd055, 0x43 }, { 0xd056, 0x00 }, { 0xd057, 0x00 }, { 0xd058, 0x18 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	{ 0xd059, 0x60 }, { 0xd05a, 0x00 }, { 0xd05b, 0x01 }, { 0xd05c, 0xa8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 	{ 0xd05d, 0x63 }, { 0xd05e, 0x03 }, { 0xd05f, 0xf0 }, { 0xd060, 0x98 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	{ 0xd061, 0xa3 }, { 0xd062, 0x00 }, { 0xd063, 0x00 }, { 0xd064, 0x8c },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 	{ 0xd065, 0x6a }, { 0xd066, 0x00 }, { 0xd067, 0x6e }, { 0xd068, 0xe5 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	{ 0xd069, 0x85 }, { 0xd06a, 0x18 }, { 0xd06b, 0x00 }, { 0xd06c, 0x10 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	{ 0xd06d, 0x00 }, { 0xd06e, 0x00 }, { 0xd06f, 0x10 }, { 0xd070, 0x9c },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 	{ 0xd071, 0x80 }, { 0xd072, 0x00 }, { 0xd073, 0x03 }, { 0xd074, 0x18 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	{ 0xd075, 0x60 }, { 0xd076, 0x00 }, { 0xd077, 0x01 }, { 0xd078, 0xa8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 	{ 0xd079, 0x63 }, { 0xd07a, 0x07 }, { 0xd07b, 0x80 }, { 0xd07c, 0x07 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 	{ 0xd07d, 0xff }, { 0xd07e, 0xf9 }, { 0xd07f, 0x03 }, { 0xd080, 0x8c },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	{ 0xd081, 0x63 }, { 0xd082, 0x00 }, { 0xd083, 0x00 }, { 0xd084, 0xa5 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 	{ 0xd085, 0x6b }, { 0xd086, 0x00 }, { 0xd087, 0xff }, { 0xd088, 0x18 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 	{ 0xd089, 0x80 }, { 0xd08a, 0x00 }, { 0xd08b, 0x01 }, { 0xd08c, 0xa8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	{ 0xd08d, 0x84 }, { 0xd08e, 0x01 }, { 0xd08f, 0x04 }, { 0xd090, 0xe1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 	{ 0xd091, 0x6b }, { 0xd092, 0x58 }, { 0xd093, 0x00 }, { 0xd094, 0x94 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	{ 0xd095, 0x6a }, { 0xd096, 0x00 }, { 0xd097, 0x70 }, { 0xd098, 0xe1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 	{ 0xd099, 0x6b }, { 0xd09a, 0x20 }, { 0xd09b, 0x00 }, { 0xd09c, 0x95 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	{ 0xd09d, 0x6b }, { 0xd09e, 0x00 }, { 0xd09f, 0x00 }, { 0xd0a0, 0xe4 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 	{ 0xd0a1, 0x8b }, { 0xd0a2, 0x18 }, { 0xd0a3, 0x00 }, { 0xd0a4, 0x0c },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	{ 0xd0a5, 0x00 }, { 0xd0a6, 0x00 }, { 0xd0a7, 0x23 }, { 0xd0a8, 0x15 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 	{ 0xd0a9, 0x00 }, { 0xd0aa, 0x00 }, { 0xd0ab, 0x00 }, { 0xd0ac, 0x18 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 	{ 0xd0ad, 0x60 }, { 0xd0ae, 0x80 }, { 0xd0af, 0x06 }, { 0xd0b0, 0xa8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 	{ 0xd0b1, 0x83 }, { 0xd0b2, 0x40 }, { 0xd0b3, 0x08 }, { 0xd0b4, 0xa8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 	{ 0xd0b5, 0xe3 }, { 0xd0b6, 0x38 }, { 0xd0b7, 0x2a }, { 0xd0b8, 0xa8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	{ 0xd0b9, 0xc3 }, { 0xd0ba, 0x40 }, { 0xd0bb, 0x09 }, { 0xd0bc, 0xa8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 	{ 0xd0bd, 0xa3 }, { 0xd0be, 0x38 }, { 0xd0bf, 0x29 }, { 0xd0c0, 0x8c },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 	{ 0xd0c1, 0x65 }, { 0xd0c2, 0x00 }, { 0xd0c3, 0x00 }, { 0xd0c4, 0xd8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 	{ 0xd0c5, 0x04 }, { 0xd0c6, 0x18 }, { 0xd0c7, 0x00 }, { 0xd0c8, 0x8c },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 	{ 0xd0c9, 0x67 }, { 0xd0ca, 0x00 }, { 0xd0cb, 0x00 }, { 0xd0cc, 0xd8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 	{ 0xd0cd, 0x06 }, { 0xd0ce, 0x18 }, { 0xd0cf, 0x00 }, { 0xd0d0, 0x18 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 	{ 0xd0d1, 0x60 }, { 0xd0d2, 0x80 }, { 0xd0d3, 0x06 }, { 0xd0d4, 0xa8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 	{ 0xd0d5, 0xe3 }, { 0xd0d6, 0x67 }, { 0xd0d7, 0x02 }, { 0xd0d8, 0xa9 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 	{ 0xd0d9, 0x03 }, { 0xd0da, 0x67 }, { 0xd0db, 0x03 }, { 0xd0dc, 0xa8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 	{ 0xd0dd, 0xc3 }, { 0xd0de, 0x3d }, { 0xd0df, 0x05 }, { 0xd0e0, 0x8c },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 	{ 0xd0e1, 0x66 }, { 0xd0e2, 0x00 }, { 0xd0e3, 0x00 }, { 0xd0e4, 0xb8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	{ 0xd0e5, 0x63 }, { 0xd0e6, 0x00 }, { 0xd0e7, 0x18 }, { 0xd0e8, 0xb8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 	{ 0xd0e9, 0x63 }, { 0xd0ea, 0x00 }, { 0xd0eb, 0x98 }, { 0xd0ec, 0xbc },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 	{ 0xd0ed, 0x03 }, { 0xd0ee, 0x00 }, { 0xd0ef, 0x00 }, { 0xd0f0, 0x10 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 	{ 0xd0f1, 0x00 }, { 0xd0f2, 0x00 }, { 0xd0f3, 0x16 }, { 0xd0f4, 0xb8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 	{ 0xd0f5, 0x83 }, { 0xd0f6, 0x00 }, { 0xd0f7, 0x19 }, { 0xd0f8, 0x8c },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 	{ 0xd0f9, 0x67 }, { 0xd0fa, 0x00 }, { 0xd0fb, 0x00 }, { 0xd0fc, 0xb8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 	{ 0xd0fd, 0xa4 }, { 0xd0fe, 0x00 }, { 0xd0ff, 0x98 }, { 0xd100, 0xb8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 	{ 0xd101, 0x83 }, { 0xd102, 0x00 }, { 0xd103, 0x08 }, { 0xd104, 0x8c },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 	{ 0xd105, 0x68 }, { 0xd106, 0x00 }, { 0xd107, 0x00 }, { 0xd108, 0xe0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 	{ 0xd109, 0x63 }, { 0xd10a, 0x20 }, { 0xd10b, 0x04 }, { 0xd10c, 0xe0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 	{ 0xd10d, 0x65 }, { 0xd10e, 0x18 }, { 0xd10f, 0x00 }, { 0xd110, 0xa4 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 	{ 0xd111, 0x83 }, { 0xd112, 0xff }, { 0xd113, 0xff }, { 0xd114, 0xb8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 	{ 0xd115, 0x64 }, { 0xd116, 0x00 }, { 0xd117, 0x48 }, { 0xd118, 0xd8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 	{ 0xd119, 0x07 }, { 0xd11a, 0x18 }, { 0xd11b, 0x00 }, { 0xd11c, 0xd8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 	{ 0xd11d, 0x08 }, { 0xd11e, 0x20 }, { 0xd11f, 0x00 }, { 0xd120, 0x9c },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 	{ 0xd121, 0x60 }, { 0xd122, 0x00 }, { 0xd123, 0x00 }, { 0xd124, 0xd8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 	{ 0xd125, 0x06 }, { 0xd126, 0x18 }, { 0xd127, 0x00 }, { 0xd128, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 	{ 0xd129, 0x00 }, { 0xd12a, 0x00 }, { 0xd12b, 0x08 }, { 0xd12c, 0x15 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 	{ 0xd12d, 0x00 }, { 0xd12e, 0x00 }, { 0xd12f, 0x00 }, { 0xd130, 0x8c },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 	{ 0xd131, 0x6a }, { 0xd132, 0x00 }, { 0xd133, 0x76 }, { 0xd134, 0xbc },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 	{ 0xd135, 0x23 }, { 0xd136, 0x00 }, { 0xd137, 0x00 }, { 0xd138, 0x13 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 	{ 0xd139, 0xff }, { 0xd13a, 0xff }, { 0xd13b, 0xe6 }, { 0xd13c, 0x18 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 	{ 0xd13d, 0x60 }, { 0xd13e, 0x80 }, { 0xd13f, 0x06 }, { 0xd140, 0x03 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 	{ 0xd141, 0xff }, { 0xd142, 0xff }, { 0xd143, 0xdd }, { 0xd144, 0xa8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 	{ 0xd145, 0x83 }, { 0xd146, 0x40 }, { 0xd147, 0x08 }, { 0xd148, 0x85 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 	{ 0xd149, 0x21 }, { 0xd14a, 0x00 }, { 0xd14b, 0x00 }, { 0xd14c, 0x85 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 	{ 0xd14d, 0x41 }, { 0xd14e, 0x00 }, { 0xd14f, 0x04 }, { 0xd150, 0x44 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 	{ 0xd151, 0x00 }, { 0xd152, 0x48 }, { 0xd153, 0x00 }, { 0xd154, 0x9c },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 	{ 0xd155, 0x21 }, { 0xd156, 0x00 }, { 0xd157, 0x08 }, { 0x6f0e, 0x03 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 	{ 0x6f0f, 0x00 }, { 0x460e, 0x08 }, { 0x460f, 0x01 }, { 0x4610, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 	{ 0x4611, 0x01 }, { 0x4612, 0x00 }, { 0x4613, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 	/* 8 bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 	{ 0x4605, 0x08 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 	/* Swap data bits order [9:0] -> [0:9] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 	{ 0x4709, 0x10 }, { 0x4608, 0x00 }, { 0x4609, 0x08 }, { 0x6804, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 	{ 0x6805, 0x06 }, { 0x6806, 0x00 }, { 0x5120, 0x00 }, { 0x3510, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 	{ 0x3504, 0x00 }, { 0x6800, 0x00 }, { 0x6f0d, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 	/* PCLK falling edge */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 	{ 0x4708, 0x01 }, { 0x5000, 0xff }, { 0x5001, 0xbf }, { 0x5002, 0x7e },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 	{ 0x503d, 0x00 }, { 0xc450, 0x01 }, { 0xc452, 0x04 }, { 0xc453, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 	{ 0xc454, 0x00 }, { 0xc455, 0x01 }, { 0xc456, 0x01 }, { 0xc457, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 	{ 0xc458, 0x00 }, { 0xc459, 0x00 }, { 0xc45b, 0x00 }, { 0xc45c, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 	{ 0xc45d, 0x00 }, { 0xc45e, 0x00 }, { 0xc45f, 0x00 }, { 0xc460, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 	{ 0xc461, 0x01 }, { 0xc462, 0x01 }, { 0xc464, 0x03 }, { 0xc465, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 	{ 0xc466, 0x8a }, { 0xc467, 0x00 }, { 0xc468, 0x86 }, { 0xc469, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 	{ 0xc46a, 0x40 }, { 0xc46b, 0x50 }, { 0xc46c, 0x30 }, { 0xc46d, 0x28 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 	{ 0xc46e, 0x60 }, { 0xc46f, 0x40 }, { 0xc47c, 0x01 }, { 0xc47d, 0x38 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 	{ 0xc47e, 0x00 }, { 0xc47f, 0x00 }, { 0xc480, 0x00 }, { 0xc481, 0xff },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 	{ 0xc482, 0x00 }, { 0xc483, 0x40 }, { 0xc484, 0x00 }, { 0xc485, 0x18 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 	{ 0xc486, 0x00 }, { 0xc487, 0x18 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 	{ 0xc488, (OV10635_VTS - 8) * 16 >> 8},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 	{ 0xc489, (OV10635_VTS - 8) * 16 & 0xff},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 	{ 0xc48a, (OV10635_VTS - 8) * 16 >> 8},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 	{ 0xc48b, (OV10635_VTS - 8) * 16 & 0xff}, { 0xc48c, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 	{ 0xc48d, 0x04 }, { 0xc48e, 0x00 }, { 0xc48f, 0x04 }, { 0xc490, 0x03 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 	{ 0xc492, 0x20 }, { 0xc493, 0x08 }, { 0xc498, 0x02 }, { 0xc499, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 	{ 0xc49a, 0x02 }, { 0xc49b, 0x00 }, { 0xc49c, 0x02 }, { 0xc49d, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 	{ 0xc49e, 0x02 }, { 0xc49f, 0x60 }, { 0xc4a0, 0x03 }, { 0xc4a1, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 	{ 0xc4a2, 0x04 }, { 0xc4a3, 0x00 }, { 0xc4a4, 0x00 }, { 0xc4a5, 0x10 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 	{ 0xc4a6, 0x00 }, { 0xc4a7, 0x40 }, { 0xc4a8, 0x00 }, { 0xc4a9, 0x80 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 	{ 0xc4aa, 0x0d }, { 0xc4ab, 0x00 }, { 0xc4ac, 0x0f }, { 0xc4ad, 0xc0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 	{ 0xc4b4, 0x01 }, { 0xc4b5, 0x01 }, { 0xc4b6, 0x00 }, { 0xc4b7, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 	{ 0xc4b8, 0x00 }, { 0xc4b9, 0x01 }, { 0xc4ba, 0x01 }, { 0xc4bb, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 	{ 0xc4bc, 0x01 }, { 0xc4bd, 0x60 }, { 0xc4be, 0x02 }, { 0xc4bf, 0x33 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 	{ 0xc4c8, 0x03 }, { 0xc4c9, 0xd0 }, { 0xc4ca, 0x0e }, { 0xc4cb, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 	{ 0xc4cc, 0x0e }, { 0xc4cd, 0x51 }, { 0xc4ce, 0x0e }, { 0xc4cf, 0x51 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 	{ 0xc4d0, 0x04 }, { 0xc4d1, 0x80 }, { 0xc4e0, 0x04 }, { 0xc4e1, 0x02 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 	{ 0xc4e2, 0x01 }, { 0xc4e4, 0x10 }, { 0xc4e5, 0x20 }, { 0xc4e6, 0x30 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 	{ 0xc4e7, 0x40 }, { 0xc4e8, 0x50 }, { 0xc4e9, 0x60 }, { 0xc4ea, 0x70 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 	{ 0xc4eb, 0x80 }, { 0xc4ec, 0x90 }, { 0xc4ed, 0xa0 }, { 0xc4ee, 0xb0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 	{ 0xc4ef, 0xc0 }, { 0xc4f0, 0xd0 }, { 0xc4f1, 0xe0 }, { 0xc4f2, 0xf0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 	{ 0xc4f3, 0x80 }, { 0xc4f4, 0x00 }, { 0xc4f5, 0x20 }, { 0xc4f6, 0x02 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 	{ 0xc4f7, 0x00 }, { 0xc4f8, 0x00 }, { 0xc4f9, 0x00 }, { 0xc4fa, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 	{ 0xc4fb, 0x01 }, { 0xc4fc, 0x01 }, { 0xc4fd, 0x00 }, { 0xc4fe, 0x04 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 	{ 0xc4ff, 0x02 }, { 0xc500, 0x48 }, { 0xc501, 0x74 }, { 0xc502, 0x58 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 	{ 0xc503, 0x80 }, { 0xc504, 0x05 }, { 0xc505, 0x80 }, { 0xc506, 0x03 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 	{ 0xc507, 0x80 }, { 0xc508, 0x01 }, { 0xc509, 0xc0 }, { 0xc50a, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 	{ 0xc50b, 0xa0 }, { 0xc50c, 0x01 }, { 0xc50d, 0x2c }, { 0xc50e, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 	{ 0xc50f, 0x0a }, { 0xc510, 0x00 }, { 0xc511, 0x00 }, { 0xc512, 0xe5 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 	{ 0xc513, 0x14 }, { 0xc514, 0x04 }, { 0xc515, 0x00 }, { 0xc518, OV10635_VTS >> 8},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 	{ 0xc519, OV10635_VTS & 0xff}, { 0xc51a, OV10635_HTS >> 8},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 	{ 0xc51b, OV10635_HTS & 0xff}, { 0xc2e0, 0x00 }, { 0xc2e1, 0x51 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 	{ 0xc2e2, 0x00 }, { 0xc2e3, 0xd6 }, { 0xc2e4, 0x01 }, { 0xc2e5, 0x5e },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 	{ 0xc2e9, 0x01 }, { 0xc2ea, 0x7a }, { 0xc2eb, 0x90 }, { 0xc2ed, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 	{ 0xc2ee, 0x7a }, { 0xc2ef, 0x64 }, { 0xc308, 0x00 }, { 0xc309, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 	{ 0xc30a, 0x00 }, { 0xc30c, 0x00 }, { 0xc30d, 0x01 }, { 0xc30e, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 	{ 0xc30f, 0x00 }, { 0xc310, 0x01 }, { 0xc311, 0x60 }, { 0xc312, 0xff },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 	{ 0xc313, 0x08 }, { 0xc314, 0x01 }, { 0xc315, 0x00 }, { 0xc316, 0xff },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 	{ 0xc317, 0x0b }, { 0xc318, 0x00 }, { 0xc319, 0x0c }, { 0xc31a, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 	{ 0xc31b, 0xe0 }, { 0xc31c, 0x00 }, { 0xc31d, 0x14 }, { 0xc31e, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 	{ 0xc31f, 0xc5 }, { 0xc320, 0xff }, { 0xc321, 0x4b }, { 0xc322, 0xff },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 	{ 0xc323, 0xf0 }, { 0xc324, 0xff }, { 0xc325, 0xe8 }, { 0xc326, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 	{ 0xc327, 0x46 }, { 0xc328, 0xff }, { 0xc329, 0xd2 }, { 0xc32a, 0xff },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 	{ 0xc32b, 0xe4 }, { 0xc32c, 0xff }, { 0xc32d, 0xbb }, { 0xc32e, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 	{ 0xc32f, 0x61 }, { 0xc330, 0xff }, { 0xc331, 0xf9 }, { 0xc332, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 	{ 0xc333, 0xd9 }, { 0xc334, 0x00 }, { 0xc335, 0x2e }, { 0xc336, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 	{ 0xc337, 0xb1 }, { 0xc338, 0xff }, { 0xc339, 0x64 }, { 0xc33a, 0xff },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 	{ 0xc33b, 0xeb }, { 0xc33c, 0xff }, { 0xc33d, 0xe8 }, { 0xc33e, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 	{ 0xc33f, 0x48 }, { 0xc340, 0xff }, { 0xc341, 0xd0 }, { 0xc342, 0xff },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 	{ 0xc343, 0xed }, { 0xc344, 0xff }, { 0xc345, 0xad }, { 0xc346, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 	{ 0xc347, 0x66 }, { 0xc348, 0x01 }, { 0xc349, 0x00 }, { 0x6700, 0x04 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 	{ 0x6701, 0x7b }, { 0x6702, 0xfd }, { 0x6703, 0xf9 }, { 0x6704, 0x3d },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 	{ 0x6705, 0x71 }, { 0x6706, 0x78 }, { 0x6708, 0x05 }, { 0x6f06, 0x6f },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 	{ 0x6f07, 0x00 }, { 0x6f0a, 0x6f }, { 0x6f0b, 0x00 }, { 0x6f00, 0x03 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 	{ 0xc34c, 0x01 }, { 0xc34d, 0x00 }, { 0xc34e, 0x46 }, { 0xc34f, 0x55 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 	{ 0xc350, 0x00 }, { 0xc351, 0x40 }, { 0xc352, 0x00 }, { 0xc353, 0xff },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 	{ 0xc354, 0x04 }, { 0xc355, 0x08 }, { 0xc356, 0x01 }, { 0xc357, 0xef },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 	{ 0xc358, 0x30 }, { 0xc359, 0x01 }, { 0xc35a, 0x64 }, { 0xc35b, 0x46 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 	{ 0xc35c, 0x00 }, { 0x3042, 0xf0 }, { 0x3042, 0xf0 }, { 0x3042, 0xf0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 	{ 0x3042, 0xf0 }, { 0x3042, 0xf0 }, { 0x3042, 0xf0 }, { 0x3042, 0xf0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 	{ 0x3042, 0xf0 }, { 0x3042, 0xf0 }, { 0x3042, 0xf0 }, { 0x3042, 0xf0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 	{ 0x3042, 0xf0 }, { 0x3042, 0xf0 }, { 0x3042, 0xf0 }, { 0x3042, 0xf0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 	{ 0x3042, 0xf0 }, { 0x3042, 0xf0 }, { 0x3042, 0xf0 }, { 0x3042, 0xf0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 	{ 0x3042, 0xf0 }, { 0x3042, 0xf0 }, { 0x3042, 0xf0 }, { 0x3042, 0xf0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 	{ 0x3042, 0xf0 }, { 0x3042, 0xf0 }, { 0x3042, 0xf0 }, { 0xc261, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 	{ 0x301b, 0xf0 }, { 0x301c, 0xf0 }, { 0x301a, 0xf0 }, { 0x6f00, 0xc3 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 	{ 0xc46a, 0x30 }, { 0xc46d, 0x20 }, { 0xc464, 0x84 }, { 0xc465, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 	{ 0x6f00, 0x03 }, { 0x6f00, 0x43 }, { 0x381c, 0x00 }, { 0x381d, 0x40 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 	{ 0xc454, 0x01 }, { 0x6f00, 0xc3 }, { 0xc454, 0x00 }, { 0xc4b1, 0x02 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 	{ 0xc4b2, 0x01 }, { 0xc4b3, 0x03 }, { 0x6f00, 0x03 }, { 0x6f00, 0x43 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 	/* enable FSIN (FRAMESYNC input) functionality */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 	{ 0x3832, (0x0d + 2 * 0x20 + 0x15 + 38) >> 8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 	{ 0x3833, (0x0d + 2 * 0x20 + 0x15 + 38) & 0xff },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 	{ 0x3834, OV10635_VTS >> 8 }, { 0x3835, OV10635_VTS & 0xff },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 	{ 0x302e, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) struct rdacm20_device {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 	struct device			*dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 	struct max9271_device		*serializer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 	struct i2c_client		*sensor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 	struct v4l2_subdev		sd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 	struct media_pad		pad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 	struct v4l2_ctrl_handler	ctrls;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 	u32				addrs[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) static inline struct rdacm20_device *sd_to_rdacm20(struct v4l2_subdev *sd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 	return container_of(sd, struct rdacm20_device, sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) static inline struct rdacm20_device *i2c_to_rdacm20(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 	return sd_to_rdacm20(i2c_get_clientdata(client));
^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) static int ov10635_read16(struct rdacm20_device *dev, u16 reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 	u8 buf[2] = { reg >> 8, reg & 0xff };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 	ret = i2c_master_send(dev->sensor, buf, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 	if (ret != 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 		dev_dbg(dev->dev, "%s: register 0x%04x write failed (%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 			__func__, reg, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 	ret = i2c_master_recv(dev->sensor, buf, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 		dev_dbg(dev->dev, "%s: register 0x%04x read failed (%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 			__func__, reg, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 	return (buf[0] << 8) | buf[1];
^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) static int __ov10635_write(struct rdacm20_device *dev, u16 reg, u8 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 	u8 buf[3] = { reg >> 8, reg & 0xff, val };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 	dev_dbg(dev->dev, "%s(0x%04x, 0x%02x)\n", __func__, reg, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 	ret = i2c_master_send(dev->sensor, buf, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 	return ret < 0 ? ret : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) static int ov10635_write(struct rdacm20_device *dev, u16 reg, u8 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 	ret = __ov10635_write(dev, reg, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 		dev_err(dev->dev, "%s: register 0x%04x write failed (%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 			__func__, reg, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) static int ov10635_set_regs(struct rdacm20_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 			    const struct ov10635_reg *regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 			    unsigned int nr_regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 	unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 	for (i = 0; i < nr_regs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 		ret = __ov10635_write(dev, regs[i].reg, regs[i].val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 		if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 			dev_err(dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 				"%s: register %u (0x%04x) write failed (%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 				__func__, i, regs[i].reg, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) static int rdacm20_s_stream(struct v4l2_subdev *sd, int enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 	struct rdacm20_device *dev = sd_to_rdacm20(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 	return max9271_set_serial_link(dev->serializer, enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) static int rdacm20_enum_mbus_code(struct v4l2_subdev *sd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 				  struct v4l2_subdev_pad_config *cfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 				  struct v4l2_subdev_mbus_code_enum *code)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 	if (code->pad || code->index > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 	code->code = MEDIA_BUS_FMT_UYVY8_2X8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) static int rdacm20_get_fmt(struct v4l2_subdev *sd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 			   struct v4l2_subdev_pad_config *cfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 			   struct v4l2_subdev_format *format)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 	struct v4l2_mbus_framefmt *mf = &format->format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 	if (format->pad)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 	mf->width		= OV10635_WIDTH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 	mf->height		= OV10635_HEIGHT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 	mf->code		= MEDIA_BUS_FMT_UYVY8_2X8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 	mf->colorspace		= V4L2_COLORSPACE_RAW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 	mf->field		= V4L2_FIELD_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 	mf->ycbcr_enc		= V4L2_YCBCR_ENC_601;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 	mf->quantization	= V4L2_QUANTIZATION_FULL_RANGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 	mf->xfer_func		= V4L2_XFER_FUNC_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) static struct v4l2_subdev_video_ops rdacm20_video_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 	.s_stream	= rdacm20_s_stream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) static const struct v4l2_subdev_pad_ops rdacm20_subdev_pad_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 	.enum_mbus_code = rdacm20_enum_mbus_code,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 	.get_fmt	= rdacm20_get_fmt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 	.set_fmt	= rdacm20_get_fmt,
^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) static struct v4l2_subdev_ops rdacm20_subdev_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 	.video		= &rdacm20_video_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 	.pad		= &rdacm20_subdev_pad_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) static int rdacm20_initialize(struct rdacm20_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 	unsigned int retry = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 	/* Verify communication with the MAX9271: ping to wakeup. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 	dev->serializer->client->addr = MAX9271_DEFAULT_ADDR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 	i2c_smbus_read_byte(dev->serializer->client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 	/* Serial link disabled during config as it needs a valid pixel clock. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 	ret = max9271_set_serial_link(dev->serializer, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 	 *  Ensure that we have a good link configuration before attempting to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 	 *  identify the device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 	max9271_configure_i2c(dev->serializer, MAX9271_I2CSLVSH_469NS_234NS |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 					       MAX9271_I2CSLVTO_1024US |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 					       MAX9271_I2CMSTBT_105KBPS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 	max9271_configure_gmsl_link(dev->serializer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 	ret = max9271_verify_id(dev->serializer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 	if (ret < 0)
^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) 	ret = max9271_set_address(dev->serializer, dev->addrs[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 	dev->serializer->client->addr = dev->addrs[0];
^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) 	 * Reset the sensor by cycling the OV10635 reset signal connected to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 	 * MAX9271 GPIO1 and verify communication with the OV10635.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 	ret = max9271_enable_gpios(dev->serializer, MAX9271_GPIO1OUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 	ret = max9271_clear_gpios(dev->serializer, MAX9271_GPIO1OUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 	usleep_range(10000, 15000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 	ret = max9271_set_gpios(dev->serializer, MAX9271_GPIO1OUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 	usleep_range(10000, 15000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) again:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 	ret = ov10635_read16(dev, OV10635_PID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 		if (retry--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 			goto again;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 		dev_err(dev->dev, "OV10635 ID read failed (%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 			ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 		return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 	if (ret != OV10635_VERSION) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) 		if (retry--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 			goto again;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 		dev_err(dev->dev, "OV10635 ID mismatch (0x%04x)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 			ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 		return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) 	/* Change the sensor I2C address. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 	ret = ov10635_write(dev, OV10635_SC_CMMN_SCCB_ID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 			    (dev->addrs[1] << 1) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) 			    OV10635_SC_CMMN_SCCB_ID_SELECT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) 		dev_err(dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 			"OV10635 I2C address change failed (%d)\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) 	dev->sensor->addr = dev->addrs[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) 	usleep_range(3500, 5000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) 	/* Program the 0V10635 initial configuration. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) 	ret = ov10635_set_regs(dev, ov10635_regs_wizard,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) 			       ARRAY_SIZE(ov10635_regs_wizard));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) 	dev_info(dev->dev, "Identified MAX9271 + OV10635 device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) static int rdacm20_probe(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) 	struct rdacm20_device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) 	struct fwnode_handle *ep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) 	dev = devm_kzalloc(&client->dev, sizeof(*dev), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) 	if (!dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) 	dev->dev = &client->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) 	dev->serializer = devm_kzalloc(&client->dev, sizeof(*dev->serializer),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) 				       GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) 	if (!dev->serializer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) 	dev->serializer->client = client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) 	ret = of_property_read_u32_array(client->dev.of_node, "reg",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) 					 dev->addrs, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) 		dev_err(dev->dev, "Invalid DT reg property: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) 	/* Create the dummy I2C client for the sensor. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) 	dev->sensor = i2c_new_dummy_device(client->adapter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) 					   OV10635_I2C_ADDRESS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) 	if (IS_ERR(dev->sensor)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) 		ret = PTR_ERR(dev->sensor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) 	/* Initialize the hardware. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) 	ret = rdacm20_initialize(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) 	/* Initialize and register the subdevice. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) 	v4l2_i2c_subdev_init(&dev->sd, client, &rdacm20_subdev_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) 	dev->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) 	v4l2_ctrl_handler_init(&dev->ctrls, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) 	v4l2_ctrl_new_std(&dev->ctrls, NULL, V4L2_CID_PIXEL_RATE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) 			  OV10635_PIXEL_RATE, OV10635_PIXEL_RATE, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) 			  OV10635_PIXEL_RATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) 	dev->sd.ctrl_handler = &dev->ctrls;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) 	ret = dev->ctrls.error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) 		goto error_free_ctrls;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) 	dev->pad.flags = MEDIA_PAD_FL_SOURCE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) 	dev->sd.entity.flags |= MEDIA_ENT_F_CAM_SENSOR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) 	ret = media_entity_pads_init(&dev->sd.entity, 1, &dev->pad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) 		goto error_free_ctrls;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) 	ep = fwnode_graph_get_next_endpoint(dev_fwnode(&client->dev), NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) 	if (!ep) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) 		dev_err(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) 			"Unable to get endpoint in node %pOF\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) 			client->dev.of_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) 		ret = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) 		goto error_free_ctrls;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) 	dev->sd.fwnode = ep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) 	ret = v4l2_async_register_subdev(&dev->sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) 		goto error_put_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) error_put_node:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) 	fwnode_handle_put(ep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) error_free_ctrls:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) 	v4l2_ctrl_handler_free(&dev->ctrls);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) 	media_entity_cleanup(&dev->sd.entity);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) 	if (dev->sensor)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) 		i2c_unregister_device(dev->sensor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) 	dev_err(&client->dev, "probe failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) static int rdacm20_remove(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) 	struct rdacm20_device *dev = i2c_to_rdacm20(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) 	fwnode_handle_put(dev->sd.fwnode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) 	v4l2_async_unregister_subdev(&dev->sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) 	v4l2_ctrl_handler_free(&dev->ctrls);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) 	media_entity_cleanup(&dev->sd.entity);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) 	i2c_unregister_device(dev->sensor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) static void rdacm20_shutdown(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) 	struct rdacm20_device *dev = i2c_to_rdacm20(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) 	/* make sure stream off during shutdown (reset/reboot) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) 	rdacm20_s_stream(&dev->sd, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) static const struct of_device_id rdacm20_of_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) 	{ .compatible = "imi,rdacm20", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) 	{ }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) MODULE_DEVICE_TABLE(of, rdacm20_of_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) static struct i2c_driver rdacm20_i2c_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) 	.driver	= {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) 		.name	= "rdacm20",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) 		.of_match_table = rdacm20_of_ids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) 	.probe_new	= rdacm20_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) 	.remove		= rdacm20_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) 	.shutdown	= rdacm20_shutdown,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) module_i2c_driver(rdacm20_i2c_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) MODULE_DESCRIPTION("GMSL Camera driver for RDACM20");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) MODULE_AUTHOR("Vladimir Barinov");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) MODULE_LICENSE("GPL");