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, ®, 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