brintos

brintos / linux-shallow public Read only

0
0
Text · 25.2 KiB · b947a55 Raw
954 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Driver for ST MIPID02 CSI-2 to PARALLEL bridge4 *5 * Copyright (C) STMicroelectronics SA 20196 * Authors: Mickael Guene <mickael.guene@st.com>7 *          for STMicroelectronics.8 *9 *10 */11 12#include <linux/clk.h>13#include <linux/delay.h>14#include <linux/gpio/consumer.h>15#include <linux/i2c.h>16#include <linux/module.h>17#include <linux/of_graph.h>18#include <linux/regulator/consumer.h>19#include <media/mipi-csi2.h>20#include <media/v4l2-async.h>21#include <media/v4l2-cci.h>22#include <media/v4l2-ctrls.h>23#include <media/v4l2-device.h>24#include <media/v4l2-fwnode.h>25#include <media/v4l2-subdev.h>26 27#define MIPID02_CLK_LANE_WR_REG1	CCI_REG8(0x01)28#define MIPID02_CLK_LANE_REG1		CCI_REG8(0x02)29#define MIPID02_CLK_LANE_REG3		CCI_REG8(0x04)30#define MIPID02_DATA_LANE0_REG1		CCI_REG8(0x05)31#define MIPID02_DATA_LANE0_REG2		CCI_REG8(0x06)32#define MIPID02_DATA_LANE1_REG1		CCI_REG8(0x09)33#define MIPID02_DATA_LANE1_REG2		CCI_REG8(0x0a)34#define MIPID02_MODE_REG1		CCI_REG8(0x14)35#define MIPID02_MODE_REG2		CCI_REG8(0x15)36#define MIPID02_DATA_ID_RREG		CCI_REG8(0x17)37#define MIPID02_DATA_SELECTION_CTRL	CCI_REG8(0x19)38#define MIPID02_PIX_WIDTH_CTRL		CCI_REG8(0x1e)39#define MIPID02_PIX_WIDTH_CTRL_EMB	CCI_REG8(0x1f)40 41/* Bits definition for MIPID02_CLK_LANE_REG1 */42#define CLK_ENABLE					BIT(0)43/* Bits definition for MIPID02_CLK_LANE_REG3 */44#define CLK_MIPI_CSI					BIT(1)45/* Bits definition for MIPID02_DATA_LANE0_REG1 */46#define DATA_ENABLE					BIT(0)47/* Bits definition for MIPID02_DATA_LANEx_REG2 */48#define DATA_MIPI_CSI					BIT(0)49/* Bits definition for MIPID02_MODE_REG1 */50#define MODE_DATA_SWAP					BIT(2)51#define MODE_NO_BYPASS					BIT(6)52/* Bits definition for MIPID02_MODE_REG2 */53#define MODE_HSYNC_ACTIVE_HIGH				BIT(1)54#define MODE_VSYNC_ACTIVE_HIGH				BIT(2)55#define MODE_PCLK_SAMPLE_RISING				BIT(3)56/* Bits definition for MIPID02_DATA_SELECTION_CTRL */57#define SELECTION_MANUAL_DATA				BIT(2)58#define SELECTION_MANUAL_WIDTH				BIT(3)59 60static const u32 mipid02_supported_fmt_codes[] = {61	MEDIA_BUS_FMT_SBGGR8_1X8, MEDIA_BUS_FMT_SGBRG8_1X8,62	MEDIA_BUS_FMT_SGRBG8_1X8, MEDIA_BUS_FMT_SRGGB8_1X8,63	MEDIA_BUS_FMT_SBGGR10_1X10, MEDIA_BUS_FMT_SGBRG10_1X10,64	MEDIA_BUS_FMT_SGRBG10_1X10, MEDIA_BUS_FMT_SRGGB10_1X10,65	MEDIA_BUS_FMT_SBGGR12_1X12, MEDIA_BUS_FMT_SGBRG12_1X12,66	MEDIA_BUS_FMT_SGRBG12_1X12, MEDIA_BUS_FMT_SRGGB12_1X12,67	MEDIA_BUS_FMT_YUYV8_1X16, MEDIA_BUS_FMT_YVYU8_1X16,68	MEDIA_BUS_FMT_UYVY8_1X16, MEDIA_BUS_FMT_VYUY8_1X16,69	MEDIA_BUS_FMT_RGB565_1X16, MEDIA_BUS_FMT_BGR888_1X24,70	MEDIA_BUS_FMT_RGB565_2X8_LE, MEDIA_BUS_FMT_RGB565_2X8_BE,71	MEDIA_BUS_FMT_YUYV8_2X8, MEDIA_BUS_FMT_YVYU8_2X8,72	MEDIA_BUS_FMT_UYVY8_2X8, MEDIA_BUS_FMT_VYUY8_2X8,73	MEDIA_BUS_FMT_Y8_1X8, MEDIA_BUS_FMT_JPEG_1X874};75 76/* regulator supplies */77static const char * const mipid02_supply_name[] = {78	"VDDE", /* 1.8V digital I/O supply */79	"VDDIN", /* 1V8 voltage regulator supply */80};81 82#define MIPID02_NUM_SUPPLIES		ARRAY_SIZE(mipid02_supply_name)83 84#define MIPID02_SINK_0			085#define MIPID02_SINK_1			186#define MIPID02_SOURCE			287#define MIPID02_PAD_NB			388 89struct mipid02_dev {90	struct i2c_client *i2c_client;91	struct regulator_bulk_data supplies[MIPID02_NUM_SUPPLIES];92	struct v4l2_subdev sd;93	struct regmap *regmap;94	struct media_pad pad[MIPID02_PAD_NB];95	struct clk *xclk;96	struct gpio_desc *reset_gpio;97	/* endpoints info */98	struct v4l2_fwnode_endpoint rx;99	struct v4l2_fwnode_endpoint tx;100	/* remote source */101	struct v4l2_async_notifier notifier;102	struct v4l2_subdev *s_subdev;103	/* registers */104	struct {105		u8 clk_lane_reg1;106		u8 data_lane0_reg1;107		u8 data_lane1_reg1;108		u8 mode_reg1;109		u8 mode_reg2;110		u8 data_selection_ctrl;111		u8 data_id_rreg;112		u8 pix_width_ctrl;113		u8 pix_width_ctrl_emb;114	} r;115};116 117static int bpp_from_code(__u32 code)118{119	switch (code) {120	case MEDIA_BUS_FMT_SBGGR8_1X8:121	case MEDIA_BUS_FMT_SGBRG8_1X8:122	case MEDIA_BUS_FMT_SGRBG8_1X8:123	case MEDIA_BUS_FMT_SRGGB8_1X8:124	case MEDIA_BUS_FMT_Y8_1X8:125		return 8;126	case MEDIA_BUS_FMT_SBGGR10_1X10:127	case MEDIA_BUS_FMT_SGBRG10_1X10:128	case MEDIA_BUS_FMT_SGRBG10_1X10:129	case MEDIA_BUS_FMT_SRGGB10_1X10:130		return 10;131	case MEDIA_BUS_FMT_SBGGR12_1X12:132	case MEDIA_BUS_FMT_SGBRG12_1X12:133	case MEDIA_BUS_FMT_SGRBG12_1X12:134	case MEDIA_BUS_FMT_SRGGB12_1X12:135		return 12;136	case MEDIA_BUS_FMT_YUYV8_1X16:137	case MEDIA_BUS_FMT_YVYU8_1X16:138	case MEDIA_BUS_FMT_UYVY8_1X16:139	case MEDIA_BUS_FMT_VYUY8_1X16:140	case MEDIA_BUS_FMT_RGB565_1X16:141	case MEDIA_BUS_FMT_YUYV8_2X8:142	case MEDIA_BUS_FMT_YVYU8_2X8:143	case MEDIA_BUS_FMT_UYVY8_2X8:144	case MEDIA_BUS_FMT_VYUY8_2X8:145	case MEDIA_BUS_FMT_RGB565_2X8_LE:146	case MEDIA_BUS_FMT_RGB565_2X8_BE:147		return 16;148	case MEDIA_BUS_FMT_BGR888_1X24:149		return 24;150	default:151		return 0;152	}153}154 155static u8 data_type_from_code(__u32 code)156{157	switch (code) {158	case MEDIA_BUS_FMT_SBGGR8_1X8:159	case MEDIA_BUS_FMT_SGBRG8_1X8:160	case MEDIA_BUS_FMT_SGRBG8_1X8:161	case MEDIA_BUS_FMT_SRGGB8_1X8:162	case MEDIA_BUS_FMT_Y8_1X8:163		return MIPI_CSI2_DT_RAW8;164	case MEDIA_BUS_FMT_SBGGR10_1X10:165	case MEDIA_BUS_FMT_SGBRG10_1X10:166	case MEDIA_BUS_FMT_SGRBG10_1X10:167	case MEDIA_BUS_FMT_SRGGB10_1X10:168		return MIPI_CSI2_DT_RAW10;169	case MEDIA_BUS_FMT_SBGGR12_1X12:170	case MEDIA_BUS_FMT_SGBRG12_1X12:171	case MEDIA_BUS_FMT_SGRBG12_1X12:172	case MEDIA_BUS_FMT_SRGGB12_1X12:173		return MIPI_CSI2_DT_RAW12;174	case MEDIA_BUS_FMT_YUYV8_1X16:175	case MEDIA_BUS_FMT_YVYU8_1X16:176	case MEDIA_BUS_FMT_UYVY8_1X16:177	case MEDIA_BUS_FMT_VYUY8_1X16:178	case MEDIA_BUS_FMT_YUYV8_2X8:179	case MEDIA_BUS_FMT_YVYU8_2X8:180	case MEDIA_BUS_FMT_UYVY8_2X8:181	case MEDIA_BUS_FMT_VYUY8_2X8:182		return MIPI_CSI2_DT_YUV422_8B;183	case MEDIA_BUS_FMT_BGR888_1X24:184		return MIPI_CSI2_DT_RGB888;185	case MEDIA_BUS_FMT_RGB565_1X16:186	case MEDIA_BUS_FMT_RGB565_2X8_LE:187	case MEDIA_BUS_FMT_RGB565_2X8_BE:188		return MIPI_CSI2_DT_RGB565;189	default:190		return 0;191	}192}193 194static __u32 get_fmt_code(__u32 code)195{196	unsigned int i;197 198	for (i = 0; i < ARRAY_SIZE(mipid02_supported_fmt_codes); i++) {199		if (code == mipid02_supported_fmt_codes[i])200			return code;201	}202 203	return mipid02_supported_fmt_codes[0];204}205 206static __u32 serial_to_parallel_code(__u32 serial)207{208	if (serial == MEDIA_BUS_FMT_RGB565_1X16)209		return MEDIA_BUS_FMT_RGB565_2X8_LE;210	if (serial == MEDIA_BUS_FMT_YUYV8_1X16)211		return MEDIA_BUS_FMT_YUYV8_2X8;212	if (serial == MEDIA_BUS_FMT_YVYU8_1X16)213		return MEDIA_BUS_FMT_YVYU8_2X8;214	if (serial == MEDIA_BUS_FMT_UYVY8_1X16)215		return MEDIA_BUS_FMT_UYVY8_2X8;216	if (serial == MEDIA_BUS_FMT_VYUY8_1X16)217		return MEDIA_BUS_FMT_VYUY8_2X8;218	if (serial == MEDIA_BUS_FMT_BGR888_1X24)219		return MEDIA_BUS_FMT_BGR888_3X8;220 221	return serial;222}223 224static inline struct mipid02_dev *to_mipid02_dev(struct v4l2_subdev *sd)225{226	return container_of(sd, struct mipid02_dev, sd);227}228 229static int mipid02_get_regulators(struct mipid02_dev *bridge)230{231	unsigned int i;232 233	for (i = 0; i < MIPID02_NUM_SUPPLIES; i++)234		bridge->supplies[i].supply = mipid02_supply_name[i];235 236	return devm_regulator_bulk_get(&bridge->i2c_client->dev,237				       MIPID02_NUM_SUPPLIES,238				       bridge->supplies);239}240 241static void mipid02_apply_reset(struct mipid02_dev *bridge)242{243	gpiod_set_value_cansleep(bridge->reset_gpio, 0);244	usleep_range(5000, 10000);245	gpiod_set_value_cansleep(bridge->reset_gpio, 1);246	usleep_range(5000, 10000);247	gpiod_set_value_cansleep(bridge->reset_gpio, 0);248	usleep_range(5000, 10000);249}250 251static int mipid02_set_power_on(struct mipid02_dev *bridge)252{253	struct i2c_client *client = bridge->i2c_client;254	int ret;255 256	ret = clk_prepare_enable(bridge->xclk);257	if (ret) {258		dev_err(&client->dev, "%s: failed to enable clock\n", __func__);259		return ret;260	}261 262	ret = regulator_bulk_enable(MIPID02_NUM_SUPPLIES,263				    bridge->supplies);264	if (ret) {265		dev_err(&client->dev, "%s: failed to enable regulators\n",266			    __func__);267		goto xclk_off;268	}269 270	if (bridge->reset_gpio) {271		dev_dbg(&client->dev, "apply reset");272		mipid02_apply_reset(bridge);273	} else {274		dev_dbg(&client->dev, "don't apply reset");275		usleep_range(5000, 10000);276	}277 278	return 0;279 280xclk_off:281	clk_disable_unprepare(bridge->xclk);282	return ret;283}284 285static void mipid02_set_power_off(struct mipid02_dev *bridge)286{287	regulator_bulk_disable(MIPID02_NUM_SUPPLIES, bridge->supplies);288	clk_disable_unprepare(bridge->xclk);289}290 291static int mipid02_detect(struct mipid02_dev *bridge)292{293	u64 reg;294 295	/*296	 * There is no version registers. Just try to read register297	 * MIPID02_CLK_LANE_WR_REG1.298	 */299	return cci_read(bridge->regmap, MIPID02_CLK_LANE_WR_REG1, &reg, NULL);300}301 302/*303 * We need to know link frequency to setup clk_lane_reg1 timings. Link frequency304 * will be retrieve from connected device via v4l2_get_link_freq, bit per pixel305 * and number of lanes.306 */307static int mipid02_configure_from_rx_speed(struct mipid02_dev *bridge,308					   struct v4l2_mbus_framefmt *fmt)309{310	struct i2c_client *client = bridge->i2c_client;311	struct v4l2_subdev *subdev = bridge->s_subdev;312	struct v4l2_fwnode_endpoint *ep = &bridge->rx;313	u32 bpp = bpp_from_code(fmt->code);314	/*315	 * clk_lane_reg1 requires 4 times the unit interval time, and bitrate316	 * is twice the link frequency, hence ui_4 = 1000000000 * 4 / 2317	 */318	u64 ui_4 = 2000000000;319	s64 link_freq;320 321	link_freq = v4l2_get_link_freq(subdev->ctrl_handler, bpp,322				       2 * ep->bus.mipi_csi2.num_data_lanes);323	if (link_freq < 0) {324		dev_err(&client->dev, "Failed to get link frequency");325		return -EINVAL;326	}327 328	dev_dbg(&client->dev, "detect link_freq = %lld Hz", link_freq);329	ui_4 = div64_u64(ui_4, link_freq);330	bridge->r.clk_lane_reg1 |= ui_4 << 2;331 332	return 0;333}334 335static int mipid02_configure_clk_lane(struct mipid02_dev *bridge)336{337	struct i2c_client *client = bridge->i2c_client;338	struct v4l2_fwnode_endpoint *ep = &bridge->rx;339	bool *polarities = ep->bus.mipi_csi2.lane_polarities;340 341	/* midid02 doesn't support clock lane remapping */342	if (ep->bus.mipi_csi2.clock_lane != 0) {343		dev_err(&client->dev, "clk lane must be map to lane 0\n");344		return -EINVAL;345	}346	bridge->r.clk_lane_reg1 |= (polarities[0] << 1) | CLK_ENABLE;347 348	return 0;349}350 351static int mipid02_configure_data0_lane(struct mipid02_dev *bridge, int nb,352					bool are_lanes_swap, bool *polarities)353{354	bool are_pin_swap = are_lanes_swap ? polarities[2] : polarities[1];355 356	if (nb == 1 && are_lanes_swap)357		return 0;358 359	/*360	 * data lane 0 as pin swap polarity reversed compared to clock and361	 * data lane 1362	 */363	if (!are_pin_swap)364		bridge->r.data_lane0_reg1 = 1 << 1;365	bridge->r.data_lane0_reg1 |= DATA_ENABLE;366 367	return 0;368}369 370static int mipid02_configure_data1_lane(struct mipid02_dev *bridge, int nb,371					bool are_lanes_swap, bool *polarities)372{373	bool are_pin_swap = are_lanes_swap ? polarities[1] : polarities[2];374 375	if (nb == 1 && !are_lanes_swap)376		return 0;377 378	if (are_pin_swap)379		bridge->r.data_lane1_reg1 = 1 << 1;380	bridge->r.data_lane1_reg1 |= DATA_ENABLE;381 382	return 0;383}384 385static int mipid02_configure_from_rx(struct mipid02_dev *bridge,386				     struct v4l2_mbus_framefmt *fmt)387{388	struct v4l2_fwnode_endpoint *ep = &bridge->rx;389	bool are_lanes_swap = ep->bus.mipi_csi2.data_lanes[0] == 2;390	bool *polarities = ep->bus.mipi_csi2.lane_polarities;391	int nb = ep->bus.mipi_csi2.num_data_lanes;392	int ret;393 394	ret = mipid02_configure_clk_lane(bridge);395	if (ret)396		return ret;397 398	ret = mipid02_configure_data0_lane(bridge, nb, are_lanes_swap,399					   polarities);400	if (ret)401		return ret;402 403	ret = mipid02_configure_data1_lane(bridge, nb, are_lanes_swap,404					   polarities);405	if (ret)406		return ret;407 408	bridge->r.mode_reg1 |= are_lanes_swap ? MODE_DATA_SWAP : 0;409	bridge->r.mode_reg1 |= (nb - 1) << 1;410 411	return mipid02_configure_from_rx_speed(bridge, fmt);412}413 414static int mipid02_configure_from_tx(struct mipid02_dev *bridge)415{416	struct v4l2_fwnode_endpoint *ep = &bridge->tx;417 418	bridge->r.data_selection_ctrl = SELECTION_MANUAL_WIDTH;419	bridge->r.pix_width_ctrl = ep->bus.parallel.bus_width;420	bridge->r.pix_width_ctrl_emb = ep->bus.parallel.bus_width;421	if (ep->bus.parallel.flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH)422		bridge->r.mode_reg2 |= MODE_HSYNC_ACTIVE_HIGH;423	if (ep->bus.parallel.flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH)424		bridge->r.mode_reg2 |= MODE_VSYNC_ACTIVE_HIGH;425	if (ep->bus.parallel.flags & V4L2_MBUS_PCLK_SAMPLE_RISING)426		bridge->r.mode_reg2 |= MODE_PCLK_SAMPLE_RISING;427 428	return 0;429}430 431static int mipid02_configure_from_code(struct mipid02_dev *bridge,432				       struct v4l2_mbus_framefmt *fmt)433{434	u8 data_type;435 436	bridge->r.data_id_rreg = 0;437 438	if (fmt->code != MEDIA_BUS_FMT_JPEG_1X8) {439		bridge->r.data_selection_ctrl |= SELECTION_MANUAL_DATA;440 441		data_type = data_type_from_code(fmt->code);442		if (!data_type)443			return -EINVAL;444		bridge->r.data_id_rreg = data_type;445	}446 447	return 0;448}449 450static int mipid02_stream_disable(struct mipid02_dev *bridge)451{452	struct i2c_client *client = bridge->i2c_client;453	int ret = -EINVAL;454 455	if (!bridge->s_subdev)456		goto error;457 458	ret = v4l2_subdev_call(bridge->s_subdev, video, s_stream, 0);459	if (ret)460		goto error;461 462	/* Disable all lanes */463	cci_write(bridge->regmap, MIPID02_CLK_LANE_REG1, 0, &ret);464	cci_write(bridge->regmap, MIPID02_DATA_LANE0_REG1, 0, &ret);465	cci_write(bridge->regmap, MIPID02_DATA_LANE1_REG1, 0, &ret);466	if (ret)467		goto error;468error:469	if (ret)470		dev_err(&client->dev, "failed to stream off %d", ret);471 472	return ret;473}474 475static int mipid02_stream_enable(struct mipid02_dev *bridge)476{477	struct i2c_client *client = bridge->i2c_client;478	struct v4l2_subdev_state *state;479	struct v4l2_mbus_framefmt *fmt;480	int ret = -EINVAL;481 482	if (!bridge->s_subdev)483		goto error;484 485	memset(&bridge->r, 0, sizeof(bridge->r));486 487	state = v4l2_subdev_lock_and_get_active_state(&bridge->sd);488	fmt = v4l2_subdev_state_get_format(state, MIPID02_SINK_0);489 490	/* build registers content */491	ret = mipid02_configure_from_rx(bridge, fmt);492	if (ret)493		goto error;494	ret = mipid02_configure_from_tx(bridge);495	if (ret)496		goto error;497	ret = mipid02_configure_from_code(bridge, fmt);498	if (ret)499		goto error;500 501	v4l2_subdev_unlock_state(state);502 503	/* write mipi registers */504	cci_write(bridge->regmap, MIPID02_CLK_LANE_REG1,505		  bridge->r.clk_lane_reg1, &ret);506	cci_write(bridge->regmap, MIPID02_CLK_LANE_REG3, CLK_MIPI_CSI, &ret);507	cci_write(bridge->regmap, MIPID02_DATA_LANE0_REG1,508		  bridge->r.data_lane0_reg1, &ret);509	cci_write(bridge->regmap, MIPID02_DATA_LANE0_REG2, DATA_MIPI_CSI, &ret);510	cci_write(bridge->regmap, MIPID02_DATA_LANE1_REG1,511		  bridge->r.data_lane1_reg1, &ret);512	cci_write(bridge->regmap, MIPID02_DATA_LANE1_REG2, DATA_MIPI_CSI, &ret);513	cci_write(bridge->regmap, MIPID02_MODE_REG1,514		  MODE_NO_BYPASS | bridge->r.mode_reg1, &ret);515	cci_write(bridge->regmap, MIPID02_MODE_REG2, bridge->r.mode_reg2, &ret);516	cci_write(bridge->regmap, MIPID02_DATA_ID_RREG, bridge->r.data_id_rreg,517		  &ret);518	cci_write(bridge->regmap, MIPID02_DATA_SELECTION_CTRL,519		  bridge->r.data_selection_ctrl, &ret);520	cci_write(bridge->regmap, MIPID02_PIX_WIDTH_CTRL,521		  bridge->r.pix_width_ctrl, &ret);522	cci_write(bridge->regmap, MIPID02_PIX_WIDTH_CTRL_EMB,523		  bridge->r.pix_width_ctrl_emb, &ret);524	if (ret)525		goto error;526 527	ret = v4l2_subdev_call(bridge->s_subdev, video, s_stream, 1);528	if (ret)529		goto error;530 531	return 0;532 533error:534	dev_err(&client->dev, "failed to stream on %d", ret);535	mipid02_stream_disable(bridge);536 537	return ret;538}539 540static int mipid02_s_stream(struct v4l2_subdev *sd, int enable)541{542	struct mipid02_dev *bridge = to_mipid02_dev(sd);543	struct i2c_client *client = bridge->i2c_client;544	int ret = 0;545 546	dev_dbg(&client->dev, "%s : requested %d\n", __func__, enable);547 548	ret = enable ? mipid02_stream_enable(bridge) :549		       mipid02_stream_disable(bridge);550	if (ret)551		dev_err(&client->dev, "failed to stream %s (%d)\n",552			enable ? "enable" : "disable", ret);553 554	return ret;555}556 557static const struct v4l2_mbus_framefmt default_fmt = {558	.code = MEDIA_BUS_FMT_SBGGR8_1X8,559	.field = V4L2_FIELD_NONE,560	.colorspace = V4L2_COLORSPACE_SRGB,561	.ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT,562	.quantization = V4L2_QUANTIZATION_FULL_RANGE,563	.xfer_func = V4L2_XFER_FUNC_DEFAULT,564	.width = 640,565	.height = 480,566};567 568static int mipid02_init_state(struct v4l2_subdev *sd,569			      struct v4l2_subdev_state *state)570{571	*v4l2_subdev_state_get_format(state, MIPID02_SINK_0) = default_fmt;572	/* MIPID02_SINK_1 isn't supported yet */573	*v4l2_subdev_state_get_format(state, MIPID02_SOURCE) = default_fmt;574 575	return 0;576}577 578static int mipid02_enum_mbus_code(struct v4l2_subdev *sd,579				 struct v4l2_subdev_state *sd_state,580				 struct v4l2_subdev_mbus_code_enum *code)581{582	struct v4l2_mbus_framefmt *sink_fmt;583	int ret = 0;584 585	switch (code->pad) {586	case MIPID02_SINK_0:587		if (code->index >= ARRAY_SIZE(mipid02_supported_fmt_codes))588			ret = -EINVAL;589		else590			code->code = mipid02_supported_fmt_codes[code->index];591		break;592	case MIPID02_SOURCE:593		if (code->index == 0) {594			sink_fmt = v4l2_subdev_state_get_format(sd_state,595								MIPID02_SINK_0);596			code->code = serial_to_parallel_code(sink_fmt->code);597		} else {598			ret = -EINVAL;599		}600		break;601	default:602		ret = -EINVAL;603	}604 605	return ret;606}607 608static int mipid02_set_fmt(struct v4l2_subdev *sd,609			   struct v4l2_subdev_state *sd_state,610			   struct v4l2_subdev_format *fmt)611{612	struct mipid02_dev *bridge = to_mipid02_dev(sd);613	struct i2c_client *client = bridge->i2c_client;614	struct v4l2_mbus_framefmt *pad_fmt;615 616	dev_dbg(&client->dev, "%s for %d", __func__, fmt->pad);617 618	/* second CSI-2 pad not yet supported */619	if (fmt->pad == MIPID02_SINK_1)620		return -EINVAL;621 622	pad_fmt = v4l2_subdev_state_get_format(sd_state, fmt->pad);623	fmt->format.code = get_fmt_code(fmt->format.code);624 625	/* code may need to be converted */626	if (fmt->pad == MIPID02_SOURCE)627		fmt->format.code = serial_to_parallel_code(fmt->format.code);628 629	*pad_fmt = fmt->format;630 631	/* Propagate the format to the source pad in case of sink pad update */632	if (fmt->pad == MIPID02_SINK_0) {633		pad_fmt = v4l2_subdev_state_get_format(sd_state,634						       MIPID02_SOURCE);635		*pad_fmt = fmt->format;636		pad_fmt->code = serial_to_parallel_code(fmt->format.code);637	}638 639	return 0;640}641 642static const struct v4l2_subdev_video_ops mipid02_video_ops = {643	.s_stream = mipid02_s_stream,644};645 646static const struct v4l2_subdev_pad_ops mipid02_pad_ops = {647	.enum_mbus_code = mipid02_enum_mbus_code,648	.get_fmt = v4l2_subdev_get_fmt,649	.set_fmt = mipid02_set_fmt,650};651 652static const struct v4l2_subdev_ops mipid02_subdev_ops = {653	.video = &mipid02_video_ops,654	.pad = &mipid02_pad_ops,655};656 657static const struct v4l2_subdev_internal_ops mipid02_subdev_internal_ops = {658	.init_state = mipid02_init_state,659};660 661static const struct media_entity_operations mipid02_subdev_entity_ops = {662	.link_validate = v4l2_subdev_link_validate,663};664 665static int mipid02_async_bound(struct v4l2_async_notifier *notifier,666			       struct v4l2_subdev *s_subdev,667			       struct v4l2_async_connection *asd)668{669	struct mipid02_dev *bridge = to_mipid02_dev(notifier->sd);670	struct i2c_client *client = bridge->i2c_client;671	int source_pad;672	int ret;673 674	dev_dbg(&client->dev, "sensor_async_bound call %p", s_subdev);675 676	source_pad = media_entity_get_fwnode_pad(&s_subdev->entity,677						 s_subdev->fwnode,678						 MEDIA_PAD_FL_SOURCE);679	if (source_pad < 0) {680		dev_err(&client->dev, "Couldn't find output pad for subdev %s\n",681			s_subdev->name);682		return source_pad;683	}684 685	ret = media_create_pad_link(&s_subdev->entity, source_pad,686				    &bridge->sd.entity, 0,687				    MEDIA_LNK_FL_ENABLED |688				    MEDIA_LNK_FL_IMMUTABLE);689	if (ret) {690		dev_err(&client->dev, "Couldn't create media link %d", ret);691		return ret;692	}693 694	bridge->s_subdev = s_subdev;695 696	return 0;697}698 699static void mipid02_async_unbind(struct v4l2_async_notifier *notifier,700				 struct v4l2_subdev *s_subdev,701				 struct v4l2_async_connection *asd)702{703	struct mipid02_dev *bridge = to_mipid02_dev(notifier->sd);704 705	bridge->s_subdev = NULL;706}707 708static const struct v4l2_async_notifier_operations mipid02_notifier_ops = {709	.bound		= mipid02_async_bound,710	.unbind		= mipid02_async_unbind,711};712 713static int mipid02_parse_rx_ep(struct mipid02_dev *bridge)714{715	struct v4l2_fwnode_endpoint ep = { .bus_type = V4L2_MBUS_CSI2_DPHY };716	struct i2c_client *client = bridge->i2c_client;717	struct v4l2_async_connection *asd;718	struct device_node *ep_node;719	int ret;720 721	/* parse rx (endpoint 0) */722	ep_node = of_graph_get_endpoint_by_regs(bridge->i2c_client->dev.of_node,723						0, 0);724	if (!ep_node) {725		dev_err(&client->dev, "unable to find port0 ep");726		ret = -EINVAL;727		goto error;728	}729 730	ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(ep_node), &ep);731	if (ret) {732		dev_err(&client->dev, "Could not parse v4l2 endpoint %d\n",733			ret);734		goto error_of_node_put;735	}736 737	/* do some sanity checks */738	if (ep.bus.mipi_csi2.num_data_lanes > 2) {739		dev_err(&client->dev, "max supported data lanes is 2 / got %d",740			ep.bus.mipi_csi2.num_data_lanes);741		ret = -EINVAL;742		goto error_of_node_put;743	}744 745	/* register it for later use */746	bridge->rx = ep;747 748	/* register async notifier so we get noticed when sensor is connected */749	v4l2_async_subdev_nf_init(&bridge->notifier, &bridge->sd);750	asd = v4l2_async_nf_add_fwnode_remote(&bridge->notifier,751					      of_fwnode_handle(ep_node),752					      struct v4l2_async_connection);753	of_node_put(ep_node);754 755	if (IS_ERR(asd)) {756		dev_err(&client->dev, "fail to register asd to notifier %ld",757			PTR_ERR(asd));758		return PTR_ERR(asd);759	}760	bridge->notifier.ops = &mipid02_notifier_ops;761 762	ret = v4l2_async_nf_register(&bridge->notifier);763	if (ret)764		v4l2_async_nf_cleanup(&bridge->notifier);765 766	return ret;767 768error_of_node_put:769	of_node_put(ep_node);770error:771 772	return ret;773}774 775static int mipid02_parse_tx_ep(struct mipid02_dev *bridge)776{777	struct v4l2_fwnode_endpoint ep = { .bus_type = V4L2_MBUS_PARALLEL };778	struct i2c_client *client = bridge->i2c_client;779	struct device_node *ep_node;780	int ret;781 782	/* parse tx (endpoint 2) */783	ep_node = of_graph_get_endpoint_by_regs(bridge->i2c_client->dev.of_node,784						2, 0);785	if (!ep_node) {786		dev_err(&client->dev, "unable to find port1 ep");787		ret = -EINVAL;788		goto error;789	}790 791	ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(ep_node), &ep);792	if (ret) {793		dev_err(&client->dev, "Could not parse v4l2 endpoint\n");794		goto error_of_node_put;795	}796 797	of_node_put(ep_node);798	bridge->tx = ep;799 800	return 0;801 802error_of_node_put:803	of_node_put(ep_node);804error:805 806	return -EINVAL;807}808 809static int mipid02_probe(struct i2c_client *client)810{811	struct device *dev = &client->dev;812	struct mipid02_dev *bridge;813	u32 clk_freq;814	int ret;815 816	bridge = devm_kzalloc(dev, sizeof(*bridge), GFP_KERNEL);817	if (!bridge)818		return -ENOMEM;819 820	bridge->i2c_client = client;821	v4l2_i2c_subdev_init(&bridge->sd, client, &mipid02_subdev_ops);822 823	/* got and check clock */824	bridge->xclk = devm_clk_get(dev, "xclk");825	if (IS_ERR(bridge->xclk)) {826		dev_err(dev, "failed to get xclk\n");827		return PTR_ERR(bridge->xclk);828	}829 830	clk_freq = clk_get_rate(bridge->xclk);831	if (clk_freq < 6000000 || clk_freq > 27000000) {832		dev_err(dev, "xclk freq must be in 6-27 Mhz range. got %d Hz\n",833			clk_freq);834		return -EINVAL;835	}836 837	bridge->reset_gpio = devm_gpiod_get_optional(dev, "reset",838						     GPIOD_OUT_HIGH);839 840	if (IS_ERR(bridge->reset_gpio)) {841		dev_err(dev, "failed to get reset GPIO\n");842		return PTR_ERR(bridge->reset_gpio);843	}844 845	ret = mipid02_get_regulators(bridge);846	if (ret) {847		dev_err(dev, "failed to get regulators %d", ret);848		return ret;849	}850 851	/* Initialise the regmap for further cci access */852	bridge->regmap = devm_cci_regmap_init_i2c(client, 16);853	if (IS_ERR(bridge->regmap))854		return dev_err_probe(dev, PTR_ERR(bridge->regmap),855				     "failed to get cci regmap\n");856 857	bridge->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;858	bridge->sd.entity.function = MEDIA_ENT_F_VID_IF_BRIDGE;859	bridge->sd.internal_ops = &mipid02_subdev_internal_ops;860	bridge->sd.entity.ops = &mipid02_subdev_entity_ops;861	bridge->pad[0].flags = MEDIA_PAD_FL_SINK;862	bridge->pad[1].flags = MEDIA_PAD_FL_SINK;863	bridge->pad[2].flags = MEDIA_PAD_FL_SOURCE;864	ret = media_entity_pads_init(&bridge->sd.entity, MIPID02_PAD_NB,865				     bridge->pad);866	if (ret) {867		dev_err(&client->dev, "pads init failed %d", ret);868		return ret;869	}870 871	ret = v4l2_subdev_init_finalize(&bridge->sd);872	if (ret < 0) {873		dev_err(dev, "subdev init error: %d\n", ret);874		goto entity_cleanup;875	}876 877	/* enable clock, power and reset device if available */878	ret = mipid02_set_power_on(bridge);879	if (ret)880		goto entity_cleanup;881 882	ret = mipid02_detect(bridge);883	if (ret) {884		dev_err(&client->dev, "failed to detect mipid02 %d", ret);885		goto power_off;886	}887 888	ret = mipid02_parse_tx_ep(bridge);889	if (ret) {890		dev_err(&client->dev, "failed to parse tx %d", ret);891		goto power_off;892	}893 894	ret = mipid02_parse_rx_ep(bridge);895	if (ret) {896		dev_err(&client->dev, "failed to parse rx %d", ret);897		goto power_off;898	}899 900	ret = v4l2_async_register_subdev(&bridge->sd);901	if (ret < 0) {902		dev_err(&client->dev, "v4l2_async_register_subdev failed %d",903			    ret);904		goto unregister_notifier;905	}906 907	dev_info(&client->dev, "mipid02 device probe successfully");908 909	return 0;910 911unregister_notifier:912	v4l2_async_nf_unregister(&bridge->notifier);913	v4l2_async_nf_cleanup(&bridge->notifier);914power_off:915	mipid02_set_power_off(bridge);916entity_cleanup:917	media_entity_cleanup(&bridge->sd.entity);918 919	return ret;920}921 922static void mipid02_remove(struct i2c_client *client)923{924	struct v4l2_subdev *sd = i2c_get_clientdata(client);925	struct mipid02_dev *bridge = to_mipid02_dev(sd);926 927	v4l2_async_nf_unregister(&bridge->notifier);928	v4l2_async_nf_cleanup(&bridge->notifier);929	v4l2_async_unregister_subdev(&bridge->sd);930	mipid02_set_power_off(bridge);931	media_entity_cleanup(&bridge->sd.entity);932}933 934static const struct of_device_id mipid02_dt_ids[] = {935	{ .compatible = "st,st-mipid02" },936	{ /* sentinel */ }937};938MODULE_DEVICE_TABLE(of, mipid02_dt_ids);939 940static struct i2c_driver mipid02_i2c_driver = {941	.driver = {942		.name  = "st-mipid02",943		.of_match_table = mipid02_dt_ids,944	},945	.probe = mipid02_probe,946	.remove = mipid02_remove,947};948 949module_i2c_driver(mipid02_i2c_driver);950 951MODULE_AUTHOR("Mickael Guene <mickael.guene@st.com>");952MODULE_DESCRIPTION("STMicroelectronics MIPID02 CSI-2 bridge driver");953MODULE_LICENSE("GPL v2");954