FILE
mt9m114.c
File preview with syntax highlighting.
linux-6.19.14/drivers/media/i2c/mt9m114.c
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * mt9m114.c onsemi MT9M114 sensor driver 4 * 5 * Copyright (c) 2020-2023 Laurent Pinchart <laurent.pinchart@ideasonboard.com> 6 * Copyright (c) 2012 Analog Devices Inc. 7 * 8 * Almost complete rewrite of work by Scott Jiang <Scott.Jiang.Linux@gmail.com> 9 * itself based on work from Andrew Chew <achew@nvidia.com>. 10 */ 11 12#include <linux/clk.h> 13#include <linux/delay.h> 14#include <linux/errno.h> 15#include <linux/gpio/consumer.h> 16#include <linux/i2c.h> 17#include <linux/mod_devicetable.h> 18#include <linux/module.h> 19#include <linux/mutex.h> 20#include <linux/pm_runtime.h> 21#include <linux/property.h> 22#include <linux/regmap.h> 23#include <linux/regulator/consumer.h> 24#include <linux/types.h> 25#include <linux/videodev2.h> 26 27#include <media/v4l2-async.h> 28#include <media/v4l2-cci.h> 29#include <media/v4l2-ctrls.h> 30#include <media/v4l2-device.h> 31#include <media/v4l2-fwnode.h> 32#include <media/v4l2-mediabus.h> 33#include <media/v4l2-subdev.h> 34 35/* Sysctl registers */ 36#define MT9M114_CHIP_ID CCI_REG16(0x0000) 37#define MT9M114_COMMAND_REGISTER CCI_REG16(0x0080) 38#define MT9M114_COMMAND_REGISTER_APPLY_PATCH BIT(0) 39#define MT9M114_COMMAND_REGISTER_SET_STATE BIT(1) 40#define MT9M114_COMMAND_REGISTER_REFRESH BIT(2) 41#define MT9M114_COMMAND_REGISTER_WAIT_FOR_EVENT BIT(3) 42#define MT9M114_COMMAND_REGISTER_OK BIT(15) 43#define MT9M114_RESET_AND_MISC_CONTROL CCI_REG16(0x001a) 44#define MT9M114_RESET_SOC BIT(0) 45#define MT9M114_PAD_SLEW CCI_REG16(0x001e) 46#define MT9M114_PAD_SLEW_MIN 0 47#define MT9M114_PAD_SLEW_MAX 7 48#define MT9M114_PAD_SLEW_DEFAULT 7 49#define MT9M114_PAD_CONTROL CCI_REG16(0x0032) 50 51/* XDMA registers */ 52#define MT9M114_ACCESS_CTL_STAT CCI_REG16(0x0982) 53#define MT9M114_PHYSICAL_ADDRESS_ACCESS CCI_REG16(0x098a) 54#define MT9M114_LOGICAL_ADDRESS_ACCESS CCI_REG16(0x098e) 55 56/* Sensor Core registers */ 57#define MT9M114_COARSE_INTEGRATION_TIME CCI_REG16(0x3012) 58#define MT9M114_FINE_INTEGRATION_TIME CCI_REG16(0x3014) 59#define MT9M114_RESET_REGISTER CCI_REG16(0x301a) 60#define MT9M114_RESET_REGISTER_LOCK_REG BIT(3) 61#define MT9M114_RESET_REGISTER_MASK_BAD BIT(9) 62#define MT9M114_FLASH CCI_REG16(0x3046) 63#define MT9M114_GREEN1_GAIN CCI_REG16(0x3056) 64#define MT9M114_BLUE_GAIN CCI_REG16(0x3058) 65#define MT9M114_RED_GAIN CCI_REG16(0x305a) 66#define MT9M114_GREEN2_GAIN CCI_REG16(0x305c) 67#define MT9M114_GLOBAL_GAIN CCI_REG16(0x305e) 68#define MT9M114_GAIN_DIGITAL_GAIN(n) ((n) << 12) 69#define MT9M114_GAIN_DIGITAL_GAIN_MASK (0xf << 12) 70#define MT9M114_GAIN_ANALOG_GAIN(n) ((n) << 0) 71#define MT9M114_GAIN_ANALOG_GAIN_MASK (0xff << 0) 72#define MT9M114_CUSTOMER_REV CCI_REG16(0x31fe) 73 74/* Monitor registers */ 75#define MT9M114_MON_MAJOR_VERSION CCI_REG16(0x8000) 76#define MT9M114_MON_MINOR_VERSION CCI_REG16(0x8002) 77#define MT9M114_MON_RELEASE_VERSION CCI_REG16(0x8004) 78 79/* Auto-Exposure Track registers */ 80#define MT9M114_AE_TRACK_ALGO CCI_REG16(0xa804) 81#define MT9M114_AE_TRACK_EXEC_AUTOMATIC_EXPOSURE BIT(0) 82#define MT9M114_AE_TRACK_AE_TRACKING_DAMPENING_SPEED CCI_REG8(0xa80a) 83 84/* Color Correction Matrix registers */ 85#define MT9M114_CCM_ALGO CCI_REG16(0xb404) 86#define MT9M114_CCM_EXEC_CALC_CCM_MATRIX BIT(4) 87#define MT9M114_CCM_DELTA_GAIN CCI_REG8(0xb42a) 88 89/* Camera Control registers */ 90#define MT9M114_CAM_SENSOR_CFG_Y_ADDR_START CCI_REG16(0xc800) 91#define MT9M114_CAM_SENSOR_CFG_X_ADDR_START CCI_REG16(0xc802) 92#define MT9M114_CAM_SENSOR_CFG_Y_ADDR_END CCI_REG16(0xc804) 93#define MT9M114_CAM_SENSOR_CFG_X_ADDR_END CCI_REG16(0xc806) 94#define MT9M114_CAM_SENSOR_CFG_PIXCLK CCI_REG32(0xc808) 95#define MT9M114_CAM_SENSOR_CFG_ROW_SPEED CCI_REG16(0xc80c) 96#define MT9M114_CAM_SENSOR_CFG_FINE_INTEG_TIME_MIN CCI_REG16(0xc80e) 97#define MT9M114_CAM_SENSOR_CFG_FINE_INTEG_TIME_MAX CCI_REG16(0xc810) 98#define MT9M114_CAM_SENSOR_CFG_FRAME_LENGTH_LINES CCI_REG16(0xc812) 99#define MT9M114_CAM_SENSOR_CFG_FRAME_LENGTH_LINES_MAX 65535 100#define MT9M114_CAM_SENSOR_CFG_LINE_LENGTH_PCK CCI_REG16(0xc814) 101#define MT9M114_CAM_SENSOR_CFG_LINE_LENGTH_PCK_MAX 8191 102#define MT9M114_CAM_SENSOR_CFG_FINE_CORRECTION CCI_REG16(0xc816) 103#define MT9M114_CAM_SENSOR_CFG_CPIPE_LAST_ROW CCI_REG16(0xc818) 104#define MT9M114_CAM_SENSOR_CFG_REG_0_DATA CCI_REG16(0xc826) 105#define MT9M114_CAM_SENSOR_CONTROL_READ_MODE CCI_REG16(0xc834) 106#define MT9M114_CAM_SENSOR_CONTROL_HORZ_MIRROR_EN BIT(0) 107#define MT9M114_CAM_SENSOR_CONTROL_VERT_FLIP_EN BIT(1) 108#define MT9M114_CAM_SENSOR_CONTROL_X_READ_OUT_NORMAL (0 << 4) 109#define MT9M114_CAM_SENSOR_CONTROL_X_READ_OUT_SKIPPING (1 << 4) 110#define MT9M114_CAM_SENSOR_CONTROL_X_READ_OUT_AVERAGE (2 << 4) 111#define MT9M114_CAM_SENSOR_CONTROL_X_READ_OUT_SUMMING (3 << 4) 112#define MT9M114_CAM_SENSOR_CONTROL_X_READ_OUT_MASK (3 << 4) 113#define MT9M114_CAM_SENSOR_CONTROL_Y_READ_OUT_NORMAL (0 << 8) 114#define MT9M114_CAM_SENSOR_CONTROL_Y_READ_OUT_SKIPPING (1 << 8) 115#define MT9M114_CAM_SENSOR_CONTROL_Y_READ_OUT_SUMMING (3 << 8) 116#define MT9M114_CAM_SENSOR_CONTROL_Y_READ_OUT_MASK (3 << 8) 117#define MT9M114_CAM_SENSOR_CONTROL_ANALOG_GAIN CCI_REG16(0xc836) 118#define MT9M114_CAM_SENSOR_CONTROL_COARSE_INTEGRATION_TIME CCI_REG16(0xc83c) 119#define MT9M114_CAM_SENSOR_CONTROL_FINE_INTEGRATION_TIME CCI_REG16(0xc83e) 120#define MT9M114_CAM_MODE_SELECT CCI_REG8(0xc84c) 121#define MT9M114_CAM_MODE_SELECT_NORMAL (0 << 0) 122#define MT9M114_CAM_MODE_SELECT_LENS_CALIBRATION (1 << 0) 123#define MT9M114_CAM_MODE_SELECT_TEST_PATTERN (2 << 0) 124#define MT9M114_CAM_MODE_TEST_PATTERN_SELECT CCI_REG8(0xc84d) 125#define MT9M114_CAM_MODE_TEST_PATTERN_SELECT_SOLID (1 << 0) 126#define MT9M114_CAM_MODE_TEST_PATTERN_SELECT_SOLID_BARS (4 << 0) 127#define MT9M114_CAM_MODE_TEST_PATTERN_SELECT_RANDOM (5 << 0) 128#define MT9M114_CAM_MODE_TEST_PATTERN_SELECT_FADING_BARS (8 << 0) 129#define MT9M114_CAM_MODE_TEST_PATTERN_SELECT_WALKING_1S_10B (10 << 0) 130#define MT9M114_CAM_MODE_TEST_PATTERN_SELECT_WALKING_1S_8B (11 << 0) 131#define MT9M114_CAM_MODE_TEST_PATTERN_RED CCI_REG16(0xc84e) 132#define MT9M114_CAM_MODE_TEST_PATTERN_GREEN CCI_REG16(0xc850) 133#define MT9M114_CAM_MODE_TEST_PATTERN_BLUE CCI_REG16(0xc852) 134#define MT9M114_CAM_CROP_WINDOW_XOFFSET CCI_REG16(0xc854) 135#define MT9M114_CAM_CROP_WINDOW_YOFFSET CCI_REG16(0xc856) 136#define MT9M114_CAM_CROP_WINDOW_WIDTH CCI_REG16(0xc858) 137#define MT9M114_CAM_CROP_WINDOW_HEIGHT CCI_REG16(0xc85a) 138#define MT9M114_CAM_CROP_CROPMODE CCI_REG8(0xc85c) 139#define MT9M114_CAM_CROP_MODE_AE_AUTO_CROP_EN BIT(0) 140#define MT9M114_CAM_CROP_MODE_AWB_AUTO_CROP_EN BIT(1) 141#define MT9M114_CAM_OUTPUT_WIDTH CCI_REG16(0xc868) 142#define MT9M114_CAM_OUTPUT_HEIGHT CCI_REG16(0xc86a) 143#define MT9M114_CAM_OUTPUT_FORMAT CCI_REG16(0xc86c) 144#define MT9M114_CAM_OUTPUT_FORMAT_SWAP_RED_BLUE BIT(0) 145#define MT9M114_CAM_OUTPUT_FORMAT_SWAP_BYTES BIT(1) 146#define MT9M114_CAM_OUTPUT_FORMAT_MONO_ENABLE BIT(2) 147#define MT9M114_CAM_OUTPUT_FORMAT_BT656_ENABLE BIT(3) 148#define MT9M114_CAM_OUTPUT_FORMAT_BT656_CROP_SCALE_DISABLE BIT(4) 149#define MT9M114_CAM_OUTPUT_FORMAT_FVLV_DISABLE BIT(5) 150#define MT9M114_CAM_OUTPUT_FORMAT_FORMAT_YUV (0 << 8) 151#define MT9M114_CAM_OUTPUT_FORMAT_FORMAT_RGB (1 << 8) 152#define MT9M114_CAM_OUTPUT_FORMAT_FORMAT_BAYER (2 << 8) 153#define MT9M114_CAM_OUTPUT_FORMAT_FORMAT_NONE (3 << 8) 154#define MT9M114_CAM_OUTPUT_FORMAT_FORMAT_MASK (3 << 8) 155#define MT9M114_CAM_OUTPUT_FORMAT_BAYER_FORMAT_RAWR10 (0 << 10) 156#define MT9M114_CAM_OUTPUT_FORMAT_BAYER_FORMAT_PRELSC_8_2 (1 << 10) 157#define MT9M114_CAM_OUTPUT_FORMAT_BAYER_FORMAT_POSTLSC_8_2 (2 << 10) 158#define MT9M114_CAM_OUTPUT_FORMAT_BAYER_FORMAT_PROCESSED8 (3 << 10) 159#define MT9M114_CAM_OUTPUT_FORMAT_BAYER_FORMAT_MASK (3 << 10) 160#define MT9M114_CAM_OUTPUT_FORMAT_RGB_FORMAT_565RGB (0 << 12) 161#define MT9M114_CAM_OUTPUT_FORMAT_RGB_FORMAT_555RGB (1 << 12) 162#define MT9M114_CAM_OUTPUT_FORMAT_RGB_FORMAT_444xRGB (2 << 12) 163#define MT9M114_CAM_OUTPUT_FORMAT_RGB_FORMAT_444RGBx (3 << 12) 164#define MT9M114_CAM_OUTPUT_FORMAT_RGB_FORMAT_MASK (3 << 12) 165#define MT9M114_CAM_OUTPUT_FORMAT_YUV CCI_REG16(0xc86e) 166#define MT9M114_CAM_OUTPUT_FORMAT_YUV_CLIP BIT(5) 167#define MT9M114_CAM_OUTPUT_FORMAT_YUV_AUV_OFFSET BIT(4) 168#define MT9M114_CAM_OUTPUT_FORMAT_YUV_SELECT_601 BIT(3) 169#define MT9M114_CAM_OUTPUT_FORMAT_YUV_NORMALISE BIT(2) 170#define MT9M114_CAM_OUTPUT_FORMAT_YUV_SAMPLING_EVEN_UV (0 << 0) 171#define MT9M114_CAM_OUTPUT_FORMAT_YUV_SAMPLING_ODD_UV (1 << 0) 172#define MT9M114_CAM_OUTPUT_FORMAT_YUV_SAMPLING_EVENU_ODDV (2 << 0) 173#define MT9M114_CAM_OUTPUT_Y_OFFSET CCI_REG8(0xc870) 174#define MT9M114_CAM_AET_AEMODE CCI_REG8(0xc878) 175#define MT9M114_CAM_AET_EXEC_SET_INDOOR BIT(0) 176#define MT9M114_CAM_AET_DISCRETE_FRAMERATE BIT(1) 177#define MT9M114_CAM_AET_ADAPTATIVE_TARGET_LUMA BIT(2) 178#define MT9M114_CAM_AET_ADAPTATIVE_SKIP_FRAMES BIT(3) 179#define MT9M114_CAM_AET_SKIP_FRAMES CCI_REG8(0xc879) 180#define MT9M114_CAM_AET_TARGET_AVERAGE_LUMA CCI_REG8(0xc87a) 181#define MT9M114_CAM_AET_TARGET_AVERAGE_LUMA_DARK CCI_REG8(0xc87b) 182#define MT9M114_CAM_AET_BLACK_CLIPPING_TARGET CCI_REG16(0xc87c) 183#define MT9M114_CAM_AET_AE_MIN_VIRT_INT_TIME_PCLK CCI_REG16(0xc87e) 184#define MT9M114_CAM_AET_AE_MIN_VIRT_DGAIN CCI_REG16(0xc880) 185#define MT9M114_CAM_AET_AE_MAX_VIRT_DGAIN CCI_REG16(0xc882) 186#define MT9M114_CAM_AET_AE_MIN_VIRT_AGAIN CCI_REG16(0xc884) 187#define MT9M114_CAM_AET_AE_MAX_VIRT_AGAIN CCI_REG16(0xc886) 188#define MT9M114_CAM_AET_AE_VIRT_GAIN_TH_EG CCI_REG16(0xc888) 189#define MT9M114_CAM_AET_AE_EG_GATE_PERCENTAGE CCI_REG8(0xc88a) 190#define MT9M114_CAM_AET_FLICKER_FREQ_HZ CCI_REG8(0xc88b) 191#define MT9M114_CAM_AET_MAX_FRAME_RATE CCI_REG16(0xc88c) 192#define MT9M114_CAM_AET_MIN_FRAME_RATE CCI_REG16(0xc88e) 193#define MT9M114_CAM_AET_TARGET_GAIN CCI_REG16(0xc890) 194#define MT9M114_CAM_AWB_CCM_L(n) CCI_REG16(0xc892 + (n) * 2) 195#define MT9M114_CAM_AWB_CCM_M(n) CCI_REG16(0xc8a4 + (n) * 2) 196#define MT9M114_CAM_AWB_CCM_R(n) CCI_REG16(0xc8b6 + (n) * 2) 197#define MT9M114_CAM_AWB_CCM_L_RG_GAIN CCI_REG16(0xc8c8) 198#define MT9M114_CAM_AWB_CCM_L_BG_GAIN CCI_REG16(0xc8ca) 199#define MT9M114_CAM_AWB_CCM_M_RG_GAIN CCI_REG16(0xc8cc) 200#define MT9M114_CAM_AWB_CCM_M_BG_GAIN CCI_REG16(0xc8ce) 201#define MT9M114_CAM_AWB_CCM_R_RG_GAIN CCI_REG16(0xc8d0) 202#define MT9M114_CAM_AWB_CCM_R_BG_GAIN CCI_REG16(0xc8d2) 203#define MT9M114_CAM_AWB_CCM_L_CTEMP CCI_REG16(0xc8d4) 204#define MT9M114_CAM_AWB_CCM_M_CTEMP CCI_REG16(0xc8d6) 205#define MT9M114_CAM_AWB_CCM_R_CTEMP CCI_REG16(0xc8d8) 206#define MT9M114_CAM_AWB_AWB_XSCALE CCI_REG8(0xc8f2) 207#define MT9M114_CAM_AWB_AWB_YSCALE CCI_REG8(0xc8f3) 208#define MT9M114_CAM_AWB_AWB_WEIGHTS(n) CCI_REG16(0xc8f4 + (n) * 2) 209#define MT9M114_CAM_AWB_AWB_XSHIFT_PRE_ADJ CCI_REG16(0xc904) 210#define MT9M114_CAM_AWB_AWB_YSHIFT_PRE_ADJ CCI_REG16(0xc906) 211#define MT9M114_CAM_AWB_AWBMODE CCI_REG8(0xc909) 212#define MT9M114_CAM_AWB_MODE_AUTO BIT(1) 213#define MT9M114_CAM_AWB_MODE_EXCLUSIVE_AE BIT(0) 214#define MT9M114_CAM_AWB_K_R_L CCI_REG8(0xc90c) 215#define MT9M114_CAM_AWB_K_G_L CCI_REG8(0xc90d) 216#define MT9M114_CAM_AWB_K_B_L CCI_REG8(0xc90e) 217#define MT9M114_CAM_AWB_K_R_R CCI_REG8(0xc90f) 218#define MT9M114_CAM_AWB_K_G_R CCI_REG8(0xc910) 219#define MT9M114_CAM_AWB_K_B_R CCI_REG8(0xc911) 220#define MT9M114_CAM_STAT_AWB_CLIP_WINDOW_XSTART CCI_REG16(0xc914) 221#define MT9M114_CAM_STAT_AWB_CLIP_WINDOW_YSTART CCI_REG16(0xc916) 222#define MT9M114_CAM_STAT_AWB_CLIP_WINDOW_XEND CCI_REG16(0xc918) 223#define MT9M114_CAM_STAT_AWB_CLIP_WINDOW_YEND CCI_REG16(0xc91a) 224#define MT9M114_CAM_STAT_AE_INITIAL_WINDOW_XSTART CCI_REG16(0xc91c) 225#define MT9M114_CAM_STAT_AE_INITIAL_WINDOW_YSTART CCI_REG16(0xc91e) 226#define MT9M114_CAM_STAT_AE_INITIAL_WINDOW_XEND CCI_REG16(0xc920) 227#define MT9M114_CAM_STAT_AE_INITIAL_WINDOW_YEND CCI_REG16(0xc922) 228#define MT9M114_CAM_LL_LLMODE CCI_REG16(0xc924) 229#define MT9M114_CAM_LL_START_BRIGHTNESS CCI_REG16(0xc926) 230#define MT9M114_CAM_LL_STOP_BRIGHTNESS CCI_REG16(0xc928) 231#define MT9M114_CAM_LL_START_SATURATION CCI_REG8(0xc92a) 232#define MT9M114_CAM_LL_END_SATURATION CCI_REG8(0xc92b) 233#define MT9M114_CAM_LL_START_DESATURATION CCI_REG8(0xc92c) 234#define MT9M114_CAM_LL_END_DESATURATION CCI_REG8(0xc92d) 235#define MT9M114_CAM_LL_START_DEMOSAICING CCI_REG8(0xc92e) 236#define MT9M114_CAM_LL_START_AP_GAIN CCI_REG8(0xc92f) 237#define MT9M114_CAM_LL_START_AP_THRESH CCI_REG8(0xc930) 238#define MT9M114_CAM_LL_STOP_DEMOSAICING CCI_REG8(0xc931) 239#define MT9M114_CAM_LL_STOP_AP_GAIN CCI_REG8(0xc932) 240#define MT9M114_CAM_LL_STOP_AP_THRESH CCI_REG8(0xc933) 241#define MT9M114_CAM_LL_START_NR_RED CCI_REG8(0xc934) 242#define MT9M114_CAM_LL_START_NR_GREEN CCI_REG8(0xc935) 243#define MT9M114_CAM_LL_START_NR_BLUE CCI_REG8(0xc936) 244#define MT9M114_CAM_LL_START_NR_THRESH CCI_REG8(0xc937) 245#define MT9M114_CAM_LL_STOP_NR_RED CCI_REG8(0xc938) 246#define MT9M114_CAM_LL_STOP_NR_GREEN CCI_REG8(0xc939) 247#define MT9M114_CAM_LL_STOP_NR_BLUE CCI_REG8(0xc93a) 248#define MT9M114_CAM_LL_STOP_NR_THRESH CCI_REG8(0xc93b) 249#define MT9M114_CAM_LL_START_CONTRAST_BM CCI_REG16(0xc93c) 250#define MT9M114_CAM_LL_STOP_CONTRAST_BM CCI_REG16(0xc93e) 251#define MT9M114_CAM_LL_GAMMA CCI_REG16(0xc940) 252#define MT9M114_CAM_LL_START_CONTRAST_GRADIENT CCI_REG8(0xc942) 253#define MT9M114_CAM_LL_STOP_CONTRAST_GRADIENT CCI_REG8(0xc943) 254#define MT9M114_CAM_LL_START_CONTRAST_LUMA_PERCENTAGE CCI_REG8(0xc944) 255#define MT9M114_CAM_LL_STOP_CONTRAST_LUMA_PERCENTAGE CCI_REG8(0xc945) 256#define MT9M114_CAM_LL_START_GAIN_METRIC CCI_REG16(0xc946) 257#define MT9M114_CAM_LL_STOP_GAIN_METRIC CCI_REG16(0xc948) 258#define MT9M114_CAM_LL_START_FADE_TO_BLACK_LUMA CCI_REG16(0xc94a) 259#define MT9M114_CAM_LL_STOP_FADE_TO_BLACK_LUMA CCI_REG16(0xc94c) 260#define MT9M114_CAM_LL_CLUSTER_DC_TH_BM CCI_REG16(0xc94e) 261#define MT9M114_CAM_LL_CLUSTER_DC_GATE_PERCENTAGE CCI_REG8(0xc950) 262#define MT9M114_CAM_LL_SUMMING_SENSITIVITY_FACTOR CCI_REG8(0xc951) 263#define MT9M114_CAM_LL_START_TARGET_LUMA_BM CCI_REG16(0xc952) 264#define MT9M114_CAM_LL_STOP_TARGET_LUMA_BM CCI_REG16(0xc954) 265#define MT9M114_CAM_PGA_PGA_CONTROL CCI_REG16(0xc95e) 266#define MT9M114_CAM_SYSCTL_PLL_ENABLE CCI_REG8(0xc97e) 267#define MT9M114_CAM_SYSCTL_PLL_ENABLE_VALUE BIT(0) 268#define MT9M114_CAM_SYSCTL_PLL_DISABLE_VALUE 0x00 269#define MT9M114_CAM_SYSCTL_PLL_DIVIDER_M_N CCI_REG16(0xc980) 270#define MT9M114_CAM_SYSCTL_PLL_DIVIDER_VALUE(m, n) (((n) << 8) | (m)) 271#define MT9M114_CAM_SYSCTL_PLL_DIVIDER_P CCI_REG16(0xc982) 272#define MT9M114_CAM_SYSCTL_PLL_DIVIDER_P_VALUE(p) ((p) << 8) 273#define MT9M114_CAM_PORT_OUTPUT_CONTROL CCI_REG16(0xc984) 274#define MT9M114_CAM_PORT_PORT_SELECT_PARALLEL (0 << 0) 275#define MT9M114_CAM_PORT_PORT_SELECT_MIPI (1 << 0) 276#define MT9M114_CAM_PORT_CLOCK_SLOWDOWN BIT(3) 277#define MT9M114_CAM_PORT_TRUNCATE_RAW_BAYER BIT(4) 278#define MT9M114_CAM_PORT_PIXCLK_GATE BIT(5) 279#define MT9M114_CAM_PORT_CONT_MIPI_CLK BIT(6) 280#define MT9M114_CAM_PORT_CHAN_NUM(vc) ((vc) << 8) 281#define MT9M114_CAM_PORT_MIPI_TIMING_T_HS_ZERO CCI_REG16(0xc988) 282#define MT9M114_CAM_PORT_MIPI_TIMING_T_HS_ZERO_VALUE(n) ((n) << 8) 283#define MT9M114_CAM_PORT_MIPI_TIMING_T_HS_EXIT_TRAIL CCI_REG16(0xc98a) 284#define MT9M114_CAM_PORT_MIPI_TIMING_T_HS_EXIT_VALUE(n) ((n) << 8) 285#define MT9M114_CAM_PORT_MIPI_TIMING_T_HS_TRAIL_VALUE(n) ((n) << 0) 286#define MT9M114_CAM_PORT_MIPI_TIMING_T_CLK_POST_PRE CCI_REG16(0xc98c) 287#define MT9M114_CAM_PORT_MIPI_TIMING_T_CLK_POST_VALUE(n) ((n) << 8) 288#define MT9M114_CAM_PORT_MIPI_TIMING_T_CLK_PRE_VALUE(n) ((n) << 0) 289#define MT9M114_CAM_PORT_MIPI_TIMING_T_CLK_TRAIL_ZERO CCI_REG16(0xc98e) 290#define MT9M114_CAM_PORT_MIPI_TIMING_T_CLK_TRAIL_VALUE(n) ((n) << 8) 291#define MT9M114_CAM_PORT_MIPI_TIMING_T_CLK_ZERO_VALUE(n) ((n) << 0) 292 293/* System Manager registers */ 294#define MT9M114_SYSMGR_NEXT_STATE CCI_REG8(0xdc00) 295#define MT9M114_SYSMGR_CURRENT_STATE CCI_REG8(0xdc01) 296#define MT9M114_SYSMGR_CMD_STATUS CCI_REG8(0xdc02) 297 298/* Patch Loader registers */ 299#define MT9M114_PATCHLDR_LOADER_ADDRESS CCI_REG16(0xe000) 300#define MT9M114_PATCHLDR_PATCH_ID CCI_REG16(0xe002) 301#define MT9M114_PATCHLDR_FIRMWARE_ID CCI_REG32(0xe004) 302#define MT9M114_PATCHLDR_APPLY_STATUS CCI_REG8(0xe008) 303#define MT9M114_PATCHLDR_NUM_PATCHES CCI_REG8(0xe009) 304#define MT9M114_PATCHLDR_PATCH_ID_0 CCI_REG16(0xe00a) 305#define MT9M114_PATCHLDR_PATCH_ID_1 CCI_REG16(0xe00c) 306#define MT9M114_PATCHLDR_PATCH_ID_2 CCI_REG16(0xe00e) 307#define MT9M114_PATCHLDR_PATCH_ID_3 CCI_REG16(0xe010) 308#define MT9M114_PATCHLDR_PATCH_ID_4 CCI_REG16(0xe012) 309#define MT9M114_PATCHLDR_PATCH_ID_5 CCI_REG16(0xe014) 310#define MT9M114_PATCHLDR_PATCH_ID_6 CCI_REG16(0xe016) 311#define MT9M114_PATCHLDR_PATCH_ID_7 CCI_REG16(0xe018) 312 313/* SYS_STATE values (for SYSMGR_NEXT_STATE and SYSMGR_CURRENT_STATE) */ 314#define MT9M114_SYS_STATE_ENTER_CONFIG_CHANGE 0x28 315#define MT9M114_SYS_STATE_STREAMING 0x31 316#define MT9M114_SYS_STATE_START_STREAMING 0x34 317#define MT9M114_SYS_STATE_ENTER_SUSPEND 0x40 318#define MT9M114_SYS_STATE_SUSPENDED 0x41 319#define MT9M114_SYS_STATE_ENTER_STANDBY 0x50 320#define MT9M114_SYS_STATE_STANDBY 0x52 321#define MT9M114_SYS_STATE_LEAVE_STANDBY 0x54 322 323/* Result status of last SET_STATE comamnd */ 324#define MT9M114_SET_STATE_RESULT_ENOERR 0x00 325#define MT9M114_SET_STATE_RESULT_EINVAL 0x0c 326#define MT9M114_SET_STATE_RESULT_ENOSPC 0x0d 327 328/* 329 * The minimum amount of horizontal and vertical blanking is undocumented. The 330 * minimum values that have been seen in register lists are 303 and 38, use 331 * them. 332 * 333 * Set the default to achieve 1280x960 at 30fps. 334 */ 335#define MT9M114_MIN_HBLANK 303 336#define MT9M114_MIN_VBLANK 38 337#define MT9M114_DEF_HBLANK 323 338#define MT9M114_DEF_VBLANK 39 339 340#define MT9M114_DEF_FRAME_RATE 30 341#define MT9M114_MAX_FRAME_RATE 120 342 343#define MT9M114_PIXEL_ARRAY_WIDTH 1296U 344#define MT9M114_PIXEL_ARRAY_HEIGHT 976U 345 346/* 347 * These values are not well documented and are semi-arbitrary. The pixel array 348 * minimum output size is 8 pixels larger than the minimum scaler cropped input 349 * width to account for the demosaicing. 350 */ 351#define MT9M114_PIXEL_ARRAY_MIN_OUTPUT_WIDTH (32U + 8U) 352#define MT9M114_PIXEL_ARRAY_MIN_OUTPUT_HEIGHT (32U + 8U) 353#define MT9M114_SCALER_CROPPED_INPUT_WIDTH 32U 354#define MT9M114_SCALER_CROPPED_INPUT_HEIGHT 32U 355 356/* Indices into the mt9m114.ifp.tpg array. */ 357#define MT9M114_TPG_PATTERN 0 358#define MT9M114_TPG_RED 1 359#define MT9M114_TPG_GREEN 2 360#define MT9M114_TPG_BLUE 3 361 362/* ----------------------------------------------------------------------------- 363 * Data Structures 364 */ 365 366enum mt9m114_format_flag { 367 MT9M114_FMT_FLAG_PARALLEL = BIT(0), 368 MT9M114_FMT_FLAG_CSI2 = BIT(1), 369}; 370 371struct mt9m114_format_info { 372 u32 code; 373 u32 output_format; 374 u32 flags; 375}; 376 377struct mt9m114 { 378 struct i2c_client *client; 379 struct regmap *regmap; 380 381 struct clk *clk; 382 struct gpio_desc *reset; 383 struct regulator_bulk_data supplies[3]; 384 struct v4l2_fwnode_endpoint bus_cfg; 385 bool bypass_pll; 386 387 struct { 388 unsigned int m; 389 unsigned int n; 390 unsigned int p; 391 } pll; 392 393 unsigned int pixrate; 394 bool streaming; 395 u32 pad_slew_rate; 396 397 /* Pixel Array */ 398 struct { 399 struct v4l2_subdev sd; 400 struct media_pad pad; 401 402 struct v4l2_ctrl_handler hdl; 403 struct v4l2_ctrl *exposure; 404 struct v4l2_ctrl *gain; 405 struct v4l2_ctrl *hblank; 406 struct v4l2_ctrl *vblank; 407 } pa; 408 409 /* Image Flow Processor */ 410 struct { 411 struct v4l2_subdev sd; 412 struct media_pad pads[2]; 413 414 struct v4l2_ctrl_handler hdl; 415 unsigned int frame_rate; 416 417 struct v4l2_ctrl *tpg[4]; 418 } ifp; 419}; 420 421/* ----------------------------------------------------------------------------- 422 * Formats 423 */ 424 425static const struct mt9m114_format_info mt9m114_format_infos[] = { 426 { 427 /* 428 * The first two entries are used as defaults, for parallel and 429 * CSI-2 buses respectively. Keep them in that order. 430 */ 431 .code = MEDIA_BUS_FMT_UYVY8_2X8, 432 .flags = MT9M114_FMT_FLAG_PARALLEL, 433 .output_format = MT9M114_CAM_OUTPUT_FORMAT_FORMAT_YUV, 434 }, { 435 .code = MEDIA_BUS_FMT_UYVY8_1X16, 436 .flags = MT9M114_FMT_FLAG_CSI2, 437 .output_format = MT9M114_CAM_OUTPUT_FORMAT_FORMAT_YUV, 438 }, { 439 .code = MEDIA_BUS_FMT_YUYV8_2X8, 440 .flags = MT9M114_FMT_FLAG_PARALLEL, 441 .output_format = MT9M114_CAM_OUTPUT_FORMAT_FORMAT_YUV 442 | MT9M114_CAM_OUTPUT_FORMAT_SWAP_BYTES, 443 }, { 444 .code = MEDIA_BUS_FMT_YUYV8_1X16, 445 .flags = MT9M114_FMT_FLAG_CSI2, 446 .output_format = MT9M114_CAM_OUTPUT_FORMAT_FORMAT_YUV 447 | MT9M114_CAM_OUTPUT_FORMAT_SWAP_BYTES, 448 }, { 449 .code = MEDIA_BUS_FMT_RGB565_2X8_LE, 450 .flags = MT9M114_FMT_FLAG_PARALLEL, 451 .output_format = MT9M114_CAM_OUTPUT_FORMAT_RGB_FORMAT_565RGB 452 | MT9M114_CAM_OUTPUT_FORMAT_FORMAT_RGB 453 | MT9M114_CAM_OUTPUT_FORMAT_SWAP_BYTES, 454 }, { 455 .code = MEDIA_BUS_FMT_RGB565_2X8_BE, 456 .flags = MT9M114_FMT_FLAG_PARALLEL, 457 .output_format = MT9M114_CAM_OUTPUT_FORMAT_RGB_FORMAT_565RGB 458 | MT9M114_CAM_OUTPUT_FORMAT_FORMAT_RGB, 459 }, { 460 .code = MEDIA_BUS_FMT_RGB565_1X16, 461 .flags = MT9M114_FMT_FLAG_CSI2, 462 .output_format = MT9M114_CAM_OUTPUT_FORMAT_RGB_FORMAT_565RGB 463 | MT9M114_CAM_OUTPUT_FORMAT_FORMAT_RGB, 464 }, { 465 .code = MEDIA_BUS_FMT_SGRBG8_1X8, 466 .output_format = MT9M114_CAM_OUTPUT_FORMAT_BAYER_FORMAT_PROCESSED8 467 | MT9M114_CAM_OUTPUT_FORMAT_FORMAT_BAYER, 468 .flags = MT9M114_FMT_FLAG_PARALLEL | MT9M114_FMT_FLAG_CSI2, 469 }, { 470 /* Keep the format compatible with the IFP sink pad last. */ 471 .code = MEDIA_BUS_FMT_SGRBG10_1X10, 472 .output_format = MT9M114_CAM_OUTPUT_FORMAT_BAYER_FORMAT_RAWR10 473 | MT9M114_CAM_OUTPUT_FORMAT_FORMAT_BAYER, 474 .flags = MT9M114_FMT_FLAG_PARALLEL | MT9M114_FMT_FLAG_CSI2, 475 } 476}; 477 478static const struct mt9m114_format_info * 479mt9m114_default_format_info(struct mt9m114 *sensor) 480{ 481 if (sensor->bus_cfg.bus_type == V4L2_MBUS_CSI2_DPHY) 482 return &mt9m114_format_infos[1]; 483 else 484 return &mt9m114_format_infos[0]; 485} 486 487static const struct mt9m114_format_info * 488mt9m114_format_info(struct mt9m114 *sensor, unsigned int pad, u32 code) 489{ 490 const unsigned int num_formats = ARRAY_SIZE(mt9m114_format_infos); 491 unsigned int flag; 492 unsigned int i; 493 494 switch (pad) { 495 case 0: 496 return &mt9m114_format_infos[num_formats - 1]; 497 498 case 1: 499 if (sensor->bus_cfg.bus_type == V4L2_MBUS_CSI2_DPHY) 500 flag = MT9M114_FMT_FLAG_CSI2; 501 else 502 flag = MT9M114_FMT_FLAG_PARALLEL; 503 504 for (i = 0; i < num_formats; ++i) { 505 const struct mt9m114_format_info *info = 506 &mt9m114_format_infos[i]; 507 508 if (info->code == code && info->flags & flag) 509 return info; 510 } 511 512 return mt9m114_default_format_info(sensor); 513 514 default: 515 return NULL; 516 } 517} 518 519/* ----------------------------------------------------------------------------- 520 * Initialization 521 */ 522 523static const struct cci_reg_sequence mt9m114_init[] = { 524 { MT9M114_RESET_REGISTER, MT9M114_RESET_REGISTER_MASK_BAD | 525 MT9M114_RESET_REGISTER_LOCK_REG | 526 0x0010 }, 527 528 /* Sensor optimization */ 529 { CCI_REG16(0x316a), 0x8270 }, 530 { CCI_REG16(0x316c), 0x8270 }, 531 { CCI_REG16(0x3ed0), 0x2305 }, 532 { CCI_REG16(0x3ed2), 0x77cf }, 533 { CCI_REG16(0x316e), 0x8202 }, 534 { CCI_REG16(0x3180), 0x87ff }, 535 { CCI_REG16(0x30d4), 0x6080 }, 536 { CCI_REG16(0xa802), 0x0008 }, 537 538 { CCI_REG16(0x3e14), 0xff39 }, 539 540 /* APGA */ 541 { MT9M114_CAM_PGA_PGA_CONTROL, 0x0000 }, 542 543 /* Automatic White balance */ 544 { MT9M114_CAM_AWB_CCM_L(0), 0x0267 }, 545 { MT9M114_CAM_AWB_CCM_L(1), 0xff1a }, 546 { MT9M114_CAM_AWB_CCM_L(2), 0xffb3 }, 547 { MT9M114_CAM_AWB_CCM_L(3), 0xff80 }, 548 { MT9M114_CAM_AWB_CCM_L(4), 0x0166 }, 549 { MT9M114_CAM_AWB_CCM_L(5), 0x0003 }, 550 { MT9M114_CAM_AWB_CCM_L(6), 0xff9a }, 551 { MT9M114_CAM_AWB_CCM_L(7), 0xfeb4 }, 552 { MT9M114_CAM_AWB_CCM_L(8), 0x024d }, 553 { MT9M114_CAM_AWB_CCM_M(0), 0x01bf }, 554 { MT9M114_CAM_AWB_CCM_M(1), 0xff01 }, 555 { MT9M114_CAM_AWB_CCM_M(2), 0xfff3 }, 556 { MT9M114_CAM_AWB_CCM_M(3), 0xff75 }, 557 { MT9M114_CAM_AWB_CCM_M(4), 0x0198 }, 558 { MT9M114_CAM_AWB_CCM_M(5), 0xfffd }, 559 { MT9M114_CAM_AWB_CCM_M(6), 0xff9a }, 560 { MT9M114_CAM_AWB_CCM_M(7), 0xfee7 }, 561 { MT9M114_CAM_AWB_CCM_M(8), 0x02a8 }, 562 { MT9M114_CAM_AWB_CCM_R(0), 0x01d9 }, 563 { MT9M114_CAM_AWB_CCM_R(1), 0xff26 }, 564 { MT9M114_CAM_AWB_CCM_R(2), 0xfff3 }, 565 { MT9M114_CAM_AWB_CCM_R(3), 0xffb3 }, 566 { MT9M114_CAM_AWB_CCM_R(4), 0x0132 }, 567 { MT9M114_CAM_AWB_CCM_R(5), 0xffe8 }, 568 { MT9M114_CAM_AWB_CCM_R(6), 0xffda }, 569 { MT9M114_CAM_AWB_CCM_R(7), 0xfecd }, 570 { MT9M114_CAM_AWB_CCM_R(8), 0x02c2 }, 571 { MT9M114_CAM_AWB_CCM_L_RG_GAIN, 0x0075 }, 572 { MT9M114_CAM_AWB_CCM_L_BG_GAIN, 0x011c }, 573 { MT9M114_CAM_AWB_CCM_M_RG_GAIN, 0x009a }, 574 { MT9M114_CAM_AWB_CCM_M_BG_GAIN, 0x0105 }, 575 { MT9M114_CAM_AWB_CCM_R_RG_GAIN, 0x00a4 }, 576 { MT9M114_CAM_AWB_CCM_R_BG_GAIN, 0x00ac }, 577 { MT9M114_CAM_AWB_CCM_L_CTEMP, 0x0a8c }, 578 { MT9M114_CAM_AWB_CCM_M_CTEMP, 0x0f0a }, 579 { MT9M114_CAM_AWB_CCM_R_CTEMP, 0x1964 }, 580 { MT9M114_CAM_AWB_AWB_XSHIFT_PRE_ADJ, 51 }, 581 { MT9M114_CAM_AWB_AWB_YSHIFT_PRE_ADJ, 60 }, 582 { MT9M114_CAM_AWB_AWB_XSCALE, 3 }, 583 { MT9M114_CAM_AWB_AWB_YSCALE, 2 }, 584 { MT9M114_CAM_AWB_AWB_WEIGHTS(0), 0x0000 }, 585 { MT9M114_CAM_AWB_AWB_WEIGHTS(1), 0x0000 }, 586 { MT9M114_CAM_AWB_AWB_WEIGHTS(2), 0x0000 }, 587 { MT9M114_CAM_AWB_AWB_WEIGHTS(3), 0xe724 }, 588 { MT9M114_CAM_AWB_AWB_WEIGHTS(4), 0x1583 }, 589 { MT9M114_CAM_AWB_AWB_WEIGHTS(5), 0x2045 }, 590 { MT9M114_CAM_AWB_AWB_WEIGHTS(6), 0x03ff }, 591 { MT9M114_CAM_AWB_AWB_WEIGHTS(7), 0x007c }, 592 { MT9M114_CAM_AWB_K_R_L, 0x80 }, 593 { MT9M114_CAM_AWB_K_G_L, 0x80 }, 594 { MT9M114_CAM_AWB_K_B_L, 0x80 }, 595 { MT9M114_CAM_AWB_K_R_R, 0x88 }, 596 { MT9M114_CAM_AWB_K_G_R, 0x80 }, 597 { MT9M114_CAM_AWB_K_B_R, 0x80 }, 598 599 /* Low-Light Image Enhancements */ 600 { MT9M114_CAM_LL_START_BRIGHTNESS, 0x0020 }, 601 { MT9M114_CAM_LL_STOP_BRIGHTNESS, 0x009a }, 602 { MT9M114_CAM_LL_START_GAIN_METRIC, 0x0070 }, 603 { MT9M114_CAM_LL_STOP_GAIN_METRIC, 0x00f3 }, 604 { MT9M114_CAM_LL_START_CONTRAST_LUMA_PERCENTAGE, 0x20 }, 605 { MT9M114_CAM_LL_STOP_CONTRAST_LUMA_PERCENTAGE, 0x9a }, 606 { MT9M114_CAM_LL_START_SATURATION, 0x80 }, 607 { MT9M114_CAM_LL_END_SATURATION, 0x4b }, 608 { MT9M114_CAM_LL_START_DESATURATION, 0x00 }, 609 { MT9M114_CAM_LL_END_DESATURATION, 0xff }, 610 { MT9M114_CAM_LL_START_DEMOSAICING, 0x3c }, 611 { MT9M114_CAM_LL_START_AP_GAIN, 0x02 }, 612 { MT9M114_CAM_LL_START_AP_THRESH, 0x06 }, 613 { MT9M114_CAM_LL_STOP_DEMOSAICING, 0x64 }, 614 { MT9M114_CAM_LL_STOP_AP_GAIN, 0x01 }, 615 { MT9M114_CAM_LL_STOP_AP_THRESH, 0x0c }, 616 { MT9M114_CAM_LL_START_NR_RED, 0x3c }, 617 { MT9M114_CAM_LL_START_NR_GREEN, 0x3c }, 618 { MT9M114_CAM_LL_START_NR_BLUE, 0x3c }, 619 { MT9M114_CAM_LL_START_NR_THRESH, 0x0f }, 620 { MT9M114_CAM_LL_STOP_NR_RED, 0x64 }, 621 { MT9M114_CAM_LL_STOP_NR_GREEN, 0x64 }, 622 { MT9M114_CAM_LL_STOP_NR_BLUE, 0x64 }, 623 { MT9M114_CAM_LL_STOP_NR_THRESH, 0x32 }, 624 { MT9M114_CAM_LL_START_CONTRAST_BM, 0x0020 }, 625 { MT9M114_CAM_LL_STOP_CONTRAST_BM, 0x009a }, 626 { MT9M114_CAM_LL_GAMMA, 0x00dc }, 627 { MT9M114_CAM_LL_START_CONTRAST_GRADIENT, 0x38 }, 628 { MT9M114_CAM_LL_STOP_CONTRAST_GRADIENT, 0x30 }, 629 { MT9M114_CAM_LL_START_CONTRAST_LUMA_PERCENTAGE, 0x50 }, 630 { MT9M114_CAM_LL_STOP_CONTRAST_LUMA_PERCENTAGE, 0x19 }, 631 { MT9M114_CAM_LL_START_FADE_TO_BLACK_LUMA, 0x0230 }, 632 { MT9M114_CAM_LL_STOP_FADE_TO_BLACK_LUMA, 0x0010 }, 633 { MT9M114_CAM_LL_CLUSTER_DC_TH_BM, 0x01cd }, 634 { MT9M114_CAM_LL_CLUSTER_DC_GATE_PERCENTAGE, 0x05 }, 635 { MT9M114_CAM_LL_SUMMING_SENSITIVITY_FACTOR, 0x40 }, 636 637 /* Auto-Exposure */ 638 { MT9M114_CAM_AET_TARGET_AVERAGE_LUMA_DARK, 0x1b }, 639 { MT9M114_CAM_AET_AEMODE, 0x00 }, 640 { MT9M114_CAM_AET_TARGET_GAIN, 0x0080 }, 641 { MT9M114_CAM_AET_AE_MAX_VIRT_AGAIN, 0x0100 }, 642 { MT9M114_CAM_AET_BLACK_CLIPPING_TARGET, 0x005a }, 643 644 { MT9M114_CCM_DELTA_GAIN, 0x05 }, 645 { MT9M114_AE_TRACK_AE_TRACKING_DAMPENING_SPEED, 0x20 }, 646 647 /* Pixel array timings and integration time */ 648 { MT9M114_CAM_SENSOR_CFG_ROW_SPEED, 1 }, 649 { MT9M114_CAM_SENSOR_CFG_FINE_INTEG_TIME_MIN, 219 }, 650 { MT9M114_CAM_SENSOR_CFG_FINE_INTEG_TIME_MAX, 1459 }, 651 { MT9M114_CAM_SENSOR_CFG_FINE_CORRECTION, 96 }, 652 { MT9M114_CAM_SENSOR_CFG_REG_0_DATA, 32 }, 653}; 654 655/* ----------------------------------------------------------------------------- 656 * Hardware Configuration 657 */ 658 659/* Wait for a command to complete. */ 660static int mt9m114_poll_command(struct mt9m114 *sensor, u32 command) 661{ 662 unsigned int i; 663 u64 value; 664 int ret; 665 666 for (i = 0; i < 100; ++i) { 667 ret = cci_read(sensor->regmap, MT9M114_COMMAND_REGISTER, &value, 668 NULL); 669 if (ret < 0) 670 return ret; 671 672 if (!(value & command)) 673 break; 674 675 usleep_range(5000, 6000); 676 } 677 678 if (value & command) { 679 dev_err(&sensor->client->dev, "Command %u completion timeout\n", 680 command); 681 return -ETIMEDOUT; 682 } 683 684 if (!(value & MT9M114_COMMAND_REGISTER_OK)) { 685 dev_err(&sensor->client->dev, "Command %u failed\n", command); 686 return -EIO; 687 } 688 689 return 0; 690} 691 692/* Wait for a state to be entered. */ 693static int mt9m114_poll_state(struct mt9m114 *sensor, u32 state) 694{ 695 unsigned int i; 696 u64 value; 697 int ret; 698 699 for (i = 0; i < 100; ++i) { 700 ret = cci_read(sensor->regmap, MT9M114_SYSMGR_CURRENT_STATE, 701 &value, NULL); 702 if (ret < 0) 703 return ret; 704 705 if (value == state) 706 return 0; 707 708 usleep_range(1000, 1500); 709 } 710 711 dev_err(&sensor->client->dev, "Timeout waiting for state 0x%02x\n", 712 state); 713 return -ETIMEDOUT; 714} 715 716static int mt9m114_set_state(struct mt9m114 *sensor, u8 next_state) 717{ 718 int ret = 0; 719 720 /* Set the next desired state and start the state transition. */ 721 cci_write(sensor->regmap, MT9M114_SYSMGR_NEXT_STATE, next_state, &ret); 722 cci_write(sensor->regmap, MT9M114_COMMAND_REGISTER, 723 MT9M114_COMMAND_REGISTER_OK | 724 MT9M114_COMMAND_REGISTER_SET_STATE, &ret); 725 if (ret < 0) 726 return ret; 727 728 /* Wait for the state transition to complete. */ 729 ret = mt9m114_poll_command(sensor, MT9M114_COMMAND_REGISTER_SET_STATE); 730 if (ret < 0) 731 return ret; 732 733 return 0; 734} 735 736static int mt9m114_initialize(struct mt9m114 *sensor) 737{ 738 u32 value; 739 int ret; 740 741 ret = cci_multi_reg_write(sensor->regmap, mt9m114_init, 742 ARRAY_SIZE(mt9m114_init), NULL); 743 if (ret < 0) { 744 dev_err(&sensor->client->dev, 745 "Failed to initialize the sensor\n"); 746 return ret; 747 } 748 749 /* Configure the PLL. */ 750 if (sensor->bypass_pll) { 751 cci_write(sensor->regmap, MT9M114_CAM_SYSCTL_PLL_ENABLE, 752 MT9M114_CAM_SYSCTL_PLL_DISABLE_VALUE, &ret); 753 } else { 754 cci_write(sensor->regmap, MT9M114_CAM_SYSCTL_PLL_ENABLE, 755 MT9M114_CAM_SYSCTL_PLL_ENABLE_VALUE, &ret); 756 cci_write(sensor->regmap, MT9M114_CAM_SYSCTL_PLL_DIVIDER_M_N, 757 MT9M114_CAM_SYSCTL_PLL_DIVIDER_VALUE(sensor->pll.m, 758 sensor->pll.n), 759 &ret); 760 cci_write(sensor->regmap, MT9M114_CAM_SYSCTL_PLL_DIVIDER_P, 761 MT9M114_CAM_SYSCTL_PLL_DIVIDER_P_VALUE(sensor->pll.p), 762 &ret); 763 } 764 765 cci_write(sensor->regmap, MT9M114_CAM_SENSOR_CFG_PIXCLK, 766 sensor->pixrate, &ret); 767 768 /* Configure the output mode. */ 769 if (sensor->bus_cfg.bus_type == V4L2_MBUS_CSI2_DPHY) { 770 value = MT9M114_CAM_PORT_PORT_SELECT_MIPI 771 | MT9M114_CAM_PORT_CHAN_NUM(0) 772 | 0x8000; 773 if (!(sensor->bus_cfg.bus.mipi_csi2.flags & 774 V4L2_MBUS_CSI2_NONCONTINUOUS_CLOCK)) 775 value |= MT9M114_CAM_PORT_CONT_MIPI_CLK; 776 } else { 777 value = MT9M114_CAM_PORT_PORT_SELECT_PARALLEL 778 | 0x8000; 779 } 780 cci_write(sensor->regmap, MT9M114_CAM_PORT_OUTPUT_CONTROL, value, &ret); 781 if (ret < 0) 782 return ret; 783 784 value = sensor->pad_slew_rate 785 | sensor->pad_slew_rate << 4 786 | sensor->pad_slew_rate << 8; 787 cci_write(sensor->regmap, MT9M114_PAD_SLEW, value, &ret); 788 if (ret < 0) 789 return ret; 790 791 ret = mt9m114_set_state(sensor, MT9M114_SYS_STATE_ENTER_CONFIG_CHANGE); 792 if (ret < 0) 793 return ret; 794 795 ret = mt9m114_set_state(sensor, MT9M114_SYS_STATE_ENTER_SUSPEND); 796 if (ret < 0) 797 return ret; 798 799 return 0; 800} 801 802static int mt9m114_configure_pa(struct mt9m114 *sensor, 803 struct v4l2_subdev_state *state) 804{ 805 const struct v4l2_mbus_framefmt *format; 806 const struct v4l2_rect *crop; 807 unsigned int hratio, vratio; 808 u64 read_mode; 809 int ret; 810 811 format = v4l2_subdev_state_get_format(state, 0); 812 crop = v4l2_subdev_state_get_crop(state, 0); 813 814 ret = cci_read(sensor->regmap, MT9M114_CAM_SENSOR_CONTROL_READ_MODE, 815 &read_mode, NULL); 816 if (ret < 0) 817 return ret; 818 819 hratio = crop->width / format->width; 820 vratio = crop->height / format->height; 821 822 /* 823 * Pixel array crop and binning. The CAM_SENSOR_CFG_CPIPE_LAST_ROW 824 * register isn't clearly documented, but is always set to the number 825 * of active rows minus 4 divided by the vertical binning factor in all 826 * example sensor modes. 827 */ 828 cci_write(sensor->regmap, MT9M114_CAM_SENSOR_CFG_X_ADDR_START, 829 crop->left, &ret); 830 cci_write(sensor->regmap, MT9M114_CAM_SENSOR_CFG_Y_ADDR_START, 831 crop->top, &ret); 832 cci_write(sensor->regmap, MT9M114_CAM_SENSOR_CFG_X_ADDR_END, 833 crop->width + crop->left - 1, &ret); 834 cci_write(sensor->regmap, MT9M114_CAM_SENSOR_CFG_Y_ADDR_END, 835 crop->height + crop->top - 1, &ret); 836 cci_write(sensor->regmap, MT9M114_CAM_SENSOR_CFG_CPIPE_LAST_ROW, 837 (crop->height - 4) / vratio - 1, &ret); 838 839 read_mode &= ~(MT9M114_CAM_SENSOR_CONTROL_X_READ_OUT_MASK | 840 MT9M114_CAM_SENSOR_CONTROL_Y_READ_OUT_MASK); 841 842 if (hratio > 1) 843 read_mode |= MT9M114_CAM_SENSOR_CONTROL_X_READ_OUT_SUMMING; 844 if (vratio > 1) 845 read_mode |= MT9M114_CAM_SENSOR_CONTROL_Y_READ_OUT_SUMMING; 846 847 cci_write(sensor->regmap, MT9M114_CAM_SENSOR_CONTROL_READ_MODE, 848 read_mode, &ret); 849 850 return ret; 851} 852 853static int mt9m114_configure_ifp(struct mt9m114 *sensor, 854 struct v4l2_subdev_state *state) 855{ 856 const struct mt9m114_format_info *info; 857 const struct v4l2_mbus_framefmt *format; 858 const struct v4l2_rect *crop; 859 const struct v4l2_rect *compose; 860 u64 output_format; 861 int ret = 0; 862 863 format = v4l2_subdev_state_get_format(state, 1); 864 info = mt9m114_format_info(sensor, 1, format->code); 865 crop = v4l2_subdev_state_get_crop(state, 0); 866 compose = v4l2_subdev_state_get_compose(state, 0); 867 868 ret = cci_read(sensor->regmap, MT9M114_CAM_OUTPUT_FORMAT, 869 &output_format, NULL); 870 if (ret < 0) 871 return ret; 872 873 /* 874 * Color pipeline (IFP) cropping and scaling. Subtract 4 from the left 875 * and top coordinates to compensate for the lines and columns removed 876 * by demosaicing that are taken into account in the crop rectangle but 877 * not in the hardware. 878 */ 879 cci_write(sensor->regmap, MT9M114_CAM_CROP_WINDOW_XOFFSET, 880 crop->left - 4, &ret); 881 cci_write(sensor->regmap, MT9M114_CAM_CROP_WINDOW_YOFFSET, 882 crop->top - 4, &ret); 883 cci_write(sensor->regmap, MT9M114_CAM_CROP_WINDOW_WIDTH, 884 crop->width, &ret); 885 cci_write(sensor->regmap, MT9M114_CAM_CROP_WINDOW_HEIGHT, 886 crop->height, &ret); 887 888 cci_write(sensor->regmap, MT9M114_CAM_OUTPUT_WIDTH, 889 compose->width, &ret); 890 cci_write(sensor->regmap, MT9M114_CAM_OUTPUT_HEIGHT, 891 compose->height, &ret); 892 893 /* AWB and AE windows, use the full frame. */ 894 cci_write(sensor->regmap, MT9M114_CAM_STAT_AWB_CLIP_WINDOW_XSTART, 895 0, &ret); 896 cci_write(sensor->regmap, MT9M114_CAM_STAT_AWB_CLIP_WINDOW_YSTART, 897 0, &ret); 898 cci_write(sensor->regmap, MT9M114_CAM_STAT_AWB_CLIP_WINDOW_XEND, 899 compose->width - 1, &ret); 900 cci_write(sensor->regmap, MT9M114_CAM_STAT_AWB_CLIP_WINDOW_YEND, 901 compose->height - 1, &ret); 902 903 cci_write(sensor->regmap, MT9M114_CAM_STAT_AE_INITIAL_WINDOW_XSTART, 904 0, &ret); 905 cci_write(sensor->regmap, MT9M114_CAM_STAT_AE_INITIAL_WINDOW_YSTART, 906 0, &ret); 907 cci_write(sensor->regmap, MT9M114_CAM_STAT_AE_INITIAL_WINDOW_XEND, 908 compose->width / 5 - 1, &ret); 909 cci_write(sensor->regmap, MT9M114_CAM_STAT_AE_INITIAL_WINDOW_YEND, 910 compose->height / 5 - 1, &ret); 911 912 cci_write(sensor->regmap, MT9M114_CAM_CROP_CROPMODE, 913 MT9M114_CAM_CROP_MODE_AWB_AUTO_CROP_EN | 914 MT9M114_CAM_CROP_MODE_AE_AUTO_CROP_EN, &ret); 915 916 /* Set the media bus code. */ 917 output_format &= ~(MT9M114_CAM_OUTPUT_FORMAT_RGB_FORMAT_MASK | 918 MT9M114_CAM_OUTPUT_FORMAT_BAYER_FORMAT_MASK | 919 MT9M114_CAM_OUTPUT_FORMAT_FORMAT_MASK | 920 MT9M114_CAM_OUTPUT_FORMAT_SWAP_BYTES | 921 MT9M114_CAM_OUTPUT_FORMAT_SWAP_RED_BLUE); 922 output_format |= info->output_format; 923 924 cci_write(sensor->regmap, MT9M114_CAM_OUTPUT_FORMAT, 925 output_format, &ret); 926 927 return ret; 928} 929 930static int mt9m114_set_frame_rate(struct mt9m114 *sensor) 931{ 932 u16 frame_rate = sensor->ifp.frame_rate << 8; 933 int ret = 0; 934 935 cci_write(sensor->regmap, MT9M114_CAM_AET_MIN_FRAME_RATE, 936 frame_rate, &ret); 937 cci_write(sensor->regmap, MT9M114_CAM_AET_MAX_FRAME_RATE, 938 frame_rate, &ret); 939 940 return ret; 941} 942 943static int mt9m114_start_streaming(struct mt9m114 *sensor, 944 struct v4l2_subdev_state *pa_state, 945 struct v4l2_subdev_state *ifp_state) 946{ 947 int ret; 948 949 ret = pm_runtime_resume_and_get(&sensor->client->dev); 950 if (ret) 951 return ret; 952 953 ret = mt9m114_configure_ifp(sensor, ifp_state); 954 if (ret) 955 goto error; 956 957 ret = mt9m114_configure_pa(sensor, pa_state); 958 if (ret) 959 goto error; 960 961 ret = mt9m114_set_frame_rate(sensor); 962 if (ret) 963 goto error; 964 965 ret = __v4l2_ctrl_handler_setup(&sensor->pa.hdl); 966 if (ret) 967 goto error; 968 969 ret = __v4l2_ctrl_handler_setup(&sensor->ifp.hdl); 970 if (ret) 971 goto error; 972 973 /* 974 * The Change-Config state is transient and moves to the streaming 975 * state automatically. 976 */ 977 ret = mt9m114_set_state(sensor, MT9M114_SYS_STATE_ENTER_CONFIG_CHANGE); 978 if (ret) 979 goto error; 980 981 sensor->streaming = true; 982 983 return 0; 984 985error: 986 pm_runtime_put_autosuspend(&sensor->client->dev); 987 988 return ret; 989} 990 991static int mt9m114_stop_streaming(struct mt9m114 *sensor) 992{ 993 int ret; 994 995 sensor->streaming = false; 996 997 ret = mt9m114_set_state(sensor, MT9M114_SYS_STATE_ENTER_SUSPEND); 998 999 pm_runtime_put_autosuspend(&sensor->client->dev); 1000 1001 return ret; 1002} 1003 1004/* ----------------------------------------------------------------------------- 1005 * Common Subdev Operations 1006 */ 1007 1008static const struct media_entity_operations mt9m114_entity_ops = { 1009 .link_validate = v4l2_subdev_link_validate, 1010}; 1011 1012/* ----------------------------------------------------------------------------- 1013 * Pixel Array Control Operations 1014 */ 1015 1016static inline struct mt9m114 *pa_ctrl_to_mt9m114(struct v4l2_ctrl *ctrl) 1017{ 1018 return container_of(ctrl->handler, struct mt9m114, pa.hdl); 1019} 1020 1021static int mt9m114_pa_g_ctrl(struct v4l2_ctrl *ctrl) 1022{ 1023 struct mt9m114 *sensor = pa_ctrl_to_mt9m114(ctrl); 1024 u64 value; 1025 int ret; 1026 1027 if (!pm_runtime_get_if_in_use(&sensor->client->dev)) 1028 return 0; 1029 1030 switch (ctrl->id) { 1031 case V4L2_CID_EXPOSURE: 1032 ret = cci_read(sensor->regmap, 1033 MT9M114_CAM_SENSOR_CONTROL_COARSE_INTEGRATION_TIME, 1034 &value, NULL); 1035 if (ret) 1036 break; 1037 1038 ctrl->val = value; 1039 break; 1040 1041 case V4L2_CID_ANALOGUE_GAIN: 1042 ret = cci_read(sensor->regmap, 1043 MT9M114_CAM_SENSOR_CONTROL_ANALOG_GAIN, 1044 &value, NULL); 1045 if (ret) 1046 break; 1047 1048 ctrl->val = value; 1049 break; 1050 1051 default: 1052 ret = -EINVAL; 1053 break; 1054 } 1055 1056 pm_runtime_put_autosuspend(&sensor->client->dev); 1057 1058 return ret; 1059} 1060 1061static int mt9m114_pa_s_ctrl(struct v4l2_ctrl *ctrl) 1062{ 1063 struct mt9m114 *sensor = pa_ctrl_to_mt9m114(ctrl); 1064 const struct v4l2_mbus_framefmt *format; 1065 struct v4l2_subdev_state *state; 1066 int ret = 0; 1067 u64 mask; 1068 1069 /* V4L2 controls values are applied only when power is up. */ 1070 if (!pm_runtime_get_if_in_use(&sensor->client->dev)) 1071 return 0; 1072 1073 state = v4l2_subdev_get_locked_active_state(&sensor->pa.sd); 1074 format = v4l2_subdev_state_get_format(state, 0); 1075 1076 switch (ctrl->id) { 1077 case V4L2_CID_HBLANK: 1078 cci_write(sensor->regmap, MT9M114_CAM_SENSOR_CFG_LINE_LENGTH_PCK, 1079 ctrl->val + format->width, &ret); 1080 break; 1081 1082 case V4L2_CID_VBLANK: 1083 cci_write(sensor->regmap, MT9M114_CAM_SENSOR_CFG_FRAME_LENGTH_LINES, 1084 ctrl->val + format->height, &ret); 1085 break; 1086 1087 case V4L2_CID_EXPOSURE: 1088 cci_write(sensor->regmap, 1089 MT9M114_CAM_SENSOR_CONTROL_COARSE_INTEGRATION_TIME, 1090 ctrl->val, &ret); 1091 break; 1092 1093 case V4L2_CID_ANALOGUE_GAIN: 1094 /* 1095 * The CAM_SENSOR_CONTROL_ANALOG_GAIN contains linear analog 1096 * gain values that are mapped to the GLOBAL_GAIN register 1097 * values by the sensor firmware. 1098 */ 1099 cci_write(sensor->regmap, MT9M114_CAM_SENSOR_CONTROL_ANALOG_GAIN, 1100 ctrl->val, &ret); 1101 break; 1102 1103 case V4L2_CID_HFLIP: 1104 mask = MT9M114_CAM_SENSOR_CONTROL_HORZ_MIRROR_EN; 1105 ret = cci_update_bits(sensor->regmap, 1106 MT9M114_CAM_SENSOR_CONTROL_READ_MODE, 1107 mask, ctrl->val ? mask : 0, NULL); 1108 break; 1109 1110 case V4L2_CID_VFLIP: 1111 mask = MT9M114_CAM_SENSOR_CONTROL_VERT_FLIP_EN; 1112 ret = cci_update_bits(sensor->regmap, 1113 MT9M114_CAM_SENSOR_CONTROL_READ_MODE, 1114 mask, ctrl->val ? mask : 0, NULL); 1115 break; 1116 1117 default: 1118 ret = -EINVAL; 1119 break; 1120 } 1121 1122 pm_runtime_put_autosuspend(&sensor->client->dev); 1123 1124 return ret; 1125} 1126 1127static const struct v4l2_ctrl_ops mt9m114_pa_ctrl_ops = { 1128 .g_volatile_ctrl = mt9m114_pa_g_ctrl, 1129 .s_ctrl = mt9m114_pa_s_ctrl, 1130}; 1131 1132static void mt9m114_pa_ctrl_update_exposure(struct mt9m114 *sensor, bool manual) 1133{ 1134 /* 1135 * Update the volatile flag on the manual exposure and gain controls. 1136 * If the controls have switched to manual, read their current value 1137 * from the hardware to ensure that control read and write operations 1138 * will behave correctly 1139 */ 1140 if (manual) { 1141 mt9m114_pa_g_ctrl(sensor->pa.exposure); 1142 sensor->pa.exposure->cur.val = sensor->pa.exposure->val; 1143 sensor->pa.exposure->flags &= ~V4L2_CTRL_FLAG_VOLATILE; 1144 1145 mt9m114_pa_g_ctrl(sensor->pa.gain); 1146 sensor->pa.gain->cur.val = sensor->pa.gain->val; 1147 sensor->pa.gain->flags &= ~V4L2_CTRL_FLAG_VOLATILE; 1148 } else { 1149 sensor->pa.exposure->flags |= V4L2_CTRL_FLAG_VOLATILE; 1150 sensor->pa.gain->flags |= V4L2_CTRL_FLAG_VOLATILE; 1151 } 1152} 1153 1154static void mt9m114_pa_ctrl_update_blanking(struct mt9m114 *sensor, 1155 const struct v4l2_mbus_framefmt *format) 1156{ 1157 unsigned int max_blank; 1158 1159 /* Update the blanking controls ranges based on the output size. */ 1160 max_blank = MT9M114_CAM_SENSOR_CFG_LINE_LENGTH_PCK_MAX 1161 - format->width; 1162 __v4l2_ctrl_modify_range(sensor->pa.hblank, MT9M114_MIN_HBLANK, 1163 max_blank, 1, MT9M114_DEF_HBLANK); 1164 1165 max_blank = MT9M114_CAM_SENSOR_CFG_FRAME_LENGTH_LINES_MAX 1166 - format->height; 1167 __v4l2_ctrl_modify_range(sensor->pa.vblank, MT9M114_MIN_VBLANK, 1168 max_blank, 1, MT9M114_DEF_VBLANK); 1169} 1170 1171/* ----------------------------------------------------------------------------- 1172 * Pixel Array Subdev Operations 1173 */ 1174 1175static inline struct mt9m114 *pa_to_mt9m114(struct v4l2_subdev *sd) 1176{ 1177 return container_of(sd, struct mt9m114, pa.sd); 1178} 1179 1180static int mt9m114_pa_init_state(struct v4l2_subdev *sd, 1181 struct v4l2_subdev_state *state) 1182{ 1183 struct v4l2_mbus_framefmt *format; 1184 struct v4l2_rect *crop; 1185 1186 crop = v4l2_subdev_state_get_crop(state, 0); 1187 1188 crop->left = 0; 1189 crop->top = 0; 1190 crop->width = MT9M114_PIXEL_ARRAY_WIDTH; 1191 crop->height = MT9M114_PIXEL_ARRAY_HEIGHT; 1192 1193 format = v4l2_subdev_state_get_format(state, 0); 1194 1195 format->width = MT9M114_PIXEL_ARRAY_WIDTH; 1196 format->height = MT9M114_PIXEL_ARRAY_HEIGHT; 1197 format->code = MEDIA_BUS_FMT_SGRBG10_1X10; 1198 format->field = V4L2_FIELD_NONE; 1199 format->colorspace = V4L2_COLORSPACE_RAW; 1200 format->ycbcr_enc = V4L2_YCBCR_ENC_601; 1201 format->quantization = V4L2_QUANTIZATION_FULL_RANGE; 1202 format->xfer_func = V4L2_XFER_FUNC_NONE; 1203 1204 return 0; 1205} 1206 1207static int mt9m114_pa_enum_mbus_code(struct v4l2_subdev *sd, 1208 struct v4l2_subdev_state *state, 1209 struct v4l2_subdev_mbus_code_enum *code) 1210{ 1211 if (code->index > 0) 1212 return -EINVAL; 1213 1214 code->code = MEDIA_BUS_FMT_SGRBG10_1X10; 1215 1216 return 0; 1217} 1218 1219static int mt9m114_pa_enum_framesizes(struct v4l2_subdev *sd, 1220 struct v4l2_subdev_state *state, 1221 struct v4l2_subdev_frame_size_enum *fse) 1222{ 1223 if (fse->index > 1) 1224 return -EINVAL; 1225 1226 if (fse->code != MEDIA_BUS_FMT_SGRBG10_1X10) 1227 return -EINVAL; 1228 1229 /* Report binning capability through frame size enumeration. */ 1230 fse->min_width = MT9M114_PIXEL_ARRAY_WIDTH / (fse->index + 1); 1231 fse->max_width = MT9M114_PIXEL_ARRAY_WIDTH / (fse->index + 1); 1232 fse->min_height = MT9M114_PIXEL_ARRAY_HEIGHT / (fse->index + 1); 1233 fse->max_height = MT9M114_PIXEL_ARRAY_HEIGHT / (fse->index + 1); 1234 1235 return 0; 1236} 1237 1238static int mt9m114_pa_set_fmt(struct v4l2_subdev *sd, 1239 struct v4l2_subdev_state *state, 1240 struct v4l2_subdev_format *fmt) 1241{ 1242 struct mt9m114 *sensor = pa_to_mt9m114(sd); 1243 struct v4l2_mbus_framefmt *format; 1244 struct v4l2_rect *crop; 1245 unsigned int hscale; 1246 unsigned int vscale; 1247 1248 crop = v4l2_subdev_state_get_crop(state, fmt->pad); 1249 format = v4l2_subdev_state_get_format(state, fmt->pad); 1250 1251 /* The sensor can bin horizontally and vertically. */ 1252 hscale = DIV_ROUND_CLOSEST(crop->width, fmt->format.width ? : 1); 1253 vscale = DIV_ROUND_CLOSEST(crop->height, fmt->format.height ? : 1); 1254 format->width = crop->width / clamp(hscale, 1U, 2U); 1255 format->height = crop->height / clamp(vscale, 1U, 2U); 1256 1257 fmt->format = *format; 1258 1259 if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) 1260 mt9m114_pa_ctrl_update_blanking(sensor, format); 1261 1262 return 0; 1263} 1264 1265static int mt9m114_pa_get_selection(struct v4l2_subdev *sd, 1266 struct v4l2_subdev_state *state, 1267 struct v4l2_subdev_selection *sel) 1268{ 1269 switch (sel->target) { 1270 case V4L2_SEL_TGT_CROP: 1271 sel->r = *v4l2_subdev_state_get_crop(state, sel->pad); 1272 return 0; 1273 1274 case V4L2_SEL_TGT_CROP_DEFAULT: 1275 case V4L2_SEL_TGT_CROP_BOUNDS: 1276 case V4L2_SEL_TGT_NATIVE_SIZE: 1277 sel->r.left = 0; 1278 sel->r.top = 0; 1279 sel->r.width = MT9M114_PIXEL_ARRAY_WIDTH; 1280 sel->r.height = MT9M114_PIXEL_ARRAY_HEIGHT; 1281 return 0; 1282 1283 default: 1284 return -EINVAL; 1285 } 1286} 1287 1288static int mt9m114_pa_set_selection(struct v4l2_subdev *sd, 1289 struct v4l2_subdev_state *state, 1290 struct v4l2_subdev_selection *sel) 1291{ 1292 struct mt9m114 *sensor = pa_to_mt9m114(sd); 1293 struct v4l2_mbus_framefmt *format; 1294 struct v4l2_rect *crop; 1295 int ret = 0; 1296 1297 if (sel->target != V4L2_SEL_TGT_CROP) 1298 return -EINVAL; 1299 1300 crop = v4l2_subdev_state_get_crop(state, sel->pad); 1301 format = v4l2_subdev_state_get_format(state, sel->pad); 1302 1303 /* 1304 * Clamp the crop rectangle. The vertical coordinates must be even, and 1305 * the horizontal coordinates must be a multiple of 4. 1306 * 1307 * FIXME: The horizontal coordinates must be a multiple of 8 when 1308 * binning, but binning is configured after setting the selection, so 1309 * we can't know tell here if it will be used. 1310 */ 1311 sel->r.left = ALIGN(sel->r.left, 4); 1312 sel->r.top = ALIGN(sel->r.top, 2); 1313 sel->r.width = clamp_t(unsigned int, ALIGN(sel->r.width, 4), 1314 MT9M114_PIXEL_ARRAY_MIN_OUTPUT_WIDTH, 1315 MT9M114_PIXEL_ARRAY_WIDTH - sel->r.left); 1316 sel->r.height = clamp_t(unsigned int, ALIGN(sel->r.height, 2), 1317 MT9M114_PIXEL_ARRAY_MIN_OUTPUT_HEIGHT, 1318 MT9M114_PIXEL_ARRAY_HEIGHT - sel->r.top); 1319 1320 /* Changing the selection size is not allowed in streaming state. */ 1321 if (sensor->streaming && 1322 (sel->r.height != crop->height || sel->r.width != crop->width)) 1323 return -EBUSY; 1324 1325 *crop = sel->r; 1326 1327 /* Reset the format. */ 1328 format->width = crop->width; 1329 format->height = crop->height; 1330 1331 if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE) 1332 return ret; 1333 1334 mt9m114_pa_ctrl_update_blanking(sensor, format); 1335 1336 /* Apply values immediately if streaming. */ 1337 if (sensor->streaming) { 1338 ret = mt9m114_configure_pa(sensor, state); 1339 if (ret) 1340 return ret; 1341 /* Changing the cropping config requires a CONFIG_CHANGE. */ 1342 ret = mt9m114_set_state(sensor, 1343 MT9M114_SYS_STATE_ENTER_CONFIG_CHANGE); 1344 } 1345 return ret; 1346} 1347 1348static const struct v4l2_subdev_pad_ops mt9m114_pa_pad_ops = { 1349 .enum_mbus_code = mt9m114_pa_enum_mbus_code, 1350 .enum_frame_size = mt9m114_pa_enum_framesizes, 1351 .get_fmt = v4l2_subdev_get_fmt, 1352 .set_fmt = mt9m114_pa_set_fmt, 1353 .get_selection = mt9m114_pa_get_selection, 1354 .set_selection = mt9m114_pa_set_selection, 1355}; 1356 1357static const struct v4l2_subdev_ops mt9m114_pa_ops = { 1358 .pad = &mt9m114_pa_pad_ops, 1359}; 1360 1361static const struct v4l2_subdev_internal_ops mt9m114_pa_internal_ops = { 1362 .init_state = mt9m114_pa_init_state, 1363}; 1364 1365static int mt9m114_pa_init(struct mt9m114 *sensor) 1366{ 1367 struct v4l2_ctrl_handler *hdl = &sensor->pa.hdl; 1368 struct v4l2_subdev *sd = &sensor->pa.sd; 1369 struct media_pad *pads = &sensor->pa.pad; 1370 const struct v4l2_mbus_framefmt *format; 1371 struct v4l2_subdev_state *state; 1372 unsigned int max_exposure; 1373 int ret; 1374 1375 /* Initialize the subdev. */ 1376 v4l2_subdev_init(sd, &mt9m114_pa_ops); 1377 sd->internal_ops = &mt9m114_pa_internal_ops; 1378 v4l2_i2c_subdev_set_name(sd, sensor->client, NULL, " pixel array"); 1379 1380 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; 1381 sd->owner = THIS_MODULE; 1382 sd->dev = &sensor->client->dev; 1383 v4l2_set_subdevdata(sd, sensor->client); 1384 1385 /* Initialize the media entity. */ 1386 sd->entity.function = MEDIA_ENT_F_CAM_SENSOR; 1387 sd->entity.ops = &mt9m114_entity_ops; 1388 pads[0].flags = MEDIA_PAD_FL_SOURCE; 1389 ret = media_entity_pads_init(&sd->entity, 1, pads); 1390 if (ret < 0) 1391 return ret; 1392 1393 /* Initialize the control handler. */ 1394 v4l2_ctrl_handler_init(hdl, 7); 1395 1396 /* The range of the HBLANK and VBLANK controls will be updated below. */ 1397 sensor->pa.hblank = v4l2_ctrl_new_std(hdl, &mt9m114_pa_ctrl_ops, 1398 V4L2_CID_HBLANK, 1399 MT9M114_DEF_HBLANK, 1400 MT9M114_DEF_HBLANK, 1, 1401 MT9M114_DEF_HBLANK); 1402 sensor->pa.vblank = v4l2_ctrl_new_std(hdl, &mt9m114_pa_ctrl_ops, 1403 V4L2_CID_VBLANK, 1404 MT9M114_DEF_VBLANK, 1405 MT9M114_DEF_VBLANK, 1, 1406 MT9M114_DEF_VBLANK); 1407 1408 /* 1409 * The maximum coarse integration time is the frame length in lines 1410 * minus two. The default is taken directly from the datasheet, but 1411 * makes little sense as auto-exposure is enabled by default. 1412 */ 1413 max_exposure = MT9M114_PIXEL_ARRAY_HEIGHT + MT9M114_MIN_VBLANK - 2; 1414 sensor->pa.exposure = v4l2_ctrl_new_std(hdl, &mt9m114_pa_ctrl_ops, 1415 V4L2_CID_EXPOSURE, 1, 1416 max_exposure, 1, 16); 1417 if (sensor->pa.exposure) 1418 sensor->pa.exposure->flags |= V4L2_CTRL_FLAG_VOLATILE; 1419 1420 sensor->pa.gain = v4l2_ctrl_new_std(hdl, &mt9m114_pa_ctrl_ops, 1421 V4L2_CID_ANALOGUE_GAIN, 1, 1422 511, 1, 32); 1423 if (sensor->pa.gain) 1424 sensor->pa.gain->flags |= V4L2_CTRL_FLAG_VOLATILE; 1425 1426 v4l2_ctrl_new_std(hdl, &mt9m114_pa_ctrl_ops, 1427 V4L2_CID_PIXEL_RATE, 1428 sensor->pixrate, sensor->pixrate, 1, 1429 sensor->pixrate); 1430 1431 v4l2_ctrl_new_std(hdl, &mt9m114_pa_ctrl_ops, 1432 V4L2_CID_HFLIP, 1433 0, 1, 1, 0); 1434 v4l2_ctrl_new_std(hdl, &mt9m114_pa_ctrl_ops, 1435 V4L2_CID_VFLIP, 1436 0, 1, 1, 0); 1437 1438 if (hdl->error) { 1439 ret = hdl->error; 1440 goto error; 1441 } 1442 1443 sd->state_lock = hdl->lock; 1444 1445 ret = v4l2_subdev_init_finalize(sd); 1446 if (ret) 1447 goto error; 1448 1449 /* Update the range of the blanking controls based on the format. */ 1450 state = v4l2_subdev_lock_and_get_active_state(sd); 1451 format = v4l2_subdev_state_get_format(state, 0); 1452 mt9m114_pa_ctrl_update_blanking(sensor, format); 1453 v4l2_subdev_unlock_state(state); 1454 1455 sd->ctrl_handler = hdl; 1456 1457 return 0; 1458 1459error: 1460 v4l2_ctrl_handler_free(&sensor->pa.hdl); 1461 media_entity_cleanup(&sensor->pa.sd.entity); 1462 return ret; 1463} 1464 1465static void mt9m114_pa_cleanup(struct mt9m114 *sensor) 1466{ 1467 v4l2_ctrl_handler_free(&sensor->pa.hdl); 1468 media_entity_cleanup(&sensor->pa.sd.entity); 1469} 1470 1471/* ----------------------------------------------------------------------------- 1472 * Image Flow Processor Control Operations 1473 */ 1474 1475static const char * const mt9m114_test_pattern_menu[] = { 1476 "Disabled", 1477 "Solid Color", 1478 "100% Color Bars", 1479 "Pseudo-Random", 1480 "Fade-to-Gray Color Bars", 1481 "Walking Ones 10-bit", 1482 "Walking Ones 8-bit", 1483}; 1484 1485/* Keep in sync with mt9m114_test_pattern_menu */ 1486static const unsigned int mt9m114_test_pattern_value[] = { 1487 MT9M114_CAM_MODE_TEST_PATTERN_SELECT_SOLID, 1488 MT9M114_CAM_MODE_TEST_PATTERN_SELECT_SOLID_BARS, 1489 MT9M114_CAM_MODE_TEST_PATTERN_SELECT_RANDOM, 1490 MT9M114_CAM_MODE_TEST_PATTERN_SELECT_FADING_BARS, 1491 MT9M114_CAM_MODE_TEST_PATTERN_SELECT_WALKING_1S_10B, 1492 MT9M114_CAM_MODE_TEST_PATTERN_SELECT_WALKING_1S_8B, 1493}; 1494 1495static inline struct mt9m114 *ifp_ctrl_to_mt9m114(struct v4l2_ctrl *ctrl) 1496{ 1497 return container_of(ctrl->handler, struct mt9m114, ifp.hdl); 1498} 1499 1500static int mt9m114_ifp_s_ctrl(struct v4l2_ctrl *ctrl) 1501{ 1502 struct mt9m114 *sensor = ifp_ctrl_to_mt9m114(ctrl); 1503 u32 value; 1504 int ret = 0; 1505 1506 if (ctrl->id == V4L2_CID_EXPOSURE_AUTO) 1507 mt9m114_pa_ctrl_update_exposure(sensor, 1508 ctrl->val != V4L2_EXPOSURE_AUTO); 1509 1510 /* V4L2 controls values are applied only when power is up. */ 1511 if (!pm_runtime_get_if_in_use(&sensor->client->dev)) 1512 return 0; 1513 1514 switch (ctrl->id) { 1515 case V4L2_CID_AUTO_WHITE_BALANCE: 1516 /* Control both the AWB mode and the CCM algorithm. */ 1517 if (ctrl->val) 1518 value = MT9M114_CAM_AWB_MODE_AUTO 1519 | MT9M114_CAM_AWB_MODE_EXCLUSIVE_AE; 1520 else 1521 value = 0; 1522 1523 cci_write(sensor->regmap, MT9M114_CAM_AWB_AWBMODE, value, &ret); 1524 1525 if (ctrl->val) 1526 value = MT9M114_CCM_EXEC_CALC_CCM_MATRIX | 0x22; 1527 else 1528 value = 0; 1529 1530 cci_write(sensor->regmap, MT9M114_CCM_ALGO, value, &ret); 1531 break; 1532 1533 case V4L2_CID_EXPOSURE_AUTO: 1534 if (ctrl->val == V4L2_EXPOSURE_AUTO) 1535 value = MT9M114_AE_TRACK_EXEC_AUTOMATIC_EXPOSURE 1536 | 0x00fe; 1537 else 1538 value = 0; 1539 1540 cci_write(sensor->regmap, MT9M114_AE_TRACK_ALGO, value, &ret); 1541 if (ret) 1542 break; 1543 1544 break; 1545 1546 case V4L2_CID_TEST_PATTERN: 1547 case V4L2_CID_TEST_PATTERN_RED: 1548 case V4L2_CID_TEST_PATTERN_GREENR: 1549 case V4L2_CID_TEST_PATTERN_BLUE: { 1550 unsigned int pattern = sensor->ifp.tpg[MT9M114_TPG_PATTERN]->val; 1551 1552 if (pattern) { 1553 cci_write(sensor->regmap, MT9M114_CAM_MODE_SELECT, 1554 MT9M114_CAM_MODE_SELECT_TEST_PATTERN, &ret); 1555 cci_write(sensor->regmap, 1556 MT9M114_CAM_MODE_TEST_PATTERN_SELECT, 1557 mt9m114_test_pattern_value[pattern - 1], &ret); 1558 cci_write(sensor->regmap, 1559 MT9M114_CAM_MODE_TEST_PATTERN_RED, 1560 sensor->ifp.tpg[MT9M114_TPG_RED]->val, &ret); 1561 cci_write(sensor->regmap, 1562 MT9M114_CAM_MODE_TEST_PATTERN_GREEN, 1563 sensor->ifp.tpg[MT9M114_TPG_GREEN]->val, &ret); 1564 cci_write(sensor->regmap, 1565 MT9M114_CAM_MODE_TEST_PATTERN_BLUE, 1566 sensor->ifp.tpg[MT9M114_TPG_BLUE]->val, &ret); 1567 } else { 1568 cci_write(sensor->regmap, MT9M114_CAM_MODE_SELECT, 1569 MT9M114_CAM_MODE_SELECT_NORMAL, &ret); 1570 } 1571 1572 /* 1573 * A Config-Change needs to be issued for the change to take 1574 * effect. If we're not streaming ignore this, the change will 1575 * be applied when the stream is started. 1576 */ 1577 if (ret || !sensor->streaming) 1578 break; 1579 1580 ret = mt9m114_set_state(sensor, 1581 MT9M114_SYS_STATE_ENTER_CONFIG_CHANGE); 1582 break; 1583 } 1584 1585 default: 1586 ret = -EINVAL; 1587 break; 1588 } 1589 1590 pm_runtime_put_autosuspend(&sensor->client->dev); 1591 1592 return ret; 1593} 1594 1595static const struct v4l2_ctrl_ops mt9m114_ifp_ctrl_ops = { 1596 .s_ctrl = mt9m114_ifp_s_ctrl, 1597}; 1598 1599/* ----------------------------------------------------------------------------- 1600 * Image Flow Processor Subdev Operations 1601 */ 1602 1603static inline struct mt9m114 *ifp_to_mt9m114(struct v4l2_subdev *sd) 1604{ 1605 return container_of(sd, struct mt9m114, ifp.sd); 1606} 1607 1608static int mt9m114_ifp_s_stream(struct v4l2_subdev *sd, int enable) 1609{ 1610 struct mt9m114 *sensor = ifp_to_mt9m114(sd); 1611 struct v4l2_subdev_state *pa_state; 1612 struct v4l2_subdev_state *ifp_state; 1613 int ret; 1614 1615 if (!enable) 1616 return mt9m114_stop_streaming(sensor); 1617 1618 ifp_state = v4l2_subdev_lock_and_get_active_state(&sensor->ifp.sd); 1619 pa_state = v4l2_subdev_lock_and_get_active_state(&sensor->pa.sd); 1620 1621 ret = mt9m114_start_streaming(sensor, pa_state, ifp_state); 1622 1623 v4l2_subdev_unlock_state(pa_state); 1624 v4l2_subdev_unlock_state(ifp_state); 1625 1626 return ret; 1627} 1628 1629static int mt9m114_ifp_get_frame_interval(struct v4l2_subdev *sd, 1630 struct v4l2_subdev_state *sd_state, 1631 struct v4l2_subdev_frame_interval *interval) 1632{ 1633 struct v4l2_fract *ival = &interval->interval; 1634 struct mt9m114 *sensor = ifp_to_mt9m114(sd); 1635 1636 /* 1637 * FIXME: Implement support for V4L2_SUBDEV_FORMAT_TRY, using the V4L2 1638 * subdev active state API. 1639 */ 1640 if (interval->which != V4L2_SUBDEV_FORMAT_ACTIVE) 1641 return -EINVAL; 1642 1643 ival->numerator = 1; 1644 ival->denominator = sensor->ifp.frame_rate; 1645 1646 return 0; 1647} 1648 1649static int mt9m114_ifp_set_frame_interval(struct v4l2_subdev *sd, 1650 struct v4l2_subdev_state *sd_state, 1651 struct v4l2_subdev_frame_interval *interval) 1652{ 1653 struct v4l2_fract *ival = &interval->interval; 1654 struct mt9m114 *sensor = ifp_to_mt9m114(sd); 1655 int ret = 0; 1656 1657 /* 1658 * FIXME: Implement support for V4L2_SUBDEV_FORMAT_TRY, using the V4L2 1659 * subdev active state API. 1660 */ 1661 if (interval->which != V4L2_SUBDEV_FORMAT_ACTIVE) 1662 return -EINVAL; 1663 1664 if (ival->numerator != 0 && ival->denominator != 0) 1665 sensor->ifp.frame_rate = min_t(unsigned int, 1666 ival->denominator / ival->numerator, 1667 MT9M114_MAX_FRAME_RATE); 1668 else 1669 sensor->ifp.frame_rate = MT9M114_MAX_FRAME_RATE; 1670 1671 ival->numerator = 1; 1672 ival->denominator = sensor->ifp.frame_rate; 1673 1674 if (sensor->streaming) 1675 ret = mt9m114_set_frame_rate(sensor); 1676 1677 return ret; 1678} 1679 1680static int mt9m114_ifp_init_state(struct v4l2_subdev *sd, 1681 struct v4l2_subdev_state *state) 1682{ 1683 struct mt9m114 *sensor = ifp_to_mt9m114(sd); 1684 struct v4l2_mbus_framefmt *format; 1685 struct v4l2_rect *crop; 1686 struct v4l2_rect *compose; 1687 1688 format = v4l2_subdev_state_get_format(state, 0); 1689 1690 format->width = MT9M114_PIXEL_ARRAY_WIDTH; 1691 format->height = MT9M114_PIXEL_ARRAY_HEIGHT; 1692 format->code = MEDIA_BUS_FMT_SGRBG10_1X10; 1693 format->field = V4L2_FIELD_NONE; 1694 format->colorspace = V4L2_COLORSPACE_RAW; 1695 format->ycbcr_enc = V4L2_YCBCR_ENC_601; 1696 format->quantization = V4L2_QUANTIZATION_FULL_RANGE; 1697 format->xfer_func = V4L2_XFER_FUNC_NONE; 1698 1699 crop = v4l2_subdev_state_get_crop(state, 0); 1700 1701 crop->left = 4; 1702 crop->top = 4; 1703 crop->width = format->width - 8; 1704 crop->height = format->height - 8; 1705 1706 compose = v4l2_subdev_state_get_compose(state, 0); 1707 1708 compose->left = 0; 1709 compose->top = 0; 1710 compose->width = crop->width; 1711 compose->height = crop->height; 1712 1713 format = v4l2_subdev_state_get_format(state, 1); 1714 1715 format->width = compose->width; 1716 format->height = compose->height; 1717 format->code = mt9m114_default_format_info(sensor)->code; 1718 format->field = V4L2_FIELD_NONE; 1719 format->colorspace = V4L2_COLORSPACE_SRGB; 1720 format->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT; 1721 format->quantization = V4L2_QUANTIZATION_DEFAULT; 1722 format->xfer_func = V4L2_XFER_FUNC_DEFAULT; 1723 1724 return 0; 1725} 1726 1727static int mt9m114_ifp_enum_mbus_code(struct v4l2_subdev *sd, 1728 struct v4l2_subdev_state *state, 1729 struct v4l2_subdev_mbus_code_enum *code) 1730{ 1731 const unsigned int num_formats = ARRAY_SIZE(mt9m114_format_infos); 1732 struct mt9m114 *sensor = ifp_to_mt9m114(sd); 1733 unsigned int index = 0; 1734 unsigned int flag; 1735 unsigned int i; 1736 1737 switch (code->pad) { 1738 case 0: 1739 if (code->index != 0) 1740 return -EINVAL; 1741 1742 code->code = mt9m114_format_infos[num_formats - 1].code; 1743 return 0; 1744 1745 case 1: 1746 if (sensor->bus_cfg.bus_type == V4L2_MBUS_CSI2_DPHY) 1747 flag = MT9M114_FMT_FLAG_CSI2; 1748 else 1749 flag = MT9M114_FMT_FLAG_PARALLEL; 1750 1751 for (i = 0; i < num_formats; ++i) { 1752 const struct mt9m114_format_info *info = 1753 &mt9m114_format_infos[i]; 1754 1755 if (info->flags & flag) { 1756 if (index == code->index) { 1757 code->code = info->code; 1758 return 0; 1759 } 1760 1761 index++; 1762 } 1763 } 1764 1765 return -EINVAL; 1766 1767 default: 1768 return -EINVAL; 1769 } 1770} 1771 1772static int mt9m114_ifp_enum_framesizes(struct v4l2_subdev *sd, 1773 struct v4l2_subdev_state *state, 1774 struct v4l2_subdev_frame_size_enum *fse) 1775{ 1776 struct mt9m114 *sensor = ifp_to_mt9m114(sd); 1777 const struct mt9m114_format_info *info; 1778 1779 if (fse->index > 0) 1780 return -EINVAL; 1781 1782 info = mt9m114_format_info(sensor, fse->pad, fse->code); 1783 if (!info || info->code != fse->code) 1784 return -EINVAL; 1785 1786 if (fse->pad == 0) { 1787 fse->min_width = MT9M114_PIXEL_ARRAY_MIN_OUTPUT_WIDTH; 1788 fse->max_width = MT9M114_PIXEL_ARRAY_WIDTH; 1789 fse->min_height = MT9M114_PIXEL_ARRAY_MIN_OUTPUT_HEIGHT; 1790 fse->max_height = MT9M114_PIXEL_ARRAY_HEIGHT; 1791 } else { 1792 const struct v4l2_rect *crop; 1793 1794 crop = v4l2_subdev_state_get_crop(state, 0); 1795 1796 fse->max_width = crop->width; 1797 fse->max_height = crop->height; 1798 1799 fse->min_width = fse->max_width / 4; 1800 fse->min_height = fse->max_height / 4; 1801 } 1802 1803 return 0; 1804} 1805 1806static int mt9m114_ifp_enum_frameintervals(struct v4l2_subdev *sd, 1807 struct v4l2_subdev_state *state, 1808 struct v4l2_subdev_frame_interval_enum *fie) 1809{ 1810 struct mt9m114 *sensor = ifp_to_mt9m114(sd); 1811 const struct mt9m114_format_info *info; 1812 1813 if (fie->index > 0) 1814 return -EINVAL; 1815 1816 info = mt9m114_format_info(sensor, fie->pad, fie->code); 1817 if (!info || info->code != fie->code) 1818 return -EINVAL; 1819 1820 fie->interval.numerator = 1; 1821 fie->interval.denominator = MT9M114_MAX_FRAME_RATE; 1822 1823 return 0; 1824} 1825 1826static int mt9m114_ifp_set_fmt(struct v4l2_subdev *sd, 1827 struct v4l2_subdev_state *state, 1828 struct v4l2_subdev_format *fmt) 1829{ 1830 struct mt9m114 *sensor = ifp_to_mt9m114(sd); 1831 struct v4l2_mbus_framefmt *format; 1832 1833 format = v4l2_subdev_state_get_format(state, fmt->pad); 1834 1835 if (fmt->pad == 0) { 1836 /* Only the size can be changed on the sink pad. */ 1837 format->width = clamp(ALIGN(fmt->format.width, 8), 1838 MT9M114_PIXEL_ARRAY_MIN_OUTPUT_WIDTH, 1839 MT9M114_PIXEL_ARRAY_WIDTH); 1840 format->height = clamp(ALIGN(fmt->format.height, 8), 1841 MT9M114_PIXEL_ARRAY_MIN_OUTPUT_HEIGHT, 1842 MT9M114_PIXEL_ARRAY_HEIGHT); 1843 } else { 1844 const struct mt9m114_format_info *info; 1845 1846 /* Only the media bus code can be changed on the source pad. */ 1847 info = mt9m114_format_info(sensor, 1, fmt->format.code); 1848 1849 format->code = info->code; 1850 1851 /* If the output format is RAW10, bypass the scaler. */ 1852 if (format->code == MEDIA_BUS_FMT_SGRBG10_1X10) 1853 *format = *v4l2_subdev_state_get_format(state, 0); 1854 } 1855 1856 fmt->format = *format; 1857 1858 return 0; 1859} 1860 1861static int mt9m114_ifp_get_selection(struct v4l2_subdev *sd, 1862 struct v4l2_subdev_state *state, 1863 struct v4l2_subdev_selection *sel) 1864{ 1865 const struct v4l2_mbus_framefmt *format; 1866 const struct v4l2_rect *crop; 1867 int ret = 0; 1868 1869 /* Crop and compose are only supported on the sink pad. */ 1870 if (sel->pad != 0) 1871 return -EINVAL; 1872 1873 switch (sel->target) { 1874 case V4L2_SEL_TGT_CROP: 1875 sel->r = *v4l2_subdev_state_get_crop(state, 0); 1876 break; 1877 1878 case V4L2_SEL_TGT_CROP_DEFAULT: 1879 case V4L2_SEL_TGT_CROP_BOUNDS: 1880 /* 1881 * The crop default and bounds are equal to the sink 1882 * format size minus 4 pixels on each side for demosaicing. 1883 */ 1884 format = v4l2_subdev_state_get_format(state, 0); 1885 1886 sel->r.left = 4; 1887 sel->r.top = 4; 1888 sel->r.width = format->width - 8; 1889 sel->r.height = format->height - 8; 1890 break; 1891 1892 case V4L2_SEL_TGT_COMPOSE: 1893 sel->r = *v4l2_subdev_state_get_compose(state, 0); 1894 break; 1895 1896 case V4L2_SEL_TGT_COMPOSE_DEFAULT: 1897 case V4L2_SEL_TGT_COMPOSE_BOUNDS: 1898 /* 1899 * The compose default and bounds sizes are equal to the sink 1900 * crop rectangle size. 1901 */ 1902 crop = v4l2_subdev_state_get_crop(state, 0); 1903 sel->r.left = 0; 1904 sel->r.top = 0; 1905 sel->r.width = crop->width; 1906 sel->r.height = crop->height; 1907 break; 1908 1909 default: 1910 ret = -EINVAL; 1911 break; 1912 } 1913 1914 return ret; 1915} 1916 1917static int mt9m114_ifp_set_selection(struct v4l2_subdev *sd, 1918 struct v4l2_subdev_state *state, 1919 struct v4l2_subdev_selection *sel) 1920{ 1921 struct v4l2_mbus_framefmt *format; 1922 struct v4l2_rect *crop; 1923 struct v4l2_rect *compose; 1924 1925 if (sel->target != V4L2_SEL_TGT_CROP && 1926 sel->target != V4L2_SEL_TGT_COMPOSE) 1927 return -EINVAL; 1928 1929 /* Crop and compose are only supported on the sink pad. */ 1930 if (sel->pad != 0) 1931 return -EINVAL; 1932 1933 format = v4l2_subdev_state_get_format(state, 0); 1934 crop = v4l2_subdev_state_get_crop(state, 0); 1935 compose = v4l2_subdev_state_get_compose(state, 0); 1936 1937 if (sel->target == V4L2_SEL_TGT_CROP) { 1938 /* 1939 * Clamp the crop rectangle. Demosaicing removes 4 pixels on 1940 * each side of the image. 1941 */ 1942 crop->left = clamp_t(unsigned int, ALIGN(sel->r.left, 2), 4, 1943 format->width - 4 - 1944 MT9M114_SCALER_CROPPED_INPUT_WIDTH); 1945 crop->top = clamp_t(unsigned int, ALIGN(sel->r.top, 2), 4, 1946 format->height - 4 - 1947 MT9M114_SCALER_CROPPED_INPUT_HEIGHT); 1948 crop->width = clamp_t(unsigned int, ALIGN(sel->r.width, 2), 1949 MT9M114_SCALER_CROPPED_INPUT_WIDTH, 1950 format->width - 4 - crop->left); 1951 crop->height = clamp_t(unsigned int, ALIGN(sel->r.height, 2), 1952 MT9M114_SCALER_CROPPED_INPUT_HEIGHT, 1953 format->height - 4 - crop->top); 1954 1955 sel->r = *crop; 1956 1957 /* Propagate to the compose rectangle. */ 1958 compose->width = crop->width; 1959 compose->height = crop->height; 1960 } else { 1961 /* 1962 * Clamp the compose rectangle. The scaler can only downscale. 1963 */ 1964 compose->left = 0; 1965 compose->top = 0; 1966 compose->width = clamp_t(unsigned int, ALIGN(sel->r.width, 2), 1967 MT9M114_SCALER_CROPPED_INPUT_WIDTH, 1968 crop->width); 1969 compose->height = clamp_t(unsigned int, ALIGN(sel->r.height, 2), 1970 MT9M114_SCALER_CROPPED_INPUT_HEIGHT, 1971 crop->height); 1972 1973 sel->r = *compose; 1974 } 1975 1976 /* Propagate the compose rectangle to the source format. */ 1977 format = v4l2_subdev_state_get_format(state, 1); 1978 format->width = compose->width; 1979 format->height = compose->height; 1980 1981 return 0; 1982} 1983 1984static void mt9m114_ifp_unregistered(struct v4l2_subdev *sd) 1985{ 1986 struct mt9m114 *sensor = ifp_to_mt9m114(sd); 1987 1988 v4l2_device_unregister_subdev(&sensor->pa.sd); 1989} 1990 1991static int mt9m114_ifp_registered(struct v4l2_subdev *sd) 1992{ 1993 struct mt9m114 *sensor = ifp_to_mt9m114(sd); 1994 int ret; 1995 1996 ret = v4l2_device_register_subdev(sd->v4l2_dev, &sensor->pa.sd); 1997 if (ret < 0) { 1998 dev_err(&sensor->client->dev, 1999 "Failed to register pixel array subdev\n"); 2000 return ret; 2001 } 2002 2003 ret = media_create_pad_link(&sensor->pa.sd.entity, 0, 2004 &sensor->ifp.sd.entity, 0, 2005 MEDIA_LNK_FL_ENABLED | 2006 MEDIA_LNK_FL_IMMUTABLE); 2007 if (ret < 0) { 2008 dev_err(&sensor->client->dev, 2009 "Failed to link pixel array to ifp\n"); 2010 v4l2_device_unregister_subdev(&sensor->pa.sd); 2011 return ret; 2012 } 2013 2014 return 0; 2015} 2016 2017static const struct v4l2_subdev_video_ops mt9m114_ifp_video_ops = { 2018 .s_stream = mt9m114_ifp_s_stream, 2019}; 2020 2021static const struct v4l2_subdev_pad_ops mt9m114_ifp_pad_ops = { 2022 .enum_mbus_code = mt9m114_ifp_enum_mbus_code, 2023 .enum_frame_size = mt9m114_ifp_enum_framesizes, 2024 .enum_frame_interval = mt9m114_ifp_enum_frameintervals, 2025 .get_fmt = v4l2_subdev_get_fmt, 2026 .set_fmt = mt9m114_ifp_set_fmt, 2027 .get_selection = mt9m114_ifp_get_selection, 2028 .set_selection = mt9m114_ifp_set_selection, 2029 .get_frame_interval = mt9m114_ifp_get_frame_interval, 2030 .set_frame_interval = mt9m114_ifp_set_frame_interval, 2031}; 2032 2033static const struct v4l2_subdev_ops mt9m114_ifp_ops = { 2034 .video = &mt9m114_ifp_video_ops, 2035 .pad = &mt9m114_ifp_pad_ops, 2036}; 2037 2038static const struct v4l2_subdev_internal_ops mt9m114_ifp_internal_ops = { 2039 .init_state = mt9m114_ifp_init_state, 2040 .registered = mt9m114_ifp_registered, 2041 .unregistered = mt9m114_ifp_unregistered, 2042}; 2043 2044static int mt9m114_ifp_init(struct mt9m114 *sensor) 2045{ 2046 struct v4l2_subdev *sd = &sensor->ifp.sd; 2047 struct media_pad *pads = sensor->ifp.pads; 2048 struct v4l2_ctrl_handler *hdl = &sensor->ifp.hdl; 2049 struct v4l2_ctrl *link_freq; 2050 int ret; 2051 2052 /* Initialize the subdev. */ 2053 v4l2_i2c_subdev_init(sd, sensor->client, &mt9m114_ifp_ops); 2054 v4l2_i2c_subdev_set_name(sd, sensor->client, NULL, " ifp"); 2055 2056 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; 2057 sd->internal_ops = &mt9m114_ifp_internal_ops; 2058 2059 /* Initialize the media entity. */ 2060 sd->entity.function = MEDIA_ENT_F_PROC_VIDEO_ISP; 2061 sd->entity.ops = &mt9m114_entity_ops; 2062 pads[0].flags = MEDIA_PAD_FL_SINK; 2063 pads[1].flags = MEDIA_PAD_FL_SOURCE; 2064 ret = media_entity_pads_init(&sd->entity, 2, pads); 2065 if (ret < 0) 2066 return ret; 2067 2068 sensor->ifp.frame_rate = MT9M114_DEF_FRAME_RATE; 2069 2070 /* Initialize the control handler. */ 2071 v4l2_ctrl_handler_init(hdl, 8); 2072 v4l2_ctrl_new_std(hdl, &mt9m114_ifp_ctrl_ops, 2073 V4L2_CID_AUTO_WHITE_BALANCE, 2074 0, 1, 1, 1); 2075 v4l2_ctrl_new_std_menu(hdl, &mt9m114_ifp_ctrl_ops, 2076 V4L2_CID_EXPOSURE_AUTO, 2077 V4L2_EXPOSURE_MANUAL, 0, 2078 V4L2_EXPOSURE_AUTO); 2079 2080 link_freq = v4l2_ctrl_new_int_menu(hdl, &mt9m114_ifp_ctrl_ops, 2081 V4L2_CID_LINK_FREQ, 2082 sensor->bus_cfg.nr_of_link_frequencies - 1, 2083 0, sensor->bus_cfg.link_frequencies); 2084 if (link_freq) 2085 link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY; 2086 2087 v4l2_ctrl_new_std(hdl, &mt9m114_ifp_ctrl_ops, 2088 V4L2_CID_PIXEL_RATE, 2089 sensor->pixrate, sensor->pixrate, 1, 2090 sensor->pixrate); 2091 2092 sensor->ifp.tpg[MT9M114_TPG_PATTERN] = 2093 v4l2_ctrl_new_std_menu_items(hdl, &mt9m114_ifp_ctrl_ops, 2094 V4L2_CID_TEST_PATTERN, 2095 ARRAY_SIZE(mt9m114_test_pattern_menu) - 1, 2096 0, 0, mt9m114_test_pattern_menu); 2097 sensor->ifp.tpg[MT9M114_TPG_RED] = 2098 v4l2_ctrl_new_std(hdl, &mt9m114_ifp_ctrl_ops, 2099 V4L2_CID_TEST_PATTERN_RED, 2100 0, 1023, 1, 1023); 2101 sensor->ifp.tpg[MT9M114_TPG_GREEN] = 2102 v4l2_ctrl_new_std(hdl, &mt9m114_ifp_ctrl_ops, 2103 V4L2_CID_TEST_PATTERN_GREENR, 2104 0, 1023, 1, 1023); 2105 sensor->ifp.tpg[MT9M114_TPG_BLUE] = 2106 v4l2_ctrl_new_std(hdl, &mt9m114_ifp_ctrl_ops, 2107 V4L2_CID_TEST_PATTERN_BLUE, 2108 0, 1023, 1, 1023); 2109 2110 v4l2_ctrl_cluster(ARRAY_SIZE(sensor->ifp.tpg), sensor->ifp.tpg); 2111 2112 if (hdl->error) { 2113 ret = hdl->error; 2114 goto error; 2115 } 2116 2117 sd->ctrl_handler = hdl; 2118 sd->state_lock = hdl->lock; 2119 2120 ret = v4l2_subdev_init_finalize(sd); 2121 if (ret) 2122 goto error; 2123 2124 return 0; 2125 2126error: 2127 v4l2_ctrl_handler_free(&sensor->ifp.hdl); 2128 media_entity_cleanup(&sensor->ifp.sd.entity); 2129 return ret; 2130} 2131 2132static void mt9m114_ifp_cleanup(struct mt9m114 *sensor) 2133{ 2134 v4l2_ctrl_handler_free(&sensor->ifp.hdl); 2135 media_entity_cleanup(&sensor->ifp.sd.entity); 2136} 2137 2138/* ----------------------------------------------------------------------------- 2139 * Power Management 2140 */ 2141 2142static int mt9m114_power_on(struct mt9m114 *sensor) 2143{ 2144 int ret; 2145 2146 /* Enable power and clocks. */ 2147 ret = regulator_bulk_enable(ARRAY_SIZE(sensor->supplies), 2148 sensor->supplies); 2149 if (ret < 0) 2150 return ret; 2151 2152 ret = clk_prepare_enable(sensor->clk); 2153 if (ret < 0) 2154 goto error_regulator; 2155 2156 /* Perform a hard reset if available, or a soft reset otherwise. */ 2157 if (sensor->reset) { 2158 long freq = clk_get_rate(sensor->clk); 2159 unsigned int duration; 2160 2161 /* 2162 * The minimum duration is 50 clock cycles, thus typically 2163 * around 2µs. Double it to be safe. 2164 */ 2165 duration = DIV_ROUND_UP(2 * 50 * 1000000, freq); 2166 2167 gpiod_set_value(sensor->reset, 1); 2168 fsleep(duration); 2169 gpiod_set_value(sensor->reset, 0); 2170 } else { 2171 /* 2172 * The power may have just been turned on, we need to wait for 2173 * the sensor to be ready to accept I2C commands. 2174 */ 2175 usleep_range(44500, 50000); 2176 2177 cci_write(sensor->regmap, MT9M114_RESET_AND_MISC_CONTROL, 2178 MT9M114_RESET_SOC, &ret); 2179 cci_write(sensor->regmap, MT9M114_RESET_AND_MISC_CONTROL, 0, 2180 &ret); 2181 2182 if (ret < 0) { 2183 dev_err(&sensor->client->dev, "Soft reset failed\n"); 2184 goto error_clock; 2185 } 2186 } 2187 2188 /* 2189 * Wait for the sensor to be ready to accept I2C commands by polling the 2190 * command register to wait for initialization to complete. 2191 */ 2192 usleep_range(44500, 50000); 2193 2194 ret = mt9m114_poll_command(sensor, MT9M114_COMMAND_REGISTER_SET_STATE); 2195 if (ret < 0) 2196 goto error_clock; 2197 2198 if (sensor->bus_cfg.bus_type == V4L2_MBUS_PARALLEL) { 2199 /* 2200 * In parallel mode (OE set to low), the sensor will enter the 2201 * streaming state after initialization. Enter the standby 2202 * manually to stop streaming. 2203 */ 2204 ret = mt9m114_set_state(sensor, 2205 MT9M114_SYS_STATE_ENTER_STANDBY); 2206 if (ret < 0) 2207 goto error_clock; 2208 } 2209 2210 /* 2211 * Before issuing any Set-State command, we must ensure that the sensor 2212 * reaches the standby mode (either initiated manually above in 2213 * parallel mode, or automatically after reset in MIPI mode). 2214 */ 2215 ret = mt9m114_poll_state(sensor, MT9M114_SYS_STATE_STANDBY); 2216 if (ret < 0) 2217 goto error_clock; 2218 2219 return 0; 2220 2221error_clock: 2222 clk_disable_unprepare(sensor->clk); 2223error_regulator: 2224 regulator_bulk_disable(ARRAY_SIZE(sensor->supplies), sensor->supplies); 2225 return ret; 2226} 2227 2228static void mt9m114_power_off(struct mt9m114 *sensor) 2229{ 2230 clk_disable_unprepare(sensor->clk); 2231 regulator_bulk_disable(ARRAY_SIZE(sensor->supplies), sensor->supplies); 2232} 2233 2234static int __maybe_unused mt9m114_runtime_resume(struct device *dev) 2235{ 2236 struct v4l2_subdev *sd = dev_get_drvdata(dev); 2237 struct mt9m114 *sensor = ifp_to_mt9m114(sd); 2238 int ret; 2239 2240 ret = mt9m114_power_on(sensor); 2241 if (ret) 2242 return ret; 2243 2244 ret = mt9m114_initialize(sensor); 2245 if (ret) { 2246 mt9m114_power_off(sensor); 2247 return ret; 2248 } 2249 2250 return 0; 2251} 2252 2253static int __maybe_unused mt9m114_runtime_suspend(struct device *dev) 2254{ 2255 struct v4l2_subdev *sd = dev_get_drvdata(dev); 2256 struct mt9m114 *sensor = ifp_to_mt9m114(sd); 2257 2258 mt9m114_power_off(sensor); 2259 2260 return 0; 2261} 2262 2263static const struct dev_pm_ops mt9m114_pm_ops = { 2264 SET_RUNTIME_PM_OPS(mt9m114_runtime_suspend, mt9m114_runtime_resume, NULL) 2265}; 2266 2267/* ----------------------------------------------------------------------------- 2268 * Probe & Remove 2269 */ 2270 2271static int mt9m114_verify_link_frequency(struct mt9m114 *sensor, 2272 unsigned int pixrate) 2273{ 2274 unsigned int link_freq = sensor->bus_cfg.bus_type == V4L2_MBUS_CSI2_DPHY 2275 ? pixrate * 8 : pixrate * 2; 2276 2277 if (sensor->bus_cfg.nr_of_link_frequencies != 1 || 2278 sensor->bus_cfg.link_frequencies[0] != link_freq) 2279 return -EINVAL; 2280 2281 return 0; 2282} 2283 2284static int mt9m114_clk_init(struct mt9m114 *sensor) 2285{ 2286 unsigned int pixrate; 2287 2288 /* Hardcode the PLL multiplier and dividers to default settings. */ 2289 sensor->pll.m = 32; 2290 sensor->pll.n = 1; 2291 sensor->pll.p = 7; 2292 2293 /* 2294 * Calculate the pixel rate and link frequency. The CSI-2 bus is clocked 2295 * for 16-bit per pixel, transmitted in DDR over a single lane. For 2296 * parallel mode, the sensor ouputs one pixel in two PIXCLK cycles. 2297 */ 2298 2299 /* 2300 * Check if EXTCLK fits the configured link frequency. Bypass the PLL 2301 * in this case. 2302 */ 2303 pixrate = clk_get_rate(sensor->clk) / 2; 2304 if (mt9m114_verify_link_frequency(sensor, pixrate) == 0) { 2305 sensor->pixrate = pixrate; 2306 sensor->bypass_pll = true; 2307 return 0; 2308 } 2309 2310 /* Check if the PLL configuration fits the configured link frequency. */ 2311 pixrate = clk_get_rate(sensor->clk) * sensor->pll.m 2312 / ((sensor->pll.n + 1) * (sensor->pll.p + 1)); 2313 if (mt9m114_verify_link_frequency(sensor, pixrate) == 0) { 2314 sensor->pixrate = pixrate; 2315 sensor->bypass_pll = false; 2316 return 0; 2317 } 2318 2319 dev_err(&sensor->client->dev, "Unsupported DT link-frequencies\n"); 2320 return -EINVAL; 2321} 2322 2323static int mt9m114_identify(struct mt9m114 *sensor) 2324{ 2325 u64 major, minor, release, customer; 2326 u64 value; 2327 int ret; 2328 2329 ret = cci_read(sensor->regmap, MT9M114_CHIP_ID, &value, NULL); 2330 if (ret) { 2331 dev_err(&sensor->client->dev, "Failed to read chip ID\n"); 2332 return -ENXIO; 2333 } 2334 2335 if (value != 0x2481) { 2336 dev_err(&sensor->client->dev, "Invalid chip ID 0x%04llx\n", 2337 value); 2338 return -ENXIO; 2339 } 2340 2341 cci_read(sensor->regmap, MT9M114_MON_MAJOR_VERSION, &major, &ret); 2342 cci_read(sensor->regmap, MT9M114_MON_MINOR_VERSION, &minor, &ret); 2343 cci_read(sensor->regmap, MT9M114_MON_RELEASE_VERSION, &release, &ret); 2344 cci_read(sensor->regmap, MT9M114_CUSTOMER_REV, &customer, &ret); 2345 if (ret) { 2346 dev_err(&sensor->client->dev, "Failed to read version\n"); 2347 return -ENXIO; 2348 } 2349 2350 dev_dbg(&sensor->client->dev, 2351 "monitor v%llu.%llu.%04llx customer rev 0x%04llx\n", 2352 major, minor, release, customer); 2353 2354 return 0; 2355} 2356 2357static int mt9m114_parse_dt(struct mt9m114 *sensor) 2358{ 2359 struct fwnode_handle *fwnode = dev_fwnode(&sensor->client->dev); 2360 struct fwnode_handle *ep; 2361 int ret; 2362 2363 /* 2364 * On ACPI systems the fwnode graph can be initialized by a bridge 2365 * driver, which may not have probed yet. Wait for this. 2366 * 2367 * TODO: Return an error once bridge driver code will have moved 2368 * to the ACPI core. 2369 */ 2370 ep = fwnode_graph_get_next_endpoint(fwnode, NULL); 2371 if (!ep) 2372 return dev_err_probe(&sensor->client->dev, -EPROBE_DEFER, 2373 "waiting for fwnode graph endpoint\n"); 2374 2375 sensor->bus_cfg.bus_type = V4L2_MBUS_UNKNOWN; 2376 ret = v4l2_fwnode_endpoint_alloc_parse(ep, &sensor->bus_cfg); 2377 fwnode_handle_put(ep); 2378 if (ret < 0) { 2379 dev_err(&sensor->client->dev, "Failed to parse endpoint\n"); 2380 goto error; 2381 } 2382 2383 switch (sensor->bus_cfg.bus_type) { 2384 case V4L2_MBUS_CSI2_DPHY: 2385 case V4L2_MBUS_PARALLEL: 2386 break; 2387 2388 default: 2389 dev_err(&sensor->client->dev, "unsupported bus type %u\n", 2390 sensor->bus_cfg.bus_type); 2391 ret = -EINVAL; 2392 goto error; 2393 } 2394 2395 sensor->pad_slew_rate = MT9M114_PAD_SLEW_DEFAULT; 2396 device_property_read_u32(&sensor->client->dev, "slew-rate", 2397 &sensor->pad_slew_rate); 2398 2399 if (sensor->pad_slew_rate < MT9M114_PAD_SLEW_MIN || 2400 sensor->pad_slew_rate > MT9M114_PAD_SLEW_MAX) { 2401 dev_err(&sensor->client->dev, "Invalid slew-rate %u\n", 2402 sensor->pad_slew_rate); 2403 return -EINVAL; 2404 } 2405 2406 return 0; 2407 2408error: 2409 v4l2_fwnode_endpoint_free(&sensor->bus_cfg); 2410 return ret; 2411} 2412 2413static int mt9m114_probe(struct i2c_client *client) 2414{ 2415 struct device *dev = &client->dev; 2416 struct mt9m114 *sensor; 2417 int ret; 2418 2419 sensor = devm_kzalloc(dev, sizeof(*sensor), GFP_KERNEL); 2420 if (!sensor) 2421 return -ENOMEM; 2422 2423 sensor->client = client; 2424 2425 sensor->regmap = devm_cci_regmap_init_i2c(client, 16); 2426 if (IS_ERR(sensor->regmap)) { 2427 dev_err(dev, "Unable to initialize I2C\n"); 2428 return -ENODEV; 2429 } 2430 2431 ret = mt9m114_parse_dt(sensor); 2432 if (ret < 0) 2433 return ret; 2434 2435 /* Acquire clocks, GPIOs and regulators. */ 2436 sensor->clk = devm_v4l2_sensor_clk_get(dev, NULL); 2437 if (IS_ERR(sensor->clk)) { 2438 ret = dev_err_probe(dev, PTR_ERR(sensor->clk), 2439 "Failed to get clock\n"); 2440 goto error_ep_free; 2441 } 2442 2443 sensor->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH); 2444 if (IS_ERR(sensor->reset)) { 2445 ret = PTR_ERR(sensor->reset); 2446 dev_err_probe(dev, ret, "Failed to get reset GPIO\n"); 2447 goto error_ep_free; 2448 } 2449 2450 sensor->supplies[0].supply = "vddio"; 2451 sensor->supplies[1].supply = "vdd"; 2452 sensor->supplies[2].supply = "vaa"; 2453 2454 ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(sensor->supplies), 2455 sensor->supplies); 2456 if (ret < 0) { 2457 dev_err_probe(dev, ret, "Failed to get regulators\n"); 2458 goto error_ep_free; 2459 } 2460 2461 ret = mt9m114_clk_init(sensor); 2462 if (ret) 2463 goto error_ep_free; 2464 2465 /* 2466 * Identify the sensor. The driver supports runtime PM, but needs to 2467 * work when runtime PM is disabled in the kernel. To that end, power 2468 * the sensor on manually here, and initialize it after identification 2469 * to reach the same state as if resumed through runtime PM. 2470 */ 2471 ret = mt9m114_power_on(sensor); 2472 if (ret < 0) { 2473 dev_err_probe(dev, ret, "Could not power on the device\n"); 2474 goto error_ep_free; 2475 } 2476 2477 ret = mt9m114_identify(sensor); 2478 if (ret < 0) 2479 goto error_power_off; 2480 2481 ret = mt9m114_initialize(sensor); 2482 if (ret < 0) 2483 goto error_power_off; 2484 2485 /* 2486 * Enable runtime PM with autosuspend. As the device has been powered 2487 * manually, mark it as active, and increase the usage count without 2488 * resuming the device. 2489 */ 2490 pm_runtime_set_active(dev); 2491 pm_runtime_get_noresume(dev); 2492 pm_runtime_enable(dev); 2493 pm_runtime_set_autosuspend_delay(dev, 1000); 2494 pm_runtime_use_autosuspend(dev); 2495 2496 /* Initialize the subdevices. */ 2497 ret = mt9m114_pa_init(sensor); 2498 if (ret < 0) 2499 goto error_pm_cleanup; 2500 2501 ret = mt9m114_ifp_init(sensor); 2502 if (ret < 0) 2503 goto error_pa_cleanup; 2504 2505 ret = v4l2_async_register_subdev(&sensor->ifp.sd); 2506 if (ret < 0) 2507 goto error_ifp_cleanup; 2508 2509 /* 2510 * Decrease the PM usage count. The device will get suspended after the 2511 * autosuspend delay, turning the power off. 2512 */ 2513 pm_runtime_put_autosuspend(dev); 2514 2515 return 0; 2516 2517error_ifp_cleanup: 2518 mt9m114_ifp_cleanup(sensor); 2519error_pa_cleanup: 2520 mt9m114_pa_cleanup(sensor); 2521error_pm_cleanup: 2522 pm_runtime_disable(dev); 2523 pm_runtime_put_noidle(dev); 2524error_power_off: 2525 mt9m114_power_off(sensor); 2526error_ep_free: 2527 v4l2_fwnode_endpoint_free(&sensor->bus_cfg); 2528 return ret; 2529} 2530 2531static void mt9m114_remove(struct i2c_client *client) 2532{ 2533 struct v4l2_subdev *sd = i2c_get_clientdata(client); 2534 struct mt9m114 *sensor = ifp_to_mt9m114(sd); 2535 struct device *dev = &client->dev; 2536 2537 v4l2_async_unregister_subdev(&sensor->ifp.sd); 2538 2539 mt9m114_ifp_cleanup(sensor); 2540 mt9m114_pa_cleanup(sensor); 2541 v4l2_fwnode_endpoint_free(&sensor->bus_cfg); 2542 2543 /* 2544 * Disable runtime PM. In case runtime PM is disabled in the kernel, 2545 * make sure to turn power off manually. 2546 */ 2547 pm_runtime_disable(dev); 2548 if (!pm_runtime_status_suspended(dev)) 2549 mt9m114_power_off(sensor); 2550 pm_runtime_set_suspended(dev); 2551} 2552 2553static const struct of_device_id mt9m114_of_ids[] = { 2554 { .compatible = "onnn,mt9m114" }, 2555 { /* sentinel */ }, 2556}; 2557MODULE_DEVICE_TABLE(of, mt9m114_of_ids); 2558 2559static struct i2c_driver mt9m114_driver = { 2560 .driver = { 2561 .name = "mt9m114", 2562 .pm = &mt9m114_pm_ops, 2563 .of_match_table = mt9m114_of_ids, 2564 }, 2565 .probe = mt9m114_probe, 2566 .remove = mt9m114_remove, 2567}; 2568 2569module_i2c_driver(mt9m114_driver); 2570 2571MODULE_DESCRIPTION("onsemi MT9M114 Sensor Driver"); 2572MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@ideasonboard.com>"); 2573MODULE_LICENSE("GPL");
~/
Read-only file preview.