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)  * Driver for ST MIPID02 CSI-2 to PARALLEL bridge
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    5)  * Copyright (C) STMicroelectronics SA 2019
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    6)  * Authors: Mickael Guene <mickael.guene@st.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    7)  *          for STMicroelectronics.
^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)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   11) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   12) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   13) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   14) #include <linux/gpio/consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   15) #include <linux/i2c.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   16) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   17) #include <linux/of_graph.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   18) #include <linux/regulator/consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   19) #include <media/v4l2-async.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   20) #include <media/v4l2-ctrls.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   21) #include <media/v4l2-device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   22) #include <media/v4l2-fwnode.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   23) #include <media/v4l2-subdev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   24) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   25) #define MIPID02_CLK_LANE_WR_REG1			0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   26) #define MIPID02_CLK_LANE_REG1				0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   27) #define MIPID02_CLK_LANE_REG3				0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   28) #define MIPID02_DATA_LANE0_REG1				0x05
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   29) #define MIPID02_DATA_LANE0_REG2				0x06
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   30) #define MIPID02_DATA_LANE1_REG1				0x09
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   31) #define MIPID02_DATA_LANE1_REG2				0x0a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   32) #define MIPID02_MODE_REG1				0x14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   33) #define MIPID02_MODE_REG2				0x15
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   34) #define MIPID02_DATA_ID_RREG				0x17
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   35) #define MIPID02_DATA_SELECTION_CTRL			0x19
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   36) #define MIPID02_PIX_WIDTH_CTRL				0x1e
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   37) #define MIPID02_PIX_WIDTH_CTRL_EMB			0x1f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   38) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   39) /* Bits definition for MIPID02_CLK_LANE_REG1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   40) #define CLK_ENABLE					BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   41) /* Bits definition for MIPID02_CLK_LANE_REG3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   42) #define CLK_MIPI_CSI					BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   43) /* Bits definition for MIPID02_DATA_LANE0_REG1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   44) #define DATA_ENABLE					BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   45) /* Bits definition for MIPID02_DATA_LANEx_REG2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   46) #define DATA_MIPI_CSI					BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   47) /* Bits definition for MIPID02_MODE_REG1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   48) #define MODE_DATA_SWAP					BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   49) #define MODE_NO_BYPASS					BIT(6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   50) /* Bits definition for MIPID02_MODE_REG2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   51) #define MODE_HSYNC_ACTIVE_HIGH				BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   52) #define MODE_VSYNC_ACTIVE_HIGH				BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   53) /* Bits definition for MIPID02_DATA_SELECTION_CTRL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   54) #define SELECTION_MANUAL_DATA				BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   55) #define SELECTION_MANUAL_WIDTH				BIT(3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   56) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   57) static const u32 mipid02_supported_fmt_codes[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   58) 	MEDIA_BUS_FMT_SBGGR8_1X8, MEDIA_BUS_FMT_SGBRG8_1X8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   59) 	MEDIA_BUS_FMT_SGRBG8_1X8, MEDIA_BUS_FMT_SRGGB8_1X8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   60) 	MEDIA_BUS_FMT_SBGGR10_1X10, MEDIA_BUS_FMT_SGBRG10_1X10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   61) 	MEDIA_BUS_FMT_SGRBG10_1X10, MEDIA_BUS_FMT_SRGGB10_1X10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   62) 	MEDIA_BUS_FMT_SBGGR12_1X12, MEDIA_BUS_FMT_SGBRG12_1X12,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   63) 	MEDIA_BUS_FMT_SGRBG12_1X12, MEDIA_BUS_FMT_SRGGB12_1X12,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   64) 	MEDIA_BUS_FMT_UYVY8_1X16, MEDIA_BUS_FMT_BGR888_1X24,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   65) 	MEDIA_BUS_FMT_RGB565_2X8_LE, MEDIA_BUS_FMT_RGB565_2X8_BE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   66) 	MEDIA_BUS_FMT_YUYV8_2X8, MEDIA_BUS_FMT_UYVY8_2X8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   67) 	MEDIA_BUS_FMT_JPEG_1X8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   68) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   69) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   70) /* regulator supplies */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   71) static const char * const mipid02_supply_name[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   72) 	"VDDE", /* 1.8V digital I/O supply */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73) 	"VDDIN", /* 1V8 voltage regulator supply */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76) #define MIPID02_NUM_SUPPLIES		ARRAY_SIZE(mipid02_supply_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78) #define MIPID02_SINK_0			0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79) #define MIPID02_SINK_1			1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   80) #define MIPID02_SOURCE			2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   81) #define MIPID02_PAD_NB			3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   82) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   83) struct mipid02_dev {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84) 	struct i2c_client *i2c_client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85) 	struct regulator_bulk_data supplies[MIPID02_NUM_SUPPLIES];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86) 	struct v4l2_subdev sd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87) 	struct media_pad pad[MIPID02_PAD_NB];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88) 	struct clk *xclk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89) 	struct gpio_desc *reset_gpio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90) 	/* endpoints info */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91) 	struct v4l2_fwnode_endpoint rx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92) 	u64 link_frequency;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93) 	struct v4l2_fwnode_endpoint tx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94) 	/* remote source */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   95) 	struct v4l2_async_subdev asd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   96) 	struct v4l2_async_notifier notifier;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   97) 	struct v4l2_subdev *s_subdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98) 	/* registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99) 	struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100) 		u8 clk_lane_reg1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101) 		u8 data_lane0_reg1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102) 		u8 data_lane1_reg1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  103) 		u8 mode_reg1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  104) 		u8 mode_reg2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  105) 		u8 data_selection_ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  106) 		u8 data_id_rreg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  107) 		u8 pix_width_ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  108) 		u8 pix_width_ctrl_emb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  109) 	} r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  110) 	/* lock to protect all members below */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  111) 	struct mutex lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  112) 	bool streaming;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113) 	struct v4l2_mbus_framefmt fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116) static int bpp_from_code(__u32 code)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  117) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  118) 	switch (code) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  119) 	case MEDIA_BUS_FMT_SBGGR8_1X8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120) 	case MEDIA_BUS_FMT_SGBRG8_1X8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121) 	case MEDIA_BUS_FMT_SGRBG8_1X8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122) 	case MEDIA_BUS_FMT_SRGGB8_1X8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123) 		return 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124) 	case MEDIA_BUS_FMT_SBGGR10_1X10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125) 	case MEDIA_BUS_FMT_SGBRG10_1X10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  126) 	case MEDIA_BUS_FMT_SGRBG10_1X10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  127) 	case MEDIA_BUS_FMT_SRGGB10_1X10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  128) 		return 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129) 	case MEDIA_BUS_FMT_SBGGR12_1X12:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130) 	case MEDIA_BUS_FMT_SGBRG12_1X12:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131) 	case MEDIA_BUS_FMT_SGRBG12_1X12:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132) 	case MEDIA_BUS_FMT_SRGGB12_1X12:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133) 		return 12;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134) 	case MEDIA_BUS_FMT_UYVY8_1X16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135) 	case MEDIA_BUS_FMT_YUYV8_2X8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  136) 	case MEDIA_BUS_FMT_UYVY8_2X8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  137) 	case MEDIA_BUS_FMT_RGB565_2X8_LE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  138) 	case MEDIA_BUS_FMT_RGB565_2X8_BE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  139) 		return 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  140) 	case MEDIA_BUS_FMT_BGR888_1X24:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  141) 		return 24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  142) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147) static u8 data_type_from_code(__u32 code)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  148) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  149) 	switch (code) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  150) 	case MEDIA_BUS_FMT_SBGGR8_1X8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151) 	case MEDIA_BUS_FMT_SGBRG8_1X8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  152) 	case MEDIA_BUS_FMT_SGRBG8_1X8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  153) 	case MEDIA_BUS_FMT_SRGGB8_1X8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  154) 		return 0x2a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  155) 	case MEDIA_BUS_FMT_SBGGR10_1X10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  156) 	case MEDIA_BUS_FMT_SGBRG10_1X10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  157) 	case MEDIA_BUS_FMT_SGRBG10_1X10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  158) 	case MEDIA_BUS_FMT_SRGGB10_1X10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  159) 		return 0x2b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  160) 	case MEDIA_BUS_FMT_SBGGR12_1X12:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  161) 	case MEDIA_BUS_FMT_SGBRG12_1X12:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  162) 	case MEDIA_BUS_FMT_SGRBG12_1X12:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  163) 	case MEDIA_BUS_FMT_SRGGB12_1X12:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  164) 		return 0x2c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  165) 	case MEDIA_BUS_FMT_UYVY8_1X16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  166) 	case MEDIA_BUS_FMT_YUYV8_2X8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  167) 	case MEDIA_BUS_FMT_UYVY8_2X8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  168) 		return 0x1e;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  169) 	case MEDIA_BUS_FMT_BGR888_1X24:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  170) 		return 0x24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  171) 	case MEDIA_BUS_FMT_RGB565_2X8_LE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  172) 	case MEDIA_BUS_FMT_RGB565_2X8_BE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  173) 		return 0x22;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  176) 	}
^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 void init_format(struct v4l2_mbus_framefmt *fmt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  181) 	fmt->code = MEDIA_BUS_FMT_SBGGR8_1X8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  182) 	fmt->field = V4L2_FIELD_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  183) 	fmt->colorspace = V4L2_COLORSPACE_SRGB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184) 	fmt->ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(V4L2_COLORSPACE_SRGB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  185) 	fmt->quantization = V4L2_QUANTIZATION_FULL_RANGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  186) 	fmt->xfer_func = V4L2_MAP_XFER_FUNC_DEFAULT(V4L2_COLORSPACE_SRGB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  187) 	fmt->width = 640;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  188) 	fmt->height = 480;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  189) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  191) static __u32 get_fmt_code(__u32 code)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  192) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  193) 	unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195) 	for (i = 0; i < ARRAY_SIZE(mipid02_supported_fmt_codes); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196) 		if (code == mipid02_supported_fmt_codes[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197) 			return code;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  200) 	return mipid02_supported_fmt_codes[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  201) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  202) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  203) static __u32 serial_to_parallel_code(__u32 serial)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  204) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  205) 	if (serial == MEDIA_BUS_FMT_UYVY8_1X16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206) 		return MEDIA_BUS_FMT_UYVY8_2X8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207) 	if (serial == MEDIA_BUS_FMT_BGR888_1X24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208) 		return MEDIA_BUS_FMT_BGR888_3X8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210) 	return serial;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213) static inline struct mipid02_dev *to_mipid02_dev(struct v4l2_subdev *sd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  215) 	return container_of(sd, struct mipid02_dev, sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  216) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  217) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218) static int mipid02_read_reg(struct mipid02_dev *bridge, u16 reg, u8 *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  220) 	struct i2c_client *client = bridge->i2c_client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  221) 	struct i2c_msg msg[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  222) 	u8 buf[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225) 	buf[0] = reg >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  226) 	buf[1] = reg & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  227) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  228) 	msg[0].addr = client->addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229) 	msg[0].flags = client->flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230) 	msg[0].buf = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231) 	msg[0].len = sizeof(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233) 	msg[1].addr = client->addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  234) 	msg[1].flags = client->flags | I2C_M_RD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  235) 	msg[1].buf = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  236) 	msg[1].len = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  237) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  238) 	ret = i2c_transfer(client->adapter, msg, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  239) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  240) 		dev_dbg(&client->dev, "%s: %x i2c_transfer, reg: %x => %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  241) 			    __func__, client->addr, reg, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  242) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  243) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248) static int mipid02_write_reg(struct mipid02_dev *bridge, u16 reg, u8 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  250) 	struct i2c_client *client = bridge->i2c_client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  251) 	struct i2c_msg msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  252) 	u8 buf[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255) 	buf[0] = reg >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  256) 	buf[1] = reg & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  257) 	buf[2] = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  258) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259) 	msg.addr = client->addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260) 	msg.flags = client->flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261) 	msg.buf = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  262) 	msg.len = sizeof(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  263) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  264) 	ret = i2c_transfer(client->adapter, &msg, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  265) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  266) 		dev_dbg(&client->dev, "%s: i2c_transfer, reg: %x => %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267) 			    __func__, reg, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  269) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  270) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  271) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  272) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  273) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  274) static int mipid02_get_regulators(struct mipid02_dev *bridge)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  275) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  276) 	unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  277) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  278) 	for (i = 0; i < MIPID02_NUM_SUPPLIES; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  279) 		bridge->supplies[i].supply = mipid02_supply_name[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  280) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281) 	return devm_regulator_bulk_get(&bridge->i2c_client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282) 				       MIPID02_NUM_SUPPLIES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283) 				       bridge->supplies);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  286) static void mipid02_apply_reset(struct mipid02_dev *bridge)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  287) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  288) 	gpiod_set_value_cansleep(bridge->reset_gpio, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  289) 	usleep_range(5000, 10000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  290) 	gpiod_set_value_cansleep(bridge->reset_gpio, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291) 	usleep_range(5000, 10000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  292) 	gpiod_set_value_cansleep(bridge->reset_gpio, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  293) 	usleep_range(5000, 10000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  294) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  295) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  296) static int mipid02_set_power_on(struct mipid02_dev *bridge)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  297) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  298) 	struct i2c_client *client = bridge->i2c_client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301) 	ret = clk_prepare_enable(bridge->xclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  302) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  303) 		dev_err(&client->dev, "%s: failed to enable clock\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  304) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  305) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  306) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  307) 	ret = regulator_bulk_enable(MIPID02_NUM_SUPPLIES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308) 				    bridge->supplies);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310) 		dev_err(&client->dev, "%s: failed to enable regulators\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311) 			    __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312) 		goto xclk_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  313) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  314) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  315) 	if (bridge->reset_gpio) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  316) 		dev_dbg(&client->dev, "apply reset");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  317) 		mipid02_apply_reset(bridge);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  318) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319) 		dev_dbg(&client->dev, "don't apply reset");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  320) 		usleep_range(5000, 10000);
^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) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325) xclk_off:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326) 	clk_disable_unprepare(bridge->xclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  328) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  329) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  330) static void mipid02_set_power_off(struct mipid02_dev *bridge)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  331) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  332) 	regulator_bulk_disable(MIPID02_NUM_SUPPLIES, bridge->supplies);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  333) 	clk_disable_unprepare(bridge->xclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  334) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  335) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  336) static int mipid02_detect(struct mipid02_dev *bridge)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338) 	u8 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341) 	 * There is no version registers. Just try to read register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342) 	 * MIPID02_CLK_LANE_WR_REG1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344) 	return mipid02_read_reg(bridge, MIPID02_CLK_LANE_WR_REG1, &reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  345) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  346) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  347) static u32 mipid02_get_link_freq_from_cid_link_freq(struct mipid02_dev *bridge,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  348) 						    struct v4l2_subdev *subdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  349) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  350) 	struct v4l2_querymenu qm = {.id = V4L2_CID_LINK_FREQ, };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  351) 	struct v4l2_ctrl *ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  352) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  353) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354) 	ctrl = v4l2_ctrl_find(subdev->ctrl_handler, V4L2_CID_LINK_FREQ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355) 	if (!ctrl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  357) 	qm.index = v4l2_ctrl_g_ctrl(ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  358) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  359) 	ret = v4l2_querymenu(subdev->ctrl_handler, &qm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  360) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  361) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  362) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  363) 	return qm.value;
^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 u32 mipid02_get_link_freq_from_cid_pixel_rate(struct mipid02_dev *bridge,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367) 						     struct v4l2_subdev *subdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  369) 	struct v4l2_fwnode_endpoint *ep = &bridge->rx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  370) 	struct v4l2_ctrl *ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  371) 	u32 pixel_clock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  372) 	u32 bpp = bpp_from_code(bridge->fmt.code);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374) 	ctrl = v4l2_ctrl_find(subdev->ctrl_handler, V4L2_CID_PIXEL_RATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375) 	if (!ctrl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  377) 	pixel_clock = v4l2_ctrl_g_ctrl_int64(ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  378) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  379) 	return pixel_clock * bpp / (2 * ep->bus.mipi_csi2.num_data_lanes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383)  * We need to know link frequency to setup clk_lane_reg1 timings. Link frequency
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384)  * will be computed using connected device V4L2_CID_PIXEL_RATE, bit per pixel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385)  * and number of lanes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387) static int mipid02_configure_from_rx_speed(struct mipid02_dev *bridge)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389) 	struct i2c_client *client = bridge->i2c_client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390) 	struct v4l2_subdev *subdev = bridge->s_subdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391) 	u32 link_freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393) 	link_freq = mipid02_get_link_freq_from_cid_link_freq(bridge, subdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394) 	if (!link_freq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395) 		link_freq = mipid02_get_link_freq_from_cid_pixel_rate(bridge,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396) 								      subdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397) 		if (!link_freq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  398) 			dev_err(&client->dev, "Failed to get link frequency");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  399) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  400) 		}
^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) 	dev_dbg(&client->dev, "detect link_freq = %d Hz", link_freq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  404) 	bridge->r.clk_lane_reg1 |= (2000000000 / link_freq) << 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  408) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  409) static int mipid02_configure_clk_lane(struct mipid02_dev *bridge)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  410) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  411) 	struct i2c_client *client = bridge->i2c_client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  412) 	struct v4l2_fwnode_endpoint *ep = &bridge->rx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413) 	bool *polarities = ep->bus.mipi_csi2.lane_polarities;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  414) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  415) 	/* midid02 doesn't support clock lane remapping */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  416) 	if (ep->bus.mipi_csi2.clock_lane != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  417) 		dev_err(&client->dev, "clk lane must be map to lane 0\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  418) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  419) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  420) 	bridge->r.clk_lane_reg1 |= (polarities[0] << 1) | CLK_ENABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425) static int mipid02_configure_data0_lane(struct mipid02_dev *bridge, int nb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426) 					bool are_lanes_swap, bool *polarities)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428) 	bool are_pin_swap = are_lanes_swap ? polarities[2] : polarities[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430) 	if (nb == 1 && are_lanes_swap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434) 	 * data lane 0 as pin swap polarity reversed compared to clock and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  435) 	 * data lane 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  436) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  437) 	if (!are_pin_swap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  438) 		bridge->r.data_lane0_reg1 = 1 << 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  439) 	bridge->r.data_lane0_reg1 |= DATA_ENABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  440) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  441) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  442) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  443) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  444) static int mipid02_configure_data1_lane(struct mipid02_dev *bridge, int nb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  445) 					bool are_lanes_swap, bool *polarities)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  446) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  447) 	bool are_pin_swap = are_lanes_swap ? polarities[1] : polarities[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  448) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  449) 	if (nb == 1 && !are_lanes_swap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  450) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452) 	if (are_pin_swap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453) 		bridge->r.data_lane1_reg1 = 1 << 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  454) 	bridge->r.data_lane1_reg1 |= DATA_ENABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  455) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  456) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  457) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  458) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  459) static int mipid02_configure_from_rx(struct mipid02_dev *bridge)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  460) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461) 	struct v4l2_fwnode_endpoint *ep = &bridge->rx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462) 	bool are_lanes_swap = ep->bus.mipi_csi2.data_lanes[0] == 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463) 	bool *polarities = ep->bus.mipi_csi2.lane_polarities;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464) 	int nb = ep->bus.mipi_csi2.num_data_lanes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467) 	ret = mipid02_configure_clk_lane(bridge);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  470) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  471) 	ret = mipid02_configure_data0_lane(bridge, nb, are_lanes_swap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  472) 					   polarities);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476) 	ret = mipid02_configure_data1_lane(bridge, nb, are_lanes_swap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477) 					   polarities);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478) 	if (ret)
^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) 	bridge->r.mode_reg1 |= are_lanes_swap ? MODE_DATA_SWAP : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482) 	bridge->r.mode_reg1 |= (nb - 1) << 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  484) 	return mipid02_configure_from_rx_speed(bridge);
^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 mipid02_configure_from_tx(struct mipid02_dev *bridge)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  488) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  489) 	struct v4l2_fwnode_endpoint *ep = &bridge->tx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  490) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  491) 	bridge->r.data_selection_ctrl = SELECTION_MANUAL_WIDTH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  492) 	bridge->r.pix_width_ctrl = ep->bus.parallel.bus_width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  493) 	bridge->r.pix_width_ctrl_emb = ep->bus.parallel.bus_width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494) 	if (ep->bus.parallel.flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  495) 		bridge->r.mode_reg2 |= MODE_HSYNC_ACTIVE_HIGH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  496) 	if (ep->bus.parallel.flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  497) 		bridge->r.mode_reg2 |= MODE_VSYNC_ACTIVE_HIGH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  498) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502) static int mipid02_configure_from_code(struct mipid02_dev *bridge)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504) 	u8 data_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  506) 	bridge->r.data_id_rreg = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  507) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  508) 	if (bridge->fmt.code != MEDIA_BUS_FMT_JPEG_1X8) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  509) 		bridge->r.data_selection_ctrl |= SELECTION_MANUAL_DATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  510) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511) 		data_type = data_type_from_code(bridge->fmt.code);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512) 		if (!data_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514) 		bridge->r.data_id_rreg = data_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  520) static int mipid02_stream_disable(struct mipid02_dev *bridge)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  521) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  522) 	struct i2c_client *client = bridge->i2c_client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  525) 	/* Disable all lanes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  526) 	ret = mipid02_write_reg(bridge, MIPID02_CLK_LANE_REG1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  527) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  528) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  529) 	ret = mipid02_write_reg(bridge, MIPID02_DATA_LANE0_REG1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  530) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  531) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  532) 	ret = mipid02_write_reg(bridge, MIPID02_DATA_LANE1_REG1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  533) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  534) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537) 		dev_err(&client->dev, "failed to stream off %d", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  538) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  539) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  540) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542) static int mipid02_stream_enable(struct mipid02_dev *bridge)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544) 	struct i2c_client *client = bridge->i2c_client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545) 	int ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  546) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  547) 	if (!bridge->s_subdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  548) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  550) 	memset(&bridge->r, 0, sizeof(bridge->r));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  551) 	/* build registers content */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  552) 	ret = mipid02_configure_from_rx(bridge);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555) 	ret = mipid02_configure_from_tx(bridge);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  556) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  557) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  558) 	ret = mipid02_configure_from_code(bridge);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  560) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  561) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  562) 	/* write mipi registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563) 	ret = mipid02_write_reg(bridge, MIPID02_CLK_LANE_REG1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564) 		bridge->r.clk_lane_reg1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567) 	ret = mipid02_write_reg(bridge, MIPID02_CLK_LANE_REG3, CLK_MIPI_CSI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  569) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  570) 	ret = mipid02_write_reg(bridge, MIPID02_DATA_LANE0_REG1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  571) 		bridge->r.data_lane0_reg1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  572) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  573) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574) 	ret = mipid02_write_reg(bridge, MIPID02_DATA_LANE0_REG2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  575) 		DATA_MIPI_CSI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  576) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  577) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578) 	ret = mipid02_write_reg(bridge, MIPID02_DATA_LANE1_REG1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579) 		bridge->r.data_lane1_reg1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  580) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  581) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  582) 	ret = mipid02_write_reg(bridge, MIPID02_DATA_LANE1_REG2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583) 		DATA_MIPI_CSI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586) 	ret = mipid02_write_reg(bridge, MIPID02_MODE_REG1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587) 		MODE_NO_BYPASS | bridge->r.mode_reg1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  590) 	ret = mipid02_write_reg(bridge, MIPID02_MODE_REG2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  591) 		bridge->r.mode_reg2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  592) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  593) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  594) 	ret = mipid02_write_reg(bridge, MIPID02_DATA_ID_RREG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595) 		bridge->r.data_id_rreg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  596) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  597) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  598) 	ret = mipid02_write_reg(bridge, MIPID02_DATA_SELECTION_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  599) 		bridge->r.data_selection_ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  600) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  601) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602) 	ret = mipid02_write_reg(bridge, MIPID02_PIX_WIDTH_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603) 		bridge->r.pix_width_ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  606) 	ret = mipid02_write_reg(bridge, MIPID02_PIX_WIDTH_CTRL_EMB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  607) 		bridge->r.pix_width_ctrl_emb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  608) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  609) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  610) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  611) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  613) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  614) 	dev_err(&client->dev, "failed to stream on %d", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  615) 	mipid02_stream_disable(bridge);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  619) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  620) static int mipid02_s_stream(struct v4l2_subdev *sd, int enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  621) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  622) 	struct mipid02_dev *bridge = to_mipid02_dev(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  623) 	struct i2c_client *client = bridge->i2c_client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  624) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  625) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  626) 	dev_dbg(&client->dev, "%s : requested %d / current = %d", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  627) 		    enable, bridge->streaming);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  628) 	mutex_lock(&bridge->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  629) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630) 	if (bridge->streaming == enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633) 	ret = enable ? mipid02_stream_enable(bridge) :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634) 		       mipid02_stream_disable(bridge);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635) 	if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636) 		bridge->streaming = enable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  638) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  639) 	dev_dbg(&client->dev, "%s current now = %d / %d", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  640) 		    bridge->streaming, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  641) 	mutex_unlock(&bridge->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  643) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  644) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  645) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  646) static int mipid02_enum_mbus_code(struct v4l2_subdev *sd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  647) 				 struct v4l2_subdev_pad_config *cfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  648) 				 struct v4l2_subdev_mbus_code_enum *code)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650) 	struct mipid02_dev *bridge = to_mipid02_dev(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653) 	switch (code->pad) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654) 	case MIPID02_SINK_0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655) 		if (code->index >= ARRAY_SIZE(mipid02_supported_fmt_codes))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656) 			ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  657) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  658) 			code->code = mipid02_supported_fmt_codes[code->index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  659) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660) 	case MIPID02_SOURCE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661) 		if (code->index == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662) 			code->code = serial_to_parallel_code(bridge->fmt.code);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664) 			ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  666) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  667) 		ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  668) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  670) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  671) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  672) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673) static int mipid02_get_fmt(struct v4l2_subdev *sd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674) 			   struct v4l2_subdev_pad_config *cfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675) 			   struct v4l2_subdev_format *format)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677) 	struct v4l2_mbus_framefmt *mbus_fmt = &format->format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678) 	struct mipid02_dev *bridge = to_mipid02_dev(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679) 	struct i2c_client *client = bridge->i2c_client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680) 	struct v4l2_mbus_framefmt *fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682) 	dev_dbg(&client->dev, "%s probe %d", __func__, format->pad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684) 	if (format->pad >= MIPID02_PAD_NB)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686) 	/* second CSI-2 pad not yet supported */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687) 	if (format->pad == MIPID02_SINK_1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690) 	if (format->which == V4L2_SUBDEV_FORMAT_TRY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691) 		fmt = v4l2_subdev_get_try_format(&bridge->sd, cfg, format->pad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693) 		fmt = &bridge->fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695) 	mutex_lock(&bridge->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697) 	*mbus_fmt = *fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698) 	/* code may need to be converted for source */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699) 	if (format->pad == MIPID02_SOURCE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700) 		mbus_fmt->code = serial_to_parallel_code(mbus_fmt->code);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  702) 	mutex_unlock(&bridge->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  703) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  704) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707) static void mipid02_set_fmt_source(struct v4l2_subdev *sd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708) 				   struct v4l2_subdev_pad_config *cfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709) 				   struct v4l2_subdev_format *format)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711) 	struct mipid02_dev *bridge = to_mipid02_dev(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  712) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  713) 	/* source pad mirror active sink pad */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  714) 	format->format = bridge->fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  715) 	/* but code may need to be converted */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716) 	format->format.code = serial_to_parallel_code(format->format.code);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718) 	/* only apply format for V4L2_SUBDEV_FORMAT_TRY case */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  719) 	if (format->which != V4L2_SUBDEV_FORMAT_TRY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  720) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  721) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722) 	*v4l2_subdev_get_try_format(sd, cfg, format->pad) = format->format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  724) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  725) static void mipid02_set_fmt_sink(struct v4l2_subdev *sd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  726) 				 struct v4l2_subdev_pad_config *cfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727) 				 struct v4l2_subdev_format *format)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729) 	struct mipid02_dev *bridge = to_mipid02_dev(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730) 	struct v4l2_mbus_framefmt *fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732) 	format->format.code = get_fmt_code(format->format.code);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734) 	if (format->which == V4L2_SUBDEV_FORMAT_TRY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  735) 		fmt = v4l2_subdev_get_try_format(sd, cfg, format->pad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  736) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  737) 		fmt = &bridge->fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739) 	*fmt = format->format;
^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) static int mipid02_set_fmt(struct v4l2_subdev *sd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743) 			   struct v4l2_subdev_pad_config *cfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744) 			   struct v4l2_subdev_format *format)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746) 	struct mipid02_dev *bridge = to_mipid02_dev(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747) 	struct i2c_client *client = bridge->i2c_client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750) 	dev_dbg(&client->dev, "%s for %d", __func__, format->pad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752) 	if (format->pad >= MIPID02_PAD_NB)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754) 	/* second CSI-2 pad not yet supported */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755) 	if (format->pad == MIPID02_SINK_1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758) 	mutex_lock(&bridge->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760) 	if (bridge->streaming) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761) 		ret = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765) 	if (format->pad == MIPID02_SOURCE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766) 		mipid02_set_fmt_source(sd, cfg, format);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768) 		mipid02_set_fmt_sink(sd, cfg, format);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771) 	mutex_unlock(&bridge->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  775) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  776) static const struct v4l2_subdev_video_ops mipid02_video_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  777) 	.s_stream = mipid02_s_stream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  778) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  779) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  780) static const struct v4l2_subdev_pad_ops mipid02_pad_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  781) 	.enum_mbus_code = mipid02_enum_mbus_code,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  782) 	.get_fmt = mipid02_get_fmt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783) 	.set_fmt = mipid02_set_fmt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  785) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  786) static const struct v4l2_subdev_ops mipid02_subdev_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  787) 	.video = &mipid02_video_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  788) 	.pad = &mipid02_pad_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  789) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791) static const struct media_entity_operations mipid02_subdev_entity_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792) 	.link_validate = v4l2_subdev_link_validate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795) static int mipid02_async_bound(struct v4l2_async_notifier *notifier,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796) 			       struct v4l2_subdev *s_subdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  797) 			       struct v4l2_async_subdev *asd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  798) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  799) 	struct mipid02_dev *bridge = to_mipid02_dev(notifier->sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  800) 	struct i2c_client *client = bridge->i2c_client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  801) 	int source_pad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804) 	dev_dbg(&client->dev, "sensor_async_bound call %p", s_subdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806) 	source_pad = media_entity_get_fwnode_pad(&s_subdev->entity,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807) 						 s_subdev->fwnode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  808) 						 MEDIA_PAD_FL_SOURCE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  809) 	if (source_pad < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  810) 		dev_err(&client->dev, "Couldn't find output pad for subdev %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811) 			s_subdev->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812) 		return source_pad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  815) 	ret = media_create_pad_link(&s_subdev->entity, source_pad,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  816) 				    &bridge->sd.entity, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  817) 				    MEDIA_LNK_FL_ENABLED |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818) 				    MEDIA_LNK_FL_IMMUTABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820) 		dev_err(&client->dev, "Couldn't create media link %d", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  821) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  822) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  823) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  824) 	bridge->s_subdev = s_subdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  825) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  826) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  827) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  828) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829) static void mipid02_async_unbind(struct v4l2_async_notifier *notifier,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830) 				 struct v4l2_subdev *s_subdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831) 				 struct v4l2_async_subdev *asd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833) 	struct mipid02_dev *bridge = to_mipid02_dev(notifier->sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835) 	bridge->s_subdev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838) static const struct v4l2_async_notifier_operations mipid02_notifier_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839) 	.bound		= mipid02_async_bound,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840) 	.unbind		= mipid02_async_unbind,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843) static int mipid02_parse_rx_ep(struct mipid02_dev *bridge)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845) 	struct v4l2_fwnode_endpoint ep = { .bus_type = V4L2_MBUS_CSI2_DPHY };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846) 	struct i2c_client *client = bridge->i2c_client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  847) 	struct device_node *ep_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  848) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  849) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850) 	/* parse rx (endpoint 0) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851) 	ep_node = of_graph_get_endpoint_by_regs(bridge->i2c_client->dev.of_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852) 						0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  853) 	if (!ep_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  854) 		dev_err(&client->dev, "unable to find port0 ep");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  855) 		ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  856) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  857) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  858) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  859) 	ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(ep_node), &ep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861) 		dev_err(&client->dev, "Could not parse v4l2 endpoint %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862) 			ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863) 		goto error_of_node_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866) 	/* do some sanity checks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867) 	if (ep.bus.mipi_csi2.num_data_lanes > 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868) 		dev_err(&client->dev, "max supported data lanes is 2 / got %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869) 			ep.bus.mipi_csi2.num_data_lanes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870) 		ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871) 		goto error_of_node_put;
^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) 	/* register it for later use */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  875) 	bridge->rx = ep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  876) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  877) 	/* register async notifier so we get noticed when sensor is connected */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  878) 	bridge->asd.match.fwnode =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  879) 		fwnode_graph_get_remote_port_parent(of_fwnode_handle(ep_node));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  880) 	bridge->asd.match_type = V4L2_ASYNC_MATCH_FWNODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  881) 	of_node_put(ep_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883) 	v4l2_async_notifier_init(&bridge->notifier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884) 	ret = v4l2_async_notifier_add_subdev(&bridge->notifier, &bridge->asd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886) 		dev_err(&client->dev, "fail to register asd to notifier %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887) 			ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888) 		fwnode_handle_put(bridge->asd.match.fwnode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891) 	bridge->notifier.ops = &mipid02_notifier_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  893) 	ret = v4l2_async_subdev_notifier_register(&bridge->sd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  894) 						  &bridge->notifier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  895) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896) 		v4l2_async_notifier_cleanup(&bridge->notifier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  899) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  900) error_of_node_put:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  901) 	of_node_put(ep_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  902) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  903) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  904) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  905) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907) static int mipid02_parse_tx_ep(struct mipid02_dev *bridge)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909) 	struct v4l2_fwnode_endpoint ep = { .bus_type = V4L2_MBUS_PARALLEL };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910) 	struct i2c_client *client = bridge->i2c_client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  911) 	struct device_node *ep_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  912) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  913) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914) 	/* parse tx (endpoint 2) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915) 	ep_node = of_graph_get_endpoint_by_regs(bridge->i2c_client->dev.of_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  916) 						2, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  917) 	if (!ep_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  918) 		dev_err(&client->dev, "unable to find port1 ep");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  919) 		ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  920) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923) 	ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(ep_node), &ep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925) 		dev_err(&client->dev, "Could not parse v4l2 endpoint\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926) 		goto error_of_node_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929) 	of_node_put(ep_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930) 	bridge->tx = ep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  931) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  932) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  933) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934) error_of_node_put:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935) 	of_node_put(ep_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938) 	return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941) static int mipid02_probe(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943) 	struct device *dev = &client->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944) 	struct mipid02_dev *bridge;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  945) 	u32 clk_freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  946) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  947) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948) 	bridge = devm_kzalloc(dev, sizeof(*bridge), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949) 	if (!bridge)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  950) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  951) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  952) 	init_format(&bridge->fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  953) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  954) 	bridge->i2c_client = client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  955) 	v4l2_i2c_subdev_init(&bridge->sd, client, &mipid02_subdev_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957) 	/* got and check clock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958) 	bridge->xclk = devm_clk_get(dev, "xclk");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959) 	if (IS_ERR(bridge->xclk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960) 		dev_err(dev, "failed to get xclk\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961) 		return PTR_ERR(bridge->xclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964) 	clk_freq = clk_get_rate(bridge->xclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965) 	if (clk_freq < 6000000 || clk_freq > 27000000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966) 		dev_err(dev, "xclk freq must be in 6-27 Mhz range. got %d Hz\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967) 			clk_freq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  969) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  970) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  971) 	bridge->reset_gpio = devm_gpiod_get_optional(dev, "reset",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972) 						     GPIOD_OUT_HIGH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974) 	if (IS_ERR(bridge->reset_gpio)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975) 		dev_err(dev, "failed to get reset GPIO\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976) 		return PTR_ERR(bridge->reset_gpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  977) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  978) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  979) 	ret = mipid02_get_regulators(bridge);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981) 		dev_err(dev, "failed to get regulators %d", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985) 	mutex_init(&bridge->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986) 	bridge->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987) 	bridge->sd.entity.function = MEDIA_ENT_F_VID_IF_BRIDGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988) 	bridge->sd.entity.ops = &mipid02_subdev_entity_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989) 	bridge->pad[0].flags = MEDIA_PAD_FL_SINK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990) 	bridge->pad[1].flags = MEDIA_PAD_FL_SINK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991) 	bridge->pad[2].flags = MEDIA_PAD_FL_SOURCE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992) 	ret = media_entity_pads_init(&bridge->sd.entity, MIPID02_PAD_NB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993) 				     bridge->pad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995) 		dev_err(&client->dev, "pads init failed %d", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996) 		goto mutex_cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  999) 	/* enable clock, power and reset device if available */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) 	ret = mipid02_set_power_on(bridge);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) 		goto entity_cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) 	ret = mipid02_detect(bridge);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) 		dev_err(&client->dev, "failed to detect mipid02 %d", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) 		goto power_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) 	ret = mipid02_parse_tx_ep(bridge);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) 		dev_err(&client->dev, "failed to parse tx %d", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) 		goto power_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) 	ret = mipid02_parse_rx_ep(bridge);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) 		dev_err(&client->dev, "failed to parse rx %d", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) 		goto power_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) 	ret = v4l2_async_register_subdev(&bridge->sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) 		dev_err(&client->dev, "v4l2_async_register_subdev failed %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) 			    ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) 		goto unregister_notifier;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) 	dev_info(&client->dev, "mipid02 device probe successfully");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) unregister_notifier:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) 	v4l2_async_notifier_unregister(&bridge->notifier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) 	v4l2_async_notifier_cleanup(&bridge->notifier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) power_off:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) 	mipid02_set_power_off(bridge);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) entity_cleanup:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) 	media_entity_cleanup(&bridge->sd.entity);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) mutex_cleanup:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) 	mutex_destroy(&bridge->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) static int mipid02_remove(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) 	struct mipid02_dev *bridge = to_mipid02_dev(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) 	v4l2_async_notifier_unregister(&bridge->notifier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) 	v4l2_async_notifier_cleanup(&bridge->notifier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) 	v4l2_async_unregister_subdev(&bridge->sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) 	mipid02_set_power_off(bridge);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) 	media_entity_cleanup(&bridge->sd.entity);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) 	mutex_destroy(&bridge->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) static const struct of_device_id mipid02_dt_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) 	{ .compatible = "st,st-mipid02" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) 	{ /* sentinel */ }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) MODULE_DEVICE_TABLE(of, mipid02_dt_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) static struct i2c_driver mipid02_i2c_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) 	.driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) 		.name  = "st-mipid02",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) 		.of_match_table = mipid02_dt_ids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) 	.probe_new = mipid02_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) 	.remove = mipid02_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) module_i2c_driver(mipid02_i2c_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) MODULE_AUTHOR("Mickael Guene <mickael.guene@st.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) MODULE_DESCRIPTION("STMicroelectronics MIPID02 CSI-2 bridge driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) MODULE_LICENSE("GPL v2");