^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Driver for Samsung S5K5BAF UXGA 1/5" 2M CMOS Image Sensor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * with embedded SoC ISP.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (C) 2013, Samsung Electronics Co., Ltd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Andrzej Hajda <a.hajda@samsung.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Based on S5K6AA driver authored by Sylwester Nawrocki
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * Copyright (C) 2013, Samsung Electronics Co., Ltd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/firmware.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/gpio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/i2c.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/media.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/of_gpio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/of_graph.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/regulator/consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <media/media-entity.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <media/v4l2-ctrls.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <media/v4l2-device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <media/v4l2-subdev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <media/v4l2-mediabus.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <media/v4l2-fwnode.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) static int debug;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) module_param(debug, int, 0644);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define S5K5BAF_DRIVER_NAME "s5k5baf"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define S5K5BAF_DEFAULT_MCLK_FREQ 24000000U
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define S5K5BAF_CLK_NAME "mclk"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define S5K5BAF_FW_FILENAME "s5k5baf-cfg.bin"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define S5K5BAF_FW_TAG "SF00"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define S5K5BAG_FW_TAG_LEN 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define S5K5BAG_FW_MAX_COUNT 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define S5K5BAF_CIS_WIDTH 1600
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define S5K5BAF_CIS_HEIGHT 1200
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define S5K5BAF_WIN_WIDTH_MIN 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define S5K5BAF_WIN_HEIGHT_MIN 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define S5K5BAF_GAIN_RED_DEF 127
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define S5K5BAF_GAIN_GREEN_DEF 95
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define S5K5BAF_GAIN_BLUE_DEF 180
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) /* Default number of MIPI CSI-2 data lanes used */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define S5K5BAF_DEF_NUM_LANES 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define AHB_MSB_ADDR_PTR 0xfcfc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) * Register interface pages (the most significant word of the address)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define PAGE_IF_HW 0xd000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #define PAGE_IF_SW 0x7000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) * H/W register Interface (PAGE_IF_HW)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define REG_SW_LOAD_COMPLETE 0x0014
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #define REG_CMDWR_PAGE 0x0028
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #define REG_CMDWR_ADDR 0x002a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #define REG_CMDRD_PAGE 0x002c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #define REG_CMDRD_ADDR 0x002e
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #define REG_CMD_BUF 0x0f12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define REG_SET_HOST_INT 0x1000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define REG_CLEAR_HOST_INT 0x1030
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define REG_PATTERN_SET 0x3100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #define REG_PATTERN_WIDTH 0x3118
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #define REG_PATTERN_HEIGHT 0x311a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #define REG_PATTERN_PARAM 0x311c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) * S/W register interface (PAGE_IF_SW)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) /* Firmware revision information */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) #define REG_FW_APIVER 0x012e
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #define S5K5BAF_FW_APIVER 0x0001
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) #define REG_FW_REVISION 0x0130
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) #define REG_FW_SENSOR_ID 0x0152
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) /* Initialization parameters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) /* Master clock frequency in KHz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) #define REG_I_INCLK_FREQ_L 0x01b8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) #define REG_I_INCLK_FREQ_H 0x01ba
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) #define MIN_MCLK_FREQ_KHZ 6000U
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) #define MAX_MCLK_FREQ_KHZ 48000U
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) #define REG_I_USE_NPVI_CLOCKS 0x01c6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) #define NPVI_CLOCKS 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) #define REG_I_USE_NMIPI_CLOCKS 0x01c8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) #define NMIPI_CLOCKS 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) #define REG_I_BLOCK_INTERNAL_PLL_CALC 0x01ca
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) /* Clock configurations, n = 0..2. REG_I_* frequency unit is 4 kHz. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) #define REG_I_OPCLK_4KHZ(n) ((n) * 6 + 0x01cc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) #define REG_I_MIN_OUTRATE_4KHZ(n) ((n) * 6 + 0x01ce)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) #define REG_I_MAX_OUTRATE_4KHZ(n) ((n) * 6 + 0x01d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) #define SCLK_PVI_FREQ 24000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) #define SCLK_MIPI_FREQ 48000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) #define PCLK_MIN_FREQ 6000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) #define PCLK_MAX_FREQ 48000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) #define REG_I_USE_REGS_API 0x01de
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) #define REG_I_INIT_PARAMS_UPDATED 0x01e0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) #define REG_I_ERROR_INFO 0x01e2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) /* General purpose parameters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) #define REG_USER_BRIGHTNESS 0x01e4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) #define REG_USER_CONTRAST 0x01e6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) #define REG_USER_SATURATION 0x01e8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) #define REG_USER_SHARPBLUR 0x01ea
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) #define REG_G_SPEC_EFFECTS 0x01ee
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) #define REG_G_ENABLE_PREV 0x01f0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) #define REG_G_ENABLE_PREV_CHG 0x01f2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) #define REG_G_NEW_CFG_SYNC 0x01f8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) #define REG_G_PREVREQ_IN_WIDTH 0x01fa
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) #define REG_G_PREVREQ_IN_HEIGHT 0x01fc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) #define REG_G_PREVREQ_IN_XOFFS 0x01fe
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) #define REG_G_PREVREQ_IN_YOFFS 0x0200
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) #define REG_G_PREVZOOM_IN_WIDTH 0x020a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) #define REG_G_PREVZOOM_IN_HEIGHT 0x020c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) #define REG_G_PREVZOOM_IN_XOFFS 0x020e
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) #define REG_G_PREVZOOM_IN_YOFFS 0x0210
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) #define REG_G_INPUTS_CHANGE_REQ 0x021a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) #define REG_G_ACTIVE_PREV_CFG 0x021c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) #define REG_G_PREV_CFG_CHG 0x021e
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) #define REG_G_PREV_OPEN_AFTER_CH 0x0220
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) #define REG_G_PREV_CFG_ERROR 0x0222
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) #define CFG_ERROR_RANGE 0x0b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) #define REG_G_PREV_CFG_BYPASS_CHANGED 0x022a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) #define REG_G_ACTUAL_P_FR_TIME 0x023a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) #define REG_G_ACTUAL_P_OUT_RATE 0x023c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) #define REG_G_ACTUAL_C_FR_TIME 0x023e
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) #define REG_G_ACTUAL_C_OUT_RATE 0x0240
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) /* Preview control section. n = 0...4. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) #define PREG(n, x) ((n) * 0x26 + x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) #define REG_P_OUT_WIDTH(n) PREG(n, 0x0242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) #define REG_P_OUT_HEIGHT(n) PREG(n, 0x0244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) #define REG_P_FMT(n) PREG(n, 0x0246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) #define REG_P_MAX_OUT_RATE(n) PREG(n, 0x0248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) #define REG_P_MIN_OUT_RATE(n) PREG(n, 0x024a)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) #define REG_P_PVI_MASK(n) PREG(n, 0x024c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) #define PVI_MASK_MIPI 0x52
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) #define REG_P_CLK_INDEX(n) PREG(n, 0x024e)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) #define CLK_PVI_INDEX 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) #define CLK_MIPI_INDEX NPVI_CLOCKS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) #define REG_P_FR_RATE_TYPE(n) PREG(n, 0x0250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) #define FR_RATE_DYNAMIC 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) #define FR_RATE_FIXED 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) #define FR_RATE_FIXED_ACCURATE 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) #define REG_P_FR_RATE_Q_TYPE(n) PREG(n, 0x0252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) #define FR_RATE_Q_DYNAMIC 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) #define FR_RATE_Q_BEST_FRRATE 1 /* Binning enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) #define FR_RATE_Q_BEST_QUALITY 2 /* Binning disabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) /* Frame period in 0.1 ms units */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) #define REG_P_MAX_FR_TIME(n) PREG(n, 0x0254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) #define REG_P_MIN_FR_TIME(n) PREG(n, 0x0256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) #define S5K5BAF_MIN_FR_TIME 333 /* x100 us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) #define S5K5BAF_MAX_FR_TIME 6500 /* x100 us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) /* The below 5 registers are for "device correction" values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) #define REG_P_SATURATION(n) PREG(n, 0x0258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) #define REG_P_SHARP_BLUR(n) PREG(n, 0x025a)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) #define REG_P_GLAMOUR(n) PREG(n, 0x025c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) #define REG_P_COLORTEMP(n) PREG(n, 0x025e)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) #define REG_P_GAMMA_INDEX(n) PREG(n, 0x0260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) #define REG_P_PREV_MIRROR(n) PREG(n, 0x0262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) #define REG_P_CAP_MIRROR(n) PREG(n, 0x0264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) #define REG_P_CAP_ROTATION(n) PREG(n, 0x0266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) /* Extended image property controls */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) /* Exposure time in 10 us units */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) #define REG_SF_USR_EXPOSURE_L 0x03bc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) #define REG_SF_USR_EXPOSURE_H 0x03be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) #define REG_SF_USR_EXPOSURE_CHG 0x03c0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) #define REG_SF_USR_TOT_GAIN 0x03c2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) #define REG_SF_USR_TOT_GAIN_CHG 0x03c4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) #define REG_SF_RGAIN 0x03c6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) #define REG_SF_RGAIN_CHG 0x03c8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) #define REG_SF_GGAIN 0x03ca
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) #define REG_SF_GGAIN_CHG 0x03cc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) #define REG_SF_BGAIN 0x03ce
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) #define REG_SF_BGAIN_CHG 0x03d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) #define REG_SF_WBGAIN_CHG 0x03d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) #define REG_SF_FLICKER_QUANT 0x03d4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) #define REG_SF_FLICKER_QUANT_CHG 0x03d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) /* Output interface (parallel/MIPI) setup */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) #define REG_OIF_EN_MIPI_LANES 0x03f2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) #define REG_OIF_EN_PACKETS 0x03f4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) #define EN_PACKETS_CSI2 0xc3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) #define REG_OIF_CFG_CHG 0x03f6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) /* Auto-algorithms enable mask */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) #define REG_DBG_AUTOALG_EN 0x03f8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) #define AALG_ALL_EN BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) #define AALG_AE_EN BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) #define AALG_DIVLEI_EN BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) #define AALG_WB_EN BIT(3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) #define AALG_USE_WB_FOR_ISP BIT(4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) #define AALG_FLICKER_EN BIT(5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) #define AALG_FIT_EN BIT(6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) #define AALG_WRHW_EN BIT(7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) /* Pointers to color correction matrices */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) #define REG_PTR_CCM_HORIZON 0x06d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) #define REG_PTR_CCM_INCANDESCENT 0x06d4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) #define REG_PTR_CCM_WARM_WHITE 0x06d8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) #define REG_PTR_CCM_COOL_WHITE 0x06dc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) #define REG_PTR_CCM_DL50 0x06e0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) #define REG_PTR_CCM_DL65 0x06e4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) #define REG_PTR_CCM_OUTDOOR 0x06ec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) #define REG_ARR_CCM(n) (0x2800 + 36 * (n))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) static const char * const s5k5baf_supply_names[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) "vdda", /* Analog power supply 2.8V (2.6V to 3.0V) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) "vddreg", /* Regulator input power supply 1.8V (1.7V to 1.9V)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) or 2.8V (2.6V to 3.0) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) "vddio", /* I/O power supply 1.8V (1.65V to 1.95V)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) or 2.8V (2.5V to 3.1V) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) #define S5K5BAF_NUM_SUPPLIES ARRAY_SIZE(s5k5baf_supply_names)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) struct s5k5baf_gpio {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) int gpio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) int level;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) enum s5k5baf_gpio_id {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) STBY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) RSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) NUM_GPIOS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) #define PAD_CIS 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) #define PAD_OUT 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) #define NUM_CIS_PADS 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) #define NUM_ISP_PADS 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) struct s5k5baf_pixfmt {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) u32 code;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) u32 colorspace;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) /* REG_P_FMT(x) register value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) u16 reg_p_fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) struct s5k5baf_ctrls {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) struct v4l2_ctrl_handler handler;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) struct { /* Auto / manual white balance cluster */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) struct v4l2_ctrl *awb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) struct v4l2_ctrl *gain_red;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) struct v4l2_ctrl *gain_blue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) struct { /* Mirror cluster */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) struct v4l2_ctrl *hflip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) struct v4l2_ctrl *vflip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) struct { /* Auto exposure / manual exposure and gain cluster */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) struct v4l2_ctrl *auto_exp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) struct v4l2_ctrl *exposure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) struct v4l2_ctrl *gain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) S5K5BAF_FW_ID_PATCH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) S5K5BAF_FW_ID_CCM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) S5K5BAF_FW_ID_CIS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) struct s5k5baf_fw {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) u16 count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) u16 id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) u16 offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) } seq[];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) struct s5k5baf {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) struct s5k5baf_gpio gpios[NUM_GPIOS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) enum v4l2_mbus_type bus_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) u8 nlanes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) struct regulator_bulk_data supplies[S5K5BAF_NUM_SUPPLIES];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) struct clk *clock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) u32 mclk_frequency;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) struct s5k5baf_fw *fw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) struct v4l2_subdev cis_sd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) struct media_pad cis_pad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) struct v4l2_subdev sd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) struct media_pad pads[NUM_ISP_PADS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) /* protects the struct members below */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) struct mutex lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) struct v4l2_rect crop_sink;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) struct v4l2_rect compose;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) struct v4l2_rect crop_source;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) /* index to s5k5baf_formats array */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) int pixfmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) /* actual frame interval in 100us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) u16 fiv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) /* requested frame interval in 100us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) u16 req_fiv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) /* cache for REG_DBG_AUTOALG_EN register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) u16 auto_alg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) struct s5k5baf_ctrls ctrls;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) unsigned int streaming:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) unsigned int apply_cfg:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) unsigned int apply_crop:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) unsigned int valid_auto_alg:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) unsigned int power;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) static const struct s5k5baf_pixfmt s5k5baf_formats[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) { MEDIA_BUS_FMT_VYUY8_2X8, V4L2_COLORSPACE_JPEG, 5 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) /* range 16-240 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) { MEDIA_BUS_FMT_VYUY8_2X8, V4L2_COLORSPACE_REC709, 6 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) { MEDIA_BUS_FMT_RGB565_2X8_BE, V4L2_COLORSPACE_JPEG, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) static struct v4l2_rect s5k5baf_cis_rect = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 0, 0, S5K5BAF_CIS_WIDTH, S5K5BAF_CIS_HEIGHT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) /* Setfile contains set of I2C command sequences. Each sequence has its ID.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) * setfile format:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) * u8 magic[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) * u16 count; number of sequences
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) * struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) * u16 id; sequence id
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) * u16 offset; sequence offset in data array
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) * } seq[count];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) * u16 data[*]; array containing sequences
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) static int s5k5baf_fw_parse(struct device *dev, struct s5k5baf_fw **fw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) size_t count, const __le16 *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) struct s5k5baf_fw *f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) u16 *d, i, *end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) if (count < S5K5BAG_FW_TAG_LEN + 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) dev_err(dev, "firmware file too short (%zu)\n", count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) ret = memcmp(data, S5K5BAF_FW_TAG, S5K5BAG_FW_TAG_LEN * sizeof(u16));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) if (ret != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) dev_err(dev, "invalid firmware magic number\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) data += S5K5BAG_FW_TAG_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) count -= S5K5BAG_FW_TAG_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) d = devm_kcalloc(dev, count, sizeof(u16), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) if (!d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) for (i = 0; i < count; ++i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) d[i] = le16_to_cpu(data[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) f = (struct s5k5baf_fw *)d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) if (count < 1 + 2 * f->count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) dev_err(dev, "invalid firmware header (count=%d size=%zu)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) f->count, 2 * (count + S5K5BAG_FW_TAG_LEN));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) end = d + count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) d += 1 + 2 * f->count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) for (i = 0; i < f->count; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) if (f->seq[i].offset + d <= end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) dev_err(dev, "invalid firmware header (seq=%d)\n", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) *fw = f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) static inline struct v4l2_subdev *ctrl_to_sd(struct v4l2_ctrl *ctrl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) return &container_of(ctrl->handler, struct s5k5baf, ctrls.handler)->sd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) static inline bool s5k5baf_is_cis_subdev(struct v4l2_subdev *sd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) return sd->entity.function == MEDIA_ENT_F_CAM_SENSOR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) static inline struct s5k5baf *to_s5k5baf(struct v4l2_subdev *sd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) if (s5k5baf_is_cis_subdev(sd))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) return container_of(sd, struct s5k5baf, cis_sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) return container_of(sd, struct s5k5baf, sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) static u16 s5k5baf_i2c_read(struct s5k5baf *state, u16 addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) struct i2c_client *c = v4l2_get_subdevdata(&state->sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) __be16 w, r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) u16 res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) struct i2c_msg msg[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) { .addr = c->addr, .flags = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) .len = 2, .buf = (u8 *)&w },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) { .addr = c->addr, .flags = I2C_M_RD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) .len = 2, .buf = (u8 *)&r },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) if (state->error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) w = cpu_to_be16(addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) ret = i2c_transfer(c->adapter, msg, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) res = be16_to_cpu(r);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) v4l2_dbg(3, debug, c, "i2c_read: 0x%04x : 0x%04x\n", addr, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) if (ret != 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) v4l2_err(c, "i2c_read: error during transfer (%d)\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) state->error = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) static void s5k5baf_i2c_write(struct s5k5baf *state, u16 addr, u16 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) u8 buf[4] = { addr >> 8, addr & 0xFF, val >> 8, val & 0xFF };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) struct i2c_client *c = v4l2_get_subdevdata(&state->sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) if (state->error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) ret = i2c_master_send(c, buf, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) v4l2_dbg(3, debug, c, "i2c_write: 0x%04x : 0x%04x\n", addr, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) if (ret != 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) v4l2_err(c, "i2c_write: error during transfer (%d)\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) state->error = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) static u16 s5k5baf_read(struct s5k5baf *state, u16 addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) s5k5baf_i2c_write(state, REG_CMDRD_ADDR, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) return s5k5baf_i2c_read(state, REG_CMD_BUF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) static void s5k5baf_write(struct s5k5baf *state, u16 addr, u16 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) s5k5baf_i2c_write(state, REG_CMDWR_ADDR, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) s5k5baf_i2c_write(state, REG_CMD_BUF, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) static void s5k5baf_write_arr_seq(struct s5k5baf *state, u16 addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) u16 count, const u16 *seq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) struct i2c_client *c = v4l2_get_subdevdata(&state->sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) __be16 buf[65];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) s5k5baf_i2c_write(state, REG_CMDWR_ADDR, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) if (state->error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) v4l2_dbg(3, debug, c, "i2c_write_seq(count=%d): %*ph\n", count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) min(2 * count, 64), seq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) buf[0] = cpu_to_be16(REG_CMD_BUF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) while (count > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) int n = min_t(int, count, ARRAY_SIZE(buf) - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) int ret, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) for (i = 1; i <= n; ++i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) buf[i] = cpu_to_be16(*seq++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) i *= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) ret = i2c_master_send(c, (char *)buf, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) if (ret != i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) v4l2_err(c, "i2c_write_seq: error during transfer (%d)\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) state->error = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) count -= n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) #define s5k5baf_write_seq(state, addr, seq...) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) s5k5baf_write_arr_seq(state, addr, sizeof((char[]){ seq }), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) (const u16 []){ seq });
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) /* add items count at the beginning of the list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) #define NSEQ(seq...) sizeof((char[]){ seq }), seq
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) * s5k5baf_write_nseq() - Writes sequences of values to sensor memory via i2c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) * @nseq: sequence of u16 words in format:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) * (N, address, value[1]...value[N-1])*,0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) * Ex.:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) * u16 seq[] = { NSEQ(0x4000, 1, 1), NSEQ(0x4010, 640, 480), 0 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) * ret = s5k5baf_write_nseq(c, seq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) static void s5k5baf_write_nseq(struct s5k5baf *state, const u16 *nseq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) int count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) while ((count = *nseq++)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) u16 addr = *nseq++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) --count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) s5k5baf_write_arr_seq(state, addr, count, nseq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) nseq += count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) static void s5k5baf_synchronize(struct s5k5baf *state, int timeout, u16 addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) unsigned long end = jiffies + msecs_to_jiffies(timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) u16 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) s5k5baf_write(state, addr, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) reg = s5k5baf_read(state, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) if (state->error || !reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) usleep_range(5000, 10000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) } while (time_is_after_jiffies(end));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) v4l2_err(&state->sd, "timeout on register synchronize (%#x)\n", addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) state->error = -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) static u16 *s5k5baf_fw_get_seq(struct s5k5baf *state, u16 seq_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) struct s5k5baf_fw *fw = state->fw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) u16 *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) if (fw == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) data = &fw->seq[0].id + 2 * fw->count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) for (i = 0; i < fw->count; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) if (fw->seq[i].id == seq_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) return data + fw->seq[i].offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) static void s5k5baf_hw_patch(struct s5k5baf *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) u16 *seq = s5k5baf_fw_get_seq(state, S5K5BAF_FW_ID_PATCH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) if (seq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) s5k5baf_write_nseq(state, seq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) static void s5k5baf_hw_set_clocks(struct s5k5baf *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) unsigned long mclk = state->mclk_frequency / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) u16 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) static const u16 nseq_clk_cfg[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) NSEQ(REG_I_USE_NPVI_CLOCKS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) NPVI_CLOCKS, NMIPI_CLOCKS, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) SCLK_PVI_FREQ / 4, PCLK_MIN_FREQ / 4, PCLK_MAX_FREQ / 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) SCLK_MIPI_FREQ / 4, PCLK_MIN_FREQ / 4, PCLK_MAX_FREQ / 4),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) NSEQ(REG_I_USE_REGS_API, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) s5k5baf_write_seq(state, REG_I_INCLK_FREQ_L, mclk & 0xffff, mclk >> 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) s5k5baf_write_nseq(state, nseq_clk_cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) s5k5baf_synchronize(state, 250, REG_I_INIT_PARAMS_UPDATED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) status = s5k5baf_read(state, REG_I_ERROR_INFO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) if (!state->error && status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) v4l2_err(&state->sd, "error configuring PLL (%d)\n", status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) state->error = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) /* set custom color correction matrices for various illuminations */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) static void s5k5baf_hw_set_ccm(struct s5k5baf *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) u16 *seq = s5k5baf_fw_get_seq(state, S5K5BAF_FW_ID_CCM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) if (seq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) s5k5baf_write_nseq(state, seq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) /* CIS sensor tuning, based on undocumented android driver code */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) static void s5k5baf_hw_set_cis(struct s5k5baf *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) u16 *seq = s5k5baf_fw_get_seq(state, S5K5BAF_FW_ID_CIS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) if (!seq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) s5k5baf_i2c_write(state, REG_CMDWR_PAGE, PAGE_IF_HW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) s5k5baf_write_nseq(state, seq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) s5k5baf_i2c_write(state, REG_CMDWR_PAGE, PAGE_IF_SW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) static void s5k5baf_hw_sync_cfg(struct s5k5baf *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) s5k5baf_write(state, REG_G_PREV_CFG_CHG, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) if (state->apply_crop) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) s5k5baf_write(state, REG_G_INPUTS_CHANGE_REQ, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) s5k5baf_write(state, REG_G_PREV_CFG_BYPASS_CHANGED, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) s5k5baf_synchronize(state, 500, REG_G_NEW_CFG_SYNC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) /* Set horizontal and vertical image flipping */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) static void s5k5baf_hw_set_mirror(struct s5k5baf *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) u16 flip = state->ctrls.vflip->val | (state->ctrls.vflip->val << 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) s5k5baf_write(state, REG_P_PREV_MIRROR(0), flip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) if (state->streaming)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) s5k5baf_hw_sync_cfg(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) static void s5k5baf_hw_set_alg(struct s5k5baf *state, u16 alg, bool enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) u16 cur_alg, new_alg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) if (!state->valid_auto_alg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) cur_alg = s5k5baf_read(state, REG_DBG_AUTOALG_EN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) cur_alg = state->auto_alg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) new_alg = enable ? (cur_alg | alg) : (cur_alg & ~alg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) if (new_alg != cur_alg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) s5k5baf_write(state, REG_DBG_AUTOALG_EN, new_alg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) if (state->error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) state->valid_auto_alg = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) state->auto_alg = new_alg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) /* Configure auto/manual white balance and R/G/B gains */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) static void s5k5baf_hw_set_awb(struct s5k5baf *state, int awb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) struct s5k5baf_ctrls *ctrls = &state->ctrls;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) if (!awb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) s5k5baf_write_seq(state, REG_SF_RGAIN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) ctrls->gain_red->val, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) S5K5BAF_GAIN_GREEN_DEF, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) ctrls->gain_blue->val, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) s5k5baf_hw_set_alg(state, AALG_WB_EN, awb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) /* Program FW with exposure time, 'exposure' in us units */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) static void s5k5baf_hw_set_user_exposure(struct s5k5baf *state, int exposure)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) unsigned int time = exposure / 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) s5k5baf_write_seq(state, REG_SF_USR_EXPOSURE_L,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) time & 0xffff, time >> 16, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) static void s5k5baf_hw_set_user_gain(struct s5k5baf *state, int gain)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) s5k5baf_write_seq(state, REG_SF_USR_TOT_GAIN, gain, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) /* Set auto/manual exposure and total gain */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) static void s5k5baf_hw_set_auto_exposure(struct s5k5baf *state, int value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) if (value == V4L2_EXPOSURE_AUTO) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) s5k5baf_hw_set_alg(state, AALG_AE_EN | AALG_DIVLEI_EN, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) unsigned int exp_time = state->ctrls.exposure->val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) s5k5baf_hw_set_user_exposure(state, exp_time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) s5k5baf_hw_set_user_gain(state, state->ctrls.gain->val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) s5k5baf_hw_set_alg(state, AALG_AE_EN | AALG_DIVLEI_EN, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) static void s5k5baf_hw_set_anti_flicker(struct s5k5baf *state, int v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) if (v == V4L2_CID_POWER_LINE_FREQUENCY_AUTO) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) s5k5baf_hw_set_alg(state, AALG_FLICKER_EN, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) /* The V4L2_CID_LINE_FREQUENCY control values match
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) * the register values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) s5k5baf_write_seq(state, REG_SF_FLICKER_QUANT, v, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) s5k5baf_hw_set_alg(state, AALG_FLICKER_EN, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) static void s5k5baf_hw_set_colorfx(struct s5k5baf *state, int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) static const u16 colorfx[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) [V4L2_COLORFX_NONE] = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) [V4L2_COLORFX_BW] = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) [V4L2_COLORFX_NEGATIVE] = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) [V4L2_COLORFX_SEPIA] = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) [V4L2_COLORFX_SKY_BLUE] = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) [V4L2_COLORFX_SKETCH] = 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) s5k5baf_write(state, REG_G_SPEC_EFFECTS, colorfx[val]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) static int s5k5baf_find_pixfmt(struct v4l2_mbus_framefmt *mf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) int i, c = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) for (i = 0; i < ARRAY_SIZE(s5k5baf_formats); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) if (mf->colorspace != s5k5baf_formats[i].colorspace)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) if (mf->code == s5k5baf_formats[i].code)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) return i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) if (c < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) c = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) return (c < 0) ? 0 : c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) static int s5k5baf_clear_error(struct s5k5baf *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) int ret = state->error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) state->error = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) static int s5k5baf_hw_set_video_bus(struct s5k5baf *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) u16 en_pkts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) if (state->bus_type == V4L2_MBUS_CSI2_DPHY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) en_pkts = EN_PACKETS_CSI2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) en_pkts = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) s5k5baf_write_seq(state, REG_OIF_EN_MIPI_LANES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) state->nlanes, en_pkts, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) return s5k5baf_clear_error(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) static u16 s5k5baf_get_cfg_error(struct s5k5baf *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) u16 err = s5k5baf_read(state, REG_G_PREV_CFG_ERROR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) s5k5baf_write(state, REG_G_PREV_CFG_ERROR, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) static void s5k5baf_hw_set_fiv(struct s5k5baf *state, u16 fiv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) s5k5baf_write(state, REG_P_MAX_FR_TIME(0), fiv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) s5k5baf_hw_sync_cfg(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) static void s5k5baf_hw_find_min_fiv(struct s5k5baf *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) u16 err, fiv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) int n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) fiv = s5k5baf_read(state, REG_G_ACTUAL_P_FR_TIME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) if (state->error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) for (n = 5; n > 0; --n) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) s5k5baf_hw_set_fiv(state, fiv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) err = s5k5baf_get_cfg_error(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) if (state->error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) switch (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) case CFG_ERROR_RANGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) ++fiv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) state->fiv = fiv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) v4l2_info(&state->sd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) "found valid frame interval: %d00us\n", fiv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) v4l2_err(&state->sd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) "error setting frame interval: %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) state->error = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) v4l2_err(&state->sd, "cannot find correct frame interval\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) state->error = -ERANGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) static void s5k5baf_hw_validate_cfg(struct s5k5baf *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) u16 err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) err = s5k5baf_get_cfg_error(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) if (state->error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) switch (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) state->apply_cfg = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) case CFG_ERROR_RANGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) s5k5baf_hw_find_min_fiv(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) if (!state->error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) state->apply_cfg = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) v4l2_err(&state->sd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) "error setting format: %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) state->error = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) static void s5k5baf_rescale(struct v4l2_rect *r, const struct v4l2_rect *v,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) const struct v4l2_rect *n,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) const struct v4l2_rect *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) r->left = v->left * n->width / d->width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) r->top = v->top * n->height / d->height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) r->width = v->width * n->width / d->width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) r->height = v->height * n->height / d->height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) static int s5k5baf_hw_set_crop_rects(struct s5k5baf *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) struct v4l2_rect *p, r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) u16 err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) p = &state->crop_sink;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) s5k5baf_write_seq(state, REG_G_PREVREQ_IN_WIDTH, p->width, p->height,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) p->left, p->top);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) s5k5baf_rescale(&r, &state->crop_source, &state->crop_sink,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) &state->compose);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) s5k5baf_write_seq(state, REG_G_PREVZOOM_IN_WIDTH, r.width, r.height,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) r.left, r.top);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) s5k5baf_synchronize(state, 500, REG_G_INPUTS_CHANGE_REQ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) s5k5baf_synchronize(state, 500, REG_G_PREV_CFG_BYPASS_CHANGED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) err = s5k5baf_get_cfg_error(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) ret = s5k5baf_clear_error(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) switch (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) case CFG_ERROR_RANGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) /* retry crop with frame interval set to max */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) s5k5baf_hw_set_fiv(state, S5K5BAF_MAX_FR_TIME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) err = s5k5baf_get_cfg_error(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) ret = s5k5baf_clear_error(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) v4l2_err(&state->sd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) "crop error on max frame interval: %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) state->error = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) s5k5baf_hw_set_fiv(state, state->req_fiv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) s5k5baf_hw_validate_cfg(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) v4l2_err(&state->sd, "crop error: %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) if (!state->apply_cfg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) p = &state->crop_source;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) s5k5baf_write_seq(state, REG_P_OUT_WIDTH(0), p->width, p->height);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) s5k5baf_hw_set_fiv(state, state->req_fiv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) s5k5baf_hw_validate_cfg(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) return s5k5baf_clear_error(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) static void s5k5baf_hw_set_config(struct s5k5baf *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) u16 reg_fmt = s5k5baf_formats[state->pixfmt].reg_p_fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) struct v4l2_rect *r = &state->crop_source;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) s5k5baf_write_seq(state, REG_P_OUT_WIDTH(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) r->width, r->height, reg_fmt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) PCLK_MAX_FREQ >> 2, PCLK_MIN_FREQ >> 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) PVI_MASK_MIPI, CLK_MIPI_INDEX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) FR_RATE_FIXED, FR_RATE_Q_DYNAMIC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) state->req_fiv, S5K5BAF_MIN_FR_TIME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) s5k5baf_hw_sync_cfg(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) s5k5baf_hw_validate_cfg(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) static void s5k5baf_hw_set_test_pattern(struct s5k5baf *state, int id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) s5k5baf_i2c_write(state, REG_PATTERN_WIDTH, 800);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) s5k5baf_i2c_write(state, REG_PATTERN_HEIGHT, 511);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) s5k5baf_i2c_write(state, REG_PATTERN_PARAM, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) s5k5baf_i2c_write(state, REG_PATTERN_SET, id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) static void s5k5baf_gpio_assert(struct s5k5baf *state, int id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) struct s5k5baf_gpio *gpio = &state->gpios[id];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) gpio_set_value(gpio->gpio, gpio->level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) static void s5k5baf_gpio_deassert(struct s5k5baf *state, int id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) struct s5k5baf_gpio *gpio = &state->gpios[id];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) gpio_set_value(gpio->gpio, !gpio->level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) static int s5k5baf_power_on(struct s5k5baf *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) ret = regulator_bulk_enable(S5K5BAF_NUM_SUPPLIES, state->supplies);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) ret = clk_set_rate(state->clock, state->mclk_frequency);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) goto err_reg_dis;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) ret = clk_prepare_enable(state->clock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) goto err_reg_dis;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) v4l2_dbg(1, debug, &state->sd, "clock frequency: %ld\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) clk_get_rate(state->clock));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) s5k5baf_gpio_deassert(state, STBY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) usleep_range(50, 100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) s5k5baf_gpio_deassert(state, RSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) err_reg_dis:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) regulator_bulk_disable(S5K5BAF_NUM_SUPPLIES, state->supplies);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) v4l2_err(&state->sd, "%s() failed (%d)\n", __func__, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) static int s5k5baf_power_off(struct s5k5baf *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) state->streaming = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) state->apply_cfg = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) state->apply_crop = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) s5k5baf_gpio_assert(state, RSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) s5k5baf_gpio_assert(state, STBY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) if (!IS_ERR(state->clock))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) clk_disable_unprepare(state->clock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) ret = regulator_bulk_disable(S5K5BAF_NUM_SUPPLIES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) state->supplies);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) v4l2_err(&state->sd, "failed to disable regulators\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) static void s5k5baf_hw_init(struct s5k5baf *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) s5k5baf_i2c_write(state, AHB_MSB_ADDR_PTR, PAGE_IF_HW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) s5k5baf_i2c_write(state, REG_CLEAR_HOST_INT, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) s5k5baf_i2c_write(state, REG_SW_LOAD_COMPLETE, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) s5k5baf_i2c_write(state, REG_CMDRD_PAGE, PAGE_IF_SW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) s5k5baf_i2c_write(state, REG_CMDWR_PAGE, PAGE_IF_SW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) * V4L2 subdev core and video operations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) static void s5k5baf_initialize_data(struct s5k5baf *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) state->pixfmt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) state->req_fiv = 10000 / 15;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) state->fiv = state->req_fiv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) state->valid_auto_alg = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) static int s5k5baf_load_setfile(struct s5k5baf *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) struct i2c_client *c = v4l2_get_subdevdata(&state->sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) const struct firmware *fw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) ret = request_firmware(&fw, S5K5BAF_FW_FILENAME, &c->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) dev_warn(&c->dev, "firmware file (%s) not loaded\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) S5K5BAF_FW_FILENAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) ret = s5k5baf_fw_parse(&c->dev, &state->fw, fw->size / 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) (__le16 *)fw->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) release_firmware(fw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) static int s5k5baf_set_power(struct v4l2_subdev *sd, int on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) struct s5k5baf *state = to_s5k5baf(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) mutex_lock(&state->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) if (state->power != !on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) if (on) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) if (state->fw == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) s5k5baf_load_setfile(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) s5k5baf_initialize_data(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) ret = s5k5baf_power_on(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) s5k5baf_hw_init(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) s5k5baf_hw_patch(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) s5k5baf_i2c_write(state, REG_SET_HOST_INT, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) s5k5baf_hw_set_clocks(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) ret = s5k5baf_hw_set_video_bus(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) s5k5baf_hw_set_cis(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) s5k5baf_hw_set_ccm(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) ret = s5k5baf_clear_error(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) state->power++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) s5k5baf_power_off(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) state->power--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) mutex_unlock(&state->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) if (!ret && on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) ret = v4l2_ctrl_handler_setup(&state->ctrls.handler);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) static void s5k5baf_hw_set_stream(struct s5k5baf *state, int enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) s5k5baf_write_seq(state, REG_G_ENABLE_PREV, enable, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) static int s5k5baf_s_stream(struct v4l2_subdev *sd, int on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) struct s5k5baf *state = to_s5k5baf(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) mutex_lock(&state->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) if (state->streaming == !!on) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) if (on) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) s5k5baf_hw_set_config(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) ret = s5k5baf_hw_set_crop_rects(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) s5k5baf_hw_set_stream(state, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) s5k5baf_i2c_write(state, 0xb0cc, 0x000b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) s5k5baf_hw_set_stream(state, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) ret = s5k5baf_clear_error(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) state->streaming = !state->streaming;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) mutex_unlock(&state->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) static int s5k5baf_g_frame_interval(struct v4l2_subdev *sd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) struct v4l2_subdev_frame_interval *fi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) struct s5k5baf *state = to_s5k5baf(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) mutex_lock(&state->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) fi->interval.numerator = state->fiv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) fi->interval.denominator = 10000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) mutex_unlock(&state->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) static void s5k5baf_set_frame_interval(struct s5k5baf *state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) struct v4l2_subdev_frame_interval *fi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) struct v4l2_fract *i = &fi->interval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) if (fi->interval.denominator == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) state->req_fiv = S5K5BAF_MAX_FR_TIME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) state->req_fiv = clamp_t(u32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) i->numerator * 10000 / i->denominator,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) S5K5BAF_MIN_FR_TIME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) S5K5BAF_MAX_FR_TIME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) state->fiv = state->req_fiv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) if (state->apply_cfg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) s5k5baf_hw_set_fiv(state, state->req_fiv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) s5k5baf_hw_validate_cfg(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) *i = (struct v4l2_fract){ state->fiv, 10000 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) if (state->fiv == state->req_fiv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) v4l2_info(&state->sd, "frame interval changed to %d00us\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) state->fiv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) static int s5k5baf_s_frame_interval(struct v4l2_subdev *sd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) struct v4l2_subdev_frame_interval *fi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) struct s5k5baf *state = to_s5k5baf(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) mutex_lock(&state->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) s5k5baf_set_frame_interval(state, fi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) mutex_unlock(&state->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) * V4L2 subdev pad level and video operations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) static int s5k5baf_enum_frame_interval(struct v4l2_subdev *sd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) struct v4l2_subdev_pad_config *cfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) struct v4l2_subdev_frame_interval_enum *fie)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) if (fie->index > S5K5BAF_MAX_FR_TIME - S5K5BAF_MIN_FR_TIME ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) fie->pad != PAD_CIS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) v4l_bound_align_image(&fie->width, S5K5BAF_WIN_WIDTH_MIN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) S5K5BAF_CIS_WIDTH, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) &fie->height, S5K5BAF_WIN_HEIGHT_MIN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) S5K5BAF_CIS_HEIGHT, 1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) fie->interval.numerator = S5K5BAF_MIN_FR_TIME + fie->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) fie->interval.denominator = 10000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) static int s5k5baf_enum_mbus_code(struct v4l2_subdev *sd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) struct v4l2_subdev_pad_config *cfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) struct v4l2_subdev_mbus_code_enum *code)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) if (code->pad == PAD_CIS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) if (code->index > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) code->code = MEDIA_BUS_FMT_FIXED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) if (code->index >= ARRAY_SIZE(s5k5baf_formats))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) code->code = s5k5baf_formats[code->index].code;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) static int s5k5baf_enum_frame_size(struct v4l2_subdev *sd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) struct v4l2_subdev_pad_config *cfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) struct v4l2_subdev_frame_size_enum *fse)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) if (fse->index > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) if (fse->pad == PAD_CIS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) fse->code = MEDIA_BUS_FMT_FIXED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) fse->min_width = S5K5BAF_CIS_WIDTH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) fse->max_width = S5K5BAF_CIS_WIDTH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) fse->min_height = S5K5BAF_CIS_HEIGHT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) fse->max_height = S5K5BAF_CIS_HEIGHT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) i = ARRAY_SIZE(s5k5baf_formats);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) while (--i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) if (fse->code == s5k5baf_formats[i].code)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) fse->code = s5k5baf_formats[i].code;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) fse->min_width = S5K5BAF_WIN_WIDTH_MIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) fse->max_width = S5K5BAF_CIS_WIDTH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) fse->max_height = S5K5BAF_WIN_HEIGHT_MIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) fse->min_height = S5K5BAF_CIS_HEIGHT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) static void s5k5baf_try_cis_format(struct v4l2_mbus_framefmt *mf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) mf->width = S5K5BAF_CIS_WIDTH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) mf->height = S5K5BAF_CIS_HEIGHT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) mf->code = MEDIA_BUS_FMT_FIXED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) mf->colorspace = V4L2_COLORSPACE_JPEG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) mf->field = V4L2_FIELD_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) static int s5k5baf_try_isp_format(struct v4l2_mbus_framefmt *mf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) int pixfmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) v4l_bound_align_image(&mf->width, S5K5BAF_WIN_WIDTH_MIN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) S5K5BAF_CIS_WIDTH, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) &mf->height, S5K5BAF_WIN_HEIGHT_MIN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) S5K5BAF_CIS_HEIGHT, 1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) pixfmt = s5k5baf_find_pixfmt(mf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) mf->colorspace = s5k5baf_formats[pixfmt].colorspace;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) mf->code = s5k5baf_formats[pixfmt].code;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) mf->field = V4L2_FIELD_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) return pixfmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) static int s5k5baf_get_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) struct v4l2_subdev_format *fmt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) struct s5k5baf *state = to_s5k5baf(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) const struct s5k5baf_pixfmt *pixfmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) struct v4l2_mbus_framefmt *mf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) mf = v4l2_subdev_get_try_format(sd, cfg, fmt->pad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) fmt->format = *mf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) mf = &fmt->format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) if (fmt->pad == PAD_CIS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) s5k5baf_try_cis_format(mf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) mf->field = V4L2_FIELD_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) mutex_lock(&state->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) pixfmt = &s5k5baf_formats[state->pixfmt];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) mf->width = state->crop_source.width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) mf->height = state->crop_source.height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) mf->code = pixfmt->code;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) mf->colorspace = pixfmt->colorspace;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) mutex_unlock(&state->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) static int s5k5baf_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) struct v4l2_subdev_format *fmt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) struct v4l2_mbus_framefmt *mf = &fmt->format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) struct s5k5baf *state = to_s5k5baf(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) const struct s5k5baf_pixfmt *pixfmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) mf->field = V4L2_FIELD_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) *v4l2_subdev_get_try_format(sd, cfg, fmt->pad) = *mf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) if (fmt->pad == PAD_CIS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) s5k5baf_try_cis_format(mf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) mutex_lock(&state->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) if (state->streaming) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) mutex_unlock(&state->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) state->pixfmt = s5k5baf_try_isp_format(mf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) pixfmt = &s5k5baf_formats[state->pixfmt];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) mf->code = pixfmt->code;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) mf->colorspace = pixfmt->colorspace;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) mf->width = state->crop_source.width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) mf->height = state->crop_source.height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) mutex_unlock(&state->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) enum selection_rect { R_CIS, R_CROP_SINK, R_COMPOSE, R_CROP_SOURCE, R_INVALID };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) static enum selection_rect s5k5baf_get_sel_rect(u32 pad, u32 target)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) switch (target) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) case V4L2_SEL_TGT_CROP_BOUNDS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) return pad ? R_COMPOSE : R_CIS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) case V4L2_SEL_TGT_CROP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) return pad ? R_CROP_SOURCE : R_CROP_SINK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) case V4L2_SEL_TGT_COMPOSE_BOUNDS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) return pad ? R_INVALID : R_CROP_SINK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) case V4L2_SEL_TGT_COMPOSE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) return pad ? R_INVALID : R_COMPOSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) return R_INVALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) static int s5k5baf_is_bound_target(u32 target)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) return target == V4L2_SEL_TGT_CROP_BOUNDS ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) target == V4L2_SEL_TGT_COMPOSE_BOUNDS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) static int s5k5baf_get_selection(struct v4l2_subdev *sd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) struct v4l2_subdev_pad_config *cfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) struct v4l2_subdev_selection *sel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) enum selection_rect rtype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) struct s5k5baf *state = to_s5k5baf(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) rtype = s5k5baf_get_sel_rect(sel->pad, sel->target);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) switch (rtype) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) case R_INVALID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) case R_CIS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) sel->r = s5k5baf_cis_rect;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) if (sel->which == V4L2_SUBDEV_FORMAT_TRY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) if (rtype == R_COMPOSE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) sel->r = *v4l2_subdev_get_try_compose(sd, cfg, sel->pad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) sel->r = *v4l2_subdev_get_try_crop(sd, cfg, sel->pad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) mutex_lock(&state->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) switch (rtype) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) case R_CROP_SINK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) sel->r = state->crop_sink;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) case R_COMPOSE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) sel->r = state->compose;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) case R_CROP_SOURCE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) sel->r = state->crop_source;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) if (s5k5baf_is_bound_target(sel->target)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) sel->r.left = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) sel->r.top = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) mutex_unlock(&state->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) /* bounds range [start, start+len) to [0, max) and aligns to 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) static void s5k5baf_bound_range(u32 *start, u32 *len, u32 max)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) if (*len > max)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) *len = max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) if (*start + *len > max)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) *start = max - *len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) *start &= ~1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) *len &= ~1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) if (*len < S5K5BAF_WIN_WIDTH_MIN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) *len = S5K5BAF_WIN_WIDTH_MIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) static void s5k5baf_bound_rect(struct v4l2_rect *r, u32 width, u32 height)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) s5k5baf_bound_range(&r->left, &r->width, width);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) s5k5baf_bound_range(&r->top, &r->height, height);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) static void s5k5baf_set_rect_and_adjust(struct v4l2_rect **rects,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) enum selection_rect first,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) struct v4l2_rect *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) struct v4l2_rect *r, *br;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) enum selection_rect i = first;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) *rects[first] = *v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) r = rects[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) br = rects[i - 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) s5k5baf_bound_rect(r, br->width, br->height);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) } while (++i != R_INVALID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) *v = *rects[first];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) static bool s5k5baf_cmp_rect(const struct v4l2_rect *r1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) const struct v4l2_rect *r2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) return !memcmp(r1, r2, sizeof(*r1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) static int s5k5baf_set_selection(struct v4l2_subdev *sd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) struct v4l2_subdev_pad_config *cfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) struct v4l2_subdev_selection *sel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) static enum selection_rect rtype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) struct s5k5baf *state = to_s5k5baf(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) struct v4l2_rect **rects;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) rtype = s5k5baf_get_sel_rect(sel->pad, sel->target);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) if (rtype == R_INVALID || s5k5baf_is_bound_target(sel->target))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) /* allow only scaling on compose */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) if (rtype == R_COMPOSE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) sel->r.left = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) sel->r.top = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) if (sel->which == V4L2_SUBDEV_FORMAT_TRY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) rects = (struct v4l2_rect * []) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) &s5k5baf_cis_rect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) v4l2_subdev_get_try_crop(sd, cfg, PAD_CIS),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) v4l2_subdev_get_try_compose(sd, cfg, PAD_CIS),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) v4l2_subdev_get_try_crop(sd, cfg, PAD_OUT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) s5k5baf_set_rect_and_adjust(rects, rtype, &sel->r);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) rects = (struct v4l2_rect * []) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) &s5k5baf_cis_rect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) &state->crop_sink,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) &state->compose,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) &state->crop_source
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) mutex_lock(&state->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) if (state->streaming) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) /* adjust sel->r to avoid output resolution change */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) if (rtype < R_CROP_SOURCE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) if (sel->r.width < state->crop_source.width)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) sel->r.width = state->crop_source.width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) if (sel->r.height < state->crop_source.height)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) sel->r.height = state->crop_source.height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) sel->r.width = state->crop_source.width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) sel->r.height = state->crop_source.height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) s5k5baf_set_rect_and_adjust(rects, rtype, &sel->r);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) if (!s5k5baf_cmp_rect(&state->crop_sink, &s5k5baf_cis_rect) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) !s5k5baf_cmp_rect(&state->compose, &s5k5baf_cis_rect))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) state->apply_crop = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) if (state->streaming)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) ret = s5k5baf_hw_set_crop_rects(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) mutex_unlock(&state->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) static const struct v4l2_subdev_pad_ops s5k5baf_cis_pad_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) .enum_mbus_code = s5k5baf_enum_mbus_code,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) .enum_frame_size = s5k5baf_enum_frame_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) .get_fmt = s5k5baf_get_fmt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) .set_fmt = s5k5baf_set_fmt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) static const struct v4l2_subdev_pad_ops s5k5baf_pad_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) .enum_mbus_code = s5k5baf_enum_mbus_code,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) .enum_frame_size = s5k5baf_enum_frame_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) .enum_frame_interval = s5k5baf_enum_frame_interval,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) .get_fmt = s5k5baf_get_fmt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) .set_fmt = s5k5baf_set_fmt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) .get_selection = s5k5baf_get_selection,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) .set_selection = s5k5baf_set_selection,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) static const struct v4l2_subdev_video_ops s5k5baf_video_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) .g_frame_interval = s5k5baf_g_frame_interval,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) .s_frame_interval = s5k5baf_s_frame_interval,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) .s_stream = s5k5baf_s_stream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) * V4L2 subdev controls
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) static int s5k5baf_s_ctrl(struct v4l2_ctrl *ctrl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) struct v4l2_subdev *sd = ctrl_to_sd(ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) struct s5k5baf *state = to_s5k5baf(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) v4l2_dbg(1, debug, sd, "ctrl: %s, value: %d\n", ctrl->name, ctrl->val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) mutex_lock(&state->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) if (state->power == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) switch (ctrl->id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) case V4L2_CID_AUTO_WHITE_BALANCE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) s5k5baf_hw_set_awb(state, ctrl->val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) case V4L2_CID_BRIGHTNESS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) s5k5baf_write(state, REG_USER_BRIGHTNESS, ctrl->val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) case V4L2_CID_COLORFX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) s5k5baf_hw_set_colorfx(state, ctrl->val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) case V4L2_CID_CONTRAST:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) s5k5baf_write(state, REG_USER_CONTRAST, ctrl->val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) case V4L2_CID_EXPOSURE_AUTO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) s5k5baf_hw_set_auto_exposure(state, ctrl->val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) case V4L2_CID_HFLIP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) s5k5baf_hw_set_mirror(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) case V4L2_CID_POWER_LINE_FREQUENCY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) s5k5baf_hw_set_anti_flicker(state, ctrl->val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) case V4L2_CID_SATURATION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) s5k5baf_write(state, REG_USER_SATURATION, ctrl->val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) case V4L2_CID_SHARPNESS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) s5k5baf_write(state, REG_USER_SHARPBLUR, ctrl->val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) case V4L2_CID_WHITE_BALANCE_TEMPERATURE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) s5k5baf_write(state, REG_P_COLORTEMP(0), ctrl->val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) if (state->apply_cfg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) s5k5baf_hw_sync_cfg(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) case V4L2_CID_TEST_PATTERN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) s5k5baf_hw_set_test_pattern(state, ctrl->val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) ret = s5k5baf_clear_error(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) mutex_unlock(&state->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) static const struct v4l2_ctrl_ops s5k5baf_ctrl_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) .s_ctrl = s5k5baf_s_ctrl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) static const char * const s5k5baf_test_pattern_menu[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) "Disabled",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) "Blank",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) "Bars",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) "Gradients",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) "Textile",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) "Textile2",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) "Squares"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) static int s5k5baf_initialize_ctrls(struct s5k5baf *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) const struct v4l2_ctrl_ops *ops = &s5k5baf_ctrl_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) struct s5k5baf_ctrls *ctrls = &state->ctrls;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) struct v4l2_ctrl_handler *hdl = &ctrls->handler;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) ret = v4l2_ctrl_handler_init(hdl, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) v4l2_err(&state->sd, "cannot init ctrl handler (%d)\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) /* Auto white balance cluster */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) ctrls->awb = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_AUTO_WHITE_BALANCE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) 0, 1, 1, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) ctrls->gain_red = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_RED_BALANCE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) 0, 255, 1, S5K5BAF_GAIN_RED_DEF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) ctrls->gain_blue = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_BLUE_BALANCE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) 0, 255, 1, S5K5BAF_GAIN_BLUE_DEF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) v4l2_ctrl_auto_cluster(3, &ctrls->awb, 0, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) ctrls->hflip = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_HFLIP, 0, 1, 1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) ctrls->vflip = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_VFLIP, 0, 1, 1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) v4l2_ctrl_cluster(2, &ctrls->hflip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) ctrls->auto_exp = v4l2_ctrl_new_std_menu(hdl, ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) V4L2_CID_EXPOSURE_AUTO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) V4L2_EXPOSURE_MANUAL, 0, V4L2_EXPOSURE_AUTO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) /* Exposure time: x 1 us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) ctrls->exposure = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_EXPOSURE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) 0, 6000000U, 1, 100000U);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) /* Total gain: 256 <=> 1x */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) ctrls->gain = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_GAIN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) 0, 256, 1, 256);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) v4l2_ctrl_auto_cluster(3, &ctrls->auto_exp, 0, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) v4l2_ctrl_new_std_menu(hdl, ops, V4L2_CID_POWER_LINE_FREQUENCY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) V4L2_CID_POWER_LINE_FREQUENCY_AUTO, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) V4L2_CID_POWER_LINE_FREQUENCY_AUTO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) v4l2_ctrl_new_std_menu(hdl, ops, V4L2_CID_COLORFX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) V4L2_COLORFX_SKY_BLUE, ~0x6f, V4L2_COLORFX_NONE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) v4l2_ctrl_new_std(hdl, ops, V4L2_CID_WHITE_BALANCE_TEMPERATURE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) 0, 256, 1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) v4l2_ctrl_new_std(hdl, ops, V4L2_CID_SATURATION, -127, 127, 1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) v4l2_ctrl_new_std(hdl, ops, V4L2_CID_BRIGHTNESS, -127, 127, 1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) v4l2_ctrl_new_std(hdl, ops, V4L2_CID_CONTRAST, -127, 127, 1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) v4l2_ctrl_new_std(hdl, ops, V4L2_CID_SHARPNESS, -127, 127, 1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) v4l2_ctrl_new_std_menu_items(hdl, ops, V4L2_CID_TEST_PATTERN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) ARRAY_SIZE(s5k5baf_test_pattern_menu) - 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) 0, 0, s5k5baf_test_pattern_menu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) if (hdl->error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) v4l2_err(&state->sd, "error creating controls (%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) hdl->error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) ret = hdl->error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) v4l2_ctrl_handler_free(hdl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) state->sd.ctrl_handler = hdl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) * V4L2 subdev internal operations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) static int s5k5baf_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) struct v4l2_mbus_framefmt *mf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) mf = v4l2_subdev_get_try_format(sd, fh->pad, PAD_CIS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) s5k5baf_try_cis_format(mf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) if (s5k5baf_is_cis_subdev(sd))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) mf = v4l2_subdev_get_try_format(sd, fh->pad, PAD_OUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) mf->colorspace = s5k5baf_formats[0].colorspace;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) mf->code = s5k5baf_formats[0].code;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) mf->width = s5k5baf_cis_rect.width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) mf->height = s5k5baf_cis_rect.height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) mf->field = V4L2_FIELD_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) *v4l2_subdev_get_try_crop(sd, fh->pad, PAD_CIS) = s5k5baf_cis_rect;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) *v4l2_subdev_get_try_compose(sd, fh->pad, PAD_CIS) = s5k5baf_cis_rect;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) *v4l2_subdev_get_try_crop(sd, fh->pad, PAD_OUT) = s5k5baf_cis_rect;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) static int s5k5baf_check_fw_revision(struct s5k5baf *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) u16 api_ver = 0, fw_rev = 0, s_id = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) api_ver = s5k5baf_read(state, REG_FW_APIVER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) fw_rev = s5k5baf_read(state, REG_FW_REVISION) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) s_id = s5k5baf_read(state, REG_FW_SENSOR_ID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) ret = s5k5baf_clear_error(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) v4l2_info(&state->sd, "FW API=%#x, revision=%#x sensor_id=%#x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) api_ver, fw_rev, s_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) if (api_ver != S5K5BAF_FW_APIVER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) v4l2_err(&state->sd, "FW API version not supported\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) static int s5k5baf_registered(struct v4l2_subdev *sd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) struct s5k5baf *state = to_s5k5baf(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) ret = v4l2_device_register_subdev(sd->v4l2_dev, &state->cis_sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) v4l2_err(sd, "failed to register subdev %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) state->cis_sd.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) ret = media_create_pad_link(&state->cis_sd.entity, PAD_CIS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) &state->sd.entity, PAD_CIS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) MEDIA_LNK_FL_IMMUTABLE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) MEDIA_LNK_FL_ENABLED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) static void s5k5baf_unregistered(struct v4l2_subdev *sd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) struct s5k5baf *state = to_s5k5baf(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) v4l2_device_unregister_subdev(&state->cis_sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) static const struct v4l2_subdev_ops s5k5baf_cis_subdev_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) .pad = &s5k5baf_cis_pad_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) static const struct v4l2_subdev_internal_ops s5k5baf_cis_subdev_internal_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) .open = s5k5baf_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) static const struct v4l2_subdev_internal_ops s5k5baf_subdev_internal_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) .registered = s5k5baf_registered,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) .unregistered = s5k5baf_unregistered,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) .open = s5k5baf_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) static const struct v4l2_subdev_core_ops s5k5baf_core_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) .s_power = s5k5baf_set_power,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) .log_status = v4l2_ctrl_subdev_log_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) static const struct v4l2_subdev_ops s5k5baf_subdev_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) .core = &s5k5baf_core_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) .pad = &s5k5baf_pad_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) .video = &s5k5baf_video_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) static int s5k5baf_configure_gpios(struct s5k5baf *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) static const char * const name[] = { "S5K5BAF_STBY", "S5K5BAF_RST" };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) struct i2c_client *c = v4l2_get_subdevdata(&state->sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) struct s5k5baf_gpio *g = state->gpios;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) int ret, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) for (i = 0; i < NUM_GPIOS; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) int flags = GPIOF_DIR_OUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) if (g[i].level)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) flags |= GPIOF_INIT_HIGH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) ret = devm_gpio_request_one(&c->dev, g[i].gpio, flags, name[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) v4l2_err(c, "failed to request gpio %s\n", name[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) static int s5k5baf_parse_gpios(struct s5k5baf_gpio *gpios, struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) static const char * const names[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) "stbyn-gpios",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) "rstn-gpios",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) struct device_node *node = dev->of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) enum of_gpio_flags flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) int ret, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) for (i = 0; i < NUM_GPIOS; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) ret = of_get_named_gpio_flags(node, names[i], 0, &flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) dev_err(dev, "no %s GPIO pin provided\n", names[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) gpios[i].gpio = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) gpios[i].level = !(flags & OF_GPIO_ACTIVE_LOW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) static int s5k5baf_parse_device_node(struct s5k5baf *state, struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) struct device_node *node = dev->of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) struct device_node *node_ep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) struct v4l2_fwnode_endpoint ep = { .bus_type = 0 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) if (!node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) dev_err(dev, "no device-tree node provided\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) ret = of_property_read_u32(node, "clock-frequency",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) &state->mclk_frequency);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) state->mclk_frequency = S5K5BAF_DEFAULT_MCLK_FREQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) dev_info(dev, "using default %u Hz clock frequency\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) state->mclk_frequency);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) ret = s5k5baf_parse_gpios(state->gpios, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) node_ep = of_graph_get_next_endpoint(node, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) if (!node_ep) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) dev_err(dev, "no endpoint defined at node %pOF\n", node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(node_ep), &ep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) of_node_put(node_ep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) state->bus_type = ep.bus_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) switch (state->bus_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) case V4L2_MBUS_CSI2_DPHY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) state->nlanes = ep.bus.mipi_csi2.num_data_lanes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) case V4L2_MBUS_PARALLEL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) dev_err(dev, "unsupported bus in endpoint defined at node %pOF\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) static int s5k5baf_configure_subdevs(struct s5k5baf *state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) struct i2c_client *c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) struct v4l2_subdev *sd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) sd = &state->cis_sd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) v4l2_subdev_init(sd, &s5k5baf_cis_subdev_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) sd->owner = THIS_MODULE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) v4l2_set_subdevdata(sd, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) snprintf(sd->name, sizeof(sd->name), "S5K5BAF-CIS %d-%04x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) i2c_adapter_id(c->adapter), c->addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) sd->internal_ops = &s5k5baf_cis_subdev_internal_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) state->cis_pad.flags = MEDIA_PAD_FL_SOURCE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) sd->entity.function = MEDIA_ENT_F_CAM_SENSOR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) ret = media_entity_pads_init(&sd->entity, NUM_CIS_PADS, &state->cis_pad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) sd = &state->sd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) v4l2_i2c_subdev_init(sd, c, &s5k5baf_subdev_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) snprintf(sd->name, sizeof(sd->name), "S5K5BAF-ISP %d-%04x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) i2c_adapter_id(c->adapter), c->addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) sd->internal_ops = &s5k5baf_subdev_internal_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) state->pads[PAD_CIS].flags = MEDIA_PAD_FL_SINK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) state->pads[PAD_OUT].flags = MEDIA_PAD_FL_SOURCE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) sd->entity.function = MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) ret = media_entity_pads_init(&sd->entity, NUM_ISP_PADS, state->pads);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) media_entity_cleanup(&state->cis_sd.entity);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) dev_err(&c->dev, "cannot init media entity %s\n", sd->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) static int s5k5baf_configure_regulators(struct s5k5baf *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) struct i2c_client *c = v4l2_get_subdevdata(&state->sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) for (i = 0; i < S5K5BAF_NUM_SUPPLIES; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) state->supplies[i].supply = s5k5baf_supply_names[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) ret = devm_regulator_bulk_get(&c->dev, S5K5BAF_NUM_SUPPLIES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) state->supplies);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) v4l2_err(c, "failed to get regulators\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) static int s5k5baf_probe(struct i2c_client *c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) struct s5k5baf *state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) state = devm_kzalloc(&c->dev, sizeof(*state), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) if (!state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) mutex_init(&state->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) state->crop_sink = s5k5baf_cis_rect;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) state->compose = s5k5baf_cis_rect;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) state->crop_source = s5k5baf_cis_rect;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) ret = s5k5baf_parse_device_node(state, &c->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) ret = s5k5baf_configure_subdevs(state, c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) ret = s5k5baf_configure_gpios(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) goto err_me;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) ret = s5k5baf_configure_regulators(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) goto err_me;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) state->clock = devm_clk_get(state->sd.dev, S5K5BAF_CLK_NAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) if (IS_ERR(state->clock)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) ret = -EPROBE_DEFER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) goto err_me;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) ret = s5k5baf_power_on(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) ret = -EPROBE_DEFER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) goto err_me;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) s5k5baf_hw_init(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) ret = s5k5baf_check_fw_revision(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) s5k5baf_power_off(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) goto err_me;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) ret = s5k5baf_initialize_ctrls(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) goto err_me;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) ret = v4l2_async_register_subdev(&state->sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) goto err_ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) err_ctrl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) v4l2_ctrl_handler_free(state->sd.ctrl_handler);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) err_me:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) media_entity_cleanup(&state->sd.entity);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) media_entity_cleanup(&state->cis_sd.entity);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) static int s5k5baf_remove(struct i2c_client *c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) struct v4l2_subdev *sd = i2c_get_clientdata(c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) struct s5k5baf *state = to_s5k5baf(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) v4l2_async_unregister_subdev(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) v4l2_ctrl_handler_free(sd->ctrl_handler);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) media_entity_cleanup(&sd->entity);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) sd = &state->cis_sd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) v4l2_device_unregister_subdev(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) media_entity_cleanup(&sd->entity);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) static const struct i2c_device_id s5k5baf_id[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) { S5K5BAF_DRIVER_NAME, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) { },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) MODULE_DEVICE_TABLE(i2c, s5k5baf_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) static const struct of_device_id s5k5baf_of_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) { .compatible = "samsung,s5k5baf" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) MODULE_DEVICE_TABLE(of, s5k5baf_of_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) static struct i2c_driver s5k5baf_i2c_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) .of_match_table = s5k5baf_of_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) .name = S5K5BAF_DRIVER_NAME
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) .probe_new = s5k5baf_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) .remove = s5k5baf_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) .id_table = s5k5baf_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) module_i2c_driver(s5k5baf_i2c_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) MODULE_DESCRIPTION("Samsung S5K5BAF(X) UXGA camera driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) MODULE_AUTHOR("Andrzej Hajda <a.hajda@samsung.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) MODULE_LICENSE("GPL v2");