From cafdb02e96d7ec5e9a00a3f3911f29e9d31272a5 Mon Sep 17 00:00:00 2001 From: LongChang Ma Date: Mon, 8 Jan 2024 10:59:03 +0800 Subject: [PATCH 1/6] media: i2c: techpoint: fix tp9951 2 lane ecc error Signed-off-by: LongChang Ma Change-Id: Iddc95c2a0512e25d8a8c9575a5a55161c5c47b6d --- .../media/i2c/techpoint/techpoint_tp9951.c | 164 +++++++++--------- 1 file changed, 81 insertions(+), 83 deletions(-) diff --git a/drivers/media/i2c/techpoint/techpoint_tp9951.c b/drivers/media/i2c/techpoint/techpoint_tp9951.c index 8ad43fa4549b..199abe2281ba 100644 --- a/drivers/media/i2c/techpoint/techpoint_tp9951.c +++ b/drivers/media/i2c/techpoint/techpoint_tp9951.c @@ -15,9 +15,9 @@ static struct techpoint_video_modes supported_modes[] = { .width = 960, .height = 576, .max_fps = { - .numerator = 10000, - .denominator = 250000, - }, + .numerator = 10000, + .denominator = 250000, + }, .link_freq_value = TP9951_LINK_FREQ_148M, .common_reg_list = NULL, .common_reg_size = 0, @@ -35,9 +35,9 @@ static struct techpoint_video_modes supported_modes[] = { .width = 960, .height = 480, .max_fps = { - .numerator = 10000, - .denominator = 250000, - }, + .numerator = 10000, + .denominator = 250000, + }, .link_freq_value = TP9951_LINK_FREQ_148M, .common_reg_list = NULL, .common_reg_size = 0, @@ -55,11 +55,11 @@ static struct techpoint_video_modes supported_modes[] = { .width = 1920, .height = 1080, .max_fps = { - .numerator = 10000, - .denominator = 250000, - }, - // .link_freq_value = TP9951_LINK_FREQ_594M, - .link_freq_value = TP9951_LINK_FREQ_297M, + .numerator = 10000, + .denominator = 250000, + }, + .link_freq_value = TP9951_LINK_FREQ_594M, + //.link_freq_value = TP9951_LINK_FREQ_297M, .common_reg_list = NULL, .common_reg_size = 0, .bpp = TP9951_BITS_PER_SAMPLE, @@ -76,9 +76,9 @@ static struct techpoint_video_modes supported_modes[] = { .width = 1280, .height = 720, .max_fps = { - .numerator = 10000, - .denominator = 250000, - }, + .numerator = 10000, + .denominator = 250000, + }, .link_freq_value = TP9951_LINK_FREQ_297M, .common_reg_list = NULL, .common_reg_size = 0, @@ -136,12 +136,12 @@ int tp9951_get_all_input_status(struct techpoint *techpoint, u8 *detect_status) } static void tp9951_set_mipi_out(struct i2c_client *client, - enum techpoint_support_reso reso, - unsigned char lane) + enum techpoint_support_reso reso, + unsigned char lane) { u8 tmp; //mipi setting - techpoint_write_reg(client, 0x40, 0x08); //select MIPI page + techpoint_write_reg(client, PAGE_REG, 0x08); //select MIPI page techpoint_write_reg(client, 0x02, 0x7d); techpoint_write_reg(client, 0x03, 0x75); techpoint_write_reg(client, 0x04, 0x75); @@ -213,11 +213,11 @@ static void tp9951_set_mipi_out(struct i2c_client *client, } } - techpoint_write_reg(client, 0x40, 0x00); //back to decoder page + techpoint_write_reg(client, PAGE_REG, 0x00); //back to decoder page techpoint_read_reg(client, 0x06, &tmp); //PLL reset techpoint_write_reg(client, 0x06, 0x80 | tmp); - techpoint_write_reg(client, 0x40, 0x08); //back to mipi page + techpoint_write_reg(client, PAGE_REG, 0x08); //back to mipi page techpoint_read_reg(client, 0x14, &tmp); //PLL reset techpoint_write_reg(client, 0x14, 0x80 | tmp); @@ -226,21 +226,21 @@ static void tp9951_set_mipi_out(struct i2c_client *client, /* Enable MIPI CSI2 output */ techpoint_write_reg(client, 0x28, 0x02); //stream off techpoint_write_reg(client, 0x28, 0x00); //stream on - techpoint_write_reg(client, 0x40, 0x00); //back to decoder page + techpoint_write_reg(client, PAGE_REG, 0x00); //back to decoder page } int tp9951_set_channel_reso(struct i2c_client *client, int ch, - enum techpoint_support_reso reso) + enum techpoint_support_reso reso) { int val = reso; dev_info(&client->dev, "##$$ %s", __func__); - techpoint_write_reg(client, 0x40, 0x00); //select decoder page - techpoint_write_reg(client, 0x06, 0x12); //default value - techpoint_write_reg(client, 0x42, 0x00); //common setting for all format - techpoint_write_reg(client, 0x4e, 0x00); //common setting for MIPI output - techpoint_write_reg(client, 0x54, 0x00); //common setting for MIPI output - techpoint_write_reg(client, 0x41, ch); //video MUX select + techpoint_write_reg(client, 0x40, 0x00); //select decoder page + techpoint_write_reg(client, 0x06, 0x12); //default value + techpoint_write_reg(client, 0x42, 0x00); //common setting for all format + techpoint_write_reg(client, 0x4e, 0x00); //common setting for MIPI output + techpoint_write_reg(client, 0x54, 0x00); //common setting for MIPI output + techpoint_write_reg(client, 0x41, ch); //video MUX select switch (val) { case TECHPOINT_S_RESO_720P_25: @@ -317,8 +317,8 @@ int tp9951_set_channel_reso(struct i2c_client *client, int ch, techpoint_write_reg(client, 0x18, 0x29); techpoint_write_reg(client, 0x19, 0x38); techpoint_write_reg(client, 0x1a, 0x47); - techpoint_write_reg(client, 0x1c, 0x0a);//1920*1080, 25fps - techpoint_write_reg(client, 0x1d, 0x50);// + techpoint_write_reg(client, 0x1c, 0x0a); //1920*1080, 25fps + techpoint_write_reg(client, 0x1d, 0x50); techpoint_write_reg(client, 0x20, 0x30); techpoint_write_reg(client, 0x21, 0x84); @@ -361,65 +361,65 @@ int tp9951_set_channel_reso(struct i2c_client *client, int ch, break; case TECHPOINT_S_RESO_1080P_30: // FHD30 dev_err(&client->dev, "set channel PAL\n"); - techpoint_write_reg(client, 0x02, 0x40); - techpoint_write_reg(client, 0x07, 0xc0); - techpoint_write_reg(client, 0x0b, 0xc0); - techpoint_write_reg(client, 0x0c, 0x03); - techpoint_write_reg(client, 0x0d, 0x50); + techpoint_write_reg(client, 0x02, 0x40); + techpoint_write_reg(client, 0x07, 0xc0); + techpoint_write_reg(client, 0x0b, 0xc0); + techpoint_write_reg(client, 0x0c, 0x03); + techpoint_write_reg(client, 0x0d, 0x50); - techpoint_write_reg(client, 0x15, 0x03); - techpoint_write_reg(client, 0x16, 0xd2); - techpoint_write_reg(client, 0x17, 0x80); - techpoint_write_reg(client, 0x18, 0x29); - techpoint_write_reg(client, 0x19, 0x38); - techpoint_write_reg(client, 0x1a, 0x47); - techpoint_write_reg(client, 0x1c, 0x08); //1920*1080, 30fps - techpoint_write_reg(client, 0x1d, 0x98); // + techpoint_write_reg(client, 0x15, 0x03); + techpoint_write_reg(client, 0x16, 0xd2); + techpoint_write_reg(client, 0x17, 0x80); + techpoint_write_reg(client, 0x18, 0x29); + techpoint_write_reg(client, 0x19, 0x38); + techpoint_write_reg(client, 0x1a, 0x47); + techpoint_write_reg(client, 0x1c, 0x08); //1920*1080, 30fps + techpoint_write_reg(client, 0x1d, 0x98); // - techpoint_write_reg(client, 0x20, 0x30); - techpoint_write_reg(client, 0x21, 0x84); - techpoint_write_reg(client, 0x22, 0x36); - techpoint_write_reg(client, 0x23, 0x3c); + techpoint_write_reg(client, 0x20, 0x30); + techpoint_write_reg(client, 0x21, 0x84); + techpoint_write_reg(client, 0x22, 0x36); + techpoint_write_reg(client, 0x23, 0x3c); - techpoint_write_reg(client, 0x2b, 0x60); - techpoint_write_reg(client, 0x2c, 0x2a); - techpoint_write_reg(client, 0x2d, 0x30); - techpoint_write_reg(client, 0x2e, 0x70); + techpoint_write_reg(client, 0x2b, 0x60); + techpoint_write_reg(client, 0x2c, 0x2a); + techpoint_write_reg(client, 0x2d, 0x30); + techpoint_write_reg(client, 0x2e, 0x70); - techpoint_write_reg(client, 0x30, 0x48); - techpoint_write_reg(client, 0x31, 0xbb); - techpoint_write_reg(client, 0x32, 0x2e); - techpoint_write_reg(client, 0x33, 0x90); + techpoint_write_reg(client, 0x30, 0x48); + techpoint_write_reg(client, 0x31, 0xbb); + techpoint_write_reg(client, 0x32, 0x2e); + techpoint_write_reg(client, 0x33, 0x90); - techpoint_write_reg(client, 0x35, 0x05); - techpoint_write_reg(client, 0x38, 0x00); - techpoint_write_reg(client, 0x39, 0x1C); + techpoint_write_reg(client, 0x35, 0x05); + techpoint_write_reg(client, 0x38, 0x00); + techpoint_write_reg(client, 0x39, 0x1C); - if (STD_HDA) { //AHD1080p30 extra - techpoint_write_reg(client, 0x02, 0x44); - techpoint_write_reg(client, 0x0d, 0x72); + if (STD_HDA) { //AHD1080p30 extra + techpoint_write_reg(client, 0x02, 0x44); + techpoint_write_reg(client, 0x0d, 0x72); - techpoint_write_reg(client, 0x15, 0x01); - techpoint_write_reg(client, 0x16, 0xf0); - techpoint_write_reg(client, 0x18, 0x2a); + techpoint_write_reg(client, 0x15, 0x01); + techpoint_write_reg(client, 0x16, 0xf0); + techpoint_write_reg(client, 0x18, 0x2a); - techpoint_write_reg(client, 0x20, 0x38); - techpoint_write_reg(client, 0x21, 0x46); + techpoint_write_reg(client, 0x20, 0x38); + techpoint_write_reg(client, 0x21, 0x46); - techpoint_write_reg(client, 0x25, 0xfe); - techpoint_write_reg(client, 0x26, 0x0d); + techpoint_write_reg(client, 0x25, 0xfe); + techpoint_write_reg(client, 0x26, 0x0d); - techpoint_write_reg(client, 0x2c, 0x3a); - techpoint_write_reg(client, 0x2d, 0x54); - techpoint_write_reg(client, 0x2e, 0x40); + techpoint_write_reg(client, 0x2c, 0x3a); + techpoint_write_reg(client, 0x2d, 0x54); + techpoint_write_reg(client, 0x2e, 0x40); - techpoint_write_reg(client, 0x30, 0xa5); - techpoint_write_reg(client, 0x31, 0x95); - techpoint_write_reg(client, 0x32, 0xe0); - techpoint_write_reg(client, 0x33, 0x60); - } + techpoint_write_reg(client, 0x30, 0xa5); + techpoint_write_reg(client, 0x31, 0x95); + techpoint_write_reg(client, 0x32, 0xe0); + techpoint_write_reg(client, 0x33, 0x60); + } - tp9951_set_mipi_out(client, reso, MIPI_2LANE); // 2 lane + tp9951_set_mipi_out(client, reso, MIPI_2LANE); // 2 lane break; case TECHPOINT_S_RESO_PAL: @@ -590,7 +590,7 @@ int tp9951_get_channel_reso(struct i2c_client *client, int ch) techpoint_write_reg(client, 0x40, ch); techpoint_read_reg(client, 0x03, &detect_fmt); - reso = detect_fmt & 0x7; + reso = detect_fmt & 0x7; // CVSTD[2-0] switch (reso) { case TP9951_CVSTD_720P_25: @@ -624,15 +624,13 @@ int tp9951_get_channel_reso(struct i2c_client *client, int ch) int tp9951_set_quick_stream(struct i2c_client *client, u32 stream) { - // mutex_lock(&techpoint->mutex); if (stream) { - techpoint_write_reg(client, 0x40, 0x8); - techpoint_write_reg(client, 0x28, 0x0); + techpoint_write_reg(client, PAGE_REG, 0x08); + techpoint_write_reg(client, 0x28, 0x00); } else { - techpoint_write_reg(client, 0x40, 0x8); - techpoint_write_reg(client, 0x28, 0x2); + techpoint_write_reg(client, PAGE_REG, 0x08); + techpoint_write_reg(client, 0x28, 0x02); usleep_range(40 * 1000, 50 * 1000); } - // mutex_unlock(&techpoint->mutex); return 0; } From 88bf597f098be45ebd77ed410a8a5f4392f844fb Mon Sep 17 00:00:00 2001 From: XiaoDong Huang Date: Tue, 9 Jan 2024 14:50:27 +0800 Subject: [PATCH 2/6] ARM: fiq_glue: save/restore r6 in fiq_glue_setup Fixes: fce07a27c8e4 ("ARM: fiq_glue: fix compilation error for THUMB2_KERNEL") Signed-off-by: XiaoDong Huang Change-Id: I89c8d3d8f9665d18917b0be5be4a5fd33bf21408 --- arch/arm/common/fiq_glue.S | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/common/fiq_glue.S b/arch/arm/common/fiq_glue.S index 9881d2dc3364..57e6be8bfcfd 100644 --- a/arch/arm/common/fiq_glue.S +++ b/arch/arm/common/fiq_glue.S @@ -117,6 +117,7 @@ fiq_glue_end: ENTRY(fiq_glue_setup) /* func, data, sp, smc call number */ stmfd sp!, {r4} + THUMB( stmfd sp!, {r6} ) mrs r4, cpsr THUMB( mov r6, #(FIQ_MODE | PSR_I_BIT | PSR_F_BIT) ) THUMB( msr cpsr_c, r6 ) @@ -128,6 +129,7 @@ ENTRY(fiq_glue_setup) /* func, data, sp, smc call number */ moveq r10, #0 movne r10, #1 msr cpsr_c, r4 + THUMB( ldmfd sp!, {r6} ) ldmfd sp!, {r4} bx lr From 6ffc9632435cd09173d4492d309b8cf47b18fa73 Mon Sep 17 00:00:00 2001 From: Meiyou Chen Date: Mon, 13 Sep 2021 15:48:49 +0800 Subject: [PATCH 3/6] arm64: dts: rockchip: rk3399-ind: tc358749x use dummy codec Signed-off-by: Meiyou Chen Change-Id: Id6213f44e64cd92b0369f8dfdb411bba9b108930 --- arch/arm64/boot/dts/rockchip/rk3399-evb-ind.dtsi | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/rockchip/rk3399-evb-ind.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-evb-ind.dtsi index ddd3dcd47e2c..98f04773e351 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-evb-ind.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3399-evb-ind.dtsi @@ -205,6 +205,11 @@ status = "okay"; }; + dummy_codec: dummy-codec { + compatible = "rockchip,dummy-codec"; + #sound-dai-cells = <0>; + }; + tc358749x_sound:tc358749x-sound { status = "okay"; compatible = "simple-audio-card"; @@ -213,10 +218,10 @@ simple-audio-card,bitclock-master = <&sound0_master>; simple-audio-card,frame-master = <&sound0_master>; simple-audio-card,cpu { - sound-dai = <&i2s0>; + sound-dai = <&i2s0>; }; sound0_master: simple-audio-card,codec { - sound-dai = <&tc358749x>; + sound-dai = <&dummy_codec>; }; }; From eda8eae1470090ffca532bcc6c6b823bfdda1ca1 Mon Sep 17 00:00:00 2001 From: Jianwei Fan Date: Thu, 9 Sep 2021 12:42:20 +0000 Subject: [PATCH 4/6] arm64: dts: rockchip: rk3399-evb-ind-lpddr4-android-avb: add tc35874x configuration Signed-off-by: Jianwei Fan Change-Id: Ib3e274017f3a971b5fb301c81e3ade43141af1d3 --- .../rk3399-evb-ind-lpddr4-android-avb.dts | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/arch/arm64/boot/dts/rockchip/rk3399-evb-ind-lpddr4-android-avb.dts b/arch/arm64/boot/dts/rockchip/rk3399-evb-ind-lpddr4-android-avb.dts index 34a9b6648443..d59bb9397307 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-evb-ind-lpddr4-android-avb.dts +++ b/arch/arm64/boot/dts/rockchip/rk3399-evb-ind-lpddr4-android-avb.dts @@ -31,6 +31,13 @@ vin-supply = <&vcc5v0_sys>; }; + ext_cam_clk: external-camera-clock { + compatible = "fixed-clock"; + clock-frequency = <27000000>; + clock-output-names = "CLK_CAMERA_27MHZ"; + #clock-cells = <0>; + }; + panel: panel { compatible = "simple-panel"; backlight = <&backlight>; @@ -223,6 +230,35 @@ }; }; }; + + /delete-node/ tc358749x@0f; + + tc35874x: tc35874x@0f { + status = "disabled"; + reg = <0x0f>; + compatible = "toshiba,tc358749"; + clocks = <&ext_cam_clk>; + clock-names = "refclk"; + reset-gpios = <&gpio0 2 GPIO_ACTIVE_LOW>; + /* interrupt-parent = <&gpio2>; */ + /* interrupts = <12 IRQ_TYPE_LEVEL_HIGH>; */ + pinctrl-names = "default"; + pinctrl-0 = <&tc35874x_gpios>; + rockchip,camera-module-index = <0>; + rockchip,camera-module-facing = "back"; + rockchip,camera-module-name = "TC358749XBG"; + rockchip,camera-module-lens-name = "NC"; + + port { + hdmiin_out0: endpoint { + remote-endpoint = <&hdmi_to_mipi_in>; + data-lanes = <1 2 3 4>; + clock-noncontinuous; + link-frequencies = + /bits/ 64 <297000000>; + }; + }; + }; }; &i2s2 { @@ -282,6 +318,11 @@ #address-cells = <1>; #size-cells = <0>; + hdmi_to_mipi_in: endpoint@0 { + reg = <0>; + remote-endpoint = <&hdmiin_out0>; + data-lanes = <1 2 3 4>; + }; mipi_in_ucam1: endpoint@1 { reg = <1>; remote-endpoint = <&ucam_out1>; @@ -382,6 +423,19 @@ }; &pinctrl { + hdmiin { + tc35874x_gpios: tc35874x_gpios { + rockchip,pins = + /* PWREN_3.3 */ + <0 RK_PB5 RK_FUNC_GPIO &pcfg_output_high>, + /* HDMIIN_RST */ + <0 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>, + /* HDMIIN_STBY */ + <3 RK_PD1 RK_FUNC_GPIO &pcfg_output_high>, + /* HDMIIN_INT */ + <4 RK_PA4 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; lcd-panel { lcd_panel_reset: lcd-panel-reset { rockchip,pins = <1 RK_PC7 RK_FUNC_GPIO &pcfg_pull_up>; From cb3614d40c69adbb81eda07a64a6ecab6467f061 Mon Sep 17 00:00:00 2001 From: Jianwei Fan Date: Sat, 18 Sep 2021 09:42:05 +0000 Subject: [PATCH 5/6] arm64: dts: rockchip: rk3399-evb-ind-lpddr4-v13-android-avb: add tc35874x configuration Signed-off-by: Jianwei Fan Change-Id: Ia8e5c19ae4d37e0c7e16f8f149c17716e9f54d2d --- .../rk3399-evb-ind-lpddr4-v13-android-avb.dts | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/arch/arm64/boot/dts/rockchip/rk3399-evb-ind-lpddr4-v13-android-avb.dts b/arch/arm64/boot/dts/rockchip/rk3399-evb-ind-lpddr4-v13-android-avb.dts index 75091223a3ab..0a1dd9c8b40e 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-evb-ind-lpddr4-v13-android-avb.dts +++ b/arch/arm64/boot/dts/rockchip/rk3399-evb-ind-lpddr4-v13-android-avb.dts @@ -42,6 +42,13 @@ vin-supply = <&vcc5v0_sys>; }; + ext_cam_clk: external-camera-clock { + compatible = "fixed-clock"; + clock-frequency = <27000000>; + clock-output-names = "CLK_CAMERA_27MHZ"; + #clock-cells = <0>; + }; + panel: panel { compatible = "simple-panel"; backlight = <&backlight>; @@ -234,6 +241,35 @@ }; }; }; + + /delete-node/ tc358749x@0f; + + tc35874x: tc35874x@0f { + status = "disabled"; + reg = <0x0f>; + compatible = "toshiba,tc358749"; + clocks = <&ext_cam_clk>; + clock-names = "refclk"; + reset-gpios = <&gpio0 2 GPIO_ACTIVE_LOW>; + /* interrupt-parent = <&gpio2>; */ + /* interrupts = <12 IRQ_TYPE_LEVEL_HIGH>; */ + pinctrl-names = "default"; + pinctrl-0 = <&tc35874x_gpios>; + rockchip,camera-module-index = <0>; + rockchip,camera-module-facing = "back"; + rockchip,camera-module-name = "TC358749XBG"; + rockchip,camera-module-lens-name = "NC"; + + port { + hdmiin_out0: endpoint { + remote-endpoint = <&hdmi_to_mipi_in>; + data-lanes = <1 2 3 4>; + clock-noncontinuous; + link-frequencies = + /bits/ 64 <297000000>; + }; + }; + }; }; &i2s2 { @@ -293,6 +329,11 @@ #address-cells = <1>; #size-cells = <0>; + hdmi_to_mipi_in: endpoint@0 { + reg = <0>; + remote-endpoint = <&hdmiin_out0>; + data-lanes = <1 2 3 4>; + }; mipi_in_ucam1: endpoint@1 { reg = <1>; remote-endpoint = <&ucam_out1>; @@ -418,6 +459,19 @@ }; &pinctrl { + hdmiin { + tc35874x_gpios: tc35874x_gpios { + rockchip,pins = + /* PWREN_3.3 */ + <0 RK_PB5 RK_FUNC_GPIO &pcfg_output_high>, + /* HDMIIN_RST */ + <0 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>, + /* HDMIIN_STBY */ + <3 RK_PD1 RK_FUNC_GPIO &pcfg_output_high>, + /* HDMIIN_INT */ + <4 RK_PA4 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; lcd-panel { lcd_panel_reset: lcd-panel-reset { rockchip,pins = <1 RK_PC7 RK_FUNC_GPIO &pcfg_pull_up>; From 3aa3879e5e9d97a18cd1e735045f5ea42896d2e1 Mon Sep 17 00:00:00 2001 From: Cai Wenzhong Date: Mon, 25 Dec 2023 17:42:56 +0800 Subject: [PATCH 6/6] media: i2c: maxim: local: maxim2c: driver version v3.00.00 1. local deserializer and remote devices are associated through i2c-mux 2. remote camera is abstracted as v4l2 subdev Signed-off-by: Cai Wenzhong Change-Id: I8b383651721cc35f7a2f6985ffbb3f0aa6a065a1 --- drivers/media/i2c/Kconfig | 1 - drivers/media/i2c/Makefile | 1 - drivers/media/i2c/maxim/local/Kconfig | 1 + drivers/media/i2c/maxim/local/Makefile | 1 + drivers/media/i2c/maxim/local/maxim2c/Kconfig | 12 + .../i2c/{ => maxim/local}/maxim2c/Makefile | 6 +- .../{ => maxim/local}/maxim2c/maxim2c_api.h | 42 +- .../{ => maxim/local}/maxim2c/maxim2c_drv.c | 231 +++++----- .../{ => maxim/local}/maxim2c/maxim2c_drv.h | 21 +- .../{ => maxim/local}/maxim2c/maxim2c_i2c.c | 236 ++++++++-- .../{ => maxim/local}/maxim2c/maxim2c_i2c.h | 31 ++ .../{ => maxim/local}/maxim2c/maxim2c_link.c | 93 ++-- .../{ => maxim/local}/maxim2c/maxim2c_link.h | 2 + .../local}/maxim2c/maxim2c_mipi_txphy.c | 75 ++- .../local}/maxim2c/maxim2c_mipi_txphy.h | 0 .../local}/maxim2c/maxim2c_pattern.c | 71 ++- .../local}/maxim2c/maxim2c_pattern.h | 0 .../i2c/maxim/local/maxim2c/maxim2c_remote.c | 113 +++++ .../{ => maxim/local}/maxim2c/maxim2c_v4l2.c | 87 ++-- .../local}/maxim2c/maxim2c_video_pipe.c | 15 +- .../local}/maxim2c/maxim2c_video_pipe.h | 0 drivers/media/i2c/maxim2c/Kconfig | 46 -- drivers/media/i2c/maxim2c/maxim2c_remote.c | 434 ------------------ drivers/media/i2c/maxim2c/maxim2c_remote.h | 36 -- drivers/media/i2c/maxim2c/remote_max9295.c | 331 ------------- drivers/media/i2c/maxim2c/remote_max96715.c | 381 --------------- drivers/media/i2c/maxim2c/remote_max96717.c | 310 ------------- 27 files changed, 658 insertions(+), 1919 deletions(-) create mode 100644 drivers/media/i2c/maxim/local/maxim2c/Kconfig rename drivers/media/i2c/{ => maxim/local}/maxim2c/Makefile (52%) rename drivers/media/i2c/{ => maxim/local}/maxim2c/maxim2c_api.h (62%) rename drivers/media/i2c/{ => maxim/local}/maxim2c/maxim2c_drv.c (79%) rename drivers/media/i2c/{ => maxim/local}/maxim2c/maxim2c_drv.h (86%) rename drivers/media/i2c/{ => maxim/local}/maxim2c/maxim2c_i2c.c (61%) rename drivers/media/i2c/{ => maxim/local}/maxim2c/maxim2c_i2c.h (52%) rename drivers/media/i2c/{ => maxim/local}/maxim2c/maxim2c_link.c (86%) rename drivers/media/i2c/{ => maxim/local}/maxim2c/maxim2c_link.h (95%) rename drivers/media/i2c/{ => maxim/local}/maxim2c/maxim2c_mipi_txphy.c (88%) rename drivers/media/i2c/{ => maxim/local}/maxim2c/maxim2c_mipi_txphy.h (100%) rename drivers/media/i2c/{ => maxim/local}/maxim2c/maxim2c_pattern.c (84%) rename drivers/media/i2c/{ => maxim/local}/maxim2c/maxim2c_pattern.h (100%) create mode 100644 drivers/media/i2c/maxim/local/maxim2c/maxim2c_remote.c rename drivers/media/i2c/{ => maxim/local}/maxim2c/maxim2c_v4l2.c (92%) rename drivers/media/i2c/{ => maxim/local}/maxim2c/maxim2c_video_pipe.c (96%) rename drivers/media/i2c/{ => maxim/local}/maxim2c/maxim2c_video_pipe.h (100%) delete mode 100644 drivers/media/i2c/maxim2c/Kconfig delete mode 100644 drivers/media/i2c/maxim2c/maxim2c_remote.c delete mode 100644 drivers/media/i2c/maxim2c/maxim2c_remote.h delete mode 100644 drivers/media/i2c/maxim2c/remote_max9295.c delete mode 100644 drivers/media/i2c/maxim2c/remote_max96715.c delete mode 100644 drivers/media/i2c/maxim2c/remote_max96717.c diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig index 965a2e2e82a7..0d2ffef356e3 100644 --- a/drivers/media/i2c/Kconfig +++ b/drivers/media/i2c/Kconfig @@ -691,7 +691,6 @@ config VIDEO_MAX96756 To compile this driver as a module, choose M here: the module will be called max96756. -source "drivers/media/i2c/maxim2c/Kconfig" source "drivers/media/i2c/maxim/Kconfig" comment "Video and audio decoders" diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile index 92be925642e0..01a38d222d4c 100644 --- a/drivers/media/i2c/Makefile +++ b/drivers/media/i2c/Makefile @@ -10,7 +10,6 @@ obj-$(CONFIG_VIDEO_M5MOLS) += m5mols/ obj-$(CONFIG_VIDEO_NVP6158) += nvp6158_drv/ obj-$(CONFIG_VIDEO_NVP6188) += nvp6188.o obj-$(CONFIG_VIDEO_NVP6324) += jaguar1_drv/ -obj-$(CONFIG_VIDEO_DES_MAXIM2C) += maxim2c/ obj-$(CONFIG_VIDEO_MAXIM_SERDES) += maxim/ obj-$(CONFIG_VIDEO_APTINA_PLL) += aptina-pll.o diff --git a/drivers/media/i2c/maxim/local/Kconfig b/drivers/media/i2c/maxim/local/Kconfig index 80d168bae7fb..01548a184725 100644 --- a/drivers/media/i2c/maxim/local/Kconfig +++ b/drivers/media/i2c/maxim/local/Kconfig @@ -5,6 +5,7 @@ menu "Maxim Deserializer devices support" visible if VIDEO_MAXIM_SERDES +source "drivers/media/i2c/maxim/local/maxim2c/Kconfig" source "drivers/media/i2c/maxim/local/maxim4c/Kconfig" endmenu diff --git a/drivers/media/i2c/maxim/local/Makefile b/drivers/media/i2c/maxim/local/Makefile index 82d5080e0fbc..b0911ee529af 100644 --- a/drivers/media/i2c/maxim/local/Makefile +++ b/drivers/media/i2c/maxim/local/Makefile @@ -1,2 +1,3 @@ # SPDX-License-Identifier: GPL-2.0 +obj-$(CONFIG_VIDEO_MAXIM_DES_MAXIM2C) += maxim2c/ obj-$(CONFIG_VIDEO_MAXIM_DES_MAXIM4C) += maxim4c/ diff --git a/drivers/media/i2c/maxim/local/maxim2c/Kconfig b/drivers/media/i2c/maxim/local/maxim2c/Kconfig new file mode 100644 index 000000000000..d82beed3bc83 --- /dev/null +++ b/drivers/media/i2c/maxim/local/maxim2c/Kconfig @@ -0,0 +1,12 @@ +# SPDX-License-Identifier: GPL-2.0-only +# +# Maxim Dual GMSL deserializer devices +# +config VIDEO_MAXIM_DES_MAXIM2C + tristate "Maxim Dual GMSL deserializer support" + depends on VIDEO_MAXIM_SERDES + help + This driver supports the Maxim Dual GMSL2/GMSL1 deserializer. + + To compile this driver as a module, choose M here: the + module will be called maxim2c. diff --git a/drivers/media/i2c/maxim2c/Makefile b/drivers/media/i2c/maxim/local/maxim2c/Makefile similarity index 52% rename from drivers/media/i2c/maxim2c/Makefile rename to drivers/media/i2c/maxim/local/maxim2c/Makefile index f9b799053064..3eb0bfa15405 100644 --- a/drivers/media/i2c/maxim2c/Makefile +++ b/drivers/media/i2c/maxim/local/maxim2c/Makefile @@ -1,5 +1,5 @@ # SPDX-License-Identifier: GPL-2.0 -obj-$(CONFIG_VIDEO_DES_MAXIM2C) += maxim2c.o +obj-$(CONFIG_VIDEO_MAXIM_DES_MAXIM2C) += maxim2c.o maxim2c-objs += maxim2c_i2c.o \ maxim2c_mipi_txphy.o \ maxim2c_video_pipe.o \ @@ -8,7 +8,3 @@ maxim2c-objs += maxim2c_i2c.o \ maxim2c_pattern.o \ maxim2c_v4l2.o \ maxim2c_drv.o - -obj-$(CONFIG_MAXIM2C_SER_MAX9295) += remote_max9295.o -obj-$(CONFIG_MAXIM2C_SER_MAX96715) += remote_max96715.o -obj-$(CONFIG_MAXIM2C_SER_MAX96717) += remote_max96717.o diff --git a/drivers/media/i2c/maxim2c/maxim2c_api.h b/drivers/media/i2c/maxim/local/maxim2c/maxim2c_api.h similarity index 62% rename from drivers/media/i2c/maxim2c/maxim2c_api.h rename to drivers/media/i2c/maxim/local/maxim2c/maxim2c_api.h index 7668c1f4ae76..e7ef7ec02b02 100644 --- a/drivers/media/i2c/maxim2c/maxim2c_api.h +++ b/drivers/media/i2c/maxim/local/maxim2c/maxim2c_api.h @@ -10,11 +10,13 @@ #ifndef __MAXIM2C_API_H__ #define __MAXIM2C_API_H__ +#include +#include + #include "maxim2c_i2c.h" #include "maxim2c_link.h" #include "maxim2c_video_pipe.h" #include "maxim2c_mipi_txphy.h" -#include "maxim2c_remote.h" #include "maxim2c_pattern.h" #include "maxim2c_drv.h" @@ -26,28 +28,11 @@ /* Maxim Deserializer pwdn on/off enable */ #define MAXIM2C_LOCAL_DES_ON_OFF_EN 0 -/* maxim2c i2c api */ -int maxim2c_i2c_write_reg(struct i2c_client *client, - u16 reg_addr, u16 reg_len, u16 val_len, u32 reg_val); -int maxim2c_i2c_read_reg(struct i2c_client *client, - u16 reg_addr, u16 reg_len, u16 val_len, u32 *reg_val); -int maxim2c_i2c_update_reg(struct i2c_client *client, - u16 reg_addr, u16 reg_len, - u32 val_len, u32 val_mask, u32 reg_val); - -int maxim2c_i2c_write_byte(struct i2c_client *client, - u16 reg_addr, u16 reg_len, u8 reg_val); -int maxim2c_i2c_read_byte(struct i2c_client *client, - u16 reg_addr, u16 reg_len, u8 *reg_val); -int maxim2c_i2c_update_byte(struct i2c_client *client, - u16 reg_addr, u16 reg_len, u8 val_mask, u8 reg_val); - -int maxim2c_i2c_write_array(struct i2c_client *client, - const struct maxim2c_i2c_regval *regs); -int maxim2c_i2c_load_init_seq(struct device *dev, - struct device_node *node, struct maxim2c_i2c_init_seq *init_seq); -int maxim2c_i2c_run_init_seq(struct i2c_client *client, - struct maxim2c_i2c_init_seq *init_seq); +/* maxim2c i2c mux api */ +int maxim2c_i2c_mux_enable(maxim2c_t *maxim2c, u8 def_mask); +int maxim2c_i2c_mux_disable(maxim2c_t *maxim2c); +int maxim2c_i2c_mux_init(maxim2c_t *maxim2c); +int maxim2c_i2c_mux_deinit(maxim2c_t *maxim2c); /* maxim2c link api */ u8 maxim2c_link_get_lock_state(maxim2c_t *maxim2c, u8 link_mask); @@ -76,15 +61,8 @@ int maxim2c_dphy_dpll_predef_set(maxim2c_t *maxim2c, s64 link_freq_hz); int maxim2c_mipi_csi_output(maxim2c_t *maxim2c, bool enable); /* maxim2c remote api */ -int maxim2c_remote_mfd_add_devices(maxim2c_t *maxim2c); -int maxim2c_remote_devices_init(maxim2c_t *maxim2c, u8 link_init_mask); -int maxim2c_remote_devices_deinit(maxim2c_t *maxim2c, u8 link_init_mask); -int maxim2c_remote_load_init_seq(maxim2c_remote_t *remote_device); -int maxim2c_remote_i2c_addr_select(maxim2c_remote_t *remote_device, u32 i2c_id); -int maxim2c_remote_i2c_client_init(maxim2c_remote_t *remote_device, - struct i2c_client *des_client); -int maxim2c_remote_device_register(maxim2c_t *maxim2c, - maxim2c_remote_t *remote_device); +int maxim2c_remote_devices_power(maxim2c_t *maxim2c, u8 link_mask, int on); +int maxim2c_remote_devices_s_stream(maxim2c_t *maxim2c, u8 link_mask, int enable); /* maxim2c v4l2 subdev api */ int maxim2c_v4l2_subdev_init(maxim2c_t *maxim2c); diff --git a/drivers/media/i2c/maxim2c/maxim2c_drv.c b/drivers/media/i2c/maxim/local/maxim2c/maxim2c_drv.c similarity index 79% rename from drivers/media/i2c/maxim2c/maxim2c_drv.c rename to drivers/media/i2c/maxim/local/maxim2c/maxim2c_drv.c index 0ae41e205673..1a86997423db 100644 --- a/drivers/media/i2c/maxim2c/maxim2c_drv.c +++ b/drivers/media/i2c/maxim/local/maxim2c/maxim2c_drv.c @@ -19,6 +19,11 @@ * 1. MIPI TXPHY add tunnel mode support * 2. MIPI TXPHY mode only support 2x4Lanes and 2x2Lanes * + * V3.00.00 + * 1. deserializer and serializer are associated through i2c-mux + * 2. remote serializer is abstracted as v4l2 subdev + * 3. remote camera is bound to remote serializer + * */ #include #include @@ -42,16 +47,19 @@ #include #include #include -#include #include -#include #include "maxim2c_api.h" -#define DRIVER_VERSION KERNEL_VERSION(2, 0x00, 0x01) +#define DRIVER_VERSION KERNEL_VERSION(3, 0x00, 0x00) #define MAXIM2C_XVCLK_FREQ 25000000 +static const char *const maxim2c_supply_names[MAXIM2C_NUM_SUPPLIES] = { + "vcc1v2", + "vcc1v8", +}; + static int maxim2c_check_local_chipid(maxim2c_t *maxim2c) { struct i2c_client *client = maxim2c->client; @@ -65,9 +73,7 @@ static int maxim2c_check_local_chipid(maxim2c_t *maxim2c) msleep(10); } - ret = maxim2c_i2c_read_byte(client, - MAXIM2C_REG_CHIP_ID, MAXIM2C_I2C_REG_ADDR_16BITS, - &chipid); + ret = maxim2c_i2c_read_reg(client, MAXIM2C_REG_CHIP_ID, &chipid); if (ret == 0) { if (chipid == maxim2c->chipid) { if (chipid == MAX96716_CHIP_ID) { @@ -93,7 +99,7 @@ static int maxim2c_check_local_chipid(maxim2c_t *maxim2c) static irqreturn_t maxim2c_hot_plug_detect_irq_handler(int irq, void *dev_id) { - struct maxim2c *maxim2c = dev_id; + maxim2c_t *maxim2c = dev_id; struct device *dev = &maxim2c->client->dev; int lock_gpio_level = 0; @@ -150,7 +156,7 @@ static void maxim2c_hot_plug_state_check_work(struct work_struct *work) { struct maxim2c_hot_plug_work *hot_plug_work = container_of(work, struct maxim2c_hot_plug_work, state_d_work.work); - struct maxim2c *maxim2c = + maxim2c_t *maxim2c = container_of(hot_plug_work, struct maxim2c, hot_plug_work); struct device *dev = &maxim2c->client->dev; u8 curr_lock_state = 0, last_lock_state = 0, link_lock_change = 0; @@ -168,7 +174,8 @@ static void maxim2c_hot_plug_state_check_work(struct work_struct *work) last_lock_state = maxim2c->link_lock_state; if ((maxim2c->hot_plug_state == MAXIM2C_HOT_PLUG_OUT) && (last_lock_state == link_enable_mask)) { - maxim2c_link_select_remote_control(maxim2c, 0); + // i2c mux enable: disable all remote channel + maxim2c_i2c_mux_enable(maxim2c, 0x00); } curr_lock_state = maxim2c_link_get_lock_state(maxim2c, link_enable_mask); @@ -189,7 +196,8 @@ static void maxim2c_hot_plug_state_check_work(struct work_struct *work) if (maxim2c->hot_plug_irq > 0) disable_irq(maxim2c->hot_plug_irq); - maxim2c_remote_devices_init(maxim2c, MAXIM2C_LINK_MASK_A); + // Link A remote device start stream + maxim2c_remote_devices_s_stream(maxim2c, MAXIM2C_LINK_MASK_A, 1); if (maxim2c->hot_plug_irq > 0) enable_irq(maxim2c->hot_plug_irq); @@ -198,6 +206,9 @@ static void maxim2c_hot_plug_state_check_work(struct work_struct *work) } else { dev_info(dev, "Link A plug out\n"); + // Link A remote device stop stream + maxim2c_remote_devices_s_stream(maxim2c, MAXIM2C_LINK_MASK_A, 0); + maxim2c_video_pipe_linkid_enable(maxim2c, link_id, false); } } @@ -211,7 +222,8 @@ static void maxim2c_hot_plug_state_check_work(struct work_struct *work) if (maxim2c->hot_plug_irq > 0) disable_irq(maxim2c->hot_plug_irq); - maxim2c_remote_devices_init(maxim2c, MAXIM2C_LINK_MASK_B); + // Link B remote device start stream + maxim2c_remote_devices_s_stream(maxim2c, MAXIM2C_LINK_MASK_B, 1); if (maxim2c->hot_plug_irq > 0) enable_irq(maxim2c->hot_plug_irq); @@ -220,13 +232,16 @@ static void maxim2c_hot_plug_state_check_work(struct work_struct *work) } else { dev_info(dev, "Link B plug out\n"); + // Link B remote device stop stream + maxim2c_remote_devices_s_stream(maxim2c, MAXIM2C_LINK_MASK_B, 0); + maxim2c_video_pipe_linkid_enable(maxim2c, link_id, false); } } if (curr_lock_state == link_enable_mask) { - // remote control mask enable - maxim2c_link_select_remote_control(maxim2c, link_enable_mask); + // i2c mux enable: enable all enabled link for remote control + maxim2c_i2c_mux_enable(maxim2c, link_enable_mask); } else { queue_delayed_work(maxim2c->hot_plug_work.state_check_wq, &maxim2c->hot_plug_work.state_d_work, @@ -291,91 +306,71 @@ static inline u32 maxim2c_cal_delay(u32 cycles) return DIV_ROUND_UP(cycles, MAXIM2C_XVCLK_FREQ / 1000 / 1000); } -static int maxim2c_local_device_power_on(maxim2c_t *maxim2c) +static int maxim2c_device_power_on(maxim2c_t *maxim2c) { struct device *dev = &maxim2c->client->dev; + int ret = 0; - if (!IS_ERR(maxim2c->pwdn_gpio)) { - dev_info(dev, "local device pwdn gpio on\n"); + ret = regulator_bulk_enable(MAXIM2C_NUM_SUPPLIES, maxim2c->supplies); + if (ret < 0) { + dev_err(dev, "Failed to enable regulators\n"); + return -EINVAL; + } - gpiod_set_value_cansleep(maxim2c->pwdn_gpio, 1); - - usleep_range(20000, 20100); + ret = regulator_enable(maxim2c->pwdn_regulator); + if (ret < 0) { + dev_err(dev, "Unable to turn pwdn regulator on\n"); + return ret; } return 0; } -static void maxim2c_local_device_power_off(maxim2c_t *maxim2c) +static void maxim2c_device_power_off(maxim2c_t *maxim2c) { struct device *dev = &maxim2c->client->dev; + int ret = 0; - if (!IS_ERR(maxim2c->pwdn_gpio)) { - dev_info(dev, "local device pwdn gpio off\n"); + ret = regulator_disable(maxim2c->pwdn_regulator); + if (ret < 0) + dev_warn(dev, "Unable to turn pwdn regulator off\n"); - gpiod_set_value_cansleep(maxim2c->pwdn_gpio, 0); + ret = regulator_bulk_disable(MAXIM2C_NUM_SUPPLIES, maxim2c->supplies); + if (ret < 0) { + dev_warn(dev, "Failed to disable regulators\n"); } } -static int maxim2c_remote_device_power_on(maxim2c_t *maxim2c) -{ - struct device *dev = &maxim2c->client->dev; - - // remote PoC enable - if (!IS_ERR(maxim2c->pocen_gpio)) { - dev_info(dev, "remote device pocen gpio on\n"); - - gpiod_set_value_cansleep(maxim2c->pocen_gpio, 1); - usleep_range(5000, 10000); - } - - return 0; -} - -static int maxim2c_remote_device_power_off(maxim2c_t *maxim2c) -{ - struct device *dev = &maxim2c->client->dev; - - // remote PoC enable - if (!IS_ERR(maxim2c->pocen_gpio)) { - dev_info(dev, "remote device pocen gpio off\n"); - - gpiod_set_value_cansleep(maxim2c->pocen_gpio, 0); - } - - return 0; -} - static int maxim2c_runtime_resume(struct device *dev) { +#if MAXIM2C_LOCAL_DES_ON_OFF_EN struct i2c_client *client = to_i2c_client(dev); struct v4l2_subdev *sd = i2c_get_clientdata(client); - struct maxim2c *maxim2c = v4l2_get_subdevdata(sd); + maxim2c_t *maxim2c = v4l2_get_subdevdata(sd); int ret = 0; -#if MAXIM2C_LOCAL_DES_ON_OFF_EN - ret |= maxim2c_local_device_power_on(maxim2c); -#endif /* MAXIM2C_LOCAL_DES_ON_OFF_EN */ - - ret |= maxim2c_remote_device_power_on(maxim2c); + ret |= maxim2c_device_power_on(maxim2c); return ret; +#else + return 0; +#endif /* MAXIM2C_LOCAL_DES_ON_OFF_EN */ } static int maxim2c_runtime_suspend(struct device *dev) { +#if MAXIM2C_LOCAL_DES_ON_OFF_EN struct i2c_client *client = to_i2c_client(dev); struct v4l2_subdev *sd = i2c_get_clientdata(client); - struct maxim2c *maxim2c = v4l2_get_subdevdata(sd); + maxim2c_t *maxim2c = v4l2_get_subdevdata(sd); int ret = 0; - ret |= maxim2c_remote_device_power_off(maxim2c); - -#if MAXIM2C_LOCAL_DES_ON_OFF_EN - maxim2c_local_device_power_off(maxim2c); -#endif /* MAXIM2C_LOCAL_DES_ON_OFF_EN */ + maxim2c_device_power_off(maxim2c); return ret; +#else + return 0; +#endif /* MAXIM2C_LOCAL_DES_ON_OFF_EN */ } static const struct dev_pm_ops maxim2c_pm_ops = { @@ -386,7 +381,9 @@ static const struct dev_pm_ops maxim2c_pm_ops = { static void maxim2c_module_data_init(maxim2c_t *maxim2c) { maxim2c_link_data_init(maxim2c); + maxim2c_video_pipe_data_init(maxim2c); + maxim2c_mipi_txphy_data_init(maxim2c); } @@ -480,30 +477,22 @@ static int maxim2c_module_hw_previnit(maxim2c_t *maxim2c) int ret = 0; // Disable data transmission through video pipe. - ret = maxim2c_i2c_update_byte(client, - 0x0002, MAXIM2C_I2C_REG_ADDR_16BITS, - 0xF0, 0x00); + ret = maxim2c_i2c_update_reg(client, 0x0002, 0xF0, 0x00); if (ret) return ret; // Video Pipe Y/Z Disable - ret = maxim2c_i2c_update_byte(client, - 0x0160, MAXIM2C_I2C_REG_ADDR_16BITS, - BIT(1) | BIT(0), 0); + ret = maxim2c_i2c_update_reg(client, 0x0160, BIT(1) | BIT(0), 0); if (ret) return ret; // MIPI CSI output disable. - ret = maxim2c_i2c_write_byte(client, - 0x0313, MAXIM2C_I2C_REG_ADDR_16BITS, - 0x00); + ret = maxim2c_i2c_write_reg(client, 0x0313, 0x00); if (ret) return ret; // MIPI TXPHY standby - ret = maxim2c_i2c_update_byte(client, - 0x0332, MAXIM2C_I2C_REG_ADDR_16BITS, - 0xF0, 0x00); + ret = maxim2c_i2c_update_reg(client, 0x0332, 0xF0, 0x00); if (ret) return ret; @@ -516,17 +505,13 @@ static int maxim2c_module_hw_postinit(maxim2c_t *maxim2c) int ret = 0; // video pipe disable all - ret |= maxim2c_i2c_write_byte(client, - 0x0160, MAXIM2C_I2C_REG_ADDR_16BITS, - 0); + ret |= maxim2c_i2c_write_reg(client, 0x0160, 0); // remote control disable all ret |= maxim2c_link_select_remote_control(maxim2c, 0); // Enable data transmission through video pipe. - ret |= maxim2c_i2c_update_byte(client, - 0x0002, MAXIM2C_I2C_REG_ADDR_16BITS, - 0xF0, 0xF0); + ret |= maxim2c_i2c_update_reg(client, 0x0002, 0xF0, 0xF0); return ret; } @@ -577,6 +562,18 @@ int maxim2c_module_hw_init(maxim2c_t *maxim2c) } EXPORT_SYMBOL(maxim2c_module_hw_init); +static int maxim2c_configure_regulators(maxim2c_t *maxim2c) +{ + unsigned int i; + + for (i = 0; i < MAXIM2C_NUM_SUPPLIES; i++) + maxim2c->supplies[i].supply = maxim2c_supply_names[i]; + + return devm_regulator_bulk_get(&maxim2c->client->dev, + MAXIM2C_NUM_SUPPLIES, + maxim2c->supplies); +} + static int maxim2c_probe(struct i2c_client *client, const struct i2c_device_id *id) { @@ -621,15 +618,24 @@ static int maxim2c_probe(struct i2c_client *client, return -EINVAL; } - maxim2c->pwdn_gpio = devm_gpiod_get(dev, "pwdn", GPIOD_OUT_LOW); - if (IS_ERR(maxim2c->pwdn_gpio)) - dev_warn(dev, "Failed to get pwdn-gpios, maybe no use\n"); - else - usleep_range(1000, 1100); + ret = maxim2c_configure_regulators(maxim2c); + if (ret) { + dev_err(dev, "Failed to get power regulators\n"); + return ret; + } - maxim2c->pocen_gpio = devm_gpiod_get(dev, "pocen", GPIOD_OUT_LOW); - if (IS_ERR(maxim2c->pocen_gpio)) - dev_warn(dev, "Failed to get pocen-gpios\n"); + maxim2c->pwdn_regulator = devm_regulator_get(dev, "pwdn"); + if (IS_ERR(maxim2c->pwdn_regulator)) { + if (PTR_ERR(maxim2c->pwdn_regulator) != -EPROBE_DEFER) + dev_err(dev, "Unable to get pwdn regulator (%ld)\n", + PTR_ERR(maxim2c->pwdn_regulator)); + else + dev_err(dev, "Get pwdn regulator deferred\n"); + + ret = PTR_ERR(maxim2c->pwdn_regulator); + + return ret; + } maxim2c->lock_gpio = devm_gpiod_get(dev, "lock", GPIOD_IN); if (IS_ERR(maxim2c->lock_gpio)) @@ -637,22 +643,29 @@ static int maxim2c_probe(struct i2c_client *client, mutex_init(&maxim2c->mutex); - ret = maxim2c_local_device_power_on(maxim2c); + ret = maxim2c_device_power_on(maxim2c); if (ret) goto err_destroy_mutex; + pm_runtime_set_active(dev); + pm_runtime_get_noresume(dev); + pm_runtime_enable(dev); + ret = maxim2c_check_local_chipid(maxim2c); if (ret) goto err_power_off; - // client->dev->driver_data = subdev - // subdev->dev->driver_data = maxim2c + /* + * client->dev->driver_data = subdev + * subdev->dev->driver_data = maxim2c + */ ret = maxim2c_v4l2_subdev_init(maxim2c); if (ret) { dev_err(dev, "maxim2c probe v4l2 subdev init error\n"); goto err_power_off; } + /* maxim2c test pattern */ #if MAXIM2C_TEST_PATTERN ret = maxim2c_pattern_data_init(maxim2c); if (ret) @@ -664,9 +677,10 @@ static int maxim2c_probe(struct i2c_client *client, goto err_power_off; #endif /* MAXIM2C_LOCAL_DES_ON_OFF_EN */ - pm_runtime_set_active(dev); - pm_runtime_enable(dev); - pm_runtime_idle(dev); + pm_runtime_set_autosuspend_delay(dev, 1000); + pm_runtime_use_autosuspend(dev); + pm_runtime_mark_last_busy(dev); + pm_runtime_put_autosuspend(dev); return 0; #endif /* MAXIM2C_TEST_PATTERN */ @@ -680,23 +694,31 @@ static int maxim2c_probe(struct i2c_client *client, goto err_subdev_deinit; #endif /* MAXIM2C_LOCAL_DES_ON_OFF_EN */ - ret = maxim2c_remote_mfd_add_devices(maxim2c); + ret = maxim2c_i2c_mux_init(maxim2c); if (ret) goto err_subdev_deinit; + // i2c mux enable: default disable all remote channel + maxim2c_i2c_mux_enable(maxim2c, 0x00); + maxim2c_lock_irq_init(maxim2c); maxim2c_lock_state_work_init(maxim2c); - pm_runtime_set_active(dev); - pm_runtime_enable(dev); - pm_runtime_idle(dev); + pm_runtime_set_autosuspend_delay(dev, 1000); + pm_runtime_use_autosuspend(dev); + pm_runtime_mark_last_busy(dev); + pm_runtime_put_autosuspend(dev); return 0; err_subdev_deinit: maxim2c_v4l2_subdev_deinit(maxim2c); + err_power_off: - maxim2c_local_device_power_off(maxim2c); + pm_runtime_disable(dev); + pm_runtime_put_noidle(dev); + maxim2c_device_power_off(maxim2c); + err_destroy_mutex: mutex_destroy(&maxim2c->mutex); @@ -705,17 +727,20 @@ err_destroy_mutex: static int maxim2c_remove(struct i2c_client *client) { - maxim2c_t *maxim2c = i2c_get_clientdata(client); + struct v4l2_subdev *sd = i2c_get_clientdata(client); + maxim2c_t *maxim2c = v4l2_get_subdevdata(sd); maxim2c_lock_state_work_deinit(maxim2c); maxim2c_v4l2_subdev_deinit(maxim2c); + maxim2c_i2c_mux_deinit(maxim2c); + mutex_destroy(&maxim2c->mutex); pm_runtime_disable(&client->dev); if (!pm_runtime_status_suspended(&client->dev)) - maxim2c_local_device_power_off(maxim2c); + maxim2c_device_power_off(maxim2c); pm_runtime_set_suspended(&client->dev); return 0; diff --git a/drivers/media/i2c/maxim2c/maxim2c_drv.h b/drivers/media/i2c/maxim/local/maxim2c/maxim2c_drv.h similarity index 86% rename from drivers/media/i2c/maxim2c/maxim2c_drv.h rename to drivers/media/i2c/maxim/local/maxim2c/maxim2c_drv.h index dfaad261cd93..2376c3126d37 100644 --- a/drivers/media/i2c/maxim2c/maxim2c_drv.h +++ b/drivers/media/i2c/maxim/local/maxim2c/maxim2c_drv.h @@ -7,28 +7,31 @@ #ifndef __MAXIM2C_DRV_H__ #define __MAXIM2C_DRV_H__ +#include +#include #include -#include -#include #include +#include #include #include #include #include -#include #include -#include #include "maxim2c_i2c.h" #include "maxim2c_link.h" +#include "maxim2c_video_pipe.h" #include "maxim2c_mipi_txphy.h" -#include "maxim2c_remote.h" #include "maxim2c_pattern.h" +// max96716/max96718 chip id register and value #define MAXIM2C_REG_CHIP_ID 0x0D #define MAX96716_CHIP_ID 0xBE #define MAX96718_CHIP_ID 0xB8 +/* power supply numbers */ +#define MAXIM2C_NUM_SUPPLIES 2 + enum { MAXIM2C_HOT_PLUG_OUT = 0, MAXIM2C_HOT_PLUG_IN, @@ -56,9 +59,10 @@ struct maxim2c_mode { typedef struct maxim2c { struct i2c_client *client; + struct maxim4c_i2c_mux i2c_mux; struct clk *xvclk; - struct gpio_desc *pwdn_gpio; - struct gpio_desc *pocen_gpio; + struct regulator_bulk_data supplies[MAXIM2C_NUM_SUPPLIES]; + struct regulator *pwdn_regulator; struct gpio_desc *lock_gpio; struct mutex mutex; @@ -102,9 +106,6 @@ typedef struct maxim2c { struct maxim2c_pattern pattern; struct maxim2c_i2c_init_seq extra_init_seq; - - struct mfd_cell remote_mfd_devs[MAXIM2C_LINK_ID_MAX]; - maxim2c_remote_t *remote_device[MAXIM2C_LINK_ID_MAX]; } maxim2c_t; #endif /* __MAXIM2C_DRV_H__ */ diff --git a/drivers/media/i2c/maxim2c/maxim2c_i2c.c b/drivers/media/i2c/maxim/local/maxim2c/maxim2c_i2c.c similarity index 61% rename from drivers/media/i2c/maxim2c/maxim2c_i2c.c rename to drivers/media/i2c/maxim/local/maxim2c/maxim2c_i2c.c index 2ae75000d4a1..812b3e6d0be8 100644 --- a/drivers/media/i2c/maxim2c/maxim2c_i2c.c +++ b/drivers/media/i2c/maxim/local/maxim2c/maxim2c_i2c.c @@ -7,13 +7,15 @@ * Author: Cai Wenzhong * */ -#include #include #include -#include "maxim2c_i2c.h" +#include +#include + +#include "maxim2c_api.h" /* Write registers up to 4 at a time */ -int maxim2c_i2c_write_reg(struct i2c_client *client, +int maxim2c_i2c_write(struct i2c_client *client, u16 reg_addr, u16 reg_len, u32 val_len, u32 reg_val) { u32 buf_i, val_i; @@ -54,10 +56,10 @@ int maxim2c_i2c_write_reg(struct i2c_client *client, return 0; } -EXPORT_SYMBOL(maxim2c_i2c_write_reg); +EXPORT_SYMBOL(maxim2c_i2c_write); /* Read registers up to 4 at a time */ -int maxim2c_i2c_read_reg(struct i2c_client *client, +int maxim2c_i2c_read(struct i2c_client *client, u16 reg_addr, u16 reg_len, u32 val_len, u32 *reg_val) { struct i2c_msg msgs[2]; @@ -102,88 +104,88 @@ int maxim2c_i2c_read_reg(struct i2c_client *client, return 0; } -EXPORT_SYMBOL(maxim2c_i2c_read_reg); +EXPORT_SYMBOL(maxim2c_i2c_read); /* Update registers up to 4 at a time */ -int maxim2c_i2c_update_reg(struct i2c_client *client, +int maxim2c_i2c_update(struct i2c_client *client, u16 reg_addr, u16 reg_len, u32 val_len, u32 val_mask, u32 reg_val) { u32 value; int ret; - ret = maxim2c_i2c_read_reg(client, reg_addr, reg_len, val_len, &value); + ret = maxim2c_i2c_read(client, reg_addr, reg_len, val_len, &value); if (ret) return ret; value &= ~val_mask; value |= (reg_val & val_mask); - ret = maxim2c_i2c_write_reg(client, reg_addr, reg_len, val_len, value); + ret = maxim2c_i2c_write(client, reg_addr, reg_len, val_len, value); return ret; } -EXPORT_SYMBOL(maxim2c_i2c_update_reg); +EXPORT_SYMBOL(maxim2c_i2c_update); -int maxim2c_i2c_write_byte(struct i2c_client *client, - u16 reg_addr, u16 reg_len, u8 reg_val) +int maxim2c_i2c_write_reg(struct i2c_client *client, + u16 reg_addr, u8 reg_val) { int ret = 0; - ret = maxim2c_i2c_write_reg(client, - reg_addr, reg_len, + ret = maxim2c_i2c_write(client, + reg_addr, MAXIM2C_I2C_REG_ADDR_16BITS, MAXIM2C_I2C_REG_VALUE_08BITS, reg_val); return ret; } -EXPORT_SYMBOL(maxim2c_i2c_write_byte); +EXPORT_SYMBOL(maxim2c_i2c_write_reg); -int maxim2c_i2c_read_byte(struct i2c_client *client, - u16 reg_addr, u16 reg_len, u8 *reg_val) +int maxim2c_i2c_read_reg(struct i2c_client *client, + u16 reg_addr, u8 *reg_val) { int ret = 0; u32 value = 0; u8 *value_be_p = (u8 *)&value; - ret = maxim2c_i2c_read_reg(client, - reg_addr, reg_len, + ret = maxim2c_i2c_read(client, + reg_addr, MAXIM2C_I2C_REG_ADDR_16BITS, MAXIM2C_I2C_REG_VALUE_08BITS, &value); *reg_val = *value_be_p; return ret; } -EXPORT_SYMBOL(maxim2c_i2c_read_byte); +EXPORT_SYMBOL(maxim2c_i2c_read_reg); -int maxim2c_i2c_update_byte(struct i2c_client *client, - u16 reg_addr, u16 reg_len, u8 val_mask, u8 reg_val) +int maxim2c_i2c_update_reg(struct i2c_client *client, + u16 reg_addr, u8 val_mask, u8 reg_val) { u8 value; int ret; - ret = maxim2c_i2c_read_byte(client, reg_addr, reg_len, &value); + ret = maxim2c_i2c_read_reg(client, reg_addr, &value); if (ret) return ret; value &= ~val_mask; value |= (reg_val & val_mask); - ret = maxim2c_i2c_write_byte(client, reg_addr, reg_len, value); + ret = maxim2c_i2c_write_reg(client, reg_addr, value); return ret; } -EXPORT_SYMBOL(maxim2c_i2c_update_byte); +EXPORT_SYMBOL(maxim2c_i2c_update_reg); int maxim2c_i2c_write_array(struct i2c_client *client, - const struct maxim2c_i2c_regval *regs) + const struct maxim2c_i2c_regval *regs) { u32 i = 0; int ret = 0; for (i = 0; (ret == 0) && (regs[i].reg_addr != MAXIM2C_REG_NULL); i++) { if (regs[i].val_mask != 0) - ret = maxim2c_i2c_update_reg(client, + ret = maxim2c_i2c_update(client, regs[i].reg_addr, regs[i].reg_len, regs[i].val_len, regs[i].val_mask, regs[i].reg_val); else - ret = maxim2c_i2c_write_reg(client, + ret = maxim2c_i2c_write(client, regs[i].reg_addr, regs[i].reg_len, regs[i].val_len, regs[i].reg_val); @@ -402,6 +404,184 @@ int maxim2c_i2c_run_init_seq(struct i2c_client *client, ret = maxim2c_i2c_write_array(client, init_seq->reg_init_seq); + return ret; } EXPORT_SYMBOL(maxim2c_i2c_run_init_seq); + +static int __maybe_unused maxim2c_i2c_mux_select(struct i2c_mux_core *muxc, u32 chan) +{ + maxim2c_t *maxim2c = i2c_mux_priv(muxc); + struct i2c_client *client = maxim2c->client; + struct device *dev = &client->dev; + int ret = 0; + + dev_dbg(dev, "maxim2c i2c mux select chan = %d\n", chan); + + /* Channel select is disabled when configured in the disabled state. */ + if (maxim2c->i2c_mux.mux_disable) { + dev_err(dev, "maxim2c i2c mux is disabled, select error\n"); + return 0; + } + + if (maxim2c->i2c_mux.mux_channel == chan) + return 0; + + maxim2c->i2c_mux.mux_channel = chan; + + ret = maxim2c_link_select_remote_control(maxim2c, BIT(chan)); + if (ret) { + dev_err(dev, "maxim2c link select remote control error\n"); + return ret; + } + + return 0; +} + +static int __maybe_unused maxim2c_i2c_mux_deselect(struct i2c_mux_core *muxc, u32 chan) +{ + maxim2c_t *maxim2c = i2c_mux_priv(muxc); + struct i2c_client *client = maxim2c->client; + struct device *dev = &client->dev; + int ret = 0; + + dev_dbg(dev, "maxim2c i2c mux deselect chan = %d\n", chan); + + /* Channel deselect is disabled when configured in the disabled state. */ + if (maxim2c->i2c_mux.mux_disable) { + dev_err(dev, "maxim2c i2c mux is disabled, deselect error\n"); + return 0; + } + + ret = maxim2c_link_select_remote_control(maxim2c, 0); + if (ret) { + dev_err(dev, "maxim2c link select remote control error\n"); + return ret; + } + + return 0; +} + +int maxim2c_i2c_mux_disable(maxim2c_t *maxim2c) +{ + struct device *dev = &maxim2c->client->dev; + int ret = 0; + + dev_info(dev, "maxim2c i2c mux disable\n"); + + ret = maxim2c_link_select_remote_control(maxim2c, 0xff); + if (ret) { + dev_err(dev, "maxim2c link select remote control error\n"); + return ret; + } + + maxim2c->i2c_mux.mux_disable = true; + return 0; +} +EXPORT_SYMBOL(maxim2c_i2c_mux_disable); + +int maxim2c_i2c_mux_enable(maxim2c_t *maxim2c, u8 def_mask) +{ + struct device *dev = &maxim2c->client->dev; + int ret = 0; + + dev_info(dev, "maxim2c i2c mux enable, mask = 0x%02x\n", def_mask); + + ret = maxim2c_link_select_remote_control(maxim2c, def_mask); + if (ret) { + dev_err(dev, "maxim2c link select remote control error\n"); + return ret; + } + + maxim2c->i2c_mux.mux_disable = false; + maxim2c->i2c_mux.mux_channel = -1; + + return 0; +} +EXPORT_SYMBOL(maxim2c_i2c_mux_enable); + +static u32 maxim2c_i2c_mux_mask(maxim2c_t *maxim2c) +{ + struct device *dev = &maxim2c->client->dev; + struct device_node *i2c_mux; + struct device_node *node = NULL; + u32 i2c_mux_mask = 0; + + /* Balance the of_node_put() performed by of_find_node_by_name(). */ + of_node_get(dev->of_node); + i2c_mux = of_find_node_by_name(dev->of_node, "i2c-mux"); + if (!i2c_mux) { + dev_err(dev, "Failed to find i2c-mux node\n"); + return -EINVAL; + } + + /* Identify which i2c-mux channels are enabled */ + for_each_child_of_node(i2c_mux, node) { + u32 id = 0; + + of_property_read_u32(node, "reg", &id); + if (id >= MAXIM2C_LINK_ID_MAX) + continue; + + if (!of_device_is_available(node)) { + dev_dbg(dev, "Skipping disabled I2C bus port %u\n", id); + continue; + } + + i2c_mux_mask |= BIT(id); + } + of_node_put(node); + of_node_put(i2c_mux); + + return i2c_mux_mask; +} + +int maxim2c_i2c_mux_init(maxim2c_t *maxim2c) +{ + struct i2c_client *client = maxim2c->client; + struct device *dev = &client->dev; + u32 i2c_mux_mask = 0; + int i = 0; + int ret = 0; + + dev_info(dev, "maxim2c i2c mux init\n"); + + if (!i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) + return -ENODEV; + + maxim2c->i2c_mux.muxc = i2c_mux_alloc(client->adapter, dev, + MAXIM2C_LINK_ID_MAX, 0, I2C_MUX_LOCKED, + maxim2c_i2c_mux_select, NULL); + if (!maxim2c->i2c_mux.muxc) + return -ENOMEM; + maxim2c->i2c_mux.muxc->priv = maxim2c; + + for (i = 0; i < MAXIM2C_LINK_ID_MAX; i++) { + ret = i2c_mux_add_adapter(maxim2c->i2c_mux.muxc, 0, i, 0); + if (ret) { + i2c_mux_del_adapters(maxim2c->i2c_mux.muxc); + return ret; + } + } + + i2c_mux_mask = maxim2c_i2c_mux_mask(maxim2c); + maxim2c->i2c_mux.i2c_mux_mask = i2c_mux_mask; + dev_info(dev, "maxim2c i2c mux mask = 0x%x\n", i2c_mux_mask); + + return 0; +} +EXPORT_SYMBOL(maxim2c_i2c_mux_init); + +int maxim2c_i2c_mux_deinit(maxim2c_t *maxim2c) +{ + if (maxim2c->i2c_mux.muxc) + i2c_mux_del_adapters(maxim2c->i2c_mux.muxc); + + maxim2c->i2c_mux.i2c_mux_mask = 0; + maxim2c->i2c_mux.mux_disable = false; + maxim2c->i2c_mux.mux_channel = -1; + + return 0; +} +EXPORT_SYMBOL(maxim2c_i2c_mux_deinit); diff --git a/drivers/media/i2c/maxim2c/maxim2c_i2c.h b/drivers/media/i2c/maxim/local/maxim2c/maxim2c_i2c.h similarity index 52% rename from drivers/media/i2c/maxim2c/maxim2c_i2c.h rename to drivers/media/i2c/maxim/local/maxim2c/maxim2c_i2c.h index 620a4ffb7678..c3d9f09d8df7 100644 --- a/drivers/media/i2c/maxim2c/maxim2c_i2c.h +++ b/drivers/media/i2c/maxim/local/maxim2c/maxim2c_i2c.h @@ -8,6 +8,7 @@ #define __MAXIM2C_I2C_H__ #include +#include /* register address: 8bit or 16bit */ #define MAXIM2C_I2C_REG_ADDR_08BITS 1 @@ -31,6 +32,13 @@ enum { MAXIM2C_I2C_DEV_MAX, }; +struct maxim4c_i2c_mux { + struct i2c_mux_core *muxc; + u32 i2c_mux_mask; + u32 mux_channel; + bool mux_disable; +}; + /* i2c register array end */ #define MAXIM2C_REG_NULL 0xFFFF @@ -52,4 +60,27 @@ struct maxim2c_i2c_init_seq { u32 val_len; }; +/* maxim2c i2c read/write api */ +int maxim2c_i2c_write(struct i2c_client *client, + u16 reg_addr, u16 reg_len, u32 val_len, u32 reg_val); +int maxim2c_i2c_read(struct i2c_client *client, + u16 reg_addr, u16 reg_len, u32 val_len, u32 *reg_val); +int maxim2c_i2c_update(struct i2c_client *client, + u16 reg_addr, u16 reg_len, + u32 val_len, u32 val_mask, u32 reg_val); + +int maxim2c_i2c_write_reg(struct i2c_client *client, + u16 reg_addr, u8 reg_val); +int maxim2c_i2c_read_reg(struct i2c_client *client, + u16 reg_addr, u8 *reg_val); +int maxim2c_i2c_update_reg(struct i2c_client *client, + u16 reg_addr, u8 val_mask, u8 reg_val); + +int maxim2c_i2c_write_array(struct i2c_client *client, + const struct maxim2c_i2c_regval *regs); +int maxim2c_i2c_load_init_seq(struct device *dev, + struct device_node *node, struct maxim2c_i2c_init_seq *init_seq); +int maxim2c_i2c_run_init_seq(struct i2c_client *client, + struct maxim2c_i2c_init_seq *init_seq); + #endif /* __MAXIM2C_I2C_H__ */ diff --git a/drivers/media/i2c/maxim2c/maxim2c_link.c b/drivers/media/i2c/maxim/local/maxim2c/maxim2c_link.c similarity index 86% rename from drivers/media/i2c/maxim2c/maxim2c_link.c rename to drivers/media/i2c/maxim/local/maxim2c/maxim2c_link.c index 4b17335dd7b4..3aa775fba366 100644 --- a/drivers/media/i2c/maxim2c/maxim2c_link.c +++ b/drivers/media/i2c/maxim/local/maxim2c/maxim2c_link.c @@ -19,10 +19,8 @@ static int maxim2c_link_enable_vdd_ldo1(maxim2c_t *maxim2c) * CTRL0: Enable REG_ENABLE * CTRL2: Enable REG_MNL */ - ret |= maxim2c_i2c_update_byte(client, - 0x0010, MAXIM2C_I2C_REG_ADDR_16BITS, BIT(2), BIT(2)); - ret |= maxim2c_i2c_update_byte(client, - 0x0012, MAXIM2C_I2C_REG_ADDR_16BITS, BIT(4), BIT(4)); + ret |= maxim2c_i2c_update_reg(client, 0x0010, BIT(2), BIT(2)); + ret |= maxim2c_i2c_update_reg(client, 0x0012, BIT(4), BIT(4)); return ret; } @@ -45,9 +43,7 @@ static int maxim2c_link_set_rate(maxim2c_t *maxim2c) else link_rate |= (0x2 << 0); - ret |= maxim2c_i2c_update_byte(client, - 0x0001, MAXIM2C_I2C_REG_ADDR_16BITS, - 0x0F, link_rate); + ret |= maxim2c_i2c_update_reg(client, 0x0001, 0x0F, link_rate); } /* Link B rate setting */ @@ -60,9 +56,7 @@ static int maxim2c_link_set_rate(maxim2c_t *maxim2c) else link_rate |= (0x2 << 0); - ret |= maxim2c_i2c_update_byte(client, - 0x0004, MAXIM2C_I2C_REG_ADDR_16BITS, - 0x0F, link_rate); + ret |= maxim2c_i2c_update_reg(client, 0x0004, 0x0F, link_rate); } return ret; @@ -118,9 +112,7 @@ static int maxim2c_link_status_init(maxim2c_t *maxim2c) } } } - ret |= maxim2c_i2c_update_byte(client, - 0x0006, MAXIM2C_I2C_REG_ADDR_16BITS, - reg_mask, reg_value); + ret |= maxim2c_i2c_update_reg(client, 0x0006, reg_mask, reg_value); // AUTO_LINK disable, LINK_CFG for Link A and Link B select reg_mask = BIT(4) | BIT(1) | BIT(0); @@ -130,34 +122,26 @@ static int maxim2c_link_status_init(maxim2c_t *maxim2c) if (link_cfg->link_enable) reg_value |= BIT(link_idx); } - ret |= maxim2c_i2c_update_byte(client, - 0x0010, MAXIM2C_I2C_REG_ADDR_16BITS, - reg_mask, reg_value); + ret |= maxim2c_i2c_update_reg(client, 0x0010, reg_mask, reg_value); // GMSL1 Link disable forward and reverse control channel reg_mask = BIT(1) | BIT(0); reg_value = 0; for (link_idx = 0; link_idx < MAXIM2C_LINK_ID_MAX; link_idx++) { reg_addr = 0x0B04 + 0x100 * link_idx; - ret |= maxim2c_i2c_update_byte(client, - reg_addr, MAXIM2C_I2C_REG_ADDR_16BITS, - reg_mask, reg_value); + ret |= maxim2c_i2c_update_reg(client, reg_addr, reg_mask, reg_value); } // GMSL2 Link disable remote control channel reg_mask = BIT(4); reg_value = BIT(4); reg_addr = 0x0001; - ret |= maxim2c_i2c_update_byte(client, - reg_addr, MAXIM2C_I2C_REG_ADDR_16BITS, - reg_mask, reg_value); + ret |= maxim2c_i2c_update_reg(client, reg_addr, reg_mask, reg_value); reg_mask = BIT(2); reg_value = BIT(2); reg_addr = 0x0003; - ret |= maxim2c_i2c_update_byte(client, - reg_addr, MAXIM2C_I2C_REG_ADDR_16BITS, - reg_mask, reg_value); + ret |= maxim2c_i2c_update_reg(client, reg_addr, reg_mask, reg_value); return ret; } @@ -176,18 +160,14 @@ u8 maxim2c_link_get_lock_state(maxim2c_t *maxim2c, u8 link_mask) link_type = gmsl_link->link_cfg[MAXIM2C_LINK_ID_A].link_type; if (link_type == MAXIM2C_GMSL2) { // GMSL2 Link A - maxim2c_i2c_read_byte(client, - 0x0013, MAXIM2C_I2C_REG_ADDR_16BITS, - &link_lock); + maxim2c_i2c_read_reg(client, 0x0013, &link_lock); if (link_lock & BIT(3)) { lock_state |= MAXIM2C_LINK_MASK_A; dev_dbg(dev, "GMSL2 Link A locked\n"); } } else { // GMSL1 Link A - maxim2c_i2c_read_byte(client, - 0x0BCB, MAXIM2C_I2C_REG_ADDR_16BITS, - &link_lock); + maxim2c_i2c_read_reg(client, 0x0BCB, &link_lock); if (link_lock & BIT(0)) { lock_state |= MAXIM2C_LINK_MASK_A; dev_dbg(dev, "GMSL1 Link A locked\n"); @@ -206,18 +186,14 @@ u8 maxim2c_link_get_lock_state(maxim2c_t *maxim2c, u8 link_mask) link_type = gmsl_link->link_cfg[MAXIM2C_LINK_ID_B].link_type; if (link_type == MAXIM2C_GMSL2) { // GMSL2 Link B - maxim2c_i2c_read_byte(client, - 0x5009, MAXIM2C_I2C_REG_ADDR_16BITS, - &link_lock); + maxim2c_i2c_read_reg(client, 0x5009, &link_lock); if (link_lock & BIT(3)) { lock_state |= MAXIM2C_LINK_MASK_B; dev_dbg(dev, "GMSL2 Link B locked\n"); } } else { // GMSL1 Link B - maxim2c_i2c_read_byte(client, - 0x0CCB, MAXIM2C_I2C_REG_ADDR_16BITS, - &link_lock); + maxim2c_i2c_read_reg(client, 0x0CCB, &link_lock); if (link_lock & BIT(0)) { lock_state |= MAXIM2C_LINK_MASK_B; dev_dbg(dev, "GMSL1 Link B locked\n"); @@ -235,7 +211,7 @@ u8 maxim2c_link_get_lock_state(maxim2c_t *maxim2c, u8 link_mask) } EXPORT_SYMBOL(maxim2c_link_get_lock_state); -int maxim2c_link_oneshot_reset(struct maxim2c *maxim2c, u8 link_mask) +int maxim2c_link_oneshot_reset(maxim2c_t *maxim2c, u8 link_mask) { struct i2c_client *client = maxim2c->client; struct device *dev = &client->dev; @@ -250,9 +226,7 @@ int maxim2c_link_oneshot_reset(struct maxim2c *maxim2c, u8 link_mask) link_idx = MAXIM2C_LINK_ID_A; link_cfg = &gmsl_link->link_cfg[link_idx]; if (link_cfg->link_enable && (link_mask & BIT(link_idx))) { - ret = maxim2c_i2c_update_byte(client, - 0x0010, MAXIM2C_I2C_REG_ADDR_16BITS, - BIT(5), BIT(5)); + ret = maxim2c_i2c_update_reg(client, 0x0010, BIT(5), BIT(5)); if (ret) { dev_err(dev, "Link A oneshot reset error\n"); return ret; @@ -265,9 +239,7 @@ int maxim2c_link_oneshot_reset(struct maxim2c *maxim2c, u8 link_mask) link_idx = MAXIM2C_LINK_ID_B; link_cfg = &gmsl_link->link_cfg[link_idx]; if (link_cfg->link_enable && (link_mask & BIT(link_idx))) { - ret = maxim2c_i2c_update_byte(client, - 0x0012, MAXIM2C_I2C_REG_ADDR_16BITS, - BIT(5), BIT(5)); + ret = maxim2c_i2c_update_reg(client, 0x0012, BIT(5), BIT(5)); if (ret) { dev_err(dev, "Link B oneshot reset error\n"); return ret; @@ -279,13 +251,13 @@ int maxim2c_link_oneshot_reset(struct maxim2c *maxim2c, u8 link_mask) } EXPORT_SYMBOL(maxim2c_link_oneshot_reset); -int maxim2c_link_mask_enable(struct maxim2c *maxim2c, u8 link_mask, bool enable) +int maxim2c_link_mask_enable(maxim2c_t *maxim2c, u8 link_mask, bool enable) { return 0; } EXPORT_SYMBOL(maxim2c_link_mask_enable); -int maxim2c_link_wait_linklock(struct maxim2c *maxim2c, u8 link_mask) +int maxim2c_link_wait_linklock(maxim2c_t *maxim2c, u8 link_mask) { struct i2c_client *client = maxim2c->client; struct device *dev = &client->dev; @@ -335,7 +307,7 @@ int maxim2c_link_wait_linklock(struct maxim2c *maxim2c, u8 link_mask) } EXPORT_SYMBOL(maxim2c_link_wait_linklock); -int maxim2c_link_select_remote_enable(struct maxim2c *maxim2c, u8 link_mask) +int maxim2c_link_select_remote_enable(maxim2c_t *maxim2c, u8 link_mask) { struct i2c_client *client = maxim2c->client; struct device *dev = &client->dev; @@ -365,7 +337,7 @@ int maxim2c_link_select_remote_enable(struct maxim2c *maxim2c, u8 link_mask) } EXPORT_SYMBOL(maxim2c_link_select_remote_enable); -int maxim2c_link_select_remote_control(struct maxim2c *maxim2c, u8 link_mask) +int maxim2c_link_select_remote_control(maxim2c_t *maxim2c, u8 link_mask) { struct i2c_client *client = maxim2c->client; struct device *dev = &client->dev; @@ -394,9 +366,8 @@ int maxim2c_link_select_remote_control(struct maxim2c *maxim2c, u8 link_mask) reg_value = 0; reg_addr = 0x0B04 + 0x100 * link_idx; - ret |= maxim2c_i2c_update_byte(client, - reg_addr, MAXIM2C_I2C_REG_ADDR_16BITS, - reg_mask, reg_value); + ret |= maxim2c_i2c_update_reg(client, + reg_addr, reg_mask, reg_value); } else { // GMSL2 Link remote control channel if (link_idx == MAXIM2C_LINK_ID_A) { @@ -407,9 +378,8 @@ int maxim2c_link_select_remote_control(struct maxim2c *maxim2c, u8 link_mask) reg_value = 0; else reg_value = BIT(4); // Link A remote control channel disabled - ret |= maxim2c_i2c_update_byte(client, - reg_addr, MAXIM2C_I2C_REG_ADDR_16BITS, - reg_mask, reg_value); + ret |= maxim2c_i2c_update_reg(client, + reg_addr, reg_mask, reg_value); } else { reg_addr = 0x0003; reg_mask = BIT(2); @@ -417,9 +387,8 @@ int maxim2c_link_select_remote_control(struct maxim2c *maxim2c, u8 link_mask) reg_value = 0; else reg_value = BIT(2); // Link B remote control channel disabled - ret |= maxim2c_i2c_update_byte(client, - reg_addr, MAXIM2C_I2C_REG_ADDR_16BITS, - reg_mask, reg_value); + ret |= maxim2c_i2c_update_reg(client, + reg_addr, reg_mask, reg_value); } } } @@ -433,6 +402,7 @@ static int maxim2c_gmsl_link_config_parse_dt(struct device *dev, struct device_node *parent_node) { struct device_node *node = NULL; + struct device_node *remote_cam_node = NULL; struct device_node *init_seq_node = NULL; struct maxim2c_i2c_init_seq *init_seq = NULL; struct maxim2c_link_cfg *link_cfg = NULL; @@ -503,6 +473,15 @@ static int maxim2c_gmsl_link_config_parse_dt(struct device *dev, link_cfg->link_rx_rate = value; } + /* link get remote camera node */ + remote_cam_node = of_parse_phandle(node, "link-remote-cam", 0); + if (!IS_ERR_OR_NULL(remote_cam_node)) { + dev_info(dev, "remote camera node: %pOF\n", remote_cam_node); + link_cfg->remote_cam_node = remote_cam_node; + } else { + dev_warn(dev, "link-remote-cam node isn't exist\n"); + } + /* link init sequence */ init_seq_node = of_get_child_by_name(node, "link-init-sequence"); if (!IS_ERR_OR_NULL(init_seq_node)) { diff --git a/drivers/media/i2c/maxim2c/maxim2c_link.h b/drivers/media/i2c/maxim/local/maxim2c/maxim2c_link.h similarity index 95% rename from drivers/media/i2c/maxim2c/maxim2c_link.h rename to drivers/media/i2c/maxim/local/maxim2c/maxim2c_link.h index 3708ee95b584..a9884d46c017 100644 --- a/drivers/media/i2c/maxim2c/maxim2c_link.h +++ b/drivers/media/i2c/maxim/local/maxim2c/maxim2c_link.h @@ -7,6 +7,7 @@ #ifndef __MAXIM2C_LINK_H__ #define __MAXIM2C_LINK_H__ +#include #include "maxim2c_i2c.h" /* Link cable */ @@ -65,6 +66,7 @@ struct maxim2c_link_cfg { u8 link_rx_rate; u8 link_tx_rate; + struct device_node *remote_cam_node; struct maxim2c_i2c_init_seq link_init_seq; }; diff --git a/drivers/media/i2c/maxim2c/maxim2c_mipi_txphy.c b/drivers/media/i2c/maxim/local/maxim2c/maxim2c_mipi_txphy.c similarity index 88% rename from drivers/media/i2c/maxim2c/maxim2c_mipi_txphy.c rename to drivers/media/i2c/maxim/local/maxim2c/maxim2c_mipi_txphy.c index fd2149798242..170ba30d301e 100644 --- a/drivers/media/i2c/maxim2c/maxim2c_mipi_txphy.c +++ b/drivers/media/i2c/maxim/local/maxim2c/maxim2c_mipi_txphy.c @@ -29,9 +29,8 @@ static int maxim2c_txphy_auto_init_deskew(maxim2c_t *maxim2c) phy_cfg = &mipi_txphy->phy_cfg[phy_idx]; if (phy_cfg->phy_enable && (phy_cfg->auto_deskew & BIT(7))) { reg_addr = 0x0403 + 0x40 * phy_idx; - ret |= maxim2c_i2c_write_byte(client, - reg_addr, MAXIM2C_I2C_REG_ADDR_16BITS, - phy_cfg->auto_deskew); + ret |= maxim2c_i2c_write_reg(client, + reg_addr, phy_cfg->auto_deskew); } } @@ -60,9 +59,8 @@ static int maxim2c_mipi_txphy_lane_mapping(maxim2c_t *maxim2c) reg_value |= (phy_cfg->data_lane_map << 4); } if (reg_mask != 0) { - ret |= maxim2c_i2c_update_byte(client, - 0x0333, MAXIM2C_I2C_REG_ADDR_16BITS, - reg_mask, reg_value); + ret |= maxim2c_i2c_update_reg(client, + 0x0333, reg_mask, reg_value); } // MIPI TXPHY C/D: data lane mapping @@ -79,9 +77,8 @@ static int maxim2c_mipi_txphy_lane_mapping(maxim2c_t *maxim2c) reg_value |= (phy_cfg->data_lane_map << 4); } if (reg_mask != 0) { - ret |= maxim2c_i2c_update_byte(client, - 0x0334, MAXIM2C_I2C_REG_ADDR_16BITS, - reg_mask, reg_value); + ret |= maxim2c_i2c_update_reg(client, + 0x0334, reg_mask, reg_value); } return ret; @@ -114,9 +111,8 @@ static int maxim2c_mipi_txphy_type_vcx_lane_num(maxim2c_t *maxim2c) reg_value |= ((phy_cfg->data_lane_num - 1) << 6); reg_addr = 0x040A + 0x40 * phy_idx; - ret |= maxim2c_i2c_update_byte(client, - reg_addr, MAXIM2C_I2C_REG_ADDR_16BITS, - reg_mask, reg_value); + ret |= maxim2c_i2c_update_reg(client, + reg_addr, reg_mask, reg_value); } return ret; @@ -153,18 +149,16 @@ static int maxim2c_mipi_txphy_tunnel_init(maxim2c_t *maxim2c) } reg_addr = 0x0434 + 0x40 * phy_idx; - ret |= maxim2c_i2c_update_byte(client, - reg_addr, MAXIM2C_I2C_REG_ADDR_16BITS, - reg_mask, reg_value); + ret |= maxim2c_i2c_update_reg(client, + reg_addr, reg_mask, reg_value); if (phy_cfg->tunnel_enable) { reg_addr = 0x0433 + 0x40 * phy_idx; reg_mask = (BIT(7) | BIT(6) | BIT(5)); reg_value = ((phy_cfg->tunnel_vs_wait & 0x07) << 5); - ret |= maxim2c_i2c_update_byte(client, - reg_addr, MAXIM2C_I2C_REG_ADDR_16BITS, - reg_mask, reg_value); + ret |= maxim2c_i2c_update_reg(client, + reg_addr, reg_mask, reg_value); } } @@ -192,9 +186,8 @@ int maxim2c_mipi_txphy_enable(maxim2c_t *maxim2c, bool enable) } } - ret |= maxim2c_i2c_update_byte(client, - 0x0332, MAXIM2C_I2C_REG_ADDR_16BITS, - reg_mask, reg_value); + ret |= maxim2c_i2c_update_reg(client, + 0x0332, reg_mask, reg_value); return ret; } @@ -232,21 +225,15 @@ int maxim2c_dphy_dpll_predef_set(maxim2c_t *maxim2c, s64 link_freq_hz) // Hold DPLL in reset (config_soft_rst_n = 0) before changing the rate reg_addr = 0x1C00 + 0x100 * phy_idx; - ret |= maxim2c_i2c_write_byte(client, - reg_addr, MAXIM2C_I2C_REG_ADDR_16BITS, - 0xf4); + ret |= maxim2c_i2c_write_reg(client, reg_addr, 0xf4); // Set dpll data rate reg_addr = 0x031D + 0x03 * phy_idx; - ret |= maxim2c_i2c_update_byte(client, - reg_addr, MAXIM2C_I2C_REG_ADDR_16BITS, - 0x3F, dpll_val); + ret |= maxim2c_i2c_update_reg(client, reg_addr, 0x3F, dpll_val); // Release reset to DPLL (config_soft_rst_n = 1) reg_addr = 0x1C00 + 0x100 * phy_idx; - ret |= maxim2c_i2c_write_byte(client, - reg_addr, MAXIM2C_I2C_REG_ADDR_16BITS, - 0xf5); + ret |= maxim2c_i2c_write_reg(client, reg_addr, 0xf5); } if (ret) { @@ -255,12 +242,10 @@ int maxim2c_dphy_dpll_predef_set(maxim2c_t *maxim2c, s64 link_freq_hz) } #if 0 - ret = read_poll_timeout(maxim2c_i2c_read_byte, ret, + ret = read_poll_timeout(maxim2c_i2c_read_reg, ret, !(ret < 0) && (dpll_lock & dpll_mask), 1000, 10000, false, - client, - 0x0308, MAXIM2C_I2C_REG_ADDR_16BITS, - &dpll_lock); + client, 0x0308, &dpll_lock); if (ret < 0) { dev_err(dev, "DPLL is unlocked: 0x%02x\n", dpll_lock); return ret; @@ -271,9 +256,7 @@ int maxim2c_dphy_dpll_predef_set(maxim2c_t *maxim2c, s64 link_freq_hz) #else // The locking status of DPLL cannot be obtained before csi output usleep_range(1000, 1100); - ret = maxim2c_i2c_read_byte(client, - 0x0308, MAXIM2C_I2C_REG_ADDR_16BITS, - &dpll_lock); + ret = maxim2c_i2c_read_reg(client, 0x0308, &dpll_lock); dev_info(dev, "DPLL lock state: 0x%02x\n", dpll_lock); return ret; @@ -296,9 +279,8 @@ int maxim2c_mipi_csi_output(maxim2c_t *maxim2c, bool enable) reg_value = enable ? BIT(7) : 0; // Force all MIPI clocks running Config - ret |= maxim2c_i2c_update_byte(client, - 0x0330, MAXIM2C_I2C_REG_ADDR_16BITS, - reg_mask, reg_value); + ret |= maxim2c_i2c_update_reg(client, + 0x0330, reg_mask, reg_value); } /* Bit1 of the register 0x0313: CSI_OUT_EN @@ -309,9 +291,8 @@ int maxim2c_mipi_csi_output(maxim2c_t *maxim2c, bool enable) reg_value = enable ? BIT(1) : 0; // MIPI CSI output Setting - ret |= maxim2c_i2c_update_byte(client, - 0x0313, MAXIM2C_I2C_REG_ADDR_16BITS, - reg_mask, reg_value); + ret |= maxim2c_i2c_update_reg(client, + 0x0313, reg_mask, reg_value); return ret; } @@ -536,14 +517,10 @@ int maxim2c_mipi_txphy_hw_init(maxim2c_t *maxim2c) } // MIPI TXPHY Mode setting - ret |= maxim2c_i2c_write_byte(client, - 0x0330, MAXIM2C_I2C_REG_ADDR_16BITS, - mode); + ret |= maxim2c_i2c_write_reg(client, 0x0330, mode); // Waits for a frame before generating MIPI Packet requests to the MIPI TX - ret |= maxim2c_i2c_update_byte(client, - 0x0325, MAXIM2C_I2C_REG_ADDR_16BITS, - BIT(7), BIT(7)); + ret |= maxim2c_i2c_update_reg(client, 0x0325, BIT(7), BIT(7)); // mipi txphy data lane mapping ret |= maxim2c_mipi_txphy_lane_mapping(maxim2c); diff --git a/drivers/media/i2c/maxim2c/maxim2c_mipi_txphy.h b/drivers/media/i2c/maxim/local/maxim2c/maxim2c_mipi_txphy.h similarity index 100% rename from drivers/media/i2c/maxim2c/maxim2c_mipi_txphy.h rename to drivers/media/i2c/maxim/local/maxim2c/maxim2c_mipi_txphy.h diff --git a/drivers/media/i2c/maxim2c/maxim2c_pattern.c b/drivers/media/i2c/maxim/local/maxim2c/maxim2c_pattern.c similarity index 84% rename from drivers/media/i2c/maxim2c/maxim2c_pattern.c rename to drivers/media/i2c/maxim/local/maxim2c/maxim2c_pattern.c index 06f70f3ee27c..22cabb854475 100644 --- a/drivers/media/i2c/maxim2c/maxim2c_pattern.c +++ b/drivers/media/i2c/maxim/local/maxim2c/maxim2c_pattern.c @@ -60,9 +60,8 @@ int maxim2c_pattern_enable(maxim2c_t *maxim2c, bool enable) /* Generate gradient pattern. */ reg_val = enable ? BIT(5) : 0; } - ret = maxim2c_i2c_update_byte(client, - 0x0241, MAXIM2C_I2C_REG_ADDR_16BITS, - reg_mask, reg_val); + ret = maxim2c_i2c_update_reg(client, + 0x0241, reg_mask, reg_val); return ret; } @@ -74,30 +73,22 @@ static int maxim2c_pattern_previnit(maxim2c_t *maxim2c) int ret = 0; // Disable data transmission through video pipe. - ret = maxim2c_i2c_update_byte(client, - 0x0002, MAXIM2C_I2C_REG_ADDR_16BITS, - 0xF0, 0x00); + ret = maxim2c_i2c_update_reg(client, 0x0002, 0xF0, 0x00); if (ret) return ret; // video pipe disable. - ret = maxim2c_i2c_write_byte(client, - 0x0160, MAXIM2C_I2C_REG_ADDR_16BITS, - 0x00); + ret = maxim2c_i2c_write_reg(client, 0x0160, 0x00); if (ret) return ret; // MIPI CSI output disable. - ret = maxim2c_i2c_write_byte(client, - 0x0313, MAXIM2C_I2C_REG_ADDR_16BITS, - 0x00); + ret = maxim2c_i2c_write_reg(client, 0x0313, 0x00); if (ret) return ret; // MIPI TXPHY standby - ret = maxim2c_i2c_update_byte(client, - 0x0332, MAXIM2C_I2C_REG_ADDR_16BITS, - 0xF0, 0x00); + ret = maxim2c_i2c_update_reg(client, 0x0332, 0xF0, 0x00); if (ret) return ret; @@ -131,9 +122,8 @@ static int maxim2c_pattern_config(maxim2c_t *maxim2c) // PATGEN_MODE = 0, Pattern generator disabled // use video from the serializer input - ret |= maxim2c_i2c_update_byte(client, - 0x0241, MAXIM2C_I2C_REG_ADDR_16BITS, - BIT(5) | BIT(4), 0x00); + ret |= maxim2c_i2c_update_reg(client, + 0x0241, BIT(5) | BIT(4), 0x00); /* Pattern PCLK: * 0b00 - 25MHz @@ -141,9 +131,7 @@ static int maxim2c_pattern_config(maxim2c_t *maxim2c) * 0b1x - (PATGEN_CLK_SRC: 0 - 150MHz, 1 - 600MHz). */ pattern_pclk = (pattern_pclk & 0x03); - ret |= maxim2c_i2c_write_byte(client, - 0x0038, MAXIM2C_I2C_REG_ADDR_16BITS, - pattern_pclk); + ret |= maxim2c_i2c_write_reg(client, 0x0038, pattern_pclk); if (pattern_pclk >= PATTERN_PCLK_150M) { reg_mask = BIT(7); if (pattern_pclk == PATTERN_PCLK_600M) @@ -153,82 +141,77 @@ static int maxim2c_pattern_config(maxim2c_t *maxim2c) for (i = 0; i < 2; i++) { reg_addr = 0x01FC + i * 0x20; - ret |= maxim2c_i2c_update_byte(client, - reg_addr, MAXIM2C_I2C_REG_ADDR_16BITS, - reg_mask, reg_val); + ret |= maxim2c_i2c_update_reg(client, + reg_addr, reg_mask, reg_val); } } /* Configure Video Timing Generator for 1920x1080 @ 30 fps. */ // VS_DLY = 0 - ret |= maxim2c_i2c_write_reg(client, + ret |= maxim2c_i2c_write(client, 0x0242, MAXIM2C_I2C_REG_ADDR_16BITS, MAXIM2C_I2C_REG_VALUE_24BITS, 0x000000); // VS_HIGH = Vsw * Htot - ret |= maxim2c_i2c_write_reg(client, + ret |= maxim2c_i2c_write(client, 0x0245, MAXIM2C_I2C_REG_ADDR_16BITS, MAXIM2C_I2C_REG_VALUE_24BITS, v_sw * h_tot); // VS_LOW = (Vactive + Vfp + Vbp) * Htot - ret |= maxim2c_i2c_write_reg(client, + ret |= maxim2c_i2c_write(client, 0x0248, MAXIM2C_I2C_REG_ADDR_16BITS, MAXIM2C_I2C_REG_VALUE_24BITS, (v_active + v_fp + v_bp) * h_tot); // V2H = VS_DLY - ret |= maxim2c_i2c_write_reg(client, + ret |= maxim2c_i2c_write(client, 0x024B, MAXIM2C_I2C_REG_ADDR_16BITS, MAXIM2C_I2C_REG_VALUE_24BITS, 0x000000); // HS_HIGH = Hsw - ret |= maxim2c_i2c_write_reg(client, + ret |= maxim2c_i2c_write(client, 0x024E, MAXIM2C_I2C_REG_ADDR_16BITS, MAXIM2C_I2C_REG_VALUE_16BITS, h_sw); // HS_LOW = Hactive + Hfp + Hbp - ret |= maxim2c_i2c_write_reg(client, + ret |= maxim2c_i2c_write(client, 0x0250, MAXIM2C_I2C_REG_ADDR_16BITS, MAXIM2C_I2C_REG_VALUE_16BITS, h_active + h_fp + h_bp); // HS_CNT = Vtot - ret |= maxim2c_i2c_write_reg(client, + ret |= maxim2c_i2c_write(client, 0x0252, MAXIM2C_I2C_REG_ADDR_16BITS, MAXIM2C_I2C_REG_VALUE_16BITS, v_tot); // V2D = VS_DLY + Htot * (Vsw + Vbp) + (Hsw + Hbp) - ret |= maxim2c_i2c_write_reg(client, + ret |= maxim2c_i2c_write(client, 0x0254, MAXIM2C_I2C_REG_ADDR_16BITS, MAXIM2C_I2C_REG_VALUE_24BITS, h_tot * (v_sw + v_bp) + (h_sw + h_bp)); // DE_HIGH = Hactive - ret |= maxim2c_i2c_write_reg(client, + ret |= maxim2c_i2c_write(client, 0x0257, MAXIM2C_I2C_REG_ADDR_16BITS, MAXIM2C_I2C_REG_VALUE_16BITS, h_active); // DE_LOW = Hfp + Hsw + Hbp - ret |= maxim2c_i2c_write_reg(client, + ret |= maxim2c_i2c_write(client, 0x0259, MAXIM2C_I2C_REG_ADDR_16BITS, MAXIM2C_I2C_REG_VALUE_16BITS, h_fp + h_sw + h_bp); // DE_CNT = Vactive - ret |= maxim2c_i2c_write_reg(client, + ret |= maxim2c_i2c_write(client, 0x025B, MAXIM2C_I2C_REG_ADDR_16BITS, MAXIM2C_I2C_REG_VALUE_16BITS, v_active); /* Generate VS, HS and DE in free-running mode, Invert HS and VS. */ - ret |= maxim2c_i2c_write_byte(client, - 0x0240, MAXIM2C_I2C_REG_ADDR_16BITS, - 0xfb); + ret |= maxim2c_i2c_write_reg(client, 0x0240, 0xfb); /* Configure Video Pattern Generator. */ if (pattern_mode == PATTERN_CHECKERBOARD) { /* Set checkerboard pattern size. */ - ret |= maxim2c_i2c_write_reg(client, + ret |= maxim2c_i2c_write(client, 0x0264, MAXIM2C_I2C_REG_ADDR_16BITS, MAXIM2C_I2C_REG_VALUE_24BITS, 0x3c3c3c); /* Set checkerboard pattern colors. */ - ret |= maxim2c_i2c_write_reg(client, + ret |= maxim2c_i2c_write(client, 0x025E, MAXIM2C_I2C_REG_ADDR_16BITS, MAXIM2C_I2C_REG_VALUE_24BITS, 0xfecc00); - ret |= maxim2c_i2c_write_reg(client, + ret |= maxim2c_i2c_write(client, 0x0261, MAXIM2C_I2C_REG_ADDR_16BITS, MAXIM2C_I2C_REG_VALUE_24BITS, 0x006aa7); } else { /* Set gradient increment. */ - ret |= maxim2c_i2c_write_byte(client, - 0x025D, MAXIM2C_I2C_REG_ADDR_16BITS, - 0x10); + ret |= maxim2c_i2c_write_reg(client, 0x025D, 0x10); } return ret; diff --git a/drivers/media/i2c/maxim2c/maxim2c_pattern.h b/drivers/media/i2c/maxim/local/maxim2c/maxim2c_pattern.h similarity index 100% rename from drivers/media/i2c/maxim2c/maxim2c_pattern.h rename to drivers/media/i2c/maxim/local/maxim2c/maxim2c_pattern.h diff --git a/drivers/media/i2c/maxim/local/maxim2c/maxim2c_remote.c b/drivers/media/i2c/maxim/local/maxim2c/maxim2c_remote.c new file mode 100644 index 000000000000..5bb3d5f18197 --- /dev/null +++ b/drivers/media/i2c/maxim/local/maxim2c/maxim2c_remote.c @@ -0,0 +1,113 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Maxim Dual GMSL Deserializer Remode Device Manage + * + * Copyright (C) 2023 Rockchip Electronics Co., Ltd. + * + * Author: Cai Wenzhong + * + */ +#include +#include +#include +#include +#include +#include + +#include "maxim2c_api.h" + +int maxim2c_remote_devices_power(maxim2c_t *maxim2c, u8 link_mask, int on) +{ + struct device *dev = &maxim2c->client->dev; + maxim2c_gmsl_link_t *gmsl_link = &maxim2c->gmsl_link; + struct maxim2c_link_cfg *link_cfg = NULL; + struct device_node *remote_cam_node = NULL; + struct i2c_client *remote_cam_client = NULL; + struct v4l2_subdev *remote_cam_sd = NULL; + int ret = 0, i = 0; + + dev_dbg(dev, "%s: link mask = 0x%02x, on = %d\n", __func__, link_mask, on); + + for (i = 0; i < MAXIM2C_LINK_ID_MAX; i++) { + if ((link_mask & BIT(i)) == 0) { + dev_dbg(dev, "link id = %d mask is disabled\n", i); + continue; + } + + link_cfg = &gmsl_link->link_cfg[i]; + if (link_cfg->link_enable == 0) { + dev_info(dev, "link id = %d is disabled\n", i); + continue; + } + + remote_cam_node = link_cfg->remote_cam_node; + if (IS_ERR_OR_NULL(remote_cam_node)) { + dev_info(dev, "link id = %d remote camera node error\n", i); + continue; + } + remote_cam_client = of_find_i2c_device_by_node(remote_cam_node); + if (IS_ERR_OR_NULL(remote_cam_client)) { + dev_info(dev, "link id = %d remote camera client error\n", i); + continue; + } + remote_cam_sd = i2c_get_clientdata(remote_cam_client); + if (IS_ERR_OR_NULL(remote_cam_sd)) { + dev_info(dev, "link id = %d remote camera v4l2_subdev error\n", i); + continue; + } + + dev_info(dev, "link id = %d remote camera power = %d\n", i, on); + ret |= v4l2_subdev_call(remote_cam_sd, core, s_power, on); + } + + return ret; +} +EXPORT_SYMBOL(maxim2c_remote_devices_power); + +int maxim2c_remote_devices_s_stream(maxim2c_t *maxim2c, u8 link_mask, int enable) +{ + struct device *dev = &maxim2c->client->dev; + maxim2c_gmsl_link_t *gmsl_link = &maxim2c->gmsl_link; + struct maxim2c_link_cfg *link_cfg = NULL; + struct device_node *remote_cam_node = NULL; + struct i2c_client *remote_cam_client = NULL; + struct v4l2_subdev *remote_cam_sd = NULL; + int ret = 0, i = 0; + + dev_dbg(dev, "%s: link mask = 0x%02x, enable = %d\n", __func__, link_mask, enable); + + for (i = 0; i < MAXIM2C_LINK_ID_MAX; i++) { + if ((link_mask & BIT(i)) == 0) { + dev_dbg(dev, "link id = %d mask is disabled\n", i); + continue; + } + + link_cfg = &gmsl_link->link_cfg[i]; + if (link_cfg->link_enable == 0) { + dev_info(dev, "link id = %d is disabled\n", i); + continue; + } + + remote_cam_node = link_cfg->remote_cam_node; + if (IS_ERR_OR_NULL(remote_cam_node)) { + dev_info(dev, "link id = %d remote camera node error\n", i); + continue; + } + remote_cam_client = of_find_i2c_device_by_node(remote_cam_node); + if (IS_ERR_OR_NULL(remote_cam_client)) { + dev_info(dev, "link id = %d remote camera client error\n", i); + continue; + } + remote_cam_sd = i2c_get_clientdata(remote_cam_client); + if (IS_ERR_OR_NULL(remote_cam_sd)) { + dev_info(dev, "link id = %d remote camera v4l2_subdev error\n", i); + continue; + } + + dev_info(dev, "link id = %d remote camera s_stream = %d\n", i, enable); + ret |= v4l2_subdev_call(remote_cam_sd, video, s_stream, enable); + } + + return ret; +} +EXPORT_SYMBOL(maxim2c_remote_devices_s_stream); diff --git a/drivers/media/i2c/maxim2c/maxim2c_v4l2.c b/drivers/media/i2c/maxim/local/maxim2c/maxim2c_v4l2.c similarity index 92% rename from drivers/media/i2c/maxim2c/maxim2c_v4l2.c rename to drivers/media/i2c/maxim/local/maxim2c/maxim2c_v4l2.c index fd79ab824eed..45797000fd06 100644 --- a/drivers/media/i2c/maxim2c/maxim2c_v4l2.c +++ b/drivers/media/i2c/maxim/local/maxim2c/maxim2c_v4l2.c @@ -16,9 +16,7 @@ #include #include #include -#include #include -#include #include "maxim2c_api.h" @@ -96,9 +94,8 @@ static int maxim2c_support_mode_init(maxim2c_t *maxim2c) dev_info(dev, "=== maxim2c support mode init ===\n"); #if MAXIM2C_TEST_PATTERN - ret = maxim2c_pattern_support_mode_init(maxim2c); - return ret; -#endif + return maxim2c_pattern_support_mode_init(maxim2c); +#endif /* MAXIM2C_TEST_PATTERN */ maxim2c->cfg_modes_num = 1; maxim2c->cur_mode = &maxim2c->supported_mode; @@ -214,7 +211,7 @@ static int maxim2c_support_mode_init(maxim2c_t *maxim2c) #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API static int maxim2c_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) { - struct maxim2c *maxim2c = v4l2_get_subdevdata(sd); + maxim2c_t *maxim2c = v4l2_get_subdevdata(sd); struct v4l2_mbus_framefmt *try_fmt = v4l2_subdev_get_try_format(sd, fh->pad, 0); const struct maxim2c_mode *def_mode = &maxim2c->supported_mode; @@ -236,7 +233,7 @@ static int maxim2c_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) static int maxim2c_s_power(struct v4l2_subdev *sd, int on) { - struct maxim2c *maxim2c = v4l2_get_subdevdata(sd); + maxim2c_t *maxim2c = v4l2_get_subdevdata(sd); struct i2c_client *client = maxim2c->client; int ret = 0; @@ -265,7 +262,7 @@ unlock_and_return: return ret; } -static void maxim2c_get_module_inf(struct maxim2c *maxim2c, +static void maxim2c_get_module_inf(maxim2c_t *maxim2c, struct rkmodule_inf *inf) { memset(inf, 0, sizeof(*inf)); @@ -275,7 +272,7 @@ static void maxim2c_get_module_inf(struct maxim2c *maxim2c, strscpy(inf->base.lens, maxim2c->len_name, sizeof(inf->base.lens)); } -static void maxim2c_get_vicap_rst_inf(struct maxim2c *maxim2c, +static void maxim2c_get_vicap_rst_inf(maxim2c_t *maxim2c, struct rkmodule_vicap_reset_info *rst_info) { struct i2c_client *client = maxim2c->client; @@ -288,7 +285,7 @@ static void maxim2c_get_vicap_rst_inf(struct maxim2c *maxim2c, __func__, rst_info->is_reset); } -static void maxim2c_set_vicap_rst_inf(struct maxim2c *maxim2c, +static void maxim2c_set_vicap_rst_inf(maxim2c_t *maxim2c, struct rkmodule_vicap_reset_info rst_info) { maxim2c->is_reset = rst_info.is_reset; @@ -296,7 +293,7 @@ static void maxim2c_set_vicap_rst_inf(struct maxim2c *maxim2c, static long maxim2c_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) { - struct maxim2c *maxim2c = v4l2_get_subdevdata(sd); + maxim2c_t *maxim2c = v4l2_get_subdevdata(sd); struct rkmodule_csi_dphy_param *dphy_param; long ret = 0; @@ -425,7 +422,7 @@ static long maxim2c_compat_ioctl32(struct v4l2_subdev *sd, unsigned int cmd, } #endif /* CONFIG_COMPAT */ -static int __maxim2c_start_stream(struct maxim2c *maxim2c) +static int __maxim2c_start_stream(maxim2c_t *maxim2c) { struct device *dev = &maxim2c->client->dev; int ret = 0; @@ -452,12 +449,14 @@ static int __maxim2c_start_stream(struct maxim2c *maxim2c) link_mask = maxim2c->gmsl_link.link_enable_mask; video_pipe_mask = maxim2c->video_pipe.pipe_enable_mask; - // disable all remote control - ret = maxim2c_link_select_remote_control(maxim2c, 0); +#if (MAXIM2C_TEST_PATTERN == 0) + // remote devices power on + ret = maxim2c_remote_devices_power(maxim2c, link_mask, 1); if (ret) { - dev_err(dev, "link disable remote control error\n"); + dev_err(dev, "remote devices power on error\n"); return ret; } +#endif /* MAXIM2C_TEST_PATTERN */ // disable all video pipe ret = maxim2c_video_pipe_mask_enable(maxim2c, video_pipe_mask, false); @@ -473,11 +472,15 @@ static int __maxim2c_start_stream(struct maxim2c *maxim2c) } link_mask = maxim2c->gmsl_link.link_locked_mask; - ret = maxim2c_remote_devices_init(maxim2c, link_mask); + +#if (MAXIM2C_TEST_PATTERN == 0) + // remote devices start stream + ret = maxim2c_remote_devices_s_stream(maxim2c, link_mask, 1); if (ret) { - dev_err(dev, "remote devices init error\n"); + dev_err(dev, "remote devices start stream error\n"); return ret; } +#endif /* MAXIM2C_TEST_PATTERN */ // mipi txphy enable setting: standby or enable ret = maxim2c_mipi_txphy_enable(maxim2c, true); @@ -502,12 +505,6 @@ static int __maxim2c_start_stream(struct maxim2c *maxim2c) return ret; } - ret = maxim2c_link_select_remote_control(maxim2c, link_mask); - if (ret) { - dev_err(dev, "remote control enable error\n"); - return ret; - } - /* In case these controls are set before streaming */ mutex_unlock(&maxim2c->mutex); ret = v4l2_ctrl_handler_setup(&maxim2c->ctrl_handler); @@ -540,7 +537,7 @@ static int __maxim2c_start_stream(struct maxim2c *maxim2c) return 0; } -static int __maxim2c_stop_stream(struct maxim2c *maxim2c) +static int __maxim2c_stop_stream(maxim2c_t *maxim2c) { struct device *dev = &maxim2c->client->dev; u8 link_mask = 0, pipe_mask = 0; @@ -564,9 +561,16 @@ static int __maxim2c_stop_stream(struct maxim2c *maxim2c) ret |= maxim2c_video_pipe_mask_enable(maxim2c, pipe_mask, false); - ret |= maxim2c_remote_devices_deinit(maxim2c, link_mask); +#if (MAXIM2C_TEST_PATTERN == 0) + // remote devices stop stream + ret |= maxim2c_remote_devices_s_stream(maxim2c, link_mask, 0); + // remote devices power off + ret |= maxim2c_remote_devices_power(maxim2c, link_mask, 0); +#endif /* MAXIM2C_TEST_PATTERN */ + + // i2c mux enable: default disable all remote channel + ret |= maxim2c_i2c_mux_enable(maxim2c, 0x00); - ret |= maxim2c_link_select_remote_control(maxim2c, 0); ret |= maxim2c_link_mask_enable(maxim2c, link_mask, false); if (ret) { @@ -579,7 +583,7 @@ static int __maxim2c_stop_stream(struct maxim2c *maxim2c) static int maxim2c_s_stream(struct v4l2_subdev *sd, int on) { - struct maxim2c *maxim2c = v4l2_get_subdevdata(sd); + maxim2c_t *maxim2c = v4l2_get_subdevdata(sd); struct i2c_client *client = maxim2c->client; int ret = 0; @@ -594,21 +598,20 @@ static int maxim2c_s_stream(struct v4l2_subdev *sd, int on) goto unlock_and_return; if (on) { - ret = pm_runtime_get_sync(&client->dev); - if (ret < 0) { - pm_runtime_put_noidle(&client->dev); + ret = pm_runtime_resume_and_get(&client->dev); + if (ret < 0) goto unlock_and_return; - } ret = __maxim2c_start_stream(maxim2c); if (ret) { v4l2_err(sd, "start stream failed while write regs\n"); - pm_runtime_put(&client->dev); + pm_runtime_put_sync(&client->dev); goto unlock_and_return; } } else { __maxim2c_stop_stream(maxim2c); - pm_runtime_put(&client->dev); + pm_runtime_mark_last_busy(&client->dev); + pm_runtime_put_autosuspend(&client->dev); } maxim2c->streaming = on; @@ -622,7 +625,7 @@ unlock_and_return: static int maxim2c_g_frame_interval(struct v4l2_subdev *sd, struct v4l2_subdev_frame_interval *fi) { - struct maxim2c *maxim2c = v4l2_get_subdevdata(sd); + maxim2c_t *maxim2c = v4l2_get_subdevdata(sd); const struct maxim2c_mode *mode = maxim2c->cur_mode; mutex_lock(&maxim2c->mutex); @@ -636,7 +639,7 @@ static int maxim2c_enum_mbus_code(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, struct v4l2_subdev_mbus_code_enum *code) { - struct maxim2c *maxim2c = v4l2_get_subdevdata(sd); + maxim2c_t *maxim2c = v4l2_get_subdevdata(sd); const struct maxim2c_mode *mode = maxim2c->cur_mode; if (code->index != 0) @@ -650,7 +653,7 @@ static int maxim2c_enum_frame_sizes(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, struct v4l2_subdev_frame_size_enum *fse) { - struct maxim2c *maxim2c = v4l2_get_subdevdata(sd); + maxim2c_t *maxim2c = v4l2_get_subdevdata(sd); if (fse->index >= maxim2c->cfg_modes_num) return -EINVAL; @@ -671,7 +674,7 @@ maxim2c_enum_frame_interval(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, struct v4l2_subdev_frame_interval_enum *fie) { - struct maxim2c *maxim2c = v4l2_get_subdevdata(sd); + maxim2c_t *maxim2c = v4l2_get_subdevdata(sd); if (fie->index >= maxim2c->cfg_modes_num) return -EINVAL; @@ -688,7 +691,7 @@ static int maxim2c_get_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, struct v4l2_subdev_format *fmt) { - struct maxim2c *maxim2c = v4l2_get_subdevdata(sd); + maxim2c_t *maxim2c = v4l2_get_subdevdata(sd); const struct maxim2c_mode *mode = maxim2c->cur_mode; mutex_lock(&maxim2c->mutex); @@ -718,7 +721,7 @@ static int maxim2c_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, struct v4l2_subdev_format *fmt) { - struct maxim2c *maxim2c = v4l2_get_subdevdata(sd); + maxim2c_t *maxim2c = v4l2_get_subdevdata(sd); struct device *dev = &maxim2c->client->dev; const struct maxim2c_mode *mode = NULL; u64 link_freq = 0, pixel_rate = 0; @@ -770,7 +773,7 @@ static int maxim2c_get_selection(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, struct v4l2_subdev_selection *sel) { - struct maxim2c *maxim2c = v4l2_get_subdevdata(sd); + maxim2c_t *maxim2c = v4l2_get_subdevdata(sd); if (sel->target == V4L2_SEL_TGT_CROP_BOUNDS) { sel->r.left = 0; @@ -786,7 +789,7 @@ static int maxim2c_get_selection(struct v4l2_subdev *sd, static int maxim2c_g_mbus_config(struct v4l2_subdev *sd, unsigned int pad, struct v4l2_mbus_config *config) { - struct maxim2c *maxim2c = v4l2_get_subdevdata(sd); + maxim2c_t *maxim2c = v4l2_get_subdevdata(sd); u32 val = 0; u8 data_lanes = maxim2c->bus_cfg.bus.mipi_csi2.num_data_lanes; @@ -837,7 +840,7 @@ static const struct v4l2_subdev_ops maxim2c_subdev_ops = { .pad = &maxim2c_pad_ops, }; -static int maxim2c_initialize_controls(struct maxim2c *maxim2c) +static int maxim2c_initialize_controls(maxim2c_t *maxim2c) { struct device *dev = &maxim2c->client->dev; const struct maxim2c_mode *mode; diff --git a/drivers/media/i2c/maxim2c/maxim2c_video_pipe.c b/drivers/media/i2c/maxim/local/maxim2c/maxim2c_video_pipe.c similarity index 96% rename from drivers/media/i2c/maxim2c/maxim2c_video_pipe.c rename to drivers/media/i2c/maxim/local/maxim2c/maxim2c_video_pipe.c index 032f7d7ff26f..8b361bf895f3 100644 --- a/drivers/media/i2c/maxim2c/maxim2c_video_pipe.c +++ b/drivers/media/i2c/maxim/local/maxim2c/maxim2c_video_pipe.c @@ -40,9 +40,8 @@ static int maxim2c_video_pipe_select(maxim2c_t *maxim2c) reg_value |= ((pipe_idx + link_idx * MAXIM2C_PIPE_I_ID_MAX) << 3); } - ret |= maxim2c_i2c_update_byte(client, - 0x0161, MAXIM2C_I2C_REG_ADDR_16BITS, - reg_mask, reg_value); + ret |= maxim2c_i2c_update_reg(client, + 0x0161, reg_mask, reg_value); return ret; } @@ -251,9 +250,8 @@ int maxim2c_video_pipe_mask_enable(maxim2c_t *maxim2c, u8 video_pipe_mask, bool } if (reg_mask != 0) { - ret |= maxim2c_i2c_update_byte(client, - 0x0160, MAXIM2C_I2C_REG_ADDR_16BITS, - reg_mask, reg_value); + ret |= maxim2c_i2c_update_reg(client, + 0x0160, reg_mask, reg_value); } return ret; @@ -287,9 +285,8 @@ int maxim2c_video_pipe_linkid_enable(maxim2c_t *maxim2c, u8 link_id, bool enable } if (reg_mask != 0) { - ret = maxim2c_i2c_update_byte(client, - 0x0160, MAXIM2C_I2C_REG_ADDR_16BITS, - reg_mask, reg_value); + ret = maxim2c_i2c_update_reg(client, + 0x0160, reg_mask, reg_value); } return ret; diff --git a/drivers/media/i2c/maxim2c/maxim2c_video_pipe.h b/drivers/media/i2c/maxim/local/maxim2c/maxim2c_video_pipe.h similarity index 100% rename from drivers/media/i2c/maxim2c/maxim2c_video_pipe.h rename to drivers/media/i2c/maxim/local/maxim2c/maxim2c_video_pipe.h diff --git a/drivers/media/i2c/maxim2c/Kconfig b/drivers/media/i2c/maxim2c/Kconfig deleted file mode 100644 index b07b96ae511f..000000000000 --- a/drivers/media/i2c/maxim2c/Kconfig +++ /dev/null @@ -1,46 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -# -# Maxim Dual GMSL deserializer and serializer devices -# -config VIDEO_DES_MAXIM2C - tristate "Maxim Dual GMSL deserializer support" - depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API - depends on MEDIA_CAMERA_SUPPORT - select V4L2_FWNODE - help - This driver supports the Maxim Dual GMSL2/GMSL1 deserializer. - - To compile this driver as a module, choose M here: the - module will be called maxim2c. - -menu "Maxim Dual GMSL serializer devices support" - visible if VIDEO_DES_MAXIM2C - -config MAXIM2C_SER_MAX9295 - tristate "Maxim GMSL2 serializer max9295 support" - depends on VIDEO_DES_MAXIM2C - help - This driver supports the Maxim GMSL2 max9295 serializer. - - To compile this driver as a module, choose M here: the - module will be called remote_max9295. - -config MAXIM2C_SER_MAX96715 - tristate "Maxim GMSL1 Serializer max96715 support" - depends on VIDEO_DES_MAXIM2C - help - This driver supports the Maxim GMSL1 max96715 serializer. - - To compile this driver as a module, choose M here: the - module will be called remote_max96715. - -config MAXIM2C_SER_MAX96717 - tristate "Maxim GMSL2 Serializer max96717 support" - depends on VIDEO_DES_MAXIM2C - help - This driver supports the Maxim GMSL2 max96717 serializer. - - To compile this driver as a module, choose M here: the - module will be called remote_max96717. - -endmenu diff --git a/drivers/media/i2c/maxim2c/maxim2c_remote.c b/drivers/media/i2c/maxim2c/maxim2c_remote.c deleted file mode 100644 index 461c064bcffe..000000000000 --- a/drivers/media/i2c/maxim2c/maxim2c_remote.c +++ /dev/null @@ -1,434 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Maxim Dual GMSL Deserializer Remode Device Manage - * - * Copyright (C) 2023 Rockchip Electronics Co., Ltd. - * - * Author: Cai Wenzhong - * - */ -#include -#include -#include -#include "maxim2c_api.h" - -static const char *maxim2c_remote_devs_name[MAXIM2C_LINK_ID_MAX] = { - "remote0", "remote1" -}; - -static const char *maxim2c_remote_link_compat[MAXIM2C_LINK_ID_MAX] = { - "maxim2c,link0", "maxim2c,link1" -}; - -static int maxim2c_remote_dev_info_parse(struct device *dev, - struct mfd_cell *remote_mfd_dev, u8 link_id) -{ - struct device_node *node = NULL; - const char *remote_device_name = "serdes-remote-device"; - const char *prop_str = NULL, *link_compat = NULL; - u32 sub_idx = 0, remote_id = 0; - int ret = 0; - - node = NULL; - sub_idx = 0; - while ((node = of_get_next_child(dev->of_node, node))) { - if (!strncasecmp(node->name, - remote_device_name, - strlen(remote_device_name))) { - if (sub_idx >= MAXIM2C_LINK_ID_MAX) { - dev_err(dev, "%pOF: Too many matching %s node\n", - dev->of_node, remote_device_name); - - of_node_put(node); - break; - } - - if (!of_device_is_available(node)) { - dev_info(dev, "%pOF is disabled\n", node); - - sub_idx++; - - continue; - } - - /* remote id */ - ret = of_property_read_u32(node, "remote-id", &remote_id); - if (ret) { - sub_idx++; - - continue; - } - if (remote_id >= MAXIM2C_LINK_ID_MAX) { - sub_idx++; - - continue; - } - - if (remote_id != link_id) { - sub_idx++; - - continue; - } - - dev_info(dev, "remote device id = %d\n", remote_id); - - ret = of_property_read_string(node, "compatible", &prop_str); - if (ret) { - dev_err(dev, "%pOF no compatible error\n", node); - - of_node_put(node); - return -EINVAL; - } - - link_compat = maxim2c_remote_link_compat[remote_id]; - if (!strncasecmp(prop_str, - link_compat, strlen(link_compat))) { - dev_info(dev, "compatible property: %s\n", prop_str); - - remote_mfd_dev->name = maxim2c_remote_devs_name[remote_id]; - remote_mfd_dev->of_compatible = prop_str; - - of_node_put(node); - return 0; - } - - dev_err(dev, "%pOF compatible and remote_id mismatch\n", node); - - of_node_put(node); - return -EINVAL; - } - } - - return -EINVAL; -} - -static int maxim2c_remote_mfd_devs_init(maxim2c_t *maxim2c) -{ - struct device *dev = &maxim2c->client->dev; - maxim2c_gmsl_link_t *gmsl_link = &maxim2c->gmsl_link; - struct mfd_cell *remote_mfd_dev = NULL; - int link_idx = 0, nr_mfd_cell = 0; - int ret = 0; - - remote_mfd_dev = maxim2c->remote_mfd_devs; - nr_mfd_cell = 0; - for (link_idx = 0; link_idx < MAXIM2C_LINK_ID_MAX; link_idx++) { - remote_mfd_dev->name = NULL; - remote_mfd_dev->of_compatible = NULL; - - if (gmsl_link->link_cfg[link_idx].link_enable == 0) { - dev_dbg(dev, "%s: link id = %d is disabled\n", - __func__, link_idx); - continue; - } - - ret = maxim2c_remote_dev_info_parse(dev, remote_mfd_dev, link_idx); - if (ret == 0) { - remote_mfd_dev++; - nr_mfd_cell++; - } - } - - dev_info(dev, "Total number of remote devices is %d", nr_mfd_cell); - - return nr_mfd_cell; -} - -int maxim2c_remote_mfd_add_devices(maxim2c_t *maxim2c) -{ - struct device *dev = &maxim2c->client->dev; - int nr_mfd_cell = 0, ret = 0; - - dev_info(dev, "=== maxim2c add remote devices ==="); - - nr_mfd_cell = maxim2c_remote_mfd_devs_init(maxim2c); - if (nr_mfd_cell == 0) { - dev_err(dev, "%s: remote mfd devices init error\n", - __func__); - return -EINVAL; - } - - ret = devm_mfd_add_devices(dev, PLATFORM_DEVID_AUTO, - maxim2c->remote_mfd_devs, nr_mfd_cell, - NULL, 0, NULL); - if (ret) - dev_err(dev, "%s: add remote mfd devices error: %d\n", - __func__, ret); - - return ret; -} -EXPORT_SYMBOL(maxim2c_remote_mfd_add_devices); - -int maxim2c_remote_devices_init(maxim2c_t *maxim2c, u8 link_init_mask) -{ - struct device *dev = &maxim2c->client->dev; - struct maxim2c_remote *remote_device = NULL; - const struct maxim2c_remote_ops *remote_ops = NULL; - u8 link_mask = 0, link_enable = 0, link_locked = 0; - int ret = 0, i = 0; - - dev_dbg(dev, "%s: link init mask = 0x%02x\n", __func__, link_init_mask); - - for (i = 0; i < MAXIM2C_LINK_ID_MAX; i++) { - if ((link_init_mask & BIT(i)) == 0) { - dev_dbg(dev, "link id = %d init mask is disabled\n", i); - continue; - } - - link_enable = maxim2c->gmsl_link.link_cfg[i].link_enable; - if (link_enable == 0) { - dev_info(dev, "link id = %d is disabled\n", i); - continue; - } - - remote_device = maxim2c->remote_device[i]; - if (remote_device == NULL) { - dev_info(dev, "remote device id = %d isn't detected\n", i); - continue; - } - - if (remote_device->remote_enable == 0) { - dev_info(dev, "remote device id = %d isn't enabled\n", i); - continue; - } - - remote_ops = remote_device->remote_ops; - if (remote_ops == NULL) { - dev_info(dev, "remote device id = %d is no ops\n", i); - continue; - } - - link_mask = BIT(i); - link_locked = maxim2c_link_get_lock_state(maxim2c, link_mask); - if (link_locked != link_mask) { - dev_info(dev, "link id = %d is unlocked\n", i); - continue; - } - - maxim2c_link_select_remote_control(maxim2c, link_mask); - - if (remote_ops->remote_init) - ret |= remote_ops->remote_init(remote_device); - } - - return ret; -} -EXPORT_SYMBOL(maxim2c_remote_devices_init); - -int maxim2c_remote_devices_deinit(maxim2c_t *maxim2c, u8 link_init_mask) -{ - struct device *dev = &maxim2c->client->dev; - struct maxim2c_remote *remote_device = NULL; - const struct maxim2c_remote_ops *remote_ops = NULL; - u8 link_mask = 0, link_enable = 0, link_locked = 0; - int ret = 0, i = 0; - - dev_dbg(dev, "%s: link init mask = 0x%02x\n", __func__, link_init_mask); - - for (i = 0; i < MAXIM2C_LINK_ID_MAX; i++) { - if ((link_init_mask & BIT(i)) == 0) { - dev_dbg(dev, "link id = %d init mask is disabled\n", i); - continue; - } - - link_enable = maxim2c->gmsl_link.link_cfg[i].link_enable; - if (link_enable == 0) { - dev_info(dev, "link id = %d is disabled\n", i); - continue; - } - - remote_device = maxim2c->remote_device[i]; - if (remote_device == NULL) { - dev_info(dev, "remote device id = %d isn't detected\n", i); - continue; - } - - if (remote_device->remote_enable == 0) { - dev_info(dev, "remote device id = %d isn't enabled\n", i); - continue; - } - - remote_ops = remote_device->remote_ops; - if (remote_ops == NULL) { - dev_info(dev, "remote device id = %d is no ops\n", i); - continue; - } - - link_mask = BIT(i); - link_locked = maxim2c_link_get_lock_state(maxim2c, link_mask); - if (link_locked != link_mask) { - dev_info(dev, "link id = %d is unlocked\n", i); - continue; - } - - maxim2c_link_select_remote_control(maxim2c, link_mask); - - if (remote_ops->remote_deinit) - ret |= remote_ops->remote_deinit(remote_device); - } - - return ret; -} -EXPORT_SYMBOL(maxim2c_remote_devices_deinit); - -int maxim2c_remote_load_init_seq(maxim2c_remote_t *remote_device) -{ - struct device *dev = remote_device->dev; - struct device_node *node = NULL; - int ret = 0; - - node = of_get_child_by_name(dev->of_node, "remote-init-sequence"); - if (!IS_ERR_OR_NULL(node)) { - dev_info(dev, "load remote-init-sequence\n"); - - ret = maxim2c_i2c_load_init_seq(dev, node, - &remote_device->remote_init_seq); - - of_node_put(node); - return ret; - } - - return 0; -} -EXPORT_SYMBOL(maxim2c_remote_load_init_seq); - -int maxim2c_remote_i2c_addr_select(maxim2c_remote_t *remote_device, u32 i2c_id) -{ - struct device *dev = remote_device->dev; - struct i2c_client *client = remote_device->client; - - if (i2c_id == MAXIM2C_I2C_SER_DEF) { - client->addr = remote_device->ser_i2c_addr_def; - dev_info(dev, "ser select default i2c addr = 0x%02x\n", client->addr); - } else if (i2c_id == MAXIM2C_I2C_SER_MAP) { - client->addr = remote_device->ser_i2c_addr_map; - dev_info(dev, "ser select mapping i2c addr = 0x%02x\n", client->addr); - } else { - dev_err(dev, "i2c select id = %d error\n", i2c_id); - return -EINVAL; - } - - return 0; -} -EXPORT_SYMBOL(maxim2c_remote_i2c_addr_select); - -int maxim2c_remote_i2c_client_init(maxim2c_remote_t *remote_device, - struct i2c_client *des_client) -{ - struct device *dev = remote_device->dev; - struct i2c_client *ser_client = NULL; - u16 ser_client_addr = 0; - - if (remote_device->ser_i2c_addr_map) - ser_client_addr = remote_device->ser_i2c_addr_map; - else - ser_client_addr = remote_device->ser_i2c_addr_def; - ser_client = devm_i2c_new_dummy_device(&des_client->dev, - des_client->adapter, ser_client_addr); - if (IS_ERR(ser_client)) { - dev_err(dev, "failed to alloc i2c client.\n"); - return -PTR_ERR(ser_client); - } - ser_client->addr = remote_device->ser_i2c_addr_def; - - remote_device->client = ser_client; - i2c_set_clientdata(ser_client, remote_device); - - dev_info(dev, "remote i2c client init, i2c_addr = 0x%02x\n", - ser_client_addr); - - return 0; -} -EXPORT_SYMBOL(maxim2c_remote_i2c_client_init); - -static int maxim2c_remote_device_chain_check(maxim2c_remote_t *remote_device) -{ - struct device *dev = NULL; - struct device_node *endpoint = NULL; - struct device_node *link_node = NULL; - u8 remote_id, link_id; - u32 value; - int ret = 0; - - if (remote_device == NULL) { - dev_err(dev, "%s: input parameter is error\n", __func__); - return -EINVAL; - } - - dev = remote_device->dev; - remote_id = remote_device->remote_id; - - endpoint = of_graph_get_next_endpoint(dev->of_node, NULL); - if (!endpoint) { - dev_err(dev, "%s: no endpoint error\n", __func__); - return -EINVAL; - } - - link_node = of_graph_get_remote_port_parent(endpoint); - if (!link_node) { - dev_err(dev, "%pOF: endpoint has no remote port parent error\n", - endpoint); - return -EINVAL; - } - - ret = of_property_read_u32(link_node, "link-id", &value); - if (ret) { - dev_err(dev, "%pOF: no property link_id error\n", link_node); - - of_node_put(link_node); - return -EINVAL; - } - of_node_put(link_node); - link_id = value; - - if (remote_id != link_id) { - dev_err(dev, "remote_id (%d) != link_id (%d) of %pOF\n", - remote_id, link_id, link_node); - return -EINVAL; - } - - return 0; -} - -int maxim2c_remote_device_register(maxim2c_t *maxim2c, - maxim2c_remote_t *remote_device) -{ - struct device *dev = NULL; - u8 remote_id; - int ret = 0; - - if ((maxim2c == NULL) || (remote_device == NULL)) { - dev_err(dev, "%s: input parameter is error!\n", __func__); - - return -EINVAL; - } - - dev = remote_device->dev; - remote_id = remote_device->remote_id; - if (remote_id >= MAXIM2C_LINK_ID_MAX) { - dev_err(dev, "%s: remote_id = %d is error\n", - __func__, remote_id); - - return -EINVAL; - } - - if (maxim2c->remote_device[remote_id] != NULL) { - dev_err(dev, "%s: remote_id = %d is conflict\n", - __func__, remote_id); - - return -EINVAL; - } - - ret = maxim2c_remote_device_chain_check(remote_device); - if (ret) { - dev_err(dev, "%s: remote device id = %d chain error\n", - __func__, remote_id); - return -EINVAL; - } - - remote_device->remote_enable = 1; - maxim2c->remote_device[remote_id] = remote_device; - - return 0; -} -EXPORT_SYMBOL(maxim2c_remote_device_register); diff --git a/drivers/media/i2c/maxim2c/maxim2c_remote.h b/drivers/media/i2c/maxim2c/maxim2c_remote.h deleted file mode 100644 index 9044d4665fa8..000000000000 --- a/drivers/media/i2c/maxim2c/maxim2c_remote.h +++ /dev/null @@ -1,36 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Copyright (c) 2023 Rockchip Electronics Co., Ltd. - * - */ - -#ifndef __MAXIM2C_REMOTE_H__ -#define __MAXIM2C_REMOTE_H__ - -#include "maxim2c_i2c.h" - -struct maxim2c_remote; - -struct maxim2c_remote_ops { - int (*remote_init)(struct maxim2c_remote *remote); - int (*remote_deinit)(struct maxim2c_remote *remote); -}; - -typedef struct maxim2c_remote { - struct i2c_client *client; - struct device *dev; - void *local; - const struct maxim2c_remote_ops *remote_ops; - struct maxim2c_i2c_init_seq remote_init_seq; - - u8 remote_id; - u8 remote_enable; - - u8 ser_i2c_addr_def; - u8 ser_i2c_addr_map; - - u8 cam_i2c_addr_def; - u8 cam_i2c_addr_map; -} maxim2c_remote_t; - -#endif /* __MAXIM2C_REMOTE_H__ */ diff --git a/drivers/media/i2c/maxim2c/remote_max9295.c b/drivers/media/i2c/maxim2c/remote_max9295.c deleted file mode 100644 index 0ae8a1cc6c28..000000000000 --- a/drivers/media/i2c/maxim2c/remote_max9295.c +++ /dev/null @@ -1,331 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Maxim Dual GMSL2/GMSL1 to CSI-2 Serializer driver - * - * Copyright (C) 2023 Rockchip Electronics Co., Ltd. - * - * Author: Cai Wenzhong - * - */ -#include -#include -#include -#include -#include - -#include "maxim2c_api.h" - -#define MAX9295_I2C_ADDR_DEF 0x40 - -#define MAX9295_CHIP_ID 0x91 -#define MAX9295_REG_CHIP_ID 0x0D - -static int max9295_i2c_addr_remap(maxim2c_remote_t *max9295) -{ - struct device *dev = max9295->dev; - struct i2c_client *client = max9295->client; - u16 i2c_8bit_addr = 0; - int ret = 0; - - if (max9295->ser_i2c_addr_map) { - dev_info(dev, "Serializer i2c address remap\n"); - - maxim2c_remote_i2c_addr_select(max9295, MAXIM2C_I2C_SER_DEF); - - i2c_8bit_addr = (max9295->ser_i2c_addr_map << 1); - ret = maxim2c_i2c_write_byte(client, - 0x0000, MAXIM2C_I2C_REG_ADDR_16BITS, - i2c_8bit_addr); - if (ret) { - dev_err(dev, "ser i2c address map setting error!\n"); - return ret; - } - - maxim2c_remote_i2c_addr_select(max9295, MAXIM2C_I2C_SER_MAP); - } - - if (max9295->cam_i2c_addr_map) { - dev_info(dev, "Camera i2c address remap\n"); - - i2c_8bit_addr = (max9295->cam_i2c_addr_map << 1); - ret = maxim2c_i2c_write_byte(client, - 0x0042, MAXIM2C_I2C_REG_ADDR_16BITS, - i2c_8bit_addr); - if (ret) { - dev_err(dev, "cam i2c address source setting error!\n"); - return ret; - } - - i2c_8bit_addr = (max9295->cam_i2c_addr_def << 1); - ret = maxim2c_i2c_write_byte(client, - 0x0043, MAXIM2C_I2C_REG_ADDR_16BITS, - i2c_8bit_addr); - if (ret) { - dev_err(dev, "cam i2c address destination setting error!\n"); - return ret; - } - } - - return 0; -} - -static int max9295_i2c_addr_def(maxim2c_remote_t *max9295) -{ - struct device *dev = max9295->dev; - struct i2c_client *client = max9295->client; - u16 i2c_8bit_addr = 0; - int ret = 0; - - if (max9295->ser_i2c_addr_map) { - dev_info(dev, "Serializer i2c address def\n"); - - maxim2c_remote_i2c_addr_select(max9295, MAXIM2C_I2C_SER_MAP); - - i2c_8bit_addr = (max9295->ser_i2c_addr_def << 1); - ret = maxim2c_i2c_write_byte(client, - 0x0000, MAXIM2C_I2C_REG_ADDR_16BITS, - i2c_8bit_addr); - if (ret) { - dev_err(dev, "ser i2c address def setting error!\n"); - return ret; - } - - maxim2c_remote_i2c_addr_select(max9295, MAXIM2C_I2C_SER_DEF); - } - - return 0; -} - -static int max9295_check_chipid(maxim2c_remote_t *max9295) -{ - struct device *dev = max9295->dev; - struct i2c_client *client = max9295->client; - u8 chip_id; - int ret = 0; - - // max9295 - ret = maxim2c_i2c_read_byte(client, - MAX9295_REG_CHIP_ID, MAXIM2C_I2C_REG_ADDR_16BITS, - &chip_id); - if (ret != 0) { - dev_info(dev, "Retry check chipid using map address\n"); - maxim2c_remote_i2c_addr_select(max9295, MAXIM2C_I2C_SER_MAP); - ret = maxim2c_i2c_read_byte(client, - MAX9295_REG_CHIP_ID, MAXIM2C_I2C_REG_ADDR_16BITS, - &chip_id); - if (ret != 0) { - dev_err(dev, "MAX9295 detect error, ret(%d)\n", ret); - maxim2c_remote_i2c_addr_select(max9295, MAXIM2C_I2C_SER_DEF); - - return -ENODEV; - } - - max9295_i2c_addr_def(max9295); - } - - if (chip_id != MAX9295_CHIP_ID) { - dev_err(dev, "Unexpected chip id = %02x\n", chip_id); - return -ENODEV; - } - - dev_info(dev, "Detected MAX9295 chip id: 0x%02x\n", chip_id); - - return 0; -} - -static int max9295_soft_power_down(maxim2c_remote_t *max9295) -{ - struct device *dev = max9295->dev; - struct i2c_client *client = max9295->client; - int ret = 0; - - ret = maxim2c_i2c_write_byte(client, - 0x10, MAXIM2C_I2C_REG_ADDR_16BITS, - BIT(7)); - if (ret) { - dev_err(dev, "soft power down setting error!\n"); - return ret; - } - - return 0; -} - -static int max9295_module_init(maxim2c_remote_t *max9295) -{ - struct device *dev = max9295->dev; - struct i2c_client *client = max9295->client; - int ret = 0; - - ret = maxim2c_remote_i2c_addr_select(max9295, MAXIM2C_I2C_SER_DEF); - if (ret) - return ret; - - ret = max9295_check_chipid(max9295); - if (ret) - return ret; - - ret = max9295_i2c_addr_remap(max9295); - if (ret) - return ret; - - ret = maxim2c_i2c_run_init_seq(client, - &max9295->remote_init_seq); - if (ret) { - dev_err(dev, "remote id = %d init sequence error\n", - max9295->remote_id); - return ret; - } - - return 0; -} - -static int max9295_module_deinit(maxim2c_remote_t *max9295) -{ - int ret = 0; - -#if 0 - ret |= max9295_i2c_addr_def(max9295); -#endif - ret |= max9295_soft_power_down(max9295); - - return ret; -} - -static const struct maxim2c_remote_ops max9295_ops = { - .remote_init = max9295_module_init, - .remote_deinit = max9295_module_deinit, -}; - -static int max9295_parse_dt(maxim2c_remote_t *max9295) -{ - struct device *dev = max9295->dev; - struct device_node *of_node = dev->of_node; - u32 value = 0; - int ret = 0; - - dev_info(dev, "=== maxim2c remote max9295 parse dt ===\n"); - - ret = of_property_read_u32(of_node, "remote-id", &value); - if (ret == 0) { - dev_info(dev, "remote-id property: %d\n", value); - max9295->remote_id = value; - } else { - max9295->remote_id = MAXIM2C_LINK_ID_MAX; - } - - dev_info(dev, "max9295 remote id: %d\n", max9295->remote_id); - - ret = of_property_read_u32(of_node, "ser-i2c-addr-def", &value); - if (ret == 0) { - dev_info(dev, "ser-i2c-addr-def property: 0x%x", value); - max9295->ser_i2c_addr_def = value; - } else { - max9295->ser_i2c_addr_def = MAX9295_I2C_ADDR_DEF; - } - - ret = of_property_read_u32(of_node, "ser-i2c-addr-map", &value); - if (ret == 0) { - dev_info(dev, "ser-i2c-addr-map property: 0x%x", value); - max9295->ser_i2c_addr_map = value; - } - - ret = of_property_read_u32(of_node, "cam-i2c-addr-def", &value); - if (ret == 0) { - dev_info(dev, "cam-i2c-addr-def property: 0x%x", value); - max9295->cam_i2c_addr_def = value; - } - - ret = of_property_read_u32(of_node, "cam-i2c-addr-map", &value); - if (ret == 0) { - dev_info(dev, "cam-i2c-addr-map property: 0x%x", value); - max9295->cam_i2c_addr_map = value; - } - - return 0; -} - -static int max9295_probe(struct platform_device *pdev) -{ - struct i2c_client *client = to_i2c_client(pdev->dev.parent); - struct v4l2_subdev *sd = i2c_get_clientdata(client); - struct maxim2c *maxim2c = v4l2_get_subdevdata(sd); - struct maxim2c_remote *max9295 = NULL; - u32 link_id = MAXIM2C_LINK_ID_MAX; - int ret = 0; - - dev_info(&pdev->dev, "max9295 serializer probe\n"); - - link_id = (uintptr_t)of_device_get_match_data(&pdev->dev); - link_id = link_id - MAXIM2C_LINK_ID_MAX; - if (link_id >= MAXIM2C_LINK_ID_MAX) { - dev_err(&pdev->dev, "max9295 probe match data error\n"); - return -EINVAL; - } - dev_info(&pdev->dev, "max9295 probe link id = %d\n", link_id); - - max9295 = devm_kzalloc(&pdev->dev, sizeof(*max9295), GFP_KERNEL); - if (!max9295) { - dev_err(&pdev->dev, "max9295 probe no memory error\n"); - return -ENOMEM; - } - - max9295->dev = &pdev->dev; - max9295->remote_ops = &max9295_ops; - max9295->local = maxim2c; - dev_set_drvdata(max9295->dev, max9295); - - max9295_parse_dt(max9295); - - if (max9295->remote_id != link_id) { - dev_err(&pdev->dev, "max9295 probe remote_id error\n"); - return -EINVAL; - } - - ret = maxim2c_remote_i2c_client_init(max9295, client); - if (ret) { - dev_err(&pdev->dev, "remote i2c client init error\n"); - return ret; - } - - ret = maxim2c_remote_device_register(maxim2c, max9295); - if (ret) { - dev_err(&pdev->dev, "remote serializer register error\n"); - return ret; - } - - maxim2c_remote_load_init_seq(max9295); - - return 0; -} - -static int max9295_remove(struct platform_device *pdev) -{ - return 0; -} - -static const struct of_device_id max9295_of_table[] = { - { - .compatible = "maxim2c,link0,max9295", - .data = (const void *)(MAXIM2C_LINK_ID_MAX + MAXIM2C_LINK_ID_A) - }, { - .compatible = "maxim2c,link1,max9295", - .data = (const void *)(MAXIM2C_LINK_ID_MAX + MAXIM2C_LINK_ID_B) - }, - { /* Sentinel */ }, -}; -MODULE_DEVICE_TABLE(of, max9295_of_table); - -static struct platform_driver max9295_driver = { - .probe = max9295_probe, - .remove = max9295_remove, - .driver = { - .name = "maxim2c-max9295", - .of_match_table = max9295_of_table, - }, -}; - -module_platform_driver(max9295_driver); - -MODULE_AUTHOR("Cai Wenzhong "); -MODULE_DESCRIPTION("Maxim MAX9295 Serializer Driver"); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/i2c/maxim2c/remote_max96715.c b/drivers/media/i2c/maxim2c/remote_max96715.c deleted file mode 100644 index d1c43739b84a..000000000000 --- a/drivers/media/i2c/maxim2c/remote_max96715.c +++ /dev/null @@ -1,381 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Maxim Dual GMSL2/GMSL1 to CSI-2 Serializer driver - * - * Copyright (C) 2023 Rockchip Electronics Co., Ltd. - * - * Author: Cai Wenzhong - * - */ -#include -#include -#include -#include -#include -#include - -#include "maxim2c_api.h" - -#define MAX96715_I2C_ADDR_DEF 0x40 - -#define MAX96715_CHIP_ID 0x45 -#define MAX96715_REG_CHIP_ID 0x1E - -/* Config and Video mode switch */ -#define MAX96715_MODE_SWITCH 1 - -enum { - LINK_MODE_VIDEO = 0, - LINK_MODE_CONFIG, -}; - -static int __maybe_unused max96715_link_mode_select(maxim2c_remote_t *max96715, u32 mode) -{ - struct device *dev = max96715->dev; - struct i2c_client *client = max96715->client; - u8 reg_mask = 0, reg_value = 0; - u32 delay_ms = 0; - int ret = 0; - - dev_dbg(dev, "%s: mode = %d\n", __func__, mode); - - reg_mask = BIT(7) | BIT(6); - if (mode == LINK_MODE_CONFIG) { - reg_value = BIT(6); - delay_ms = 5; - } else { - reg_value = BIT(7); - delay_ms = 50; - } - ret |= maxim2c_i2c_update_byte(client, - 0x04, MAXIM2C_I2C_REG_ADDR_08BITS, - reg_mask, reg_value); - - msleep(delay_ms); - - return ret; -} - -static int max96715_i2c_addr_remap(maxim2c_remote_t *max96715) -{ - struct device *dev = max96715->dev; - struct i2c_client *client = max96715->client; - u16 i2c_8bit_addr = 0; - int ret = 0; - - if (max96715->ser_i2c_addr_map) { - dev_info(dev, "Serializer i2c address remap\n"); - - maxim2c_remote_i2c_addr_select(max96715, MAXIM2C_I2C_SER_DEF); - - i2c_8bit_addr = (max96715->ser_i2c_addr_map << 1); - ret = maxim2c_i2c_write_byte(client, - 0x00, MAXIM2C_I2C_REG_ADDR_08BITS, - i2c_8bit_addr); - if (ret) { - dev_err(dev, "ser i2c address map setting error!\n"); - return ret; - } - - maxim2c_remote_i2c_addr_select(max96715, MAXIM2C_I2C_SER_MAP); - } - - if (max96715->cam_i2c_addr_map) { - dev_info(dev, "Camera i2c address remap\n"); - - i2c_8bit_addr = (max96715->cam_i2c_addr_map << 1); - ret = maxim2c_i2c_write_byte(client, - 0x09, MAXIM2C_I2C_REG_ADDR_08BITS, - i2c_8bit_addr); - if (ret) { - dev_err(dev, "cam i2c address source setting error!\n"); - return ret; - } - - i2c_8bit_addr = (max96715->cam_i2c_addr_def << 1); - ret = maxim2c_i2c_write_byte(client, - 0x0A, MAXIM2C_I2C_REG_ADDR_08BITS, - i2c_8bit_addr); - if (ret) { - dev_err(dev, "cam i2c address destination setting error!\n"); - return ret; - } - } - - return 0; -} - -static int max96715_i2c_addr_def(maxim2c_remote_t *max96715) -{ - struct device *dev = max96715->dev; - struct i2c_client *client = max96715->client; - u16 i2c_8bit_addr = 0; - int ret = 0; - - if (max96715->ser_i2c_addr_map) { - dev_info(dev, "Serializer i2c address def\n"); - - maxim2c_remote_i2c_addr_select(max96715, MAXIM2C_I2C_SER_MAP); - - i2c_8bit_addr = (max96715->ser_i2c_addr_def << 1); - ret = maxim2c_i2c_write_byte(client, - 0x00, MAXIM2C_I2C_REG_ADDR_08BITS, - i2c_8bit_addr); - if (ret) { - dev_err(dev, "ser i2c address def setting error!\n"); - return ret; - } - - maxim2c_remote_i2c_addr_select(max96715, MAXIM2C_I2C_SER_DEF); - } - - return 0; -} - -static int max96715_check_chipid(maxim2c_remote_t *max96715) -{ - struct device *dev = max96715->dev; - struct i2c_client *client = max96715->client; - u8 chip_id; - int ret = 0; - - // max96715 - ret = maxim2c_i2c_read_byte(client, - MAX96715_REG_CHIP_ID, MAXIM2C_I2C_REG_ADDR_08BITS, - &chip_id); - if (ret != 0) { - dev_info(dev, "Retry check chipid using map address\n"); - maxim2c_remote_i2c_addr_select(max96715, MAXIM2C_I2C_SER_MAP); - ret = maxim2c_i2c_read_byte(client, - MAX96715_REG_CHIP_ID, MAXIM2C_I2C_REG_ADDR_08BITS, - &chip_id); - if (ret != 0) { - dev_err(dev, "MAX96715 detect error, ret(%d)\n", ret); - maxim2c_remote_i2c_addr_select(max96715, MAXIM2C_I2C_SER_DEF); - - return -ENODEV; - } - - max96715_i2c_addr_def(max96715); - } - - if (chip_id != MAX96715_CHIP_ID) { - dev_err(dev, "Unexpected chip id = %02x\n", chip_id); - return -ENODEV; - } - - dev_info(dev, "Detected MAX96715 chip id: 0x%02x\n", chip_id); - - return 0; -} - -static int max96715_soft_power_down(maxim2c_remote_t *max96715) -{ - struct device *dev = max96715->dev; - struct i2c_client *client = max96715->client; - int ret = 0; - - ret = maxim2c_i2c_write_byte(client, - 0x13, MAXIM2C_I2C_REG_ADDR_08BITS, - BIT(7)); - if (ret) { - dev_err(dev, "soft power down setting error!\n"); - return ret; - } - - return 0; -} - -static int max96715_module_init(maxim2c_remote_t *max96715) -{ - struct device *dev = max96715->dev; - struct i2c_client *client = max96715->client; - int ret = 0; - - ret = maxim2c_remote_i2c_addr_select(max96715, MAXIM2C_I2C_SER_DEF); - if (ret) - return ret; - - ret = max96715_check_chipid(max96715); - if (ret) - return ret; - - ret = max96715_i2c_addr_remap(max96715); - if (ret) - return ret; - -#if MAX96715_MODE_SWITCH - ret = max96715_link_mode_select(max96715, LINK_MODE_CONFIG); - if (ret) - return ret; -#endif - - ret = maxim2c_i2c_run_init_seq(client, - &max96715->remote_init_seq); - - if (ret) { - dev_err(dev, "remote id = %d init sequence error\n", - max96715->remote_id); - - return ret; - } - -#if MAX96715_MODE_SWITCH - ret = max96715_link_mode_select(max96715, LINK_MODE_VIDEO); - if (ret) - return ret; -#endif - - return 0; -} - -static int max96715_module_deinit(maxim2c_remote_t *max96715) -{ - int ret = 0; - -#if 0 - ret |= max96715_i2c_addr_def(max96715); -#endif - ret |= max96715_soft_power_down(max96715); - - return ret; -} - -static const struct maxim2c_remote_ops max96715_ops = { - .remote_init = max96715_module_init, - .remote_deinit = max96715_module_deinit, -}; - -static int max96715_parse_dt(maxim2c_remote_t *max96715) -{ - struct device *dev = max96715->dev; - struct device_node *of_node = dev->of_node; - u32 value = 0; - int ret = 0; - - dev_info(dev, "=== maxim2c remote max96715 parse dt ===\n"); - - ret = of_property_read_u32(of_node, "remote-id", &value); - if (ret == 0) { - dev_info(dev, "remote-id property: %d\n", value); - max96715->remote_id = value; - } else { - max96715->remote_id = MAXIM2C_LINK_ID_MAX; - } - - dev_info(dev, "max96715 remote id: %d\n", max96715->remote_id); - - ret = of_property_read_u32(of_node, "ser-i2c-addr-def", &value); - if (ret == 0) { - dev_info(dev, "ser-i2c-addr-def property: 0x%x", value); - max96715->ser_i2c_addr_def = value; - } else { - max96715->ser_i2c_addr_def = MAX96715_I2C_ADDR_DEF; - } - - ret = of_property_read_u32(of_node, "ser-i2c-addr-map", &value); - if (ret == 0) { - dev_info(dev, "ser-i2c-addr-map property: 0x%x", value); - max96715->ser_i2c_addr_map = value; - } - - ret = of_property_read_u32(of_node, "cam-i2c-addr-def", &value); - if (ret == 0) { - dev_info(dev, "cam-i2c-addr-def property: 0x%x", value); - max96715->cam_i2c_addr_def = value; - } - - ret = of_property_read_u32(of_node, "cam-i2c-addr-map", &value); - if (ret == 0) { - dev_info(dev, "cam-i2c-addr-map property: 0x%x", value); - max96715->cam_i2c_addr_map = value; - } - - return 0; -} - -static int max96715_probe(struct platform_device *pdev) -{ - struct i2c_client *client = to_i2c_client(pdev->dev.parent); - struct v4l2_subdev *sd = i2c_get_clientdata(client); - struct maxim2c *maxim2c = v4l2_get_subdevdata(sd); - struct maxim2c_remote *max96715 = NULL; - u32 link_id = MAXIM2C_LINK_ID_MAX; - int ret = 0; - - dev_info(&pdev->dev, "max96715 serializer probe\n"); - - link_id = (uintptr_t)of_device_get_match_data(&pdev->dev); - link_id = link_id - MAXIM2C_LINK_ID_MAX; - if (link_id >= MAXIM2C_LINK_ID_MAX) { - dev_err(&pdev->dev, "max96715 probe match data error\n"); - return -EINVAL; - } - dev_info(&pdev->dev, "max96715 probe link id = %d\n", link_id); - - max96715 = devm_kzalloc(&pdev->dev, sizeof(*max96715), GFP_KERNEL); - if (!max96715) { - dev_err(&pdev->dev, "max96715 probe no memory error\n"); - return -ENOMEM; - } - - max96715->dev = &pdev->dev; - max96715->remote_ops = &max96715_ops; - max96715->local = maxim2c; - dev_set_drvdata(max96715->dev, max96715); - - max96715_parse_dt(max96715); - - if (max96715->remote_id != link_id) { - dev_err(&pdev->dev, "max96715 probe remote_id error\n"); - return -EINVAL; - } - - ret = maxim2c_remote_i2c_client_init(max96715, client); - if (ret) { - dev_err(&pdev->dev, "remote i2c client init error\n"); - return ret; - } - - ret = maxim2c_remote_device_register(maxim2c, max96715); - if (ret) { - dev_err(&pdev->dev, "remote serializer register error\n"); - return ret; - } - - maxim2c_remote_load_init_seq(max96715); - - return 0; -} - -static int max96715_remove(struct platform_device *pdev) -{ - return 0; -} - -static const struct of_device_id max96715_of_table[] = { - { - .compatible = "maxim2c,link0,max96715", - .data = (const void *)(MAXIM2C_LINK_ID_MAX + MAXIM2C_LINK_ID_A) - }, { - .compatible = "maxim2c,link1,max96715", - .data = (const void *)(MAXIM2C_LINK_ID_MAX + MAXIM2C_LINK_ID_B) - }, - { /* Sentinel */ }, -}; -MODULE_DEVICE_TABLE(of, max96715_of_table); - -static struct platform_driver max96715_driver = { - .probe = max96715_probe, - .remove = max96715_remove, - .driver = { - .name = "maxim2c-max96715", - .of_match_table = max96715_of_table, - }, -}; - -module_platform_driver(max96715_driver); - -MODULE_AUTHOR("Cai Wenzhong "); -MODULE_DESCRIPTION("Maxim MAX96715 Serializer Driver"); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/i2c/maxim2c/remote_max96717.c b/drivers/media/i2c/maxim2c/remote_max96717.c deleted file mode 100644 index 6e7fb9db46f5..000000000000 --- a/drivers/media/i2c/maxim2c/remote_max96717.c +++ /dev/null @@ -1,310 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Maxim Dual GMSL2/GMSL1 to CSI-2 Serializer driver - * - * Copyright (C) 2023 Rockchip Electronics Co., Ltd. - * - * Author: Cai Wenzhong - * - */ -#include -#include -#include -#include -#include - -#include "maxim2c_api.h" - -#define MAX96717_I2C_ADDR_DEF 0x40 - -#define MAX96717_CHIP_ID 0xBF -#define MAX96717_REG_CHIP_ID 0x0D - -static int max96717_i2c_addr_remap(maxim2c_remote_t *max96717) -{ - struct device *dev = max96717->dev; - struct i2c_client *client = max96717->client; - u16 i2c_8bit_addr = 0; - int ret = 0; - - if (max96717->ser_i2c_addr_map) { - dev_info(dev, "Serializer i2c address remap\n"); - - maxim2c_remote_i2c_addr_select(max96717, MAXIM2C_I2C_SER_DEF); - - i2c_8bit_addr = (max96717->ser_i2c_addr_map << 1); - ret = maxim2c_i2c_write_byte(client, - 0x0000, MAXIM2C_I2C_REG_ADDR_16BITS, - i2c_8bit_addr); - if (ret) { - dev_err(dev, "ser i2c address map setting error!\n"); - return ret; - } - - maxim2c_remote_i2c_addr_select(max96717, MAXIM2C_I2C_SER_MAP); - } - - if (max96717->cam_i2c_addr_map) { - dev_info(dev, "Camera i2c address remap\n"); - - i2c_8bit_addr = (max96717->cam_i2c_addr_map << 1); - ret = maxim2c_i2c_write_byte(client, - 0x0042, MAXIM2C_I2C_REG_ADDR_16BITS, - i2c_8bit_addr); - if (ret) { - dev_err(dev, "cam i2c address source setting error!\n"); - return ret; - } - - i2c_8bit_addr = (max96717->cam_i2c_addr_def << 1); - ret = maxim2c_i2c_write_byte(client, - 0x0043, MAXIM2C_I2C_REG_ADDR_16BITS, - i2c_8bit_addr); - if (ret) { - dev_err(dev, "cam i2c address destination setting error!\n"); - return ret; - } - } - - return 0; -} - -static int max96717_i2c_addr_def(maxim2c_remote_t *max96717) -{ - struct device *dev = max96717->dev; - struct i2c_client *client = max96717->client; - u16 i2c_8bit_addr = 0; - int ret = 0; - - if (max96717->ser_i2c_addr_map) { - dev_info(dev, "Serializer i2c address def\n"); - - maxim2c_remote_i2c_addr_select(max96717, MAXIM2C_I2C_SER_MAP); - - i2c_8bit_addr = (max96717->ser_i2c_addr_def << 1); - ret = maxim2c_i2c_write_byte(client, - 0x0000, MAXIM2C_I2C_REG_ADDR_16BITS, - i2c_8bit_addr); - if (ret) { - dev_err(dev, "ser i2c address def setting error!\n"); - return ret; - } - - maxim2c_remote_i2c_addr_select(max96717, MAXIM2C_I2C_SER_DEF); - } - - return 0; -} - -static int max96717_check_chipid(maxim2c_remote_t *max96717) -{ - struct device *dev = max96717->dev; - struct i2c_client *client = max96717->client; - u8 chip_id; - int ret = 0; - - // max96717 - ret = maxim2c_i2c_read_byte(client, - MAX96717_REG_CHIP_ID, MAXIM2C_I2C_REG_ADDR_16BITS, - &chip_id); - if (ret != 0) { - dev_info(dev, "Retry check chipid using map address\n"); - maxim2c_remote_i2c_addr_select(max96717, MAXIM2C_I2C_SER_MAP); - ret = maxim2c_i2c_read_byte(client, - MAX96717_REG_CHIP_ID, MAXIM2C_I2C_REG_ADDR_16BITS, - &chip_id); - if (ret != 0) { - dev_err(dev, "MAX96717 detect error, ret(%d)\n", ret); - maxim2c_remote_i2c_addr_select(max96717, MAXIM2C_I2C_SER_DEF); - - return -ENODEV; - } - - max96717_i2c_addr_def(max96717); - } - - if (chip_id != MAX96717_CHIP_ID) { - dev_err(dev, "Unexpected chip id = %02x\n", chip_id); - return -ENODEV; - } - dev_info(dev, "Detected MAX96717 chip id: 0x%02x\n", chip_id); - - return 0; -} - -static int max96717_module_init(maxim2c_remote_t *max96717) -{ - struct device *dev = max96717->dev; - struct i2c_client *client = max96717->client; - int ret = 0; - - ret = maxim2c_remote_i2c_addr_select(max96717, MAXIM2C_I2C_SER_DEF); - if (ret) - return ret; - - ret = max96717_check_chipid(max96717); - if (ret) - return ret; - - ret = max96717_i2c_addr_remap(max96717); - if (ret) - return ret; - - ret = maxim2c_i2c_run_init_seq(client, - &max96717->remote_init_seq); - if (ret) { - dev_err(dev, "remote id = %d init sequence error\n", - max96717->remote_id); - return ret; - } - - return 0; -} - -static int max96717_module_deinit(maxim2c_remote_t *max96717) -{ - int ret = 0; - - ret |= max96717_i2c_addr_def(max96717); - - return ret; -} - -static const struct maxim2c_remote_ops max96717_ops = { - .remote_init = max96717_module_init, - .remote_deinit = max96717_module_deinit, -}; - -static int max96717_parse_dt(maxim2c_remote_t *max96717) -{ - struct device *dev = max96717->dev; - struct device_node *of_node = dev->of_node; - u32 value = 0; - int ret = 0; - - dev_info(dev, "=== maxim2c remote max96717 parse dt ===\n"); - - ret = of_property_read_u32(of_node, "remote-id", &value); - if (ret == 0) { - dev_info(dev, "remote-id property: %d\n", value); - max96717->remote_id = value; - } else { - max96717->remote_id = MAXIM2C_LINK_ID_MAX; - } - - dev_info(dev, "max96717 remote id: %d\n", max96717->remote_id); - - ret = of_property_read_u32(of_node, "ser-i2c-addr-def", &value); - if (ret == 0) { - dev_info(dev, "ser-i2c-addr-def property: 0x%x", value); - max96717->ser_i2c_addr_def = value; - } else { - max96717->ser_i2c_addr_def = MAX96717_I2C_ADDR_DEF; - } - - ret = of_property_read_u32(of_node, "ser-i2c-addr-map", &value); - if (ret == 0) { - dev_info(dev, "ser-i2c-addr-map property: 0x%x", value); - max96717->ser_i2c_addr_map = value; - } - - ret = of_property_read_u32(of_node, "cam-i2c-addr-def", &value); - if (ret == 0) { - dev_info(dev, "cam-i2c-addr-def property: 0x%x", value); - max96717->cam_i2c_addr_def = value; - } - - ret = of_property_read_u32(of_node, "cam-i2c-addr-map", &value); - if (ret == 0) { - dev_info(dev, "cam-i2c-addr-map property: 0x%x", value); - max96717->cam_i2c_addr_map = value; - } - - return 0; -} - -static int max96717_probe(struct platform_device *pdev) -{ - struct i2c_client *client = to_i2c_client(pdev->dev.parent); - struct v4l2_subdev *sd = i2c_get_clientdata(client); - struct maxim2c *maxim2c = v4l2_get_subdevdata(sd); - struct maxim2c_remote *max96717 = NULL; - u32 link_id = MAXIM2C_LINK_ID_MAX; - int ret = 0; - - dev_info(&pdev->dev, "max96717 serializer probe\n"); - - link_id = (uintptr_t)of_device_get_match_data(&pdev->dev); - link_id = link_id - MAXIM2C_LINK_ID_MAX; - if (link_id >= MAXIM2C_LINK_ID_MAX) { - dev_err(&pdev->dev, "max96717 probe match data error\n"); - return -EINVAL; - } - dev_info(&pdev->dev, "max96717 probe link id = %d\n", link_id); - - max96717 = devm_kzalloc(&pdev->dev, sizeof(*max96717), GFP_KERNEL); - if (!max96717) { - dev_err(&pdev->dev, "max96717 probe no memory error\n"); - return -ENOMEM; - } - - max96717->dev = &pdev->dev; - max96717->remote_ops = &max96717_ops; - max96717->local = maxim2c; - dev_set_drvdata(max96717->dev, max96717); - - max96717_parse_dt(max96717); - - if (max96717->remote_id != link_id) { - dev_err(&pdev->dev, "max96717 probe remote_id error\n"); - return -EINVAL; - } - - ret = maxim2c_remote_i2c_client_init(max96717, client); - if (ret) { - dev_err(&pdev->dev, "remote i2c client init error\n"); - return ret; - } - - ret = maxim2c_remote_device_register(maxim2c, max96717); - if (ret) { - dev_err(&pdev->dev, "remote serializer register error\n"); - return ret; - } - - maxim2c_remote_load_init_seq(max96717); - - return 0; -} - -static int max96717_remove(struct platform_device *pdev) -{ - return 0; -} - -static const struct of_device_id max96717_of_table[] = { - { - .compatible = "maxim2c,link0,max96717", - .data = (const void *)(MAXIM2C_LINK_ID_MAX + MAXIM2C_LINK_ID_A) - }, { - .compatible = "maxim2c,link1,max96717", - .data = (const void *)(MAXIM2C_LINK_ID_MAX + MAXIM2C_LINK_ID_B) - }, - { /* Sentinel */ }, -}; -MODULE_DEVICE_TABLE(of, max96717_of_table); - -static struct platform_driver max96717_driver = { - .probe = max96717_probe, - .remove = max96717_remove, - .driver = { - .name = "maxim2c-max96717", - .of_match_table = max96717_of_table, - }, -}; - -module_platform_driver(max96717_driver); - -MODULE_AUTHOR("Cai Wenzhong "); -MODULE_DESCRIPTION("Maxim MAX96717 Serializer Driver"); -MODULE_LICENSE("GPL");