mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-09 12:17:12 +09:00
Merge commit '8805d031be45943da983e3018530a1848327ac34'
* commit '8805d031be45943da983e3018530a1848327ac34': media: i2c: add support sc231hai sensor driver media: i2c: add support sc235hai sensor driver media: i2c: add support sc635hai sync mode drm/rockchip: dw_hdmi: Fix the error in the judgment condition for the dsc 1/3 compression rate ARM: configs: rv1126b-ipc: Enable CONFIG_BLK_DEV_INITRD ARM: configs: rv1126b-ipc: Enable CONFIG_EXT4_FS ARM: dts: rockchip: add rv1126b-evb2-v12.dts arm64: dts: rockchip: add rv1126b-evb2-v12.dts media: i2c: format sc635hai code to kernel style drm/rockchip: dsi2: add support support vrr by changing dclk in auto mode drm/rockchip: vop2: add support disable-writeback property arm64: configs: rv1126b_defconfig enable CONFIG_ROCKCHIP_DVBM soc: rockchip: decompress: remove unused code media: rockchp: vpss: remove 16-byte alignment enforcement for input/output stride Change-Id: I855cad54fdb5b705431401fc671c2930a94b0346
This commit is contained in:
@@ -1198,6 +1198,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += \
|
||||
rv1126b-evb2-v10-sii9022-bt1120-to-hdmi.dtb \
|
||||
rv1126b-evb2-v10-tb-400w-emmc.dtb \
|
||||
rv1126b-evb2-v10-tb-400w-spi-nor.dtb \
|
||||
rv1126b-evb2-v12.dtb \
|
||||
rv1126b-evb2-v12-aov-dual-cam.dtb \
|
||||
rv1126b-evb3-v10.dtb \
|
||||
rv1126b-evb4-v10.dtb \
|
||||
|
||||
6
arch/arm/boot/dts/rv1126b-evb2-v12.dts
Normal file
6
arch/arm/boot/dts/rv1126b-evb2-v12.dts
Normal file
@@ -0,0 +1,6 @@
|
||||
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
|
||||
/*
|
||||
* Copyright (c) 2025 Rockchip Electronics Co., Ltd.
|
||||
*/
|
||||
|
||||
#include "arm64/rockchip/rv1126b-evb2-v12.dts"
|
||||
@@ -1,3 +1,7 @@
|
||||
CONFIG_BLK_DEV_INITRD=y
|
||||
CONFIG_CRC16=y
|
||||
CONFIG_CRYPTO=y
|
||||
CONFIG_EXT4_FS=y
|
||||
CONFIG_JFFS2_FS=y
|
||||
CONFIG_MMC=y
|
||||
CONFIG_MSDOS_PARTITION=y
|
||||
@@ -85,16 +89,125 @@ CONFIG_VIDEO_SC850SL=m
|
||||
# CONFIG_BMI088_ACCEL is not set
|
||||
# CONFIG_BMI160_SPI is not set
|
||||
# CONFIG_BSD_DISKLABEL is not set
|
||||
# CONFIG_CRYPTO_842 is not set
|
||||
# CONFIG_CRYPTO_ADIANTUM is not set
|
||||
# CONFIG_CRYPTO_AEGIS128 is not set
|
||||
# CONFIG_CRYPTO_AES is not set
|
||||
# CONFIG_CRYPTO_AES_ARM is not set
|
||||
# CONFIG_CRYPTO_AES_TI is not set
|
||||
CONFIG_CRYPTO_ALGAPI=y
|
||||
CONFIG_CRYPTO_ALGAPI2=y
|
||||
# CONFIG_CRYPTO_ANSI_CPRNG is not set
|
||||
# CONFIG_CRYPTO_ARIA is not set
|
||||
# CONFIG_CRYPTO_AUTHENC is not set
|
||||
# CONFIG_CRYPTO_BLAKE2B is not set
|
||||
# CONFIG_CRYPTO_BLAKE2S_ARM is not set
|
||||
# CONFIG_CRYPTO_BLOWFISH is not set
|
||||
# CONFIG_CRYPTO_CAMELLIA is not set
|
||||
# CONFIG_CRYPTO_CAST5 is not set
|
||||
# CONFIG_CRYPTO_CAST6 is not set
|
||||
# CONFIG_CRYPTO_CBC is not set
|
||||
# CONFIG_CRYPTO_CCM is not set
|
||||
# CONFIG_CRYPTO_CFB is not set
|
||||
# CONFIG_CRYPTO_CHACHA20 is not set
|
||||
# CONFIG_CRYPTO_CHACHA20POLY1305 is not set
|
||||
# CONFIG_CRYPTO_CHACHA20_NEON is not set
|
||||
# CONFIG_CRYPTO_CMAC is not set
|
||||
# CONFIG_CRYPTO_CRC32 is not set
|
||||
CONFIG_CRYPTO_CRC32C=y
|
||||
# CONFIG_CRYPTO_CRCT10DIF is not set
|
||||
# CONFIG_CRYPTO_CRYPTD is not set
|
||||
# CONFIG_CRYPTO_CTR is not set
|
||||
# CONFIG_CRYPTO_CTS is not set
|
||||
# CONFIG_CRYPTO_CURVE25519 is not set
|
||||
# CONFIG_CRYPTO_DEFLATE is not set
|
||||
# CONFIG_CRYPTO_DES is not set
|
||||
# CONFIG_CRYPTO_DEV_AMLOGIC_GXL is not set
|
||||
# CONFIG_CRYPTO_DEV_ATMEL_ECC is not set
|
||||
# CONFIG_CRYPTO_DEV_ATMEL_SHA204A is not set
|
||||
# CONFIG_CRYPTO_DEV_CCREE is not set
|
||||
# CONFIG_CRYPTO_DEV_ROCKCHIP is not set
|
||||
# CONFIG_CRYPTO_DEV_SAFEXCEL is not set
|
||||
# CONFIG_CRYPTO_DH is not set
|
||||
# CONFIG_CRYPTO_DRBG_MENU is not set
|
||||
# CONFIG_CRYPTO_ECB is not set
|
||||
# CONFIG_CRYPTO_ECDH is not set
|
||||
# CONFIG_CRYPTO_ECDSA is not set
|
||||
# CONFIG_CRYPTO_ECHAINIV is not set
|
||||
# CONFIG_CRYPTO_ECRDSA is not set
|
||||
# CONFIG_CRYPTO_ESSIV is not set
|
||||
# CONFIG_CRYPTO_FCRYPT is not set
|
||||
# CONFIG_CRYPTO_GCM is not set
|
||||
# CONFIG_CRYPTO_GHASH is not set
|
||||
CONFIG_CRYPTO_HASH=y
|
||||
CONFIG_CRYPTO_HASH2=y
|
||||
# CONFIG_CRYPTO_HCTR2 is not set
|
||||
# CONFIG_CRYPTO_HMAC is not set
|
||||
CONFIG_CRYPTO_HW=y
|
||||
# CONFIG_CRYPTO_JITTERENTROPY is not set
|
||||
# CONFIG_CRYPTO_KEYWRAP is not set
|
||||
# CONFIG_CRYPTO_LIB_CHACHA20POLY1305 is not set
|
||||
CONFIG_CRYPTO_LIB_UTILS=y
|
||||
# CONFIG_CRYPTO_LRW is not set
|
||||
# CONFIG_CRYPTO_LZ4 is not set
|
||||
# CONFIG_CRYPTO_LZ4HC is not set
|
||||
# CONFIG_CRYPTO_LZO is not set
|
||||
# CONFIG_CRYPTO_MANAGER is not set
|
||||
CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y
|
||||
# CONFIG_CRYPTO_MD4 is not set
|
||||
# CONFIG_CRYPTO_MD5 is not set
|
||||
# CONFIG_CRYPTO_MICHAEL_MIC is not set
|
||||
# CONFIG_CRYPTO_NULL is not set
|
||||
# CONFIG_CRYPTO_OFB is not set
|
||||
# CONFIG_CRYPTO_PCBC is not set
|
||||
# CONFIG_CRYPTO_PCRYPT is not set
|
||||
# CONFIG_CRYPTO_POLY1305 is not set
|
||||
# CONFIG_CRYPTO_POLY1305_ARM is not set
|
||||
# CONFIG_CRYPTO_RMD160 is not set
|
||||
# CONFIG_CRYPTO_RSA is not set
|
||||
# CONFIG_CRYPTO_SEQIV is not set
|
||||
# CONFIG_CRYPTO_SERPENT is not set
|
||||
# CONFIG_CRYPTO_SHA1 is not set
|
||||
# CONFIG_CRYPTO_SHA1_ARM is not set
|
||||
# CONFIG_CRYPTO_SHA256 is not set
|
||||
# CONFIG_CRYPTO_SHA256_ARM is not set
|
||||
# CONFIG_CRYPTO_SHA3 is not set
|
||||
# CONFIG_CRYPTO_SHA512 is not set
|
||||
# CONFIG_CRYPTO_SHA512_ARM is not set
|
||||
# CONFIG_CRYPTO_SM2 is not set
|
||||
# CONFIG_CRYPTO_SM3_GENERIC is not set
|
||||
# CONFIG_CRYPTO_SM4_GENERIC is not set
|
||||
# CONFIG_CRYPTO_STREEBOG is not set
|
||||
# CONFIG_CRYPTO_TEST is not set
|
||||
# CONFIG_CRYPTO_TWOFISH is not set
|
||||
# CONFIG_CRYPTO_USER is not set
|
||||
# CONFIG_CRYPTO_USER_API_AEAD is not set
|
||||
# CONFIG_CRYPTO_USER_API_HASH is not set
|
||||
# CONFIG_CRYPTO_USER_API_RNG is not set
|
||||
# CONFIG_CRYPTO_USER_API_SKCIPHER is not set
|
||||
# CONFIG_CRYPTO_VMAC is not set
|
||||
# CONFIG_CRYPTO_WP512 is not set
|
||||
# CONFIG_CRYPTO_XCBC is not set
|
||||
# CONFIG_CRYPTO_XTS is not set
|
||||
# CONFIG_CRYPTO_XXHASH is not set
|
||||
# CONFIG_CRYPTO_ZSTD is not set
|
||||
CONFIG_DECOMPRESS_GZIP=y
|
||||
# CONFIG_DM9051 is not set
|
||||
# CONFIG_EEPROM_93XX46 is not set
|
||||
# CONFIG_EEPROM_AT25 is not set
|
||||
# CONFIG_ENC28J60 is not set
|
||||
# CONFIG_ENCX24J600 is not set
|
||||
# CONFIG_EXT4_DEBUG is not set
|
||||
# CONFIG_EXT4_FS_POSIX_ACL is not set
|
||||
# CONFIG_EXT4_FS_SECURITY is not set
|
||||
CONFIG_EXT4_USE_FOR_EXT2=y
|
||||
# CONFIG_EZX_PCAP is not set
|
||||
CONFIG_FAT_DEFAULT_CODEPAGE=437
|
||||
CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
|
||||
# CONFIG_FAT_DEFAULT_UTF8 is not set
|
||||
CONFIG_FAT_FS=y
|
||||
CONFIG_FS_IOMAP=y
|
||||
CONFIG_FS_MBCACHE=y
|
||||
# CONFIG_FXLS8962AF_SPI is not set
|
||||
# CONFIG_FXOS8700_SPI is not set
|
||||
# CONFIG_GPIO_74X164 is not set
|
||||
@@ -105,9 +218,13 @@ CONFIG_FAT_FS=y
|
||||
# CONFIG_GPIO_XRA1403 is not set
|
||||
# CONFIG_HI8435 is not set
|
||||
# CONFIG_IIO_SSP_SENSORHUB is not set
|
||||
# CONFIG_INITRAMFS_FORCE is not set
|
||||
CONFIG_INITRAMFS_SOURCE=""
|
||||
# CONFIG_INV_ICM42600_SPI is not set
|
||||
# CONFIG_INV_ICM42670_SPI is not set
|
||||
# CONFIG_INV_MPU6050_SPI is not set
|
||||
CONFIG_JBD2=y
|
||||
# CONFIG_JBD2_DEBUG is not set
|
||||
# CONFIG_JFFS2_CMODE_FAVOURLZO is not set
|
||||
# CONFIG_JFFS2_CMODE_NONE is not set
|
||||
CONFIG_JFFS2_CMODE_PRIORITY=y
|
||||
@@ -220,6 +337,13 @@ CONFIG_NET_VENDOR_ADI=y
|
||||
# CONFIG_PWRSEQ_EMMC is not set
|
||||
# CONFIG_PWRSEQ_SIMPLE is not set
|
||||
# CONFIG_QCA7000_SPI is not set
|
||||
# CONFIG_RD_BZIP2 is not set
|
||||
CONFIG_RD_GZIP=y
|
||||
# CONFIG_RD_LZ4 is not set
|
||||
# CONFIG_RD_LZMA is not set
|
||||
# CONFIG_RD_LZO is not set
|
||||
# CONFIG_RD_XZ is not set
|
||||
# CONFIG_RD_ZSTD is not set
|
||||
CONFIG_REGMAP_SPI=y
|
||||
# CONFIG_REGULATOR_TPS6524X is not set
|
||||
# CONFIG_ROCKCHIP_MTD_VENDOR_STORAGE is not set
|
||||
@@ -322,6 +446,8 @@ CONFIG_SPI_ROCKCHIP_SFC=y
|
||||
# CONFIG_TI_TSC2046 is not set
|
||||
# CONFIG_UNIXWARE_DISKLABEL is not set
|
||||
# CONFIG_VIDEO_GS1662 is not set
|
||||
# CONFIG_VIDEO_MS41908 is not set
|
||||
# CONFIG_VIDEO_MS41968 is not set
|
||||
# CONFIG_VIDEO_ROCKCHIP_PREISP is not set
|
||||
# CONFIG_VIDEO_S5C73M3 is not set
|
||||
CONFIG_ZLIB_DEFLATE=y
|
||||
|
||||
@@ -400,6 +400,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rv1126b-evb2-v10-dv.dtb
|
||||
dtb-$(CONFIG_ARCH_ROCKCHIP) += rv1126b-evb2-v10-mcu-k350c4516t.dtb
|
||||
dtb-$(CONFIG_ARCH_ROCKCHIP) += rv1126b-evb2-v10-rgb-Q7050ITH2641AA1T.dtb
|
||||
dtb-$(CONFIG_ARCH_ROCKCHIP) += rv1126b-evb2-v10-sii9022-bt1120-to-hdmi.dtb
|
||||
dtb-$(CONFIG_ARCH_ROCKCHIP) += rv1126b-evb2-v12.dtb
|
||||
dtb-$(CONFIG_ARCH_ROCKCHIP) += rv1126b-evb3-v10.dtb
|
||||
dtb-$(CONFIG_ARCH_ROCKCHIP) += rv1126b-evb4-v10.dtb
|
||||
dtb-$(CONFIG_ARCH_ROCKCHIP) += rv1126b-iotest-v10.dtb
|
||||
|
||||
35
arch/arm64/boot/dts/rockchip/rv1126b-evb2-v12.dts
Normal file
35
arch/arm64/boot/dts/rockchip/rv1126b-evb2-v12.dts
Normal file
@@ -0,0 +1,35 @@
|
||||
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
|
||||
/*
|
||||
* Copyright (c) 2025 Rockchip Electronics Co., Ltd.
|
||||
*/
|
||||
|
||||
/dts-v1/;
|
||||
#include "rv1126b-evb2-v10.dts"
|
||||
|
||||
/ {
|
||||
model = "Rockchip RV1126B EVB2 V12 Board";
|
||||
compatible = "rockchip,rv1126b-evb2-v12", "rockchip,rv1126b";
|
||||
};
|
||||
|
||||
&emmc {
|
||||
bus-width = <8>;
|
||||
cap-mmc-highspeed;
|
||||
non-removable;
|
||||
mmc-hs200-1_8v;
|
||||
rockchip,default-sample-phase = <90>;
|
||||
no-sdio;
|
||||
no-sd;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&fspi0 {
|
||||
status = "okay";
|
||||
|
||||
flash@0 {
|
||||
compatible = "spi-nand";
|
||||
reg = <0>;
|
||||
spi-max-frequency = <75000000>;
|
||||
spi-rx-bus-width = <4>;
|
||||
spi-tx-bus-width = <1>;
|
||||
};
|
||||
};
|
||||
@@ -226,6 +226,7 @@ CONFIG_ROCKCHIP_MULTI_RGA=y
|
||||
CONFIG_ROCKCHIP_RGA_PROC_FS=y
|
||||
# CONFIG_ROCKCHIP_RGA_DEBUG_FS is not set
|
||||
CONFIG_ROCKCHIP_MPP_OSAL=y
|
||||
CONFIG_ROCKCHIP_DVBM=y
|
||||
CONFIG_SOUND=y
|
||||
CONFIG_SND=y
|
||||
# CONFIG_SND_PCM_TIMER is not set
|
||||
@@ -292,7 +293,6 @@ CONFIG_STAGING=y
|
||||
CONFIG_COMMON_CLK_RK808=y
|
||||
CONFIG_COMMON_CLK_SCMI=y
|
||||
CONFIG_ROCKCHIP_CLK_OUT=y
|
||||
# CONFIG_ROCKCHIP_CLK_PVTM is not set
|
||||
CONFIG_ROCKCHIP_CLK_PVTPLL=y
|
||||
CONFIG_HWSPINLOCK=y
|
||||
CONFIG_HWSPINLOCK_ROCKCHIP=y
|
||||
|
||||
@@ -293,6 +293,9 @@ struct dw_mipi_dsi2 {
|
||||
|
||||
bool support_psr;
|
||||
bool enabled;
|
||||
|
||||
unsigned int min_refresh_rate;
|
||||
unsigned int max_refresh_rate;
|
||||
};
|
||||
|
||||
static inline struct dw_mipi_dsi2 *host_to_dsi2(struct mipi_dsi_host *host)
|
||||
@@ -1143,6 +1146,18 @@ dw_mipi_dsi2_encoder_atomic_check(struct drm_encoder *encoder,
|
||||
s->color_encoding = DRM_COLOR_YCBCR_BT709;
|
||||
s->color_range = DRM_COLOR_YCBCR_FULL_RANGE;
|
||||
|
||||
if (dsi2->auto_calc_mode && dsi2->max_refresh_rate && dsi2->min_refresh_rate) {
|
||||
int refresh_rate;
|
||||
|
||||
refresh_rate = drm_mode_vrefresh(&crtc_state->adjusted_mode);
|
||||
if (refresh_rate > dsi2->max_refresh_rate || refresh_rate < dsi2->min_refresh_rate)
|
||||
return -EINVAL;
|
||||
|
||||
s->max_refresh_rate = dsi2->max_refresh_rate;
|
||||
s->min_refresh_rate = dsi2->min_refresh_rate;
|
||||
s->vrr_type = ROCKCHIP_VRR_DCLK_MODE;
|
||||
}
|
||||
|
||||
if (dw_mipi_dsi2_is_cmd_mode(dsi2)) {
|
||||
s->output_flags |= ROCKCHIP_OUTPUT_MIPI_DS_MODE;
|
||||
s->soft_te = dsi2->te_gpio ? true : false;
|
||||
@@ -1997,9 +2012,18 @@ static int dw_mipi_dsi2_probe(struct platform_device *pdev)
|
||||
dsi2->pdata = of_device_get_match_data(dev);
|
||||
platform_set_drvdata(pdev, dsi2);
|
||||
|
||||
if (device_property_read_bool(dev, "auto-calculation-mode"))
|
||||
if (device_property_read_bool(dev, "auto-calculation-mode")) {
|
||||
dsi2->auto_calc_mode = true;
|
||||
|
||||
device_property_read_u32(dev, "min-refresh-rate", &dsi2->min_refresh_rate);
|
||||
device_property_read_u32(dev, "max-refresh-rate", &dsi2->max_refresh_rate);
|
||||
|
||||
if (dsi2->max_refresh_rate <= dsi2->min_refresh_rate) {
|
||||
dsi2->min_refresh_rate = 0;
|
||||
dsi2->max_refresh_rate = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (device_property_read_bool(dev, "disable-hold-mode"))
|
||||
dsi2->disable_hold_mode = true;
|
||||
|
||||
|
||||
@@ -1051,7 +1051,7 @@ static bool rockchip_hdmi_check_dsc_rate_supported(struct rockchip_hdmi *hdmi,
|
||||
/* compression ratio needs to be greater than 0.375. */
|
||||
dsc_rate = DIV_ROUND_UP_ULL(data_rate * 9, 24);
|
||||
|
||||
if ((data_rate > frl_rate) && (dsc_rate > dsc_frl_rate))
|
||||
if ((data_rate > frl_rate) && (dsc_rate < dsc_frl_rate))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
|
||||
@@ -965,6 +965,9 @@ struct vop2 {
|
||||
*/
|
||||
bool report_post_buf_empty;
|
||||
|
||||
/* disable vop writeback */
|
||||
bool disable_wb;
|
||||
|
||||
bool loader_protect;
|
||||
|
||||
bool aclk_rate_reset;
|
||||
@@ -3978,6 +3981,9 @@ static void vop2_wb_commit(struct drm_crtc *crtc)
|
||||
uint32_t fifo_throd;
|
||||
uint8_t r2y;
|
||||
|
||||
if (!vop2->wb.regs)
|
||||
return;
|
||||
|
||||
if (!conn_state)
|
||||
return;
|
||||
wb_state = to_wb_state(conn_state);
|
||||
@@ -4699,9 +4705,10 @@ static void vop2_initial(struct drm_crtc *crtc)
|
||||
rk3588_vop2_regsbak(vop2);
|
||||
else
|
||||
memcpy(vop2->regsbak, vop2->base_res.regs, vop2->len);
|
||||
|
||||
VOP_MODULE_SET(vop2, wb, axi_yrgb_id, 0xd);
|
||||
VOP_MODULE_SET(vop2, wb, axi_uv_id, 0xe);
|
||||
if (vop2->wb.regs) {
|
||||
VOP_MODULE_SET(vop2, wb, axi_yrgb_id, 0xd);
|
||||
VOP_MODULE_SET(vop2, wb, axi_uv_id, 0xe);
|
||||
}
|
||||
vop2_wb_cfg_done(vp);
|
||||
|
||||
if (is_vop3(vop2)) {
|
||||
@@ -13441,9 +13448,11 @@ static void vop2_crtc_atomic_flush(struct drm_crtc *crtc, struct drm_atomic_stat
|
||||
struct drm_writeback_connector *wb_conn = &wb->conn;
|
||||
struct drm_connector_state *conn_state = wb_conn->base.state;
|
||||
bool wb_mode = conn_state && conn_state->writeback_job && conn_state->writeback_job->fb;
|
||||
bool wb_oneframe_mode = VOP_MODULE_GET(vop2, wb, one_frame_mode);
|
||||
bool dovi_mode = vop2_is_dovi_mode(vp) && vp->enabled_win_mask;
|
||||
bool wb_oneframe_mode = false;
|
||||
|
||||
if (vop2->wb.regs)
|
||||
wb_oneframe_mode = VOP_MODULE_GET(vop2, wb, one_frame_mode);
|
||||
#if defined(CONFIG_ROCKCHIP_DRM_DEBUG)
|
||||
if (vp->rockchip_crtc.vop_dump_status == DUMP_KEEP ||
|
||||
vp->rockchip_crtc.vop_dump_times > 0) {
|
||||
@@ -14141,8 +14150,12 @@ static void vop2_wb_handler(struct vop2_video_port *vp)
|
||||
uint8_t wb_en;
|
||||
uint8_t wb_vp_id;
|
||||
uint8_t i;
|
||||
bool wb_oneframe_mode = VOP_MODULE_GET(vop2, wb, one_frame_mode);
|
||||
bool wb_oneframe_mode;
|
||||
|
||||
if (!vop2->wb.regs)
|
||||
return;
|
||||
|
||||
wb_oneframe_mode = VOP_MODULE_GET(vop2, wb, one_frame_mode);
|
||||
wb_en = VOP_MODULE_GET(vop2, wb, enable);
|
||||
wb_vp_id = VOP_MODULE_GET(vop2, wb, vp_id);
|
||||
if (wb_vp_id != vp->id)
|
||||
@@ -16318,6 +16331,7 @@ static int vop2_bind(struct device *dev, struct device *master, void *data)
|
||||
vop2->skip_ref_fb = of_property_read_bool(dev->of_node, "skip-ref-fb");
|
||||
vop2->report_iommu_fault = of_property_read_bool(dev->of_node, "rockchip,report-iommu-fault");
|
||||
vop2->report_post_buf_empty = of_property_read_bool(dev->of_node, "rockchip,report-post-buf-empty");
|
||||
vop2->disable_wb = of_property_read_bool(dev->of_node, "rockchip,disable-writeback");
|
||||
if (!is_vop3(vop2) ||
|
||||
vop2->version == VOP_VERSION_RK3528 || vop2->version == VOP_VERSION_RK3562)
|
||||
vop2->merge_irq = true;
|
||||
@@ -16556,7 +16570,8 @@ static int vop2_bind(struct device *dev, struct device *master, void *data)
|
||||
return ret;
|
||||
vop2_clk_init(vop2);
|
||||
vop2_cubic_lut_init(vop2);
|
||||
vop2_wb_connector_init(vop2, registered_num_crtcs);
|
||||
if (!vop2->disable_wb)
|
||||
vop2_wb_connector_init(vop2, registered_num_crtcs);
|
||||
rockchip_drm_dma_init_device(drm_dev, vop2->dev);
|
||||
pm_runtime_enable(&pdev->dev);
|
||||
rockchip_vop2_devfreq_init(vop2);
|
||||
|
||||
@@ -1978,6 +1978,16 @@ config VIDEO_SC2310
|
||||
This is a Video4Linux2 sensor driver for the SmartSens
|
||||
SC2310 camera.
|
||||
|
||||
config VIDEO_SC231HAI
|
||||
tristate "SmartSens SC231HAI sensor support"
|
||||
depends on I2C && VIDEO_DEV
|
||||
select MEDIA_CONTROLLER
|
||||
select VIDEO_V4L2_SUBDEV_API
|
||||
select V4L2_FWNODE
|
||||
help
|
||||
This is a Video4Linux2 sensor driver for the SmartSens
|
||||
SC231HAI camera.
|
||||
|
||||
config VIDEO_SC2336
|
||||
tristate "SmartSens SC2336 sensor support"
|
||||
depends on I2C && VIDEO_DEV
|
||||
@@ -1999,6 +2009,16 @@ config VIDEO_SC2355
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called sc2355.
|
||||
|
||||
config VIDEO_SC235HAI
|
||||
tristate "SmartSens SC235HAI sensor support"
|
||||
depends on I2C && VIDEO_DEV
|
||||
select MEDIA_CONTROLLER
|
||||
select VIDEO_V4L2_SUBDEV_API
|
||||
select V4L2_FWNODE
|
||||
help
|
||||
This is a Video4Linux2 sensor driver for the SmartSens
|
||||
SC235HAI camera.
|
||||
|
||||
config VIDEO_SC301IOT
|
||||
tristate "SmartSens SC301IOT sensor support"
|
||||
depends on I2C && VIDEO_DEV
|
||||
|
||||
@@ -245,8 +245,10 @@ obj-$(CONFIG_VIDEO_SC2239) += sc2239.o
|
||||
obj-$(CONFIG_VIDEO_SC223A) += sc223a.o
|
||||
obj-$(CONFIG_VIDEO_SC230AI) += sc230ai.o
|
||||
obj-$(CONFIG_VIDEO_SC2310) += sc2310.o
|
||||
obj-$(CONFIG_VIDEO_SC231HAI) += sc231hai.o
|
||||
obj-$(CONFIG_VIDEO_SC2336) += sc2336.o
|
||||
obj-$(CONFIG_VIDEO_SC2355) += sc2355.o
|
||||
obj-$(CONFIG_VIDEO_SC235HAI) += sc235hai.o
|
||||
obj-$(CONFIG_VIDEO_SC301IOT) += sc301iot.o
|
||||
obj-$(CONFIG_VIDEO_SC3336) += sc3336.o
|
||||
obj-$(CONFIG_VIDEO_SC3336P) += sc3336p.o
|
||||
|
||||
2189
drivers/media/i2c/sc231hai.c
Normal file
2189
drivers/media/i2c/sc231hai.c
Normal file
File diff suppressed because it is too large
Load Diff
2261
drivers/media/i2c/sc235hai.c
Normal file
2261
drivers/media/i2c/sc235hai.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -222,10 +222,36 @@ struct sc635hai {
|
||||
struct cam_sw_info *cam_sw_inf;
|
||||
struct v4l2_fwnode_endpoint bus_cfg;
|
||||
struct rk_light_param light_param;
|
||||
enum rkmodule_sync_mode sync_mode;
|
||||
};
|
||||
|
||||
#define to_sc635hai(sd) container_of(sd, struct sc635hai, subdev)
|
||||
|
||||
/* sync mode regs*/
|
||||
static __maybe_unused const struct regval sc635hai_interal_sync_master_start_regs[] = {
|
||||
{0x3222, 0x00}, //Slave mode en,0: master mode;1:slave mode
|
||||
{0x300a, 0x24}, //Bit[2]: FSYNC output en; FSYNC as output PAD
|
||||
{0x3032, 0xb0},
|
||||
{REG_NULL, 0x00},
|
||||
};
|
||||
|
||||
static __maybe_unused const struct regval sc635hai_interal_sync_master_stop_regs[] = {
|
||||
{REG_NULL, 0x00},
|
||||
};
|
||||
|
||||
static __maybe_unused const struct regval sc635hai_interal_sync_slave_start_regs[] = {
|
||||
{0x3222, 0x01}, //Slave mode en,0: master mode;1:slave mode
|
||||
{0x3224, 0xd2}, //trigger by fync
|
||||
{0x3230, 0x00}, //Rows Before Read
|
||||
{0x3231, 0x04}, //Rows Before Read
|
||||
{0x300a, 0x60}, //Bit[6]: EFSYNC output en; EFSYNC as input PAD
|
||||
{REG_NULL, 0x00},
|
||||
};
|
||||
|
||||
static __maybe_unused const struct regval sc635hai_interal_sync_slave_stop_regs[] = {
|
||||
{REG_NULL, 0x00},
|
||||
};
|
||||
|
||||
/*
|
||||
* Xclk 24Mhz
|
||||
*/
|
||||
@@ -1153,7 +1179,7 @@ static const char *const sc635hai_test_pattern_menu[] = {
|
||||
|
||||
|
||||
static int sc635hai_write_reg(struct i2c_client *client, u16 reg,
|
||||
u32 len, u32 val)
|
||||
u32 len, u32 val)
|
||||
{
|
||||
u32 buf_i, val_i;
|
||||
u8 buf[6];
|
||||
@@ -1180,20 +1206,20 @@ static int sc635hai_write_reg(struct i2c_client *client, u16 reg,
|
||||
}
|
||||
|
||||
static int sc635hai_write_array(struct i2c_client *client,
|
||||
const struct regval *regs)
|
||||
const struct regval *regs)
|
||||
{
|
||||
u32 i;
|
||||
int ret = 0;
|
||||
|
||||
for (i = 0; ret == 0 && regs[i].addr != REG_NULL; i++)
|
||||
ret = sc635hai_write_reg(client, regs[i].addr,
|
||||
SC635HAI_REG_VALUE_08BIT, regs[i].val);
|
||||
SC635HAI_REG_VALUE_08BIT, regs[i].val);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int sc635hai_read_reg(struct i2c_client *client, u16 reg, unsigned int len,
|
||||
u32 *val)
|
||||
u32 *val)
|
||||
{
|
||||
struct i2c_msg msgs[2];
|
||||
u8 *data_be_p;
|
||||
@@ -1302,44 +1328,44 @@ static int sc635hai_set_gain_reg(struct sc635hai *sc635hai, u32 gain, int mode)
|
||||
|
||||
if (mode == SC635HAI_LGAIN) {
|
||||
ret = sc635hai_write_reg(sc635hai->client,
|
||||
SC635HAI_REG_DIG_GAIN,
|
||||
SC635HAI_REG_VALUE_08BIT,
|
||||
coarse_dgain);
|
||||
ret |= sc635hai_write_reg(sc635hai->client,
|
||||
SC635HAI_REG_DIG_FINE_GAIN,
|
||||
SC635HAI_REG_DIG_GAIN,
|
||||
SC635HAI_REG_VALUE_08BIT,
|
||||
fine_dgain);
|
||||
coarse_dgain);
|
||||
ret |= sc635hai_write_reg(sc635hai->client,
|
||||
SC635HAI_REG_ANA_GAIN,
|
||||
SC635HAI_REG_VALUE_08BIT,
|
||||
coarse_again);
|
||||
SC635HAI_REG_DIG_FINE_GAIN,
|
||||
SC635HAI_REG_VALUE_08BIT,
|
||||
fine_dgain);
|
||||
ret |= sc635hai_write_reg(sc635hai->client,
|
||||
SC635HAI_REG_ANA_FINE_GAIN,
|
||||
SC635HAI_REG_VALUE_08BIT,
|
||||
fine_again);
|
||||
SC635HAI_REG_ANA_GAIN,
|
||||
SC635HAI_REG_VALUE_08BIT,
|
||||
coarse_again);
|
||||
ret |= sc635hai_write_reg(sc635hai->client,
|
||||
SC635HAI_REG_ANA_FINE_GAIN,
|
||||
SC635HAI_REG_VALUE_08BIT,
|
||||
fine_again);
|
||||
} else {
|
||||
ret = sc635hai_write_reg(sc635hai->client,
|
||||
SC635HAI_REG_SDIG_GAIN,
|
||||
SC635HAI_REG_VALUE_08BIT,
|
||||
coarse_dgain);
|
||||
ret |= sc635hai_write_reg(sc635hai->client,
|
||||
SC635HAI_REG_SDIG_FINE_GAIN,
|
||||
SC635HAI_REG_SDIG_GAIN,
|
||||
SC635HAI_REG_VALUE_08BIT,
|
||||
fine_dgain);
|
||||
coarse_dgain);
|
||||
ret |= sc635hai_write_reg(sc635hai->client,
|
||||
SC635HAI_REG_SANA_GAIN,
|
||||
SC635HAI_REG_VALUE_08BIT,
|
||||
coarse_again);
|
||||
SC635HAI_REG_SDIG_FINE_GAIN,
|
||||
SC635HAI_REG_VALUE_08BIT,
|
||||
fine_dgain);
|
||||
ret |= sc635hai_write_reg(sc635hai->client,
|
||||
SC635HAI_REG_SANA_FINE_GAIN,
|
||||
SC635HAI_REG_VALUE_08BIT,
|
||||
fine_again);
|
||||
SC635HAI_REG_SANA_GAIN,
|
||||
SC635HAI_REG_VALUE_08BIT,
|
||||
coarse_again);
|
||||
ret |= sc635hai_write_reg(sc635hai->client,
|
||||
SC635HAI_REG_SANA_FINE_GAIN,
|
||||
SC635HAI_REG_VALUE_08BIT,
|
||||
fine_again);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int sc635hai_set_hdrae(struct sc635hai *sc635hai,
|
||||
struct preisp_hdrae_exp_s *ae)
|
||||
struct preisp_hdrae_exp_s *ae)
|
||||
{
|
||||
int ret = 0;
|
||||
u32 l_exp_time, m_exp_time, s_exp_time;
|
||||
@@ -1392,25 +1418,25 @@ static int sc635hai_set_hdrae(struct sc635hai *sc635hai,
|
||||
s_exp_time = 184;
|
||||
|
||||
ret = sc635hai_write_reg(sc635hai->client,
|
||||
SC635HAI_REG_EXPOSURE_H,
|
||||
SC635HAI_REG_VALUE_08BIT,
|
||||
SC635HAI_FETCH_EXP_H(l_exp_time));
|
||||
ret |= sc635hai_write_reg(sc635hai->client,
|
||||
SC635HAI_REG_EXPOSURE_M,
|
||||
SC635HAI_REG_EXPOSURE_H,
|
||||
SC635HAI_REG_VALUE_08BIT,
|
||||
SC635HAI_FETCH_EXP_M(l_exp_time));
|
||||
SC635HAI_FETCH_EXP_H(l_exp_time));
|
||||
ret |= sc635hai_write_reg(sc635hai->client,
|
||||
SC635HAI_REG_EXPOSURE_L,
|
||||
SC635HAI_REG_VALUE_08BIT,
|
||||
SC635HAI_FETCH_EXP_L(l_exp_time));
|
||||
SC635HAI_REG_EXPOSURE_M,
|
||||
SC635HAI_REG_VALUE_08BIT,
|
||||
SC635HAI_FETCH_EXP_M(l_exp_time));
|
||||
ret |= sc635hai_write_reg(sc635hai->client,
|
||||
SC635HAI_REG_SEXPOSURE_M,
|
||||
SC635HAI_REG_VALUE_08BIT,
|
||||
SC635HAI_FETCH_EXP_M(s_exp_time));
|
||||
SC635HAI_REG_EXPOSURE_L,
|
||||
SC635HAI_REG_VALUE_08BIT,
|
||||
SC635HAI_FETCH_EXP_L(l_exp_time));
|
||||
ret |= sc635hai_write_reg(sc635hai->client,
|
||||
SC635HAI_REG_SEXPOSURE_L,
|
||||
SC635HAI_REG_VALUE_08BIT,
|
||||
SC635HAI_FETCH_EXP_L(s_exp_time));
|
||||
SC635HAI_REG_SEXPOSURE_M,
|
||||
SC635HAI_REG_VALUE_08BIT,
|
||||
SC635HAI_FETCH_EXP_M(s_exp_time));
|
||||
ret |= sc635hai_write_reg(sc635hai->client,
|
||||
SC635HAI_REG_SEXPOSURE_L,
|
||||
SC635HAI_REG_VALUE_08BIT,
|
||||
SC635HAI_FETCH_EXP_L(s_exp_time));
|
||||
|
||||
ret |= sc635hai_set_gain_reg(sc635hai, l_a_gain, SC635HAI_LGAIN);
|
||||
ret |= sc635hai_set_gain_reg(sc635hai, s_a_gain, SC635HAI_SGAIN);
|
||||
@@ -1418,7 +1444,7 @@ static int sc635hai_set_hdrae(struct sc635hai *sc635hai,
|
||||
}
|
||||
|
||||
static int sc635hai_get_reso_dist(const struct sc635hai_mode *mode,
|
||||
struct v4l2_mbus_framefmt *framefmt)
|
||||
struct v4l2_mbus_framefmt *framefmt)
|
||||
{
|
||||
return abs(mode->width - framefmt->width) +
|
||||
abs(mode->height - framefmt->height);
|
||||
@@ -1449,8 +1475,8 @@ sc635hai_find_best_fit(struct sc635hai *sc635hai, struct v4l2_subdev_format *fmt
|
||||
}
|
||||
|
||||
static int sc635hai_set_fmt(struct v4l2_subdev *sd,
|
||||
struct v4l2_subdev_state *sd_state,
|
||||
struct v4l2_subdev_format *fmt)
|
||||
struct v4l2_subdev_state *sd_state,
|
||||
struct v4l2_subdev_format *fmt)
|
||||
{
|
||||
struct sc635hai *sc635hai = to_sc635hai(sd);
|
||||
const struct sc635hai_mode *mode;
|
||||
@@ -1498,8 +1524,8 @@ static int sc635hai_set_fmt(struct v4l2_subdev *sd,
|
||||
}
|
||||
|
||||
static int sc635hai_get_fmt(struct v4l2_subdev *sd,
|
||||
struct v4l2_subdev_state *sd_state,
|
||||
struct v4l2_subdev_format *fmt)
|
||||
struct v4l2_subdev_state *sd_state,
|
||||
struct v4l2_subdev_format *fmt)
|
||||
{
|
||||
struct sc635hai *sc635hai = to_sc635hai(sd);
|
||||
const struct sc635hai_mode *mode = sc635hai->cur_mode;
|
||||
@@ -1529,8 +1555,8 @@ static int sc635hai_get_fmt(struct v4l2_subdev *sd,
|
||||
}
|
||||
|
||||
static int sc635hai_enum_mbus_code(struct v4l2_subdev *sd,
|
||||
struct v4l2_subdev_state *sd_state,
|
||||
struct v4l2_subdev_mbus_code_enum *code)
|
||||
struct v4l2_subdev_state *sd_state,
|
||||
struct v4l2_subdev_mbus_code_enum *code)
|
||||
{
|
||||
if (code->index >= ARRAY_SIZE(bus_code))
|
||||
return -EINVAL;
|
||||
@@ -1540,8 +1566,8 @@ static int sc635hai_enum_mbus_code(struct v4l2_subdev *sd,
|
||||
}
|
||||
|
||||
static int sc635hai_enum_frame_sizes(struct v4l2_subdev *sd,
|
||||
struct v4l2_subdev_state *sd_state,
|
||||
struct v4l2_subdev_frame_size_enum *fse)
|
||||
struct v4l2_subdev_state *sd_state,
|
||||
struct v4l2_subdev_frame_size_enum *fse)
|
||||
{
|
||||
struct sc635hai *sc635hai = to_sc635hai(sd);
|
||||
|
||||
@@ -1565,19 +1591,19 @@ static int sc635hai_enable_test_pattern(struct sc635hai *sc635hai, u32 pattern)
|
||||
int ret = 0;
|
||||
|
||||
ret = sc635hai_read_reg(sc635hai->client, SC635HAI_REG_TEST_PATTERN,
|
||||
SC635HAI_REG_VALUE_08BIT, &val);
|
||||
SC635HAI_REG_VALUE_08BIT, &val);
|
||||
if (pattern)
|
||||
val |= SC635HAI_TEST_PATTERN_BIT_MASK;
|
||||
else
|
||||
val &= ~SC635HAI_TEST_PATTERN_BIT_MASK;
|
||||
|
||||
ret |= sc635hai_write_reg(sc635hai->client, SC635HAI_REG_TEST_PATTERN,
|
||||
SC635HAI_REG_VALUE_08BIT, val);
|
||||
SC635HAI_REG_VALUE_08BIT, val);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int sc635hai_g_frame_interval(struct v4l2_subdev *sd,
|
||||
struct v4l2_subdev_frame_interval *fi)
|
||||
struct v4l2_subdev_frame_interval *fi)
|
||||
{
|
||||
struct sc635hai *sc635hai = to_sc635hai(sd);
|
||||
const struct sc635hai_mode *mode = sc635hai->cur_mode;
|
||||
@@ -1614,7 +1640,7 @@ static const struct sc635hai_mode *sc635hai_find_mode(struct sc635hai *sc635hai,
|
||||
}
|
||||
|
||||
static int sc635hai_s_frame_interval(struct v4l2_subdev *sd,
|
||||
struct v4l2_subdev_frame_interval *fi)
|
||||
struct v4l2_subdev_frame_interval *fi)
|
||||
{
|
||||
struct sc635hai *sc635hai = to_sc635hai(sd);
|
||||
const struct sc635hai_mode *mode = NULL;
|
||||
@@ -1662,8 +1688,8 @@ static int sc635hai_s_frame_interval(struct v4l2_subdev *sd,
|
||||
}
|
||||
|
||||
static int sc635hai_g_mbus_config(struct v4l2_subdev *sd,
|
||||
unsigned int pad_id,
|
||||
struct v4l2_mbus_config *config)
|
||||
unsigned int pad_id,
|
||||
struct v4l2_mbus_config *config)
|
||||
{
|
||||
struct sc635hai *sc635hai = to_sc635hai(sd);
|
||||
u8 lanes = sc635hai->bus_cfg.bus.mipi_csi2.num_data_lanes;
|
||||
@@ -1675,7 +1701,7 @@ static int sc635hai_g_mbus_config(struct v4l2_subdev *sd,
|
||||
}
|
||||
|
||||
static void sc635hai_get_module_inf(struct sc635hai *sc635hai,
|
||||
struct rkmodule_inf *inf)
|
||||
struct rkmodule_inf *inf)
|
||||
{
|
||||
memset(inf, 0, sizeof(*inf));
|
||||
strscpy(inf->base.sensor, SC635HAI_NAME, sizeof(inf->base.sensor));
|
||||
@@ -1782,6 +1808,7 @@ static long sc635hai_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
|
||||
int cur_best_fit = -1;
|
||||
int cur_best_fit_dist = -1;
|
||||
int cur_dist, cur_fps, dst_fps;
|
||||
u32 *sync_mode = NULL;
|
||||
|
||||
switch (cmd) {
|
||||
case RKMODULE_GET_MODULE_INFO:
|
||||
@@ -1861,8 +1888,8 @@ static long sc635hai_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
|
||||
usleep_range(4000, 5000);
|
||||
/* mipi clk on */
|
||||
ret |= sc635hai_write_reg(sc635hai->client, SC635HAI_REG_MIPI_CTRL,
|
||||
SC635HAI_REG_VALUE_08BIT,
|
||||
SC635HAI_MIPI_CTRL_ON);
|
||||
SC635HAI_REG_VALUE_08BIT,
|
||||
SC635HAI_MIPI_CTRL_ON);
|
||||
/* adjust timing */
|
||||
ret |= sc635hai_adjust_time(sc635hai);
|
||||
|
||||
@@ -1872,8 +1899,8 @@ static long sc635hai_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
|
||||
/* Check if the current mode is HDR and cam sw info is available */
|
||||
if (sc635hai->cur_mode->hdr_mode != NO_HDR && sc635hai->cam_sw_inf) {
|
||||
ret = sc635hai_ioctl(&sc635hai->subdev,
|
||||
PREISP_CMD_SET_HDRAE_EXP,
|
||||
&sc635hai->cam_sw_inf->hdr_ae);
|
||||
PREISP_CMD_SET_HDRAE_EXP,
|
||||
&sc635hai->cam_sw_inf->hdr_ae);
|
||||
if (ret) {
|
||||
dev_err(&sc635hai->client->dev,
|
||||
"Failed init exp fail in hdr mode\n");
|
||||
@@ -1885,8 +1912,8 @@ static long sc635hai_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
|
||||
|
||||
/* stream on */
|
||||
ret |= sc635hai_write_reg(sc635hai->client, SC635HAI_REG_CTRL_MODE,
|
||||
SC635HAI_REG_VALUE_08BIT,
|
||||
SC635HAI_MODE_STREAMING);
|
||||
SC635HAI_REG_VALUE_08BIT,
|
||||
SC635HAI_MODE_STREAMING);
|
||||
dev_info(&sc635hai->client->dev,
|
||||
"quickstream, streaming on: exit hw standby mode\n");
|
||||
} else {
|
||||
@@ -1895,12 +1922,12 @@ static long sc635hai_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
|
||||
|
||||
/* stream off */
|
||||
ret |= sc635hai_write_reg(sc635hai->client, SC635HAI_REG_CTRL_MODE,
|
||||
SC635HAI_REG_VALUE_08BIT,
|
||||
SC635HAI_MODE_SW_STANDBY);
|
||||
SC635HAI_REG_VALUE_08BIT,
|
||||
SC635HAI_MODE_SW_STANDBY);
|
||||
/* mipi clk off */
|
||||
ret |= sc635hai_write_reg(sc635hai->client, SC635HAI_REG_MIPI_CTRL,
|
||||
SC635HAI_REG_VALUE_08BIT,
|
||||
SC635HAI_MIPI_CTRL_OFF);
|
||||
SC635HAI_REG_VALUE_08BIT,
|
||||
SC635HAI_MIPI_CTRL_OFF);
|
||||
|
||||
sc635hai->is_standby = true;
|
||||
/* pwnd gpio pull down */
|
||||
@@ -1912,20 +1939,20 @@ static long sc635hai_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
|
||||
} else { /* software standby */
|
||||
if (stream) {
|
||||
ret |= sc635hai_write_reg(sc635hai->client, SC635HAI_REG_MIPI_CTRL,
|
||||
SC635HAI_REG_VALUE_08BIT,
|
||||
SC635HAI_MIPI_CTRL_ON);
|
||||
SC635HAI_REG_VALUE_08BIT,
|
||||
SC635HAI_MIPI_CTRL_ON);
|
||||
ret |= sc635hai_write_reg(sc635hai->client, SC635HAI_REG_CTRL_MODE,
|
||||
SC635HAI_REG_VALUE_08BIT,
|
||||
SC635HAI_MODE_STREAMING);
|
||||
SC635HAI_REG_VALUE_08BIT,
|
||||
SC635HAI_MODE_STREAMING);
|
||||
dev_info(&sc635hai->client->dev,
|
||||
"quickstream, streaming on: exit soft standby mode\n");
|
||||
} else {
|
||||
ret |= sc635hai_write_reg(sc635hai->client, SC635HAI_REG_CTRL_MODE,
|
||||
SC635HAI_REG_VALUE_08BIT,
|
||||
SC635HAI_MODE_SW_STANDBY);
|
||||
SC635HAI_REG_VALUE_08BIT,
|
||||
SC635HAI_MODE_SW_STANDBY);
|
||||
ret |= sc635hai_write_reg(sc635hai->client, SC635HAI_REG_MIPI_CTRL,
|
||||
SC635HAI_REG_VALUE_08BIT,
|
||||
SC635HAI_MIPI_CTRL_OFF);
|
||||
SC635HAI_REG_VALUE_08BIT,
|
||||
SC635HAI_MIPI_CTRL_OFF);
|
||||
dev_info(&sc635hai->client->dev,
|
||||
"quickstream, streaming off: enter soft standby mode\n");
|
||||
}
|
||||
@@ -1935,6 +1962,21 @@ static long sc635hai_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
|
||||
setting = (struct rk_sensor_setting *)arg;
|
||||
ret = sc635hai_set_setting(sc635hai, setting);
|
||||
break;
|
||||
case RKMODULE_GET_SYNC_MODE:
|
||||
sync_mode = (u32 *)arg;
|
||||
*sync_mode = sc635hai->sync_mode;
|
||||
break;
|
||||
case RKMODULE_SET_SYNC_MODE:
|
||||
sync_mode = (u32 *)arg;
|
||||
if (sync_mode) {
|
||||
sc635hai->sync_mode = *sync_mode;
|
||||
dev_info(&sc635hai->client->dev, "set sync mode is: %s\n",
|
||||
((*sync_mode == EXTERNAL_MASTER_MODE) ||
|
||||
(*sync_mode == SLAVE_MODE)) ? "secondary" : "primary");
|
||||
} else {
|
||||
dev_info(&sc635hai->client->dev, "set sync mode is: NO_SYNC_MODE\n");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ret = -ENOIOCTLCMD;
|
||||
break;
|
||||
@@ -1946,7 +1988,7 @@ static long sc635hai_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
static long sc635hai_compat_ioctl32(struct v4l2_subdev *sd,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
void __user *up = compat_ptr(arg);
|
||||
struct rkmodule_inf *inf;
|
||||
@@ -1956,6 +1998,7 @@ static long sc635hai_compat_ioctl32(struct v4l2_subdev *sd,
|
||||
struct rk_light_param *light_param;
|
||||
long ret;
|
||||
u32 stream = 0;
|
||||
u32 *sync_mode = NULL;
|
||||
|
||||
switch (cmd) {
|
||||
case RKMODULE_GET_MODULE_INFO:
|
||||
@@ -2035,6 +2078,21 @@ static long sc635hai_compat_ioctl32(struct v4l2_subdev *sd,
|
||||
ret = -EFAULT;
|
||||
kfree(setting);
|
||||
break;
|
||||
case RKMODULE_GET_SYNC_MODE:
|
||||
ret = sc635hai_ioctl(sd, cmd, &sync_mode);
|
||||
if (!ret) {
|
||||
ret = copy_to_user(up, &sync_mode, sizeof(u32));
|
||||
if (ret)
|
||||
ret = -EFAULT;
|
||||
}
|
||||
break;
|
||||
case RKMODULE_SET_SYNC_MODE:
|
||||
ret = copy_from_user(&sync_mode, up, sizeof(u32));
|
||||
if (!ret)
|
||||
ret = sc635hai_ioctl(sd, cmd, &sync_mode);
|
||||
else
|
||||
ret = -EFAULT;
|
||||
break;
|
||||
case RKCIS_CMD_FLASH_LIGHT_CTRL:
|
||||
light_param = kzalloc(sizeof(*light_param), GFP_KERNEL);
|
||||
if (!light_param) {
|
||||
@@ -2060,7 +2118,7 @@ static long sc635hai_compat_ioctl32(struct v4l2_subdev *sd,
|
||||
|
||||
static int __sc635hai_start_stream(struct sc635hai *sc635hai)
|
||||
{
|
||||
int ret;
|
||||
int ret = 0;
|
||||
|
||||
if (!sc635hai->is_thunderboot) {
|
||||
ret = sc635hai_write_array(sc635hai->client, sc635hai->cur_mode->reg_list);
|
||||
@@ -2072,7 +2130,7 @@ static int __sc635hai_start_stream(struct sc635hai *sc635hai)
|
||||
return ret;
|
||||
if (sc635hai->has_init_exp && sc635hai->cur_mode->hdr_mode != NO_HDR) {
|
||||
ret = sc635hai_ioctl(&sc635hai->subdev, PREISP_CMD_SET_HDRAE_EXP,
|
||||
&sc635hai->init_hdrae_exp);
|
||||
&sc635hai->init_hdrae_exp);
|
||||
if (ret) {
|
||||
dev_err(&sc635hai->client->dev,
|
||||
"init exp fail in hdr mode\n");
|
||||
@@ -2080,8 +2138,15 @@ static int __sc635hai_start_stream(struct sc635hai *sc635hai)
|
||||
}
|
||||
}
|
||||
}
|
||||
ret = sc635hai_write_reg(sc635hai->client, SC635HAI_REG_CTRL_MODE,
|
||||
SC635HAI_REG_VALUE_08BIT, SC635HAI_MODE_STREAMING);
|
||||
if (sc635hai->sync_mode == INTERNAL_MASTER_MODE)
|
||||
ret |= sc635hai_write_array(sc635hai->client,
|
||||
sc635hai_interal_sync_master_start_regs);
|
||||
else if (sc635hai->sync_mode == EXTERNAL_MASTER_MODE)
|
||||
ret |= sc635hai_write_array(sc635hai->client,
|
||||
sc635hai_interal_sync_slave_start_regs);
|
||||
else if (sc635hai->sync_mode == NO_SYNC_MODE)
|
||||
ret |= sc635hai_write_reg(sc635hai->client, SC635HAI_REG_CTRL_MODE,
|
||||
SC635HAI_REG_VALUE_08BIT, SC635HAI_MODE_STREAMING);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -2091,7 +2156,7 @@ static int __sc635hai_stop_stream(struct sc635hai *sc635hai)
|
||||
if (sc635hai->is_thunderboot)
|
||||
sc635hai->is_first_streamoff = true;
|
||||
return sc635hai_write_reg(sc635hai->client, SC635HAI_REG_CTRL_MODE,
|
||||
SC635HAI_REG_VALUE_08BIT, SC635HAI_MODE_SW_STANDBY);
|
||||
SC635HAI_REG_VALUE_08BIT, SC635HAI_MODE_SW_STANDBY);
|
||||
}
|
||||
|
||||
/* Calculate the delay in us by clock rate and clock cycles */
|
||||
@@ -2252,7 +2317,7 @@ static int sc635hai_s_power(struct v4l2_subdev *sd, int on)
|
||||
|
||||
if (!sc635hai->is_thunderboot) {
|
||||
ret = sc635hai_write_array(sc635hai->client,
|
||||
sc635hai->cur_mode->global_reg_list);
|
||||
sc635hai->cur_mode->global_reg_list);
|
||||
if (ret) {
|
||||
v4l2_err(sd, "could not set init registers\n");
|
||||
pm_runtime_put_noidle(&client->dev);
|
||||
@@ -2294,7 +2359,7 @@ static int __maybe_unused sc635hai_resume(struct device *dev)
|
||||
|
||||
if (sc635hai->has_init_exp && sc635hai->cur_mode != NO_HDR) { // hdr mode
|
||||
ret = sc635hai_ioctl(&sc635hai->subdev, PREISP_CMD_SET_HDRAE_EXP,
|
||||
&sc635hai->cam_sw_inf->hdr_ae);
|
||||
&sc635hai->cam_sw_inf->hdr_ae);
|
||||
if (ret) {
|
||||
dev_err(&sc635hai->client->dev, "set exp fail in hdr mode\n");
|
||||
return ret;
|
||||
@@ -2370,8 +2435,8 @@ static int sc635hai_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
|
||||
#endif
|
||||
|
||||
static int sc635hai_enum_frame_interval(struct v4l2_subdev *sd,
|
||||
struct v4l2_subdev_state *sd_state,
|
||||
struct v4l2_subdev_frame_interval_enum *fie)
|
||||
struct v4l2_subdev_state *sd_state,
|
||||
struct v4l2_subdev_frame_interval_enum *fie)
|
||||
{
|
||||
struct sc635hai *sc635hai = to_sc635hai(sd);
|
||||
|
||||
@@ -2434,13 +2499,13 @@ static void sc635hai_modify_fps_info(struct sc635hai *sc635hai)
|
||||
const struct sc635hai_mode *mode = sc635hai->cur_mode;
|
||||
|
||||
sc635hai->cur_fps.denominator = mode->max_fps.denominator * mode->vts_def /
|
||||
sc635hai->cur_vts;
|
||||
sc635hai->cur_vts;
|
||||
}
|
||||
|
||||
static int sc635hai_set_ctrl(struct v4l2_ctrl *ctrl)
|
||||
{
|
||||
struct sc635hai *sc635hai = container_of(ctrl->handler,
|
||||
struct sc635hai, ctrl_handler);
|
||||
struct sc635hai, ctrl_handler);
|
||||
struct i2c_client *client = sc635hai->client;
|
||||
s64 max;
|
||||
int ret = 0;
|
||||
@@ -2472,17 +2537,17 @@ static int sc635hai_set_ctrl(struct v4l2_ctrl *ctrl)
|
||||
if (sc635hai->cur_mode->hdr_mode == NO_HDR) {
|
||||
/* 4 least significant bits of expsoure are fractional part */
|
||||
ret = sc635hai_write_reg(sc635hai->client,
|
||||
SC635HAI_REG_EXPOSURE_H,
|
||||
SC635HAI_REG_VALUE_08BIT,
|
||||
SC635HAI_FETCH_EXP_H(ctrl->val));
|
||||
ret |= sc635hai_write_reg(sc635hai->client,
|
||||
SC635HAI_REG_EXPOSURE_M,
|
||||
SC635HAI_REG_EXPOSURE_H,
|
||||
SC635HAI_REG_VALUE_08BIT,
|
||||
SC635HAI_FETCH_EXP_M(ctrl->val));
|
||||
SC635HAI_FETCH_EXP_H(ctrl->val));
|
||||
ret |= sc635hai_write_reg(sc635hai->client,
|
||||
SC635HAI_REG_EXPOSURE_L,
|
||||
SC635HAI_REG_VALUE_08BIT,
|
||||
SC635HAI_FETCH_EXP_L(ctrl->val));
|
||||
SC635HAI_REG_EXPOSURE_M,
|
||||
SC635HAI_REG_VALUE_08BIT,
|
||||
SC635HAI_FETCH_EXP_M(ctrl->val));
|
||||
ret |= sc635hai_write_reg(sc635hai->client,
|
||||
SC635HAI_REG_EXPOSURE_L,
|
||||
SC635HAI_REG_VALUE_08BIT,
|
||||
SC635HAI_FETCH_EXP_L(ctrl->val));
|
||||
}
|
||||
break;
|
||||
case V4L2_CID_ANALOGUE_GAIN:
|
||||
@@ -2493,17 +2558,17 @@ static int sc635hai_set_ctrl(struct v4l2_ctrl *ctrl)
|
||||
case V4L2_CID_VBLANK:
|
||||
dev_dbg(&client->dev, "set vblank 0x%x\n", ctrl->val);
|
||||
ret = sc635hai_write_reg(sc635hai->client,
|
||||
SC635HAI_REG_VTS_H,
|
||||
SC635HAI_REG_VALUE_08BIT,
|
||||
0x00);
|
||||
ret |= sc635hai_write_reg(sc635hai->client,
|
||||
SC635HAI_REG_VTS_M,
|
||||
SC635HAI_REG_VTS_H,
|
||||
SC635HAI_REG_VALUE_08BIT,
|
||||
(ctrl->val + sc635hai->cur_mode->height) >> 8);
|
||||
0x00);
|
||||
ret |= sc635hai_write_reg(sc635hai->client,
|
||||
SC635HAI_REG_VTS_L,
|
||||
SC635HAI_REG_VALUE_08BIT,
|
||||
(ctrl->val + sc635hai->cur_mode->height) & 0xff);
|
||||
SC635HAI_REG_VTS_M,
|
||||
SC635HAI_REG_VALUE_08BIT,
|
||||
(ctrl->val + sc635hai->cur_mode->height) >> 8);
|
||||
ret |= sc635hai_write_reg(sc635hai->client,
|
||||
SC635HAI_REG_VTS_L,
|
||||
SC635HAI_REG_VALUE_08BIT,
|
||||
(ctrl->val + sc635hai->cur_mode->height) & 0xff);
|
||||
sc635hai->cur_vts = ctrl->val + sc635hai->cur_mode->height;
|
||||
if (sc635hai->cur_vts != sc635hai->cur_mode->vts_def)
|
||||
sc635hai_modify_fps_info(sc635hai);
|
||||
@@ -2513,17 +2578,17 @@ static int sc635hai_set_ctrl(struct v4l2_ctrl *ctrl)
|
||||
break;
|
||||
case V4L2_CID_HFLIP:
|
||||
ret = sc635hai_read_reg(sc635hai->client, SC635HAI_FLIP_MIRROR_REG,
|
||||
SC635HAI_REG_VALUE_08BIT, &val);
|
||||
SC635HAI_REG_VALUE_08BIT, &val);
|
||||
ret |= sc635hai_write_reg(sc635hai->client, SC635HAI_FLIP_MIRROR_REG,
|
||||
SC635HAI_REG_VALUE_08BIT,
|
||||
SC635HAI_FETCH_MIRROR(val, ctrl->val));
|
||||
SC635HAI_REG_VALUE_08BIT,
|
||||
SC635HAI_FETCH_MIRROR(val, ctrl->val));
|
||||
break;
|
||||
case V4L2_CID_VFLIP:
|
||||
ret = sc635hai_read_reg(sc635hai->client, SC635HAI_FLIP_MIRROR_REG,
|
||||
SC635HAI_REG_VALUE_08BIT, &val);
|
||||
SC635HAI_REG_VALUE_08BIT, &val);
|
||||
ret |= sc635hai_write_reg(sc635hai->client, SC635HAI_FLIP_MIRROR_REG,
|
||||
SC635HAI_REG_VALUE_08BIT,
|
||||
SC635HAI_FETCH_FLIP(val, ctrl->val));
|
||||
SC635HAI_REG_VALUE_08BIT,
|
||||
SC635HAI_FETCH_FLIP(val, ctrl->val));
|
||||
break;
|
||||
default:
|
||||
dev_warn(&client->dev, "%s Unhandled id:0x%x, val:0x%x\n",
|
||||
@@ -2560,9 +2625,9 @@ static int sc635hai_initialize_controls(struct sc635hai *sc635hai)
|
||||
handler->lock = &sc635hai->mutex;
|
||||
|
||||
sc635hai->link_freq = v4l2_ctrl_new_int_menu(handler, NULL,
|
||||
V4L2_CID_LINK_FREQ,
|
||||
ARRAY_SIZE(link_freq_menu_items) - 1,
|
||||
0, link_freq_menu_items);
|
||||
V4L2_CID_LINK_FREQ,
|
||||
ARRAY_SIZE(link_freq_menu_items) - 1,
|
||||
0, link_freq_menu_items);
|
||||
if (sc635hai->link_freq)
|
||||
sc635hai->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
|
||||
|
||||
@@ -2572,45 +2637,45 @@ static int sc635hai_initialize_controls(struct sc635hai *sc635hai)
|
||||
mode->bpp * 2 * lanes;
|
||||
if (lanes == 2) {
|
||||
sc635hai->pixel_rate = v4l2_ctrl_new_std(handler, NULL, V4L2_CID_PIXEL_RATE,
|
||||
0, PIXEL_RATE_WITH_540M_10BIT_2L,
|
||||
1, dst_pixel_rate);
|
||||
0, PIXEL_RATE_WITH_540M_10BIT_2L,
|
||||
1, dst_pixel_rate);
|
||||
} else if (lanes == 4) {
|
||||
if (mode->hdr_mode == NO_HDR)
|
||||
sc635hai->pixel_rate = v4l2_ctrl_new_std(handler, NULL, V4L2_CID_PIXEL_RATE,
|
||||
0, PIXEL_RATE_WITH_540M_10BIT_4L,
|
||||
1, dst_pixel_rate);
|
||||
0, PIXEL_RATE_WITH_540M_10BIT_4L,
|
||||
1, dst_pixel_rate);
|
||||
else if (mode->hdr_mode == HDR_X2)
|
||||
sc635hai->pixel_rate = v4l2_ctrl_new_std(handler, NULL, V4L2_CID_PIXEL_RATE,
|
||||
0, PIXEL_RATE_WITH_540M_10BIT_4L,
|
||||
1, dst_pixel_rate);
|
||||
0, PIXEL_RATE_WITH_540M_10BIT_4L,
|
||||
1, dst_pixel_rate);
|
||||
}
|
||||
|
||||
__v4l2_ctrl_s_ctrl(sc635hai->link_freq, dst_link_freq);
|
||||
|
||||
h_blank = mode->hts_def - mode->width;
|
||||
sc635hai->hblank = v4l2_ctrl_new_std(handler, NULL, V4L2_CID_HBLANK,
|
||||
h_blank, h_blank, 1, h_blank);
|
||||
h_blank, h_blank, 1, h_blank);
|
||||
if (sc635hai->hblank)
|
||||
sc635hai->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
|
||||
vblank_def = mode->vts_def - mode->height;
|
||||
sc635hai->vblank = v4l2_ctrl_new_std(handler, &sc635hai_ctrl_ops,
|
||||
V4L2_CID_VBLANK, vblank_def,
|
||||
SC635HAI_VTS_MAX - mode->height,
|
||||
1, vblank_def);
|
||||
V4L2_CID_VBLANK, vblank_def,
|
||||
SC635HAI_VTS_MAX - mode->height,
|
||||
1, vblank_def);
|
||||
exposure_max = mode->vts_def - 8;
|
||||
sc635hai->exposure = v4l2_ctrl_new_std(handler, &sc635hai_ctrl_ops,
|
||||
V4L2_CID_EXPOSURE, SC635HAI_EXPOSURE_MIN,
|
||||
exposure_max, SC635HAI_EXPOSURE_STEP,
|
||||
mode->exp_def); //Set default exposure
|
||||
V4L2_CID_EXPOSURE, SC635HAI_EXPOSURE_MIN,
|
||||
exposure_max, SC635HAI_EXPOSURE_STEP,
|
||||
mode->exp_def); //Set default exposure
|
||||
sc635hai->anal_gain = v4l2_ctrl_new_std(handler, &sc635hai_ctrl_ops,
|
||||
V4L2_CID_ANALOGUE_GAIN, SC635HAI_GAIN_MIN,
|
||||
SC635HAI_GAIN_MAX, SC635HAI_GAIN_STEP,
|
||||
SC635HAI_GAIN_DEFAULT); //Set default gain
|
||||
V4L2_CID_ANALOGUE_GAIN, SC635HAI_GAIN_MIN,
|
||||
SC635HAI_GAIN_MAX, SC635HAI_GAIN_STEP,
|
||||
SC635HAI_GAIN_DEFAULT); //Set default gain
|
||||
sc635hai->test_pattern = v4l2_ctrl_new_std_menu_items(handler,
|
||||
&sc635hai_ctrl_ops,
|
||||
V4L2_CID_TEST_PATTERN,
|
||||
ARRAY_SIZE(sc635hai_test_pattern_menu) - 1,
|
||||
0, 0, sc635hai_test_pattern_menu);
|
||||
&sc635hai_ctrl_ops,
|
||||
V4L2_CID_TEST_PATTERN,
|
||||
ARRAY_SIZE(sc635hai_test_pattern_menu) - 1,
|
||||
0, 0, sc635hai_test_pattern_menu);
|
||||
v4l2_ctrl_new_std(handler, &sc635hai_ctrl_ops,
|
||||
V4L2_CID_HFLIP, 0, 1, 1, 0);
|
||||
v4l2_ctrl_new_std(handler, &sc635hai_ctrl_ops,
|
||||
@@ -2636,7 +2701,7 @@ err_free_handler:
|
||||
}
|
||||
|
||||
static int sc635hai_check_sensor_id(struct sc635hai *sc635hai,
|
||||
struct i2c_client *client)
|
||||
struct i2c_client *client)
|
||||
{
|
||||
struct device *dev = &sc635hai->client->dev;
|
||||
u32 id = 0;
|
||||
@@ -2648,7 +2713,7 @@ static int sc635hai_check_sensor_id(struct sc635hai *sc635hai,
|
||||
}
|
||||
|
||||
ret = sc635hai_read_reg(client, SC635HAI_REG_CHIP_ID,
|
||||
SC635HAI_REG_VALUE_16BIT, &id);
|
||||
SC635HAI_REG_VALUE_16BIT, &id);
|
||||
if (id != CHIP_ID) {
|
||||
dev_err(dev, "Unexpected sensor id(%06x), ret(%d)\n", id, ret);
|
||||
return -ENODEV;
|
||||
@@ -2676,6 +2741,7 @@ static int sc635hai_read_module_info(struct sc635hai *sc635hai)
|
||||
int ret;
|
||||
struct device *dev = &sc635hai->client->dev;
|
||||
struct device_node *node = dev->of_node;
|
||||
const char *sync_mode_name = NULL;
|
||||
|
||||
ret = of_property_read_u32(node, RKMODULE_CAMERA_MODULE_INDEX,
|
||||
&sc635hai->module_index);
|
||||
@@ -2693,6 +2759,25 @@ static int sc635hai_read_module_info(struct sc635hai *sc635hai)
|
||||
&sc635hai->standby_hw);
|
||||
dev_info(dev, "sc635hai->standby_hw = %d\n", sc635hai->standby_hw);
|
||||
|
||||
ret = of_property_read_string(node, RKMODULE_CAMERA_SYNC_MODE,
|
||||
&sync_mode_name);
|
||||
if (ret) {
|
||||
sc635hai->sync_mode = NO_SYNC_MODE;
|
||||
dev_err(dev, "could not get sync mode!\n");
|
||||
} else {
|
||||
if (strcmp(sync_mode_name, RKMODULE_EXTERNAL_MASTER_MODE) == 0) {
|
||||
sc635hai->sync_mode = EXTERNAL_MASTER_MODE;
|
||||
dev_info(dev, "sync_mode= [EXTERNAL_MASTER_MODE]\n");
|
||||
} else if (strcmp(sync_mode_name, RKMODULE_INTERNAL_MASTER_MODE) == 0) {
|
||||
sc635hai->sync_mode = INTERNAL_MASTER_MODE;
|
||||
dev_info(dev, "sync_mode= [INTERNAL_MASTER_MODE]\n");
|
||||
} else if (strcmp(sync_mode_name, RKMODULE_SOFT_SYNC_MODE) == 0) {
|
||||
sc635hai->sync_mode = SOFT_SYNC_MODE;
|
||||
dev_info(dev, "sync_mode= [SOFT_SYNC_MODE]\n");
|
||||
} else {
|
||||
dev_info(dev, "sync_mode= [NO_SYNC_MODE]\n");
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -2725,7 +2810,7 @@ static int sc635hai_find_modes(struct sc635hai *sc635hai)
|
||||
}
|
||||
|
||||
dev_info(dev, "Detect sc635hai lane: %d\n",
|
||||
sc635hai->bus_cfg.bus.mipi_csi2.num_data_lanes);
|
||||
sc635hai->bus_cfg.bus.mipi_csi2.num_data_lanes);
|
||||
if (sc635hai->bus_cfg.bus.mipi_csi2.num_data_lanes == 4) {
|
||||
sc635hai->supported_modes = supported_modes_4lane;
|
||||
sc635hai->cfg_num = ARRAY_SIZE(supported_modes_4lane);
|
||||
@@ -2758,12 +2843,12 @@ static int sc635hai_setup_clocks_and_gpios(struct sc635hai *sc635hai)
|
||||
}
|
||||
|
||||
sc635hai->reset_gpio = devm_gpiod_get(dev, "reset",
|
||||
sc635hai->is_thunderboot ? GPIOD_ASIS : GPIOD_OUT_LOW);
|
||||
sc635hai->is_thunderboot ? GPIOD_ASIS : GPIOD_OUT_LOW);
|
||||
if (IS_ERR(sc635hai->reset_gpio))
|
||||
dev_warn(dev, "Failed to get reset-gpios\n");
|
||||
|
||||
sc635hai->pwdn_gpio = devm_gpiod_get(dev, "pwdn",
|
||||
sc635hai->is_thunderboot ? GPIOD_ASIS : GPIOD_OUT_LOW);
|
||||
sc635hai->is_thunderboot ? GPIOD_ASIS : GPIOD_OUT_LOW);
|
||||
if (IS_ERR(sc635hai->pwdn_gpio))
|
||||
dev_warn(dev, "Failed to get pwdn-gpios\n");
|
||||
|
||||
@@ -2788,7 +2873,7 @@ static int sc635hai_setup_clocks_and_gpios(struct sc635hai *sc635hai)
|
||||
}
|
||||
|
||||
static int sc635hai_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
struct device *dev = &client->dev;
|
||||
struct sc635hai *sc635hai;
|
||||
|
||||
@@ -960,12 +960,15 @@ static int read_config(struct rkvpss_offline_dev *ofl,
|
||||
u32 in_ctrl, in_size, in_c_offs, unite_r_offs, val, mask, unite_off = 0, enlarge = 0,
|
||||
header_size = 0, payload_size = 0;
|
||||
|
||||
if (!IS_ALIGNED(cfg->input.stride, 4)) {
|
||||
v4l2_err(&ofl->v4l2_dev, "input stride %d is not 4-byte aligned\n", cfg->input.stride);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
in_c_offs = 0;
|
||||
in_ctrl = 0;
|
||||
switch (cfg->input.format) {
|
||||
case V4L2_PIX_FMT_NV16:
|
||||
if (cfg->input.stride < ALIGN(cfg->input.width, 16))
|
||||
cfg->input.stride = ALIGN(cfg->input.width, 16);
|
||||
in_c_offs = cfg->input.ver_stride ?
|
||||
cfg->input.stride * cfg->input.ver_stride :
|
||||
cfg->input.stride * cfg->input.height;
|
||||
@@ -974,8 +977,6 @@ static int read_config(struct rkvpss_offline_dev *ofl,
|
||||
unite_off = 8;
|
||||
break;
|
||||
case V4L2_PIX_FMT_NV12:
|
||||
if (cfg->input.stride < ALIGN(cfg->input.width, 16))
|
||||
cfg->input.stride = ALIGN(cfg->input.width, 16);
|
||||
in_c_offs = cfg->input.ver_stride ?
|
||||
cfg->input.stride * cfg->input.ver_stride :
|
||||
cfg->input.stride * cfg->input.height;
|
||||
@@ -984,8 +985,6 @@ static int read_config(struct rkvpss_offline_dev *ofl,
|
||||
unite_off = 8;
|
||||
break;
|
||||
case V4L2_PIX_FMT_NV61:
|
||||
if (cfg->input.stride < ALIGN(cfg->input.width, 16))
|
||||
cfg->input.stride = ALIGN(cfg->input.width, 16);
|
||||
in_c_offs = cfg->input.ver_stride ?
|
||||
cfg->input.stride * cfg->input.ver_stride :
|
||||
cfg->input.stride * cfg->input.height;
|
||||
@@ -994,8 +993,6 @@ static int read_config(struct rkvpss_offline_dev *ofl,
|
||||
unite_off = 8;
|
||||
break;
|
||||
case V4L2_PIX_FMT_NV21:
|
||||
if (cfg->input.stride < ALIGN(cfg->input.width, 16))
|
||||
cfg->input.stride = ALIGN(cfg->input.width, 16);
|
||||
in_c_offs = cfg->input.ver_stride ?
|
||||
cfg->input.stride * cfg->input.ver_stride :
|
||||
cfg->input.stride * cfg->input.height;
|
||||
@@ -1004,58 +1001,42 @@ static int read_config(struct rkvpss_offline_dev *ofl,
|
||||
unite_off = 8;
|
||||
break;
|
||||
case V4L2_PIX_FMT_RGB565:
|
||||
if (cfg->input.stride < ALIGN(cfg->input.width * 2, 16))
|
||||
cfg->input.stride = ALIGN(cfg->input.width * 2, 16);
|
||||
in_size = cfg->input.stride * cfg->input.height;
|
||||
in_ctrl |= RKVPSS_MI_RD_INPUT_BGR565;
|
||||
unite_off = 16;
|
||||
break;
|
||||
case V4L2_PIX_FMT_RGB565X:
|
||||
if (cfg->input.stride < ALIGN(cfg->input.width * 2, 16))
|
||||
cfg->input.stride = ALIGN(cfg->input.width * 2, 16);
|
||||
in_size = cfg->input.stride * cfg->input.height;
|
||||
in_ctrl |= RKVPSS_MI_RD_INPUT_BGR565 | RKVPSS_MI_RD_RB_SWAP;
|
||||
unite_off = 16;
|
||||
break;
|
||||
case V4L2_PIX_FMT_RGB24:
|
||||
if (cfg->input.stride < ALIGN(cfg->input.width * 3, 16))
|
||||
cfg->input.stride = ALIGN(cfg->input.width * 3, 16);
|
||||
in_size = cfg->input.stride * cfg->input.height;
|
||||
in_ctrl |= RKVPSS_MI_RD_INPUT_BGR888;
|
||||
unite_off = 24;
|
||||
break;
|
||||
case V4L2_PIX_FMT_BGR24:
|
||||
if (cfg->input.stride < ALIGN(cfg->input.width * 3, 16))
|
||||
cfg->input.stride = ALIGN(cfg->input.width * 3, 16);
|
||||
in_size = cfg->input.stride * cfg->input.height;
|
||||
in_ctrl |= RKVPSS_MI_RD_INPUT_BGR888 | RKVPSS_MI_RD_RB_SWAP;
|
||||
unite_off = 24;
|
||||
break;
|
||||
case V4L2_PIX_FMT_XRGB32:
|
||||
if (cfg->input.stride < ALIGN(cfg->input.width * 4, 16))
|
||||
cfg->input.stride = ALIGN(cfg->input.width * 4, 16);
|
||||
in_size = cfg->input.stride * cfg->input.height;
|
||||
in_ctrl |= RKVPSS_MI_RD_INPUT_ABGR888;
|
||||
unite_off = 32;
|
||||
break;
|
||||
case V4L2_PIX_FMT_XBGR32:
|
||||
if (cfg->input.stride < ALIGN(cfg->input.width * 4, 16))
|
||||
cfg->input.stride = ALIGN(cfg->input.width * 4, 16);
|
||||
in_size = cfg->input.stride * cfg->input.height;
|
||||
in_ctrl |= RKVPSS_MI_RD_INPUT_ABGR888 | RKVPSS_MI_RD_RB_SWAP;
|
||||
unite_off = 32;
|
||||
break;
|
||||
case V4L2_PIX_FMT_RGBX32:
|
||||
if (cfg->input.stride < ALIGN(cfg->input.width * 4, 16))
|
||||
cfg->input.stride = ALIGN(cfg->input.width * 4, 16);
|
||||
in_size = cfg->input.stride * cfg->input.height;
|
||||
in_ctrl |= RKVPSS_MI_RD_INPUT_ABGR888
|
||||
| RKVPSS_MI_RD_ALPHA_SWAP;
|
||||
unite_off = 32;
|
||||
break;
|
||||
case V4L2_PIX_FMT_BGRX32:
|
||||
if (cfg->input.stride < ALIGN(cfg->input.width * 4, 16))
|
||||
cfg->input.stride = ALIGN(cfg->input.width * 4, 16);
|
||||
in_size = cfg->input.stride * cfg->input.height;
|
||||
in_ctrl |= RKVPSS_MI_RD_INPUT_ABGR888
|
||||
| RKVPSS_MI_RD_RB_SWAP
|
||||
@@ -1093,43 +1074,31 @@ static int read_config(struct rkvpss_offline_dev *ofl,
|
||||
in_ctrl |= RKVPSS_MI_RD_INPUT_422SP | RKVPSS_MI_RD_FBCD_YUV444_EN;
|
||||
break;
|
||||
case V4L2_PIX_FMT_TILE420:
|
||||
if (cfg->input.stride < ALIGN(cfg->input.width * 6, 16))
|
||||
cfg->input.stride = ALIGN(cfg->input.width * 6, 16);
|
||||
in_c_offs = 0;
|
||||
in_size = cfg->input.stride * (cfg->input.height / 4);
|
||||
in_ctrl |= RKVPSS_MI_RD_INPUT_420SP;
|
||||
break;
|
||||
case V4L2_PIX_FMT_TILE422:
|
||||
if (cfg->input.stride < ALIGN(cfg->input.width * 8, 16))
|
||||
cfg->input.stride = ALIGN(cfg->input.width * 8, 16);
|
||||
in_c_offs = 0;
|
||||
in_size = cfg->input.stride * (cfg->input.height / 4);
|
||||
in_ctrl |= RKVPSS_MI_RD_INPUT_422SP;
|
||||
break;
|
||||
case V4L2_PIX_FMT_UYVY:
|
||||
if (cfg->input.stride < ALIGN(cfg->input.width * 2, 16))
|
||||
cfg->input.stride = ALIGN(cfg->input.width * 2, 16);
|
||||
in_size = cfg->input.stride * cfg->input.height;
|
||||
in_ctrl |= RKVPSS2X_MI_RD_INPUT_UYVY;
|
||||
//unite_off todo
|
||||
break;
|
||||
case V4L2_PIX_FMT_VYUY:
|
||||
if (cfg->input.stride < ALIGN(cfg->input.width * 2, 16))
|
||||
cfg->input.stride = ALIGN(cfg->input.width * 2, 16);
|
||||
in_size = cfg->input.stride * cfg->input.height;
|
||||
in_ctrl |= RKVPSS2X_MI_RD_INPUT_UYVY | RKVPSS_MI_RD_UV_SWAP;
|
||||
//unite_off todo
|
||||
break;
|
||||
case V4L2_PIX_FMT_YUYV:
|
||||
if (cfg->input.stride < ALIGN(cfg->input.width * 2, 16))
|
||||
cfg->input.stride = ALIGN(cfg->input.width * 2, 16);
|
||||
in_size = cfg->input.stride * cfg->input.height;
|
||||
in_ctrl |= RKVPSS2X_MI_RD_INPUT_UYVY | RKVPSS_MI_RD_RB_SWAP;
|
||||
//unite_off todo
|
||||
break;
|
||||
case V4L2_PIX_FMT_YVYU:
|
||||
if (cfg->input.stride < ALIGN(cfg->input.width * 2, 16))
|
||||
cfg->input.stride = ALIGN(cfg->input.width * 2, 16);
|
||||
in_size = cfg->input.stride * cfg->input.height;
|
||||
in_ctrl |= RKVPSS2X_MI_RD_INPUT_UYVY | RKVPSS_MI_RD_RB_SWAP | RKVPSS_MI_RD_UV_SWAP;
|
||||
//unite_off todo
|
||||
@@ -1398,6 +1367,12 @@ static int write_config(struct rkvpss_offline_dev *ofl,
|
||||
continue;
|
||||
ch_en = true;
|
||||
|
||||
if (!IS_ALIGNED(cfg->output[i].stride, 4)) {
|
||||
v4l2_err(&ofl->v4l2_dev, "output stride %d is not 4-byte aligned for ch%d\n",
|
||||
cfg->output[i].stride, i);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (cfg->output[i].aspt.enable) {
|
||||
w = cfg->output[i].aspt.width;
|
||||
h = cfg->output[i].aspt.height;
|
||||
@@ -1410,36 +1385,24 @@ static int write_config(struct rkvpss_offline_dev *ofl,
|
||||
|
||||
switch (cfg->output[i].format) {
|
||||
case V4L2_PIX_FMT_RGB565:
|
||||
if (cfg->output[i].stride < ALIGN(w * 2, 16))
|
||||
cfg->output[i].stride = ALIGN(w * 2, 16);
|
||||
out_ch[i].ctrl |= RKVPSS_MI_CHN_WR_OUTPUT_RGB565 |
|
||||
RKVPSS_MI_CHN_WR_RB_SWAP;
|
||||
break;
|
||||
case V4L2_PIX_FMT_RGB24:
|
||||
if (cfg->output[i].stride < ALIGN(w * 3, 16))
|
||||
cfg->output[i].stride = ALIGN(w * 3, 16);
|
||||
out_ch[i].ctrl |= RKVPSS_MI_CHN_WR_OUTPUT_RGB888 |
|
||||
RKVPSS_MI_CHN_WR_RB_SWAP;
|
||||
break;
|
||||
case V4L2_PIX_FMT_RGB565X:
|
||||
if (cfg->output[i].stride < ALIGN(w * 2, 16))
|
||||
cfg->output[i].stride = ALIGN(w * 2, 16);
|
||||
out_ch[i].ctrl |= RKVPSS_MI_CHN_WR_OUTPUT_RGB565;
|
||||
break;
|
||||
case V4L2_PIX_FMT_BGR24:
|
||||
if (cfg->output[i].stride < ALIGN(w * 3, 16))
|
||||
cfg->output[i].stride = ALIGN(w * 3, 16);
|
||||
out_ch[i].ctrl |= RKVPSS_MI_CHN_WR_OUTPUT_RGB888;
|
||||
break;
|
||||
case V4L2_PIX_FMT_XBGR32:
|
||||
if (cfg->output[i].stride < ALIGN(w * 4, 16))
|
||||
cfg->output[i].stride = ALIGN(w * 4, 16);
|
||||
out_ch[i].ctrl |= RKVPSS_MI_CHN_WR_OUTPUT_ARGB888 |
|
||||
RKVPSS2X_CH1_WR_RGB888_ALPHA(cfg->output[i].alpha);
|
||||
break;
|
||||
case V4L2_PIX_FMT_XRGB32:
|
||||
if (cfg->output[i].stride < ALIGN(w * 4, 16))
|
||||
cfg->output[i].stride = ALIGN(w * 4, 16);
|
||||
out_ch[i].ctrl |= RKVPSS_MI_CHN_WR_OUTPUT_ARGB888 |
|
||||
RKVPSS_MI_CHN_WR_RB_SWAP |
|
||||
RKVPSS2X_CH1_WR_RGB888_ALPHA(cfg->output[i].alpha);
|
||||
@@ -1455,61 +1418,43 @@ static int write_config(struct rkvpss_offline_dev *ofl,
|
||||
}
|
||||
switch (cfg->output[i].format) {
|
||||
case V4L2_PIX_FMT_UYVY:
|
||||
if (cfg->output[i].stride < ALIGN(w * 2, 16))
|
||||
cfg->output[i].stride = ALIGN(w * 2, 16);
|
||||
out_ch[i].ctrl |= RKVPSS_MI_CHN_WR_422P | RKVPSS_MI_CHN_WR_OUTPUT_YUV422;
|
||||
out_ch[i].size = cfg->output[i].stride * h;
|
||||
break;
|
||||
case V4L2_PIX_FMT_NV16:
|
||||
if (cfg->output[i].stride < ALIGN(w, 16))
|
||||
cfg->output[i].stride = ALIGN(w, 16);
|
||||
out_ch[i].ctrl |= RKVPSS_MI_CHN_WR_42XSP | RKVPSS_MI_CHN_WR_OUTPUT_YUV422;
|
||||
out_ch[i].size = cfg->output[i].stride * h * 2;
|
||||
out_ch[i].c_offs = cfg->output[i].stride * h;
|
||||
break;
|
||||
case V4L2_PIX_FMT_NV12:
|
||||
if (cfg->output[i].stride < ALIGN(w, 16))
|
||||
cfg->output[i].stride = ALIGN(w, 16);
|
||||
out_ch[i].ctrl |= RKVPSS_MI_CHN_WR_42XSP | RKVPSS_MI_CHN_WR_OUTPUT_YUV420;
|
||||
out_ch[i].size = cfg->output[i].stride * h * 3 / 2;
|
||||
out_ch[i].c_offs = cfg->output[i].stride * h;
|
||||
break;
|
||||
case V4L2_PIX_FMT_GREY:
|
||||
if (cfg->output[i].stride < ALIGN(w, 16))
|
||||
cfg->output[i].stride = ALIGN(w, 16);
|
||||
out_ch[i].ctrl |= RKVPSS_MI_CHN_WR_42XSP | RKVPSS_MI_CHN_WR_OUTPUT_YUV400;
|
||||
out_ch[i].size = cfg->output[i].stride * h;
|
||||
break;
|
||||
case V4L2_PIX_FMT_VYUY:
|
||||
if (cfg->output[i].stride < ALIGN(w * 2, 16))
|
||||
cfg->output[i].stride = ALIGN(w * 2, 16);
|
||||
out_ch[i].ctrl |= RKVPSS_MI_CHN_WR_422P | RKVPSS_MI_CHN_WR_OUTPUT_YUV422;
|
||||
out_ch[i].size = cfg->output[i].stride * h;
|
||||
break;
|
||||
case V4L2_PIX_FMT_NV61:
|
||||
if (cfg->output[i].stride < ALIGN(w, 16))
|
||||
cfg->output[i].stride = ALIGN(w, 16);
|
||||
out_ch[i].ctrl |= RKVPSS_MI_CHN_WR_42XSP | RKVPSS_MI_CHN_WR_OUTPUT_YUV422;
|
||||
out_ch[i].size = cfg->output[i].stride * h * 2;
|
||||
out_ch[i].c_offs = cfg->output[i].stride * h;
|
||||
break;
|
||||
case V4L2_PIX_FMT_NV21:
|
||||
if (cfg->output[i].stride < ALIGN(w, 16))
|
||||
cfg->output[i].stride = ALIGN(w, 16);
|
||||
out_ch[i].ctrl |= RKVPSS_MI_CHN_WR_42XSP | RKVPSS_MI_CHN_WR_OUTPUT_YUV420;
|
||||
out_ch[i].size = cfg->output[i].stride * h * 3 / 2;
|
||||
out_ch[i].c_offs = cfg->output[i].stride * h;
|
||||
break;
|
||||
case V4L2_PIX_FMT_TILE420:
|
||||
if (cfg->output[i].stride < ALIGN(w * 6, 16))
|
||||
cfg->output[i].stride = ALIGN(w * 6, 16);
|
||||
out_ch[i].ctrl |= RKVPSS_MI_CHN_WR_OUTPUT_YUV420;
|
||||
out_ch[i].size = cfg->output[i].stride * (h / 4);
|
||||
out_ch[i].c_offs = 0;
|
||||
break;
|
||||
case V4L2_PIX_FMT_TILE422:
|
||||
if (cfg->output[i].stride < ALIGN(w * 8, 16))
|
||||
cfg->output[i].stride = ALIGN(w * 8, 16);
|
||||
out_ch[i].ctrl |= RKVPSS_MI_CHN_WR_OUTPUT_YUV422;
|
||||
out_ch[i].size = cfg->output[i].stride * (h / 4);
|
||||
out_ch[i].c_offs = 0;
|
||||
|
||||
@@ -516,7 +516,7 @@ static int __init rockchip_decom_probe(struct platform_device *pdev)
|
||||
rk_dec->regs = devm_ioremap_resource(dev, res);
|
||||
if (IS_ERR(rk_dec->regs)) {
|
||||
ret = PTR_ERR(rk_dec->regs);
|
||||
goto disable_clk;
|
||||
return ret;
|
||||
}
|
||||
|
||||
dev_set_drvdata(dev, rk_dec);
|
||||
@@ -536,7 +536,7 @@ static int __init rockchip_decom_probe(struct platform_device *pdev)
|
||||
dev_name(dev), rk_dec);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "failed to attach decompress irq\n");
|
||||
goto disable_clk;
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ROCKCHIP_HW_DECOMPRESS_TEST
|
||||
@@ -554,11 +554,6 @@ static int __init rockchip_decom_probe(struct platform_device *pdev)
|
||||
pm_runtime_get_sync(dev);
|
||||
#endif
|
||||
return 0;
|
||||
|
||||
disable_clk:
|
||||
clk_bulk_disable_unprepare(rk_dec->num_clocks, rk_dec->clocks);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifndef CONFIG_ROCKCHIP_THUNDER_BOOT
|
||||
|
||||
Reference in New Issue
Block a user