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:
Tao Huang
2025-08-19 09:17:28 +08:00
16 changed files with 4930 additions and 225 deletions

View File

@@ -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 \

View 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"

View File

@@ -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

View File

@@ -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

View 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>;
};
};

View File

@@ -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

View File

@@ -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;

View File

@@ -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;

View File

@@ -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);

View File

@@ -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

View File

@@ -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

File diff suppressed because it is too large Load Diff

2261
drivers/media/i2c/sc235hai.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -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;

View File

@@ -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;

View File

@@ -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