^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, ®);
^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");