brintos

brintos / linux-shallow public Read only

0
0
Text · 42.8 KiB · 9e30fce Raw
1564 lines · c
1// SPDX-License-Identifier: GPL-2.02// Copyright (C) 2018 Intel Corporation3 4#include <linux/acpi.h>5#include <linux/clk.h>6#include <linux/delay.h>7#include <linux/i2c.h>8#include <linux/module.h>9#include <linux/pm_runtime.h>10#include <linux/regulator/consumer.h>11#include <media/v4l2-cci.h>12#include <media/v4l2-ctrls.h>13#include <media/v4l2-device.h>14#include <media/v4l2-fwnode.h>15#include <linux/unaligned.h>16 17#define IMX258_REG_MODE_SELECT		CCI_REG8(0x0100)18#define IMX258_MODE_STANDBY		0x0019#define IMX258_MODE_STREAMING		0x0120 21#define IMX258_REG_RESET		CCI_REG8(0x0103)22 23/* Chip ID */24#define IMX258_REG_CHIP_ID		CCI_REG16(0x0016)25#define IMX258_CHIP_ID			0x025826 27/* V_TIMING internal */28#define IMX258_VTS_30FPS		0x0c5029#define IMX258_VTS_30FPS_2K		0x063830#define IMX258_VTS_30FPS_VGA		0x034c31#define IMX258_VTS_MAX			6552532 33/* HBLANK control - read only */34#define IMX258_PPL_DEFAULT		535235 36/* Exposure control */37#define IMX258_REG_EXPOSURE		CCI_REG16(0x0202)38#define IMX258_EXPOSURE_OFFSET		1039#define IMX258_EXPOSURE_MIN		440#define IMX258_EXPOSURE_STEP		141#define IMX258_EXPOSURE_DEFAULT		0x64042#define IMX258_EXPOSURE_MAX		(IMX258_VTS_MAX - IMX258_EXPOSURE_OFFSET)43 44/* Analog gain control */45#define IMX258_REG_ANALOG_GAIN		CCI_REG16(0x0204)46#define IMX258_ANA_GAIN_MIN		047#define IMX258_ANA_GAIN_MAX		48048#define IMX258_ANA_GAIN_STEP		149#define IMX258_ANA_GAIN_DEFAULT		0x050 51/* Digital gain control */52#define IMX258_REG_GR_DIGITAL_GAIN	CCI_REG16(0x020e)53#define IMX258_REG_R_DIGITAL_GAIN	CCI_REG16(0x0210)54#define IMX258_REG_B_DIGITAL_GAIN	CCI_REG16(0x0212)55#define IMX258_REG_GB_DIGITAL_GAIN	CCI_REG16(0x0214)56#define IMX258_DGTL_GAIN_MIN		057#define IMX258_DGTL_GAIN_MAX		4096	/* Max = 0xFFF */58#define IMX258_DGTL_GAIN_DEFAULT	102459#define IMX258_DGTL_GAIN_STEP		160 61/* HDR control */62#define IMX258_REG_HDR			CCI_REG8(0x0220)63#define IMX258_HDR_ON			BIT(0)64#define IMX258_REG_HDR_RATIO		CCI_REG8(0x0222)65#define IMX258_HDR_RATIO_MIN		066#define IMX258_HDR_RATIO_MAX		567#define IMX258_HDR_RATIO_STEP		168#define IMX258_HDR_RATIO_DEFAULT	0x069 70/* Test Pattern Control */71#define IMX258_REG_TEST_PATTERN		CCI_REG16(0x0600)72 73#define IMX258_CLK_BLANK_STOP		CCI_REG8(0x4040)74 75/* Orientation */76#define REG_MIRROR_FLIP_CONTROL		CCI_REG8(0x0101)77#define REG_CONFIG_MIRROR_HFLIP		0x0178#define REG_CONFIG_MIRROR_VFLIP		0x0279 80/* IMX258 native and active pixel array size. */81#define IMX258_NATIVE_WIDTH		4224U82#define IMX258_NATIVE_HEIGHT		3192U83#define IMX258_PIXEL_ARRAY_LEFT		8U84#define IMX258_PIXEL_ARRAY_TOP		16U85#define IMX258_PIXEL_ARRAY_WIDTH	4208U86#define IMX258_PIXEL_ARRAY_HEIGHT	3120U87 88/* regs */89#define IMX258_REG_PLL_MULT_DRIV                  CCI_REG8(0x0310)90#define IMX258_REG_IVTPXCK_DIV                    CCI_REG8(0x0301)91#define IMX258_REG_IVTSYCK_DIV                    CCI_REG8(0x0303)92#define IMX258_REG_PREPLLCK_VT_DIV                CCI_REG8(0x0305)93#define IMX258_REG_IOPPXCK_DIV                    CCI_REG8(0x0309)94#define IMX258_REG_IOPSYCK_DIV                    CCI_REG8(0x030b)95#define IMX258_REG_PREPLLCK_OP_DIV                CCI_REG8(0x030d)96#define IMX258_REG_PHASE_PIX_OUTEN                CCI_REG8(0x3030)97#define IMX258_REG_PDPIX_DATA_RATE                CCI_REG8(0x3032)98#define IMX258_REG_SCALE_MODE                     CCI_REG8(0x0401)99#define IMX258_REG_SCALE_MODE_EXT                 CCI_REG8(0x3038)100#define IMX258_REG_AF_WINDOW_MODE                 CCI_REG8(0x7bcd)101#define IMX258_REG_FRM_LENGTH_CTL                 CCI_REG8(0x0350)102#define IMX258_REG_CSI_LANE_MODE                  CCI_REG8(0x0114)103#define IMX258_REG_X_EVN_INC                      CCI_REG8(0x0381)104#define IMX258_REG_X_ODD_INC                      CCI_REG8(0x0383)105#define IMX258_REG_Y_EVN_INC                      CCI_REG8(0x0385)106#define IMX258_REG_Y_ODD_INC                      CCI_REG8(0x0387)107#define IMX258_REG_BINNING_MODE                   CCI_REG8(0x0900)108#define IMX258_REG_BINNING_TYPE_V                 CCI_REG8(0x0901)109#define IMX258_REG_FORCE_FD_SUM                   CCI_REG8(0x300d)110#define IMX258_REG_DIG_CROP_X_OFFSET              CCI_REG16(0x0408)111#define IMX258_REG_DIG_CROP_Y_OFFSET              CCI_REG16(0x040a)112#define IMX258_REG_DIG_CROP_IMAGE_WIDTH           CCI_REG16(0x040c)113#define IMX258_REG_DIG_CROP_IMAGE_HEIGHT          CCI_REG16(0x040e)114#define IMX258_REG_SCALE_M                        CCI_REG16(0x0404)115#define IMX258_REG_X_OUT_SIZE                     CCI_REG16(0x034c)116#define IMX258_REG_Y_OUT_SIZE                     CCI_REG16(0x034e)117#define IMX258_REG_X_ADD_STA                      CCI_REG16(0x0344)118#define IMX258_REG_Y_ADD_STA                      CCI_REG16(0x0346)119#define IMX258_REG_X_ADD_END                      CCI_REG16(0x0348)120#define IMX258_REG_Y_ADD_END                      CCI_REG16(0x034a)121#define IMX258_REG_EXCK_FREQ                      CCI_REG16(0x0136)122#define IMX258_REG_CSI_DT_FMT                     CCI_REG16(0x0112)123#define IMX258_REG_LINE_LENGTH_PCK                CCI_REG16(0x0342)124#define IMX258_REG_SCALE_M_EXT                    CCI_REG16(0x303a)125#define IMX258_REG_FRM_LENGTH_LINES               CCI_REG16(0x0340)126#define IMX258_REG_FINE_INTEG_TIME                CCI_REG8(0x0200)127#define IMX258_REG_PLL_IVT_MPY                    CCI_REG16(0x0306)128#define IMX258_REG_PLL_IOP_MPY                    CCI_REG16(0x030e)129#define IMX258_REG_REQ_LINK_BIT_RATE_MBPS_H       CCI_REG16(0x0820)130#define IMX258_REG_REQ_LINK_BIT_RATE_MBPS_L       CCI_REG16(0x0822)131 132struct imx258_reg_list {133	u32 num_of_regs;134	const struct cci_reg_sequence *regs;135};136 137struct imx258_link_cfg {138	unsigned int lf_to_pix_rate_factor;139	struct imx258_reg_list reg_list;140};141 142enum {143	IMX258_2_LANE_MODE,144	IMX258_4_LANE_MODE,145	IMX258_LANE_CONFIGS,146};147 148/* Link frequency config */149struct imx258_link_freq_config {150	u32 pixels_per_line;151 152	/* Configuration for this link frequency / num lanes selection */153	struct imx258_link_cfg link_cfg[IMX258_LANE_CONFIGS];154};155 156/* Mode : resolution and related config&values */157struct imx258_mode {158	/* Frame width */159	u32 width;160	/* Frame height */161	u32 height;162 163	/* V-timing */164	u32 vts_def;165	u32 vts_min;166 167	/* Index of Link frequency config to be used */168	u32 link_freq_index;169	/* Default register values */170	struct imx258_reg_list reg_list;171 172	/* Analog crop rectangle */173	struct v4l2_rect crop;174};175 176/*177 * 4208x3120 @ 30 fps needs 1267Mbps/lane, 4 lanes.178 * To avoid further computation of clock settings, adopt the same per179 * lane data rate when using 2 lanes, thus allowing a maximum of 15fps.180 */181static const struct cci_reg_sequence mipi_1267mbps_19_2mhz_2l[] = {182	{ IMX258_REG_EXCK_FREQ, 0x1333 },183	{ IMX258_REG_IVTPXCK_DIV, 10 },184	{ IMX258_REG_IVTSYCK_DIV, 2 },185	{ IMX258_REG_PREPLLCK_VT_DIV, 3 },186	{ IMX258_REG_PLL_IVT_MPY, 198 },187	{ IMX258_REG_IOPPXCK_DIV, 10 },188	{ IMX258_REG_IOPSYCK_DIV, 1 },189	{ IMX258_REG_PREPLLCK_OP_DIV, 2 },190	{ IMX258_REG_PLL_IOP_MPY, 216 },191	{ IMX258_REG_PLL_MULT_DRIV, 0 },192 193	{ IMX258_REG_CSI_LANE_MODE, 1 },194	{ IMX258_REG_REQ_LINK_BIT_RATE_MBPS_H, 1267 * 2 },195	{ IMX258_REG_REQ_LINK_BIT_RATE_MBPS_L, 0 },196};197 198static const struct cci_reg_sequence mipi_1267mbps_19_2mhz_4l[] = {199	{ IMX258_REG_EXCK_FREQ, 0x1333 },200	{ IMX258_REG_IVTPXCK_DIV, 5 },201	{ IMX258_REG_IVTSYCK_DIV, 2 },202	{ IMX258_REG_PREPLLCK_VT_DIV, 3 },203	{ IMX258_REG_PLL_IVT_MPY, 198 },204	{ IMX258_REG_IOPPXCK_DIV, 10 },205	{ IMX258_REG_IOPSYCK_DIV, 1 },206	{ IMX258_REG_PREPLLCK_OP_DIV, 2 },207	{ IMX258_REG_PLL_IOP_MPY, 216 },208	{ IMX258_REG_PLL_MULT_DRIV, 0 },209 210	{ IMX258_REG_CSI_LANE_MODE, 3 },211	{ IMX258_REG_REQ_LINK_BIT_RATE_MBPS_H, 1267 * 4 },212	{ IMX258_REG_REQ_LINK_BIT_RATE_MBPS_L, 0 },213};214 215static const struct cci_reg_sequence mipi_1272mbps_24mhz_2l[] = {216	{ IMX258_REG_EXCK_FREQ, 0x1800 },217	{ IMX258_REG_IVTPXCK_DIV, 10 },218	{ IMX258_REG_IVTSYCK_DIV, 2 },219	{ IMX258_REG_PREPLLCK_VT_DIV, 4 },220	{ IMX258_REG_PLL_IVT_MPY, 212 },221	{ IMX258_REG_IOPPXCK_DIV, 10 },222	{ IMX258_REG_IOPSYCK_DIV, 1 },223	{ IMX258_REG_PREPLLCK_OP_DIV, 2 },224	{ IMX258_REG_PLL_IOP_MPY, 216 },225	{ IMX258_REG_PLL_MULT_DRIV, 0 },226 227	{ IMX258_REG_CSI_LANE_MODE, 1 },228	{ IMX258_REG_REQ_LINK_BIT_RATE_MBPS_H, 1272 * 2 },229	{ IMX258_REG_REQ_LINK_BIT_RATE_MBPS_L, 0 },230};231 232static const struct cci_reg_sequence mipi_1272mbps_24mhz_4l[] = {233	{ IMX258_REG_EXCK_FREQ, 0x1800 },234	{ IMX258_REG_IVTPXCK_DIV, 5 },235	{ IMX258_REG_IVTSYCK_DIV, 2 },236	{ IMX258_REG_PREPLLCK_VT_DIV, 4 },237	{ IMX258_REG_PLL_IVT_MPY, 212 },238	{ IMX258_REG_IOPPXCK_DIV, 10 },239	{ IMX258_REG_IOPSYCK_DIV, 1 },240	{ IMX258_REG_PREPLLCK_OP_DIV, 2 },241	{ IMX258_REG_PLL_IOP_MPY, 216 },242	{ IMX258_REG_PLL_MULT_DRIV, 0 },243 244	{ IMX258_REG_CSI_LANE_MODE, 3 },245	{ IMX258_REG_REQ_LINK_BIT_RATE_MBPS_H, 1272 * 4 },246	{ IMX258_REG_REQ_LINK_BIT_RATE_MBPS_L, 0 },247};248 249static const struct cci_reg_sequence mipi_640mbps_19_2mhz_2l[] = {250	{ IMX258_REG_EXCK_FREQ, 0x1333 },251	{ IMX258_REG_IVTPXCK_DIV, 5 },252	{ IMX258_REG_IVTSYCK_DIV, 2 },253	{ IMX258_REG_PREPLLCK_VT_DIV, 3 },254	{ IMX258_REG_PLL_IVT_MPY, 100 },255	{ IMX258_REG_IOPPXCK_DIV, 10 },256	{ IMX258_REG_IOPSYCK_DIV, 1 },257	{ IMX258_REG_PREPLLCK_OP_DIV, 2 },258	{ IMX258_REG_PLL_IOP_MPY, 216 },259	{ IMX258_REG_PLL_MULT_DRIV, 0 },260 261	{ IMX258_REG_CSI_LANE_MODE, 1 },262	{ IMX258_REG_REQ_LINK_BIT_RATE_MBPS_H, 640 * 2 },263	{ IMX258_REG_REQ_LINK_BIT_RATE_MBPS_L, 0 },264};265 266static const struct cci_reg_sequence mipi_640mbps_19_2mhz_4l[] = {267	{ IMX258_REG_EXCK_FREQ, 0x1333 },268	{ IMX258_REG_IVTPXCK_DIV, 5 },269	{ IMX258_REG_IVTSYCK_DIV, 2 },270	{ IMX258_REG_PREPLLCK_VT_DIV, 3 },271	{ IMX258_REG_PLL_IVT_MPY, 100 },272	{ IMX258_REG_IOPPXCK_DIV, 10 },273	{ IMX258_REG_IOPSYCK_DIV, 1 },274	{ IMX258_REG_PREPLLCK_OP_DIV, 2 },275	{ IMX258_REG_PLL_IOP_MPY, 216 },276	{ IMX258_REG_PLL_MULT_DRIV, 0 },277 278	{ IMX258_REG_CSI_LANE_MODE, 3 },279	{ IMX258_REG_REQ_LINK_BIT_RATE_MBPS_H, 640 * 4 },280	{ IMX258_REG_REQ_LINK_BIT_RATE_MBPS_L, 0 },281};282 283static const struct cci_reg_sequence mipi_642mbps_24mhz_2l[] = {284	{ IMX258_REG_EXCK_FREQ, 0x1800 },285	{ IMX258_REG_IVTPXCK_DIV, 5 },286	{ IMX258_REG_IVTSYCK_DIV, 2 },287	{ IMX258_REG_PREPLLCK_VT_DIV, 4 },288	{ IMX258_REG_PLL_IVT_MPY, 107 },289	{ IMX258_REG_IOPPXCK_DIV, 10 },290	{ IMX258_REG_IOPSYCK_DIV, 1 },291	{ IMX258_REG_PREPLLCK_OP_DIV, 2 },292	{ IMX258_REG_PLL_IOP_MPY, 216 },293	{ IMX258_REG_PLL_MULT_DRIV, 0 },294 295	{ IMX258_REG_CSI_LANE_MODE, 1 },296	{ IMX258_REG_REQ_LINK_BIT_RATE_MBPS_H, 642 * 2 },297	{ IMX258_REG_REQ_LINK_BIT_RATE_MBPS_L, 0 },298};299 300static const struct cci_reg_sequence mipi_642mbps_24mhz_4l[] = {301	{ IMX258_REG_EXCK_FREQ, 0x1800 },302	{ IMX258_REG_IVTPXCK_DIV, 5 },303	{ IMX258_REG_IVTSYCK_DIV, 2 },304	{ IMX258_REG_PREPLLCK_VT_DIV, 4 },305	{ IMX258_REG_PLL_IVT_MPY, 107 },306	{ IMX258_REG_IOPPXCK_DIV, 10 },307	{ IMX258_REG_IOPSYCK_DIV, 1 },308	{ IMX258_REG_PREPLLCK_OP_DIV, 2 },309	{ IMX258_REG_PLL_IOP_MPY, 216 },310	{ IMX258_REG_PLL_MULT_DRIV, 0 },311 312	{ IMX258_REG_CSI_LANE_MODE, 3 },313	{ IMX258_REG_REQ_LINK_BIT_RATE_MBPS_H, 642 * 4 },314	{ IMX258_REG_REQ_LINK_BIT_RATE_MBPS_L, 0 },315};316 317static const struct cci_reg_sequence mode_common_regs[] = {318	{ CCI_REG8(0x3051), 0x00 },319	{ CCI_REG8(0x6B11), 0xCF },320	{ CCI_REG8(0x7FF0), 0x08 },321	{ CCI_REG8(0x7FF1), 0x0F },322	{ CCI_REG8(0x7FF2), 0x08 },323	{ CCI_REG8(0x7FF3), 0x1B },324	{ CCI_REG8(0x7FF4), 0x23 },325	{ CCI_REG8(0x7FF5), 0x60 },326	{ CCI_REG8(0x7FF6), 0x00 },327	{ CCI_REG8(0x7FF7), 0x01 },328	{ CCI_REG8(0x7FF8), 0x00 },329	{ CCI_REG8(0x7FF9), 0x78 },330	{ CCI_REG8(0x7FFA), 0x00 },331	{ CCI_REG8(0x7FFB), 0x00 },332	{ CCI_REG8(0x7FFC), 0x00 },333	{ CCI_REG8(0x7FFD), 0x00 },334	{ CCI_REG8(0x7FFE), 0x00 },335	{ CCI_REG8(0x7FFF), 0x03 },336	{ CCI_REG8(0x7F76), 0x03 },337	{ CCI_REG8(0x7F77), 0xFE },338	{ CCI_REG8(0x7FA8), 0x03 },339	{ CCI_REG8(0x7FA9), 0xFE },340	{ CCI_REG8(0x7B24), 0x81 },341	{ CCI_REG8(0x6564), 0x07 },342	{ CCI_REG8(0x6B0D), 0x41 },343	{ CCI_REG8(0x653D), 0x04 },344	{ CCI_REG8(0x6B05), 0x8C },345	{ CCI_REG8(0x6B06), 0xF9 },346	{ CCI_REG8(0x6B08), 0x65 },347	{ CCI_REG8(0x6B09), 0xFC },348	{ CCI_REG8(0x6B0A), 0xCF },349	{ CCI_REG8(0x6B0B), 0xD2 },350	{ CCI_REG8(0x6700), 0x0E },351	{ CCI_REG8(0x6707), 0x0E },352	{ CCI_REG8(0x9104), 0x00 },353	{ CCI_REG8(0x4648), 0x7F },354	{ CCI_REG8(0x7420), 0x00 },355	{ CCI_REG8(0x7421), 0x1C },356	{ CCI_REG8(0x7422), 0x00 },357	{ CCI_REG8(0x7423), 0xD7 },358	{ CCI_REG8(0x5F04), 0x00 },359	{ CCI_REG8(0x5F05), 0xED },360	{IMX258_REG_CSI_DT_FMT, 0x0a0a},361	{IMX258_REG_LINE_LENGTH_PCK, 5352},362	{IMX258_REG_X_ADD_STA, 0},363	{IMX258_REG_Y_ADD_STA, 0},364	{IMX258_REG_X_ADD_END, 4207},365	{IMX258_REG_Y_ADD_END, 3119},366	{IMX258_REG_X_EVN_INC, 1},367	{IMX258_REG_X_ODD_INC, 1},368	{IMX258_REG_Y_EVN_INC, 1},369	{IMX258_REG_Y_ODD_INC, 1},370	{IMX258_REG_DIG_CROP_X_OFFSET, 0},371	{IMX258_REG_DIG_CROP_Y_OFFSET, 0},372	{IMX258_REG_DIG_CROP_IMAGE_WIDTH, 4208},373	{IMX258_REG_SCALE_MODE_EXT, 0},374	{IMX258_REG_SCALE_M_EXT, 16},375	{IMX258_REG_FORCE_FD_SUM, 0},376	{IMX258_REG_FRM_LENGTH_CTL, 0},377	{IMX258_REG_ANALOG_GAIN, 0},378	{IMX258_REG_GR_DIGITAL_GAIN, 256},379	{IMX258_REG_R_DIGITAL_GAIN, 256},380	{IMX258_REG_B_DIGITAL_GAIN, 256},381	{IMX258_REG_GB_DIGITAL_GAIN, 256},382	{IMX258_REG_AF_WINDOW_MODE, 0},383	{ CCI_REG8(0x94DC), 0x20 },384	{ CCI_REG8(0x94DD), 0x20 },385	{ CCI_REG8(0x94DE), 0x20 },386	{ CCI_REG8(0x95DC), 0x20 },387	{ CCI_REG8(0x95DD), 0x20 },388	{ CCI_REG8(0x95DE), 0x20 },389	{ CCI_REG8(0x7FB0), 0x00 },390	{ CCI_REG8(0x9010), 0x3E },391	{ CCI_REG8(0x9419), 0x50 },392	{ CCI_REG8(0x941B), 0x50 },393	{ CCI_REG8(0x9519), 0x50 },394	{ CCI_REG8(0x951B), 0x50 },395	{IMX258_REG_PHASE_PIX_OUTEN, 0},396	{IMX258_REG_PDPIX_DATA_RATE, 0},397	{IMX258_REG_HDR, 0},398};399 400static const struct cci_reg_sequence mode_4208x3120_regs[] = {401	{IMX258_REG_BINNING_MODE, 0},402	{IMX258_REG_BINNING_TYPE_V, 0x11},403	{IMX258_REG_SCALE_MODE, 0},404	{IMX258_REG_SCALE_M, 16},405	{IMX258_REG_DIG_CROP_IMAGE_HEIGHT, 3120},406	{IMX258_REG_X_OUT_SIZE, 4208},407	{IMX258_REG_Y_OUT_SIZE, 3120},408};409 410static const struct cci_reg_sequence mode_2104_1560_regs[] = {411	{IMX258_REG_BINNING_MODE, 1},412	{IMX258_REG_BINNING_TYPE_V, 0x12},413	{IMX258_REG_SCALE_MODE, 1},414	{IMX258_REG_SCALE_M, 32},415	{IMX258_REG_DIG_CROP_IMAGE_HEIGHT, 1560},416	{IMX258_REG_X_OUT_SIZE, 2104},417	{IMX258_REG_Y_OUT_SIZE, 1560},418};419 420static const struct cci_reg_sequence mode_1048_780_regs[] = {421	{IMX258_REG_BINNING_MODE, 1},422	{IMX258_REG_BINNING_TYPE_V, 0x14},423	{IMX258_REG_SCALE_MODE, 1},424	{IMX258_REG_SCALE_M, 64},425	{IMX258_REG_DIG_CROP_IMAGE_HEIGHT, 780},426	{IMX258_REG_X_OUT_SIZE, 1048},427	{IMX258_REG_Y_OUT_SIZE, 780},428};429 430struct imx258_variant_cfg {431	const struct cci_reg_sequence *regs;432	unsigned int num_regs;433};434 435static const struct cci_reg_sequence imx258_cfg_regs[] = {436	{ CCI_REG8(0x3052), 0x00 },437	{ CCI_REG8(0x4E21), 0x14 },438	{ CCI_REG8(0x7B25), 0x00 },439};440 441static const struct imx258_variant_cfg imx258_cfg = {442	.regs = imx258_cfg_regs,443	.num_regs = ARRAY_SIZE(imx258_cfg_regs),444};445 446static const struct cci_reg_sequence imx258_pdaf_cfg_regs[] = {447	{ CCI_REG8(0x3052), 0x01 },448	{ CCI_REG8(0x4E21), 0x10 },449	{ CCI_REG8(0x7B25), 0x01 },450};451 452static const struct imx258_variant_cfg imx258_pdaf_cfg = {453	.regs = imx258_pdaf_cfg_regs,454	.num_regs = ARRAY_SIZE(imx258_pdaf_cfg_regs),455};456 457/*458 * The supported formats.459 * This table MUST contain 4 entries per format, to cover the various flip460 * combinations in the order461 * - no flip462 * - h flip463 * - v flip464 * - h&v flips465 */466static const u32 codes[] = {467	/* 10-bit modes. */468	MEDIA_BUS_FMT_SRGGB10_1X10,469	MEDIA_BUS_FMT_SGRBG10_1X10,470	MEDIA_BUS_FMT_SGBRG10_1X10,471	MEDIA_BUS_FMT_SBGGR10_1X10472};473 474static const char * const imx258_test_pattern_menu[] = {475	"Disabled",476	"Solid Colour",477	"Eight Vertical Colour Bars",478	"Colour Bars With Fade to Grey",479	"Pseudorandom Sequence (PN9)",480};481 482/* regulator supplies */483static const char * const imx258_supply_name[] = {484	/* Supplies can be enabled in any order */485	"vana",  /* Analog (2.8V) supply */486	"vdig",  /* Digital Core (1.2V) supply */487	"vif",  /* IF (1.8V) supply */488};489 490#define IMX258_NUM_SUPPLIES ARRAY_SIZE(imx258_supply_name)491 492enum {493	IMX258_LINK_FREQ_1267MBPS,494	IMX258_LINK_FREQ_640MBPS,495};496 497/*498 * Pixel rate does not necessarily relate to link frequency on this sensor as499 * there is a FIFO between the pixel array pipeline and the MIPI serializer.500 * The recommendation from Sony is that the pixel array is always run with a501 * line length of 5352 pixels, which means that there is a large amount of502 * blanking time for the 1048x780 mode. There is no need to replicate this503 * blanking on the CSI2 bus, and the configuration of register 0x0301 allows the504 * divider to be altered.505 *506 * The actual factor between link frequency and pixel rate is in the507 * imx258_link_cfg, so use this to convert between the two.508 * bits per pixel being 10, and D-PHY being DDR is assumed by this function, so509 * the value is only the combination of number of lanes and pixel clock divider.510 */511static u64 link_freq_to_pixel_rate(u64 f, const struct imx258_link_cfg *link_cfg)512{513	f *= 2 * link_cfg->lf_to_pix_rate_factor;514	do_div(f, 10);515 516	return f;517}518 519/* Menu items for LINK_FREQ V4L2 control */520/* Configurations for supported link frequencies */521static const s64 link_freq_menu_items_19_2[] = {522	633600000ULL,523	320000000ULL,524};525 526static const s64 link_freq_menu_items_24[] = {527	636000000ULL,528	321000000ULL,529};530 531#define REGS(_list) { .num_of_regs = ARRAY_SIZE(_list), .regs = _list, }532 533/* Link frequency configs */534static const struct imx258_link_freq_config link_freq_configs_19_2[] = {535	[IMX258_LINK_FREQ_1267MBPS] = {536		.pixels_per_line = IMX258_PPL_DEFAULT,537		.link_cfg = {538			[IMX258_2_LANE_MODE] = {539				.lf_to_pix_rate_factor = 2 * 2,540				.reg_list = REGS(mipi_1267mbps_19_2mhz_2l),541			},542			[IMX258_4_LANE_MODE] = {543				.lf_to_pix_rate_factor = 4,544				.reg_list = REGS(mipi_1267mbps_19_2mhz_4l),545			},546		}547	},548	[IMX258_LINK_FREQ_640MBPS] = {549		.pixels_per_line = IMX258_PPL_DEFAULT,550		.link_cfg = {551			[IMX258_2_LANE_MODE] = {552				.lf_to_pix_rate_factor = 2,553				.reg_list = REGS(mipi_640mbps_19_2mhz_2l),554			},555			[IMX258_4_LANE_MODE] = {556				.lf_to_pix_rate_factor = 4,557				.reg_list = REGS(mipi_640mbps_19_2mhz_4l),558			},559		}560	},561};562 563static const struct imx258_link_freq_config link_freq_configs_24[] = {564	[IMX258_LINK_FREQ_1267MBPS] = {565		.pixels_per_line = IMX258_PPL_DEFAULT,566		.link_cfg = {567			[IMX258_2_LANE_MODE] = {568				.lf_to_pix_rate_factor = 2,569				.reg_list = REGS(mipi_1272mbps_24mhz_2l),570			},571			[IMX258_4_LANE_MODE] = {572				.lf_to_pix_rate_factor = 4,573				.reg_list = REGS(mipi_1272mbps_24mhz_4l),574			},575		}576	},577	[IMX258_LINK_FREQ_640MBPS] = {578		.pixels_per_line = IMX258_PPL_DEFAULT,579		.link_cfg = {580			[IMX258_2_LANE_MODE] = {581				.lf_to_pix_rate_factor = 2 * 2,582				.reg_list = REGS(mipi_642mbps_24mhz_2l),583			},584			[IMX258_4_LANE_MODE] = {585				.lf_to_pix_rate_factor = 4,586				.reg_list = REGS(mipi_642mbps_24mhz_4l),587			},588		}589	},590};591 592/* Mode configs */593static const struct imx258_mode supported_modes[] = {594	{595		.width = 4208,596		.height = 3120,597		.vts_def = IMX258_VTS_30FPS,598		.vts_min = IMX258_VTS_30FPS,599		.reg_list = {600			.num_of_regs = ARRAY_SIZE(mode_4208x3120_regs),601			.regs = mode_4208x3120_regs,602		},603		.link_freq_index = IMX258_LINK_FREQ_1267MBPS,604		.crop = {605			.left = IMX258_PIXEL_ARRAY_LEFT,606			.top = IMX258_PIXEL_ARRAY_TOP,607			.width = 4208,608			.height = 3120,609		},610	},611	{612		.width = 2104,613		.height = 1560,614		.vts_def = IMX258_VTS_30FPS_2K,615		.vts_min = IMX258_VTS_30FPS_2K,616		.reg_list = {617			.num_of_regs = ARRAY_SIZE(mode_2104_1560_regs),618			.regs = mode_2104_1560_regs,619		},620		.link_freq_index = IMX258_LINK_FREQ_640MBPS,621		.crop = {622			.left = IMX258_PIXEL_ARRAY_LEFT,623			.top = IMX258_PIXEL_ARRAY_TOP,624			.width = 4208,625			.height = 3120,626		},627	},628	{629		.width = 1048,630		.height = 780,631		.vts_def = IMX258_VTS_30FPS_VGA,632		.vts_min = IMX258_VTS_30FPS_VGA,633		.reg_list = {634			.num_of_regs = ARRAY_SIZE(mode_1048_780_regs),635			.regs = mode_1048_780_regs,636		},637		.link_freq_index = IMX258_LINK_FREQ_640MBPS,638		.crop = {639			.left = IMX258_PIXEL_ARRAY_LEFT,640			.top = IMX258_PIXEL_ARRAY_TOP,641			.width = 4208,642			.height = 3120,643		},644	},645};646 647struct imx258 {648	struct v4l2_subdev sd;649	struct media_pad pad;650	struct regmap *regmap;651 652	const struct imx258_variant_cfg *variant_cfg;653 654	struct v4l2_ctrl_handler ctrl_handler;655	/* V4L2 Controls */656	struct v4l2_ctrl *link_freq;657	struct v4l2_ctrl *pixel_rate;658	struct v4l2_ctrl *vblank;659	struct v4l2_ctrl *hblank;660	struct v4l2_ctrl *exposure;661	struct v4l2_ctrl *hflip;662	struct v4l2_ctrl *vflip;663 664	/* Current mode */665	const struct imx258_mode *cur_mode;666 667	unsigned long link_freq_bitmap;668	const struct imx258_link_freq_config *link_freq_configs;669	const s64 *link_freq_menu_items;670	unsigned int lane_mode_idx;671	unsigned int csi2_flags;672 673	/*674	 * Mutex for serialized access:675	 * Protect sensor module set pad format and start/stop streaming safely.676	 */677	struct mutex mutex;678 679	struct clk *clk;680	struct regulator_bulk_data supplies[IMX258_NUM_SUPPLIES];681};682 683static inline struct imx258 *to_imx258(struct v4l2_subdev *_sd)684{685	return container_of(_sd, struct imx258, sd);686}687 688/* Get bayer order based on flip setting. */689static u32 imx258_get_format_code(const struct imx258 *imx258)690{691	unsigned int i;692 693	lockdep_assert_held(&imx258->mutex);694 695	i = (imx258->vflip->val ? 2 : 0) |696	    (imx258->hflip->val ? 1 : 0);697 698	return codes[i];699}700 701/* Open sub-device */702static int imx258_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)703{704	struct imx258 *imx258 = to_imx258(sd);705	struct v4l2_mbus_framefmt *try_fmt =706		v4l2_subdev_state_get_format(fh->state, 0);707	struct v4l2_rect *try_crop;708 709	/* Initialize try_fmt */710	try_fmt->width = supported_modes[0].width;711	try_fmt->height = supported_modes[0].height;712	try_fmt->code = imx258_get_format_code(imx258);713	try_fmt->field = V4L2_FIELD_NONE;714 715	/* Initialize try_crop */716	try_crop = v4l2_subdev_state_get_crop(fh->state, 0);717	try_crop->left = IMX258_PIXEL_ARRAY_LEFT;718	try_crop->top = IMX258_PIXEL_ARRAY_TOP;719	try_crop->width = IMX258_PIXEL_ARRAY_WIDTH;720	try_crop->height = IMX258_PIXEL_ARRAY_HEIGHT;721 722	return 0;723}724 725static int imx258_update_digital_gain(struct imx258 *imx258, u32 val)726{727	int ret = 0;728 729	cci_write(imx258->regmap, IMX258_REG_GR_DIGITAL_GAIN, val, &ret);730	cci_write(imx258->regmap, IMX258_REG_GB_DIGITAL_GAIN, val, &ret);731	cci_write(imx258->regmap, IMX258_REG_R_DIGITAL_GAIN, val, &ret);732	cci_write(imx258->regmap, IMX258_REG_B_DIGITAL_GAIN, val, &ret);733 734	return ret;735}736 737static void imx258_adjust_exposure_range(struct imx258 *imx258)738{739	int exposure_max, exposure_def;740 741	/* Honour the VBLANK limits when setting exposure. */742	exposure_max = imx258->cur_mode->height + imx258->vblank->val -743		       IMX258_EXPOSURE_OFFSET;744	exposure_def = min(exposure_max, imx258->exposure->val);745	__v4l2_ctrl_modify_range(imx258->exposure, imx258->exposure->minimum,746				 exposure_max, imx258->exposure->step,747				 exposure_def);748}749 750static int imx258_set_ctrl(struct v4l2_ctrl *ctrl)751{752	struct imx258 *imx258 =753		container_of(ctrl->handler, struct imx258, ctrl_handler);754	struct i2c_client *client = v4l2_get_subdevdata(&imx258->sd);755	int ret = 0;756 757	/*758	 * The VBLANK control may change the limits of usable exposure, so check759	 * and adjust if necessary.760	 */761	if (ctrl->id == V4L2_CID_VBLANK)762		imx258_adjust_exposure_range(imx258);763 764	/*765	 * Applying V4L2 control value only happens766	 * when power is up for streaming767	 */768	if (pm_runtime_get_if_in_use(&client->dev) == 0)769		return 0;770 771	switch (ctrl->id) {772	case V4L2_CID_ANALOGUE_GAIN:773		ret = cci_write(imx258->regmap, IMX258_REG_ANALOG_GAIN,774				ctrl->val, NULL);775		break;776	case V4L2_CID_EXPOSURE:777		ret = cci_write(imx258->regmap, IMX258_REG_EXPOSURE,778				ctrl->val, NULL);779		break;780	case V4L2_CID_DIGITAL_GAIN:781		ret = imx258_update_digital_gain(imx258, ctrl->val);782		break;783	case V4L2_CID_TEST_PATTERN:784		ret = cci_write(imx258->regmap, IMX258_REG_TEST_PATTERN,785				ctrl->val, NULL);786		break;787	case V4L2_CID_WIDE_DYNAMIC_RANGE:788		if (!ctrl->val) {789			ret = cci_write(imx258->regmap, IMX258_REG_HDR,790					IMX258_HDR_RATIO_MIN, NULL);791		} else {792			ret = cci_write(imx258->regmap, IMX258_REG_HDR,793					IMX258_HDR_ON, NULL);794			if (ret)795				break;796			ret = cci_write(imx258->regmap, IMX258_REG_HDR_RATIO,797					BIT(IMX258_HDR_RATIO_MAX), NULL);798		}799		break;800	case V4L2_CID_VBLANK:801		ret = cci_write(imx258->regmap, IMX258_REG_FRM_LENGTH_LINES,802				imx258->cur_mode->height + ctrl->val, NULL);803		break;804	case V4L2_CID_VFLIP:805	case V4L2_CID_HFLIP:806		ret = cci_write(imx258->regmap, REG_MIRROR_FLIP_CONTROL,807				(imx258->hflip->val ?808				 REG_CONFIG_MIRROR_HFLIP : 0) |809				(imx258->vflip->val ?810				 REG_CONFIG_MIRROR_VFLIP : 0),811				NULL);812		break;813	default:814		dev_info(&client->dev,815			 "ctrl(id:0x%x,val:0x%x) is not handled\n",816			 ctrl->id, ctrl->val);817		ret = -EINVAL;818		break;819	}820 821	pm_runtime_put(&client->dev);822 823	return ret;824}825 826static const struct v4l2_ctrl_ops imx258_ctrl_ops = {827	.s_ctrl = imx258_set_ctrl,828};829 830static int imx258_enum_mbus_code(struct v4l2_subdev *sd,831				  struct v4l2_subdev_state *sd_state,832				  struct v4l2_subdev_mbus_code_enum *code)833{834	struct imx258 *imx258 = to_imx258(sd);835 836	/* Only one bayer format (10 bit) is supported */837	if (code->index > 0)838		return -EINVAL;839 840	code->code = imx258_get_format_code(imx258);841 842	return 0;843}844 845static int imx258_enum_frame_size(struct v4l2_subdev *sd,846				  struct v4l2_subdev_state *sd_state,847				  struct v4l2_subdev_frame_size_enum *fse)848{849	struct imx258 *imx258 = to_imx258(sd);850	if (fse->index >= ARRAY_SIZE(supported_modes))851		return -EINVAL;852 853	if (fse->code != imx258_get_format_code(imx258))854		return -EINVAL;855 856	fse->min_width = supported_modes[fse->index].width;857	fse->max_width = fse->min_width;858	fse->min_height = supported_modes[fse->index].height;859	fse->max_height = fse->min_height;860 861	return 0;862}863 864static void imx258_update_pad_format(struct imx258 *imx258,865				     const struct imx258_mode *mode,866				     struct v4l2_subdev_format *fmt)867{868	fmt->format.width = mode->width;869	fmt->format.height = mode->height;870	fmt->format.code = imx258_get_format_code(imx258);871	fmt->format.field = V4L2_FIELD_NONE;872}873 874static int __imx258_get_pad_format(struct imx258 *imx258,875				   struct v4l2_subdev_state *sd_state,876				   struct v4l2_subdev_format *fmt)877{878	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY)879		fmt->format = *v4l2_subdev_state_get_format(sd_state,880							    fmt->pad);881	else882		imx258_update_pad_format(imx258, imx258->cur_mode, fmt);883 884	return 0;885}886 887static int imx258_get_pad_format(struct v4l2_subdev *sd,888				 struct v4l2_subdev_state *sd_state,889				 struct v4l2_subdev_format *fmt)890{891	struct imx258 *imx258 = to_imx258(sd);892	int ret;893 894	mutex_lock(&imx258->mutex);895	ret = __imx258_get_pad_format(imx258, sd_state, fmt);896	mutex_unlock(&imx258->mutex);897 898	return ret;899}900 901static int imx258_set_pad_format(struct v4l2_subdev *sd,902				 struct v4l2_subdev_state *sd_state,903				 struct v4l2_subdev_format *fmt)904{905	struct imx258 *imx258 = to_imx258(sd);906	const struct imx258_link_freq_config *link_freq_cfgs;907	const struct imx258_link_cfg *link_cfg;908	struct v4l2_mbus_framefmt *framefmt;909	const struct imx258_mode *mode;910	s32 vblank_def;911	s32 vblank_min;912	s64 h_blank;913	s64 pixel_rate;914	s64 link_freq;915 916	mutex_lock(&imx258->mutex);917 918	fmt->format.code = imx258_get_format_code(imx258);919 920	mode = v4l2_find_nearest_size(supported_modes,921		ARRAY_SIZE(supported_modes), width, height,922		fmt->format.width, fmt->format.height);923	imx258_update_pad_format(imx258, mode, fmt);924	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {925		framefmt = v4l2_subdev_state_get_format(sd_state, fmt->pad);926		*framefmt = fmt->format;927	} else {928		imx258->cur_mode = mode;929		__v4l2_ctrl_s_ctrl(imx258->link_freq, mode->link_freq_index);930 931		link_freq = imx258->link_freq_menu_items[mode->link_freq_index];932		link_freq_cfgs =933			&imx258->link_freq_configs[mode->link_freq_index];934 935		link_cfg = &link_freq_cfgs->link_cfg[imx258->lane_mode_idx];936		pixel_rate = link_freq_to_pixel_rate(link_freq, link_cfg);937		__v4l2_ctrl_modify_range(imx258->pixel_rate, pixel_rate,938					 pixel_rate, 1, pixel_rate);939		/* Update limits and set FPS to default */940		vblank_def = imx258->cur_mode->vts_def -941			     imx258->cur_mode->height;942		vblank_min = imx258->cur_mode->vts_min -943			     imx258->cur_mode->height;944		__v4l2_ctrl_modify_range(945			imx258->vblank, vblank_min,946			IMX258_VTS_MAX - imx258->cur_mode->height, 1,947			vblank_def);948		__v4l2_ctrl_s_ctrl(imx258->vblank, vblank_def);949		h_blank =950			imx258->link_freq_configs[mode->link_freq_index].pixels_per_line951			 - imx258->cur_mode->width;952		__v4l2_ctrl_modify_range(imx258->hblank, h_blank,953					 h_blank, 1, h_blank);954	}955 956	mutex_unlock(&imx258->mutex);957 958	return 0;959}960 961static const struct v4l2_rect *962__imx258_get_pad_crop(struct imx258 *imx258,963		      struct v4l2_subdev_state *sd_state,964		      unsigned int pad, enum v4l2_subdev_format_whence which)965{966	switch (which) {967	case V4L2_SUBDEV_FORMAT_TRY:968		return v4l2_subdev_state_get_crop(sd_state, pad);969	case V4L2_SUBDEV_FORMAT_ACTIVE:970		return &imx258->cur_mode->crop;971	}972 973	return NULL;974}975 976static int imx258_get_selection(struct v4l2_subdev *sd,977				struct v4l2_subdev_state *sd_state,978				struct v4l2_subdev_selection *sel)979{980	switch (sel->target) {981	case V4L2_SEL_TGT_CROP: {982		struct imx258 *imx258 = to_imx258(sd);983 984		mutex_lock(&imx258->mutex);985		sel->r = *__imx258_get_pad_crop(imx258, sd_state, sel->pad,986						sel->which);987		mutex_unlock(&imx258->mutex);988 989		return 0;990	}991 992	case V4L2_SEL_TGT_NATIVE_SIZE:993		sel->r.left = 0;994		sel->r.top = 0;995		sel->r.width = IMX258_NATIVE_WIDTH;996		sel->r.height = IMX258_NATIVE_HEIGHT;997 998		return 0;999 1000	case V4L2_SEL_TGT_CROP_DEFAULT:1001	case V4L2_SEL_TGT_CROP_BOUNDS:1002		sel->r.left = IMX258_PIXEL_ARRAY_LEFT;1003		sel->r.top = IMX258_PIXEL_ARRAY_TOP;1004		sel->r.width = IMX258_PIXEL_ARRAY_WIDTH;1005		sel->r.height = IMX258_PIXEL_ARRAY_HEIGHT;1006 1007		return 0;1008	}1009 1010	return -EINVAL;1011}1012 1013/* Start streaming */1014static int imx258_start_streaming(struct imx258 *imx258)1015{1016	struct i2c_client *client = v4l2_get_subdevdata(&imx258->sd);1017	const struct imx258_reg_list *reg_list;1018	const struct imx258_link_freq_config *link_freq_cfg;1019	int ret, link_freq_index;1020 1021	ret = cci_write(imx258->regmap, IMX258_REG_RESET, 0x01, NULL);1022	if (ret) {1023		dev_err(&client->dev, "%s failed to reset sensor\n", __func__);1024		return ret;1025	}1026 1027	/* 12ms is required from poweron to standby */1028	fsleep(12000);1029 1030	/* Setup PLL */1031	link_freq_index = imx258->cur_mode->link_freq_index;1032	link_freq_cfg = &imx258->link_freq_configs[link_freq_index];1033 1034	reg_list = &link_freq_cfg->link_cfg[imx258->lane_mode_idx].reg_list;1035	ret = cci_multi_reg_write(imx258->regmap, reg_list->regs, reg_list->num_of_regs, NULL);1036	if (ret) {1037		dev_err(&client->dev, "%s failed to set plls\n", __func__);1038		return ret;1039	}1040 1041	ret = cci_multi_reg_write(imx258->regmap, mode_common_regs,1042				  ARRAY_SIZE(mode_common_regs), NULL);1043	if (ret) {1044		dev_err(&client->dev, "%s failed to set common regs\n", __func__);1045		return ret;1046	}1047 1048	ret = cci_multi_reg_write(imx258->regmap, imx258->variant_cfg->regs,1049				  imx258->variant_cfg->num_regs, NULL);1050	if (ret) {1051		dev_err(&client->dev, "%s failed to set variant config\n",1052			__func__);1053		return ret;1054	}1055 1056	ret = cci_write(imx258->regmap, IMX258_CLK_BLANK_STOP,1057			!!(imx258->csi2_flags & V4L2_MBUS_CSI2_NONCONTINUOUS_CLOCK),1058			NULL);1059	if (ret) {1060		dev_err(&client->dev, "%s failed to set clock lane mode\n", __func__);1061		return ret;1062	}1063 1064	/* Apply default values of current mode */1065	reg_list = &imx258->cur_mode->reg_list;1066	ret = cci_multi_reg_write(imx258->regmap, reg_list->regs, reg_list->num_of_regs, NULL);1067	if (ret) {1068		dev_err(&client->dev, "%s failed to set mode\n", __func__);1069		return ret;1070	}1071 1072	/* Apply customized values from user */1073	ret =  __v4l2_ctrl_handler_setup(imx258->sd.ctrl_handler);1074	if (ret)1075		return ret;1076 1077	/* set stream on register */1078	return cci_write(imx258->regmap, IMX258_REG_MODE_SELECT,1079			 IMX258_MODE_STREAMING, NULL);1080}1081 1082/* Stop streaming */1083static int imx258_stop_streaming(struct imx258 *imx258)1084{1085	struct i2c_client *client = v4l2_get_subdevdata(&imx258->sd);1086	int ret;1087 1088	/* set stream off register */1089	ret = cci_write(imx258->regmap, IMX258_REG_MODE_SELECT,1090			IMX258_MODE_STANDBY, NULL);1091	if (ret)1092		dev_err(&client->dev, "%s failed to set stream\n", __func__);1093 1094	/*1095	 * Return success even if it was an error, as there is nothing the1096	 * caller can do about it.1097	 */1098	return 0;1099}1100 1101static int imx258_power_on(struct device *dev)1102{1103	struct v4l2_subdev *sd = dev_get_drvdata(dev);1104	struct imx258 *imx258 = to_imx258(sd);1105	int ret;1106 1107	ret = regulator_bulk_enable(IMX258_NUM_SUPPLIES,1108				    imx258->supplies);1109	if (ret) {1110		dev_err(dev, "%s: failed to enable regulators\n",1111			__func__);1112		return ret;1113	}1114 1115	ret = clk_prepare_enable(imx258->clk);1116	if (ret) {1117		dev_err(dev, "failed to enable clock\n");1118		regulator_bulk_disable(IMX258_NUM_SUPPLIES, imx258->supplies);1119	}1120 1121	return ret;1122}1123 1124static int imx258_power_off(struct device *dev)1125{1126	struct v4l2_subdev *sd = dev_get_drvdata(dev);1127	struct imx258 *imx258 = to_imx258(sd);1128 1129	clk_disable_unprepare(imx258->clk);1130	regulator_bulk_disable(IMX258_NUM_SUPPLIES, imx258->supplies);1131 1132	return 0;1133}1134 1135static int imx258_set_stream(struct v4l2_subdev *sd, int enable)1136{1137	struct imx258 *imx258 = to_imx258(sd);1138	struct i2c_client *client = v4l2_get_subdevdata(sd);1139	int ret = 0;1140 1141	mutex_lock(&imx258->mutex);1142 1143	if (enable) {1144		ret = pm_runtime_resume_and_get(&client->dev);1145		if (ret < 0)1146			goto err_unlock;1147 1148		/*1149		 * Apply default & customized values1150		 * and then start streaming.1151		 */1152		ret = imx258_start_streaming(imx258);1153		if (ret)1154			goto err_rpm_put;1155	} else {1156		imx258_stop_streaming(imx258);1157		pm_runtime_put(&client->dev);1158	}1159 1160	mutex_unlock(&imx258->mutex);1161 1162	return ret;1163 1164err_rpm_put:1165	pm_runtime_put(&client->dev);1166err_unlock:1167	mutex_unlock(&imx258->mutex);1168 1169	return ret;1170}1171 1172/* Verify chip ID */1173static int imx258_identify_module(struct imx258 *imx258)1174{1175	struct i2c_client *client = v4l2_get_subdevdata(&imx258->sd);1176	int ret;1177	u64 val;1178 1179	ret = cci_read(imx258->regmap, IMX258_REG_CHIP_ID,1180		       &val, NULL);1181	if (ret) {1182		dev_err(&client->dev, "failed to read chip id %x\n",1183			IMX258_CHIP_ID);1184		return ret;1185	}1186 1187	if (val != IMX258_CHIP_ID) {1188		dev_err(&client->dev, "chip id mismatch: %x!=%llx\n",1189			IMX258_CHIP_ID, val);1190		return -EIO;1191	}1192 1193	return 0;1194}1195 1196static const struct v4l2_subdev_video_ops imx258_video_ops = {1197	.s_stream = imx258_set_stream,1198};1199 1200static const struct v4l2_subdev_pad_ops imx258_pad_ops = {1201	.enum_mbus_code = imx258_enum_mbus_code,1202	.get_fmt = imx258_get_pad_format,1203	.set_fmt = imx258_set_pad_format,1204	.enum_frame_size = imx258_enum_frame_size,1205	.get_selection = imx258_get_selection,1206};1207 1208static const struct v4l2_subdev_ops imx258_subdev_ops = {1209	.video = &imx258_video_ops,1210	.pad = &imx258_pad_ops,1211};1212 1213static const struct v4l2_subdev_internal_ops imx258_internal_ops = {1214	.open = imx258_open,1215};1216 1217/* Initialize control handlers */1218static int imx258_init_controls(struct imx258 *imx258)1219{1220	struct i2c_client *client = v4l2_get_subdevdata(&imx258->sd);1221	const struct imx258_link_freq_config *link_freq_cfgs;1222	struct v4l2_fwnode_device_properties props;1223	struct v4l2_ctrl_handler *ctrl_hdlr;1224	const struct imx258_link_cfg *link_cfg;1225	s64 vblank_def;1226	s64 vblank_min;1227	s64 pixel_rate;1228	int ret;1229 1230	ctrl_hdlr = &imx258->ctrl_handler;1231	ret = v4l2_ctrl_handler_init(ctrl_hdlr, 13);1232	if (ret)1233		return ret;1234 1235	mutex_init(&imx258->mutex);1236	ctrl_hdlr->lock = &imx258->mutex;1237	imx258->link_freq = v4l2_ctrl_new_int_menu(ctrl_hdlr,1238				&imx258_ctrl_ops,1239				V4L2_CID_LINK_FREQ,1240				ARRAY_SIZE(link_freq_menu_items_19_2) - 1,1241				0,1242				imx258->link_freq_menu_items);1243 1244	if (imx258->link_freq)1245		imx258->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;1246 1247	imx258->hflip = v4l2_ctrl_new_std(ctrl_hdlr, &imx258_ctrl_ops,1248					  V4L2_CID_HFLIP, 0, 1, 1, 1);1249	if (imx258->hflip)1250		imx258->hflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT;1251 1252	imx258->vflip = v4l2_ctrl_new_std(ctrl_hdlr, &imx258_ctrl_ops,1253					  V4L2_CID_VFLIP, 0, 1, 1, 1);1254	if (imx258->vflip)1255		imx258->vflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT;1256 1257	link_freq_cfgs = &imx258->link_freq_configs[0];1258	link_cfg = link_freq_cfgs[imx258->lane_mode_idx].link_cfg;1259	pixel_rate = link_freq_to_pixel_rate(imx258->link_freq_menu_items[0],1260					     link_cfg);1261 1262	/* By default, PIXEL_RATE is read only */1263	imx258->pixel_rate = v4l2_ctrl_new_std(ctrl_hdlr, &imx258_ctrl_ops,1264				V4L2_CID_PIXEL_RATE,1265				pixel_rate, pixel_rate,1266				1, pixel_rate);1267 1268	vblank_def = imx258->cur_mode->vts_def - imx258->cur_mode->height;1269	vblank_min = imx258->cur_mode->vts_min - imx258->cur_mode->height;1270	imx258->vblank = v4l2_ctrl_new_std(1271				ctrl_hdlr, &imx258_ctrl_ops, V4L2_CID_VBLANK,1272				vblank_min,1273				IMX258_VTS_MAX - imx258->cur_mode->height, 1,1274				vblank_def);1275 1276	imx258->hblank = v4l2_ctrl_new_std(1277				ctrl_hdlr, &imx258_ctrl_ops, V4L2_CID_HBLANK,1278				IMX258_PPL_DEFAULT - imx258->cur_mode->width,1279				IMX258_PPL_DEFAULT - imx258->cur_mode->width,1280				1,1281				IMX258_PPL_DEFAULT - imx258->cur_mode->width);1282 1283	if (imx258->hblank)1284		imx258->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;1285 1286	imx258->exposure = v4l2_ctrl_new_std(1287				ctrl_hdlr, &imx258_ctrl_ops,1288				V4L2_CID_EXPOSURE, IMX258_EXPOSURE_MIN,1289				IMX258_EXPOSURE_MAX, IMX258_EXPOSURE_STEP,1290				IMX258_EXPOSURE_DEFAULT);1291 1292	v4l2_ctrl_new_std(ctrl_hdlr, &imx258_ctrl_ops, V4L2_CID_ANALOGUE_GAIN,1293				IMX258_ANA_GAIN_MIN, IMX258_ANA_GAIN_MAX,1294				IMX258_ANA_GAIN_STEP, IMX258_ANA_GAIN_DEFAULT);1295 1296	v4l2_ctrl_new_std(ctrl_hdlr, &imx258_ctrl_ops, V4L2_CID_DIGITAL_GAIN,1297				IMX258_DGTL_GAIN_MIN, IMX258_DGTL_GAIN_MAX,1298				IMX258_DGTL_GAIN_STEP,1299				IMX258_DGTL_GAIN_DEFAULT);1300 1301	v4l2_ctrl_new_std(ctrl_hdlr, &imx258_ctrl_ops, V4L2_CID_WIDE_DYNAMIC_RANGE,1302				0, 1, 1, IMX258_HDR_RATIO_DEFAULT);1303 1304	v4l2_ctrl_new_std_menu_items(ctrl_hdlr, &imx258_ctrl_ops,1305				V4L2_CID_TEST_PATTERN,1306				ARRAY_SIZE(imx258_test_pattern_menu) - 1,1307				0, 0, imx258_test_pattern_menu);1308 1309	if (ctrl_hdlr->error) {1310		ret = ctrl_hdlr->error;1311		dev_err(&client->dev, "%s control init failed (%d)\n",1312				__func__, ret);1313		goto error;1314	}1315 1316	ret = v4l2_fwnode_device_parse(&client->dev, &props);1317	if (ret)1318		goto error;1319 1320	ret = v4l2_ctrl_new_fwnode_properties(ctrl_hdlr, &imx258_ctrl_ops,1321					      &props);1322	if (ret)1323		goto error;1324 1325	imx258->sd.ctrl_handler = ctrl_hdlr;1326 1327	return 0;1328 1329error:1330	v4l2_ctrl_handler_free(ctrl_hdlr);1331	mutex_destroy(&imx258->mutex);1332 1333	return ret;1334}1335 1336static void imx258_free_controls(struct imx258 *imx258)1337{1338	v4l2_ctrl_handler_free(imx258->sd.ctrl_handler);1339	mutex_destroy(&imx258->mutex);1340}1341 1342static int imx258_get_regulators(struct imx258 *imx258,1343				 struct i2c_client *client)1344{1345	unsigned int i;1346 1347	for (i = 0; i < IMX258_NUM_SUPPLIES; i++)1348		imx258->supplies[i].supply = imx258_supply_name[i];1349 1350	return devm_regulator_bulk_get(&client->dev,1351				    IMX258_NUM_SUPPLIES, imx258->supplies);1352}1353 1354static int imx258_probe(struct i2c_client *client)1355{1356	struct imx258 *imx258;1357	struct fwnode_handle *endpoint;1358	struct v4l2_fwnode_endpoint ep = {1359		.bus_type = V4L2_MBUS_CSI2_DPHY1360	};1361	int ret;1362	u32 val = 0;1363 1364	imx258 = devm_kzalloc(&client->dev, sizeof(*imx258), GFP_KERNEL);1365	if (!imx258)1366		return -ENOMEM;1367 1368	imx258->regmap = devm_cci_regmap_init_i2c(client, 16);1369	if (IS_ERR(imx258->regmap)) {1370		ret = PTR_ERR(imx258->regmap);1371		dev_err(&client->dev, "failed to initialize CCI: %d\n", ret);1372		return ret;1373	}1374 1375	ret = imx258_get_regulators(imx258, client);1376	if (ret)1377		return dev_err_probe(&client->dev, ret,1378				     "failed to get regulators\n");1379 1380	imx258->clk = devm_clk_get_optional(&client->dev, NULL);1381	if (IS_ERR(imx258->clk))1382		return dev_err_probe(&client->dev, PTR_ERR(imx258->clk),1383				     "error getting clock\n");1384	if (!imx258->clk) {1385		dev_dbg(&client->dev,1386			"no clock provided, using clock-frequency property\n");1387 1388		device_property_read_u32(&client->dev, "clock-frequency", &val);1389	} else {1390		val = clk_get_rate(imx258->clk);1391	}1392 1393	switch (val) {1394	case 19200000:1395		imx258->link_freq_configs = link_freq_configs_19_2;1396		imx258->link_freq_menu_items = link_freq_menu_items_19_2;1397		break;1398	case 24000000:1399		imx258->link_freq_configs = link_freq_configs_24;1400		imx258->link_freq_menu_items = link_freq_menu_items_24;1401		break;1402	default:1403		dev_err(&client->dev, "input clock frequency of %u not supported\n",1404			val);1405		return -EINVAL;1406	}1407 1408	endpoint = fwnode_graph_get_next_endpoint(dev_fwnode(&client->dev), NULL);1409	if (!endpoint) {1410		dev_err(&client->dev, "Endpoint node not found\n");1411		return -EINVAL;1412	}1413 1414	ret = v4l2_fwnode_endpoint_alloc_parse(endpoint, &ep);1415	fwnode_handle_put(endpoint);1416	if (ret) {1417		dev_err(&client->dev, "Parsing endpoint node failed\n");1418		return ret;1419	}1420 1421	ret = v4l2_link_freq_to_bitmap(&client->dev,1422				       ep.link_frequencies,1423				       ep.nr_of_link_frequencies,1424				       imx258->link_freq_menu_items,1425				       ARRAY_SIZE(link_freq_menu_items_19_2),1426				       &imx258->link_freq_bitmap);1427	if (ret) {1428		dev_err(&client->dev, "Link frequency not supported\n");1429		goto error_endpoint_free;1430	}1431 1432	/* Get number of data lanes */1433	switch (ep.bus.mipi_csi2.num_data_lanes) {1434	case 2:1435		imx258->lane_mode_idx = IMX258_2_LANE_MODE;1436		break;1437	case 4:1438		imx258->lane_mode_idx = IMX258_4_LANE_MODE;1439		break;1440	default:1441		dev_err(&client->dev, "Invalid data lanes: %u\n",1442			ep.bus.mipi_csi2.num_data_lanes);1443		ret = -EINVAL;1444		goto error_endpoint_free;1445	}1446 1447	imx258->csi2_flags = ep.bus.mipi_csi2.flags;1448 1449	imx258->variant_cfg = device_get_match_data(&client->dev);1450	if (!imx258->variant_cfg)1451		imx258->variant_cfg = &imx258_cfg;1452 1453	/* Initialize subdev */1454	v4l2_i2c_subdev_init(&imx258->sd, client, &imx258_subdev_ops);1455 1456	/* Will be powered off via pm_runtime_idle */1457	ret = imx258_power_on(&client->dev);1458	if (ret)1459		goto error_endpoint_free;1460 1461	/* Check module identity */1462	ret = imx258_identify_module(imx258);1463	if (ret)1464		goto error_identify;1465 1466	/* Set default mode to max resolution */1467	imx258->cur_mode = &supported_modes[0];1468 1469	ret = imx258_init_controls(imx258);1470	if (ret)1471		goto error_identify;1472 1473	/* Initialize subdev */1474	imx258->sd.internal_ops = &imx258_internal_ops;1475	imx258->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;1476	imx258->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;1477 1478	/* Initialize source pad */1479	imx258->pad.flags = MEDIA_PAD_FL_SOURCE;1480 1481	ret = media_entity_pads_init(&imx258->sd.entity, 1, &imx258->pad);1482	if (ret)1483		goto error_handler_free;1484 1485	ret = v4l2_async_register_subdev_sensor(&imx258->sd);1486	if (ret < 0)1487		goto error_media_entity;1488 1489	pm_runtime_set_active(&client->dev);1490	pm_runtime_enable(&client->dev);1491	pm_runtime_idle(&client->dev);1492	v4l2_fwnode_endpoint_free(&ep);1493 1494	return 0;1495 1496error_media_entity:1497	media_entity_cleanup(&imx258->sd.entity);1498 1499error_handler_free:1500	imx258_free_controls(imx258);1501 1502error_identify:1503	imx258_power_off(&client->dev);1504 1505error_endpoint_free:1506	v4l2_fwnode_endpoint_free(&ep);1507 1508	return ret;1509}1510 1511static void imx258_remove(struct i2c_client *client)1512{1513	struct v4l2_subdev *sd = i2c_get_clientdata(client);1514	struct imx258 *imx258 = to_imx258(sd);1515 1516	v4l2_async_unregister_subdev(sd);1517	media_entity_cleanup(&sd->entity);1518	imx258_free_controls(imx258);1519 1520	pm_runtime_disable(&client->dev);1521	if (!pm_runtime_status_suspended(&client->dev))1522		imx258_power_off(&client->dev);1523	pm_runtime_set_suspended(&client->dev);1524}1525 1526static const struct dev_pm_ops imx258_pm_ops = {1527	SET_RUNTIME_PM_OPS(imx258_power_off, imx258_power_on, NULL)1528};1529 1530#ifdef CONFIG_ACPI1531static const struct acpi_device_id imx258_acpi_ids[] = {1532	{ "SONY258A" },1533	{ /* sentinel */ }1534};1535 1536MODULE_DEVICE_TABLE(acpi, imx258_acpi_ids);1537#endif1538 1539static const struct of_device_id imx258_dt_ids[] = {1540	{ .compatible = "sony,imx258", .data = &imx258_cfg },1541	{ .compatible = "sony,imx258-pdaf", .data = &imx258_pdaf_cfg },1542	{ /* sentinel */ }1543};1544MODULE_DEVICE_TABLE(of, imx258_dt_ids);1545 1546static struct i2c_driver imx258_i2c_driver = {1547	.driver = {1548		.name = "imx258",1549		.pm = &imx258_pm_ops,1550		.acpi_match_table = ACPI_PTR(imx258_acpi_ids),1551		.of_match_table	= imx258_dt_ids,1552	},1553	.probe = imx258_probe,1554	.remove = imx258_remove,1555};1556 1557module_i2c_driver(imx258_i2c_driver);1558 1559MODULE_AUTHOR("Yeh, Andy <andy.yeh@intel.com>");1560MODULE_AUTHOR("Chiang, Alan");1561MODULE_AUTHOR("Chen, Jason");1562MODULE_DESCRIPTION("Sony IMX258 sensor driver");1563MODULE_LICENSE("GPL v2");1564