brintos

brintos / linux-shallow public Read only

0
0
Text · 32.6 KiB · f31f988 Raw
1455 lines · c
1// SPDX-License-Identifier: GPL-2.02// Copyright (c) 2019 Intel Corporation.3 4#include <linux/unaligned.h>5#include <linux/acpi.h>6#include <linux/clk.h>7#include <linux/delay.h>8#include <linux/gpio/consumer.h>9#include <linux/i2c.h>10#include <linux/module.h>11#include <linux/pm_runtime.h>12#include <linux/regulator/consumer.h>13#include <media/v4l2-ctrls.h>14#include <media/v4l2-device.h>15#include <media/v4l2-fwnode.h>16 17#define HI556_REG_VALUE_08BIT		118#define HI556_REG_VALUE_16BIT		219#define HI556_REG_VALUE_24BIT		320 21#define HI556_LINK_FREQ_437MHZ		437000000ULL22#define HI556_MCLK			1920000023#define HI556_DATA_LANES		224#define HI556_RGB_DEPTH			1025 26#define HI556_REG_CHIP_ID		0x0f1627#define HI556_CHIP_ID			0x055628 29#define HI556_REG_MODE_SELECT		0x0a0030#define HI556_MODE_STANDBY		0x000031#define HI556_MODE_STREAMING		0x010032 33/* vertical-timings from sensor */34#define HI556_REG_FLL			0x000635#define HI556_FLL_30FPS			0x081436#define HI556_FLL_30FPS_MIN		0x081437#define HI556_FLL_MAX			0x7fff38 39/* horizontal-timings from sensor */40#define HI556_REG_LLP			0x000841 42/* Exposure controls from sensor */43#define HI556_REG_EXPOSURE		0x007444#define HI556_EXPOSURE_MIN		645#define HI556_EXPOSURE_MAX_MARGIN	246#define HI556_EXPOSURE_STEP		147 48/* Analog gain controls from sensor */49#define HI556_REG_ANALOG_GAIN		0x007750#define HI556_ANAL_GAIN_MIN		051#define HI556_ANAL_GAIN_MAX		24052#define HI556_ANAL_GAIN_STEP		153 54/* Digital gain controls from sensor */55#define HI556_REG_MWB_GR_GAIN		0x007856#define HI556_REG_MWB_GB_GAIN		0x007a57#define HI556_REG_MWB_R_GAIN		0x007c58#define HI556_REG_MWB_B_GAIN		0x007e59#define HI556_DGTL_GAIN_MIN		060#define HI556_DGTL_GAIN_MAX		204861#define HI556_DGTL_GAIN_STEP		162#define HI556_DGTL_GAIN_DEFAULT		25663 64/* Test Pattern Control */65#define HI556_REG_ISP			0X0a0566#define HI556_REG_ISP_TPG_EN		0x0167#define HI556_REG_TEST_PATTERN		0x020168 69/* HI556 native and active pixel array size. */70#define HI556_NATIVE_WIDTH		2592U71#define HI556_NATIVE_HEIGHT		1944U72#define HI556_PIXEL_ARRAY_LEFT		0U73#define HI556_PIXEL_ARRAY_TOP		0U74#define HI556_PIXEL_ARRAY_WIDTH	2592U75#define HI556_PIXEL_ARRAY_HEIGHT	1944U76 77enum {78	HI556_LINK_FREQ_437MHZ_INDEX,79};80 81struct hi556_reg {82	u16 address;83	u16 val;84};85 86struct hi556_reg_list {87	u32 num_of_regs;88	const struct hi556_reg *regs;89};90 91struct hi556_link_freq_config {92	const struct hi556_reg_list reg_list;93};94 95struct hi556_mode {96	/* Frame width in pixels */97	u32 width;98 99	/* Frame height in pixels */100	u32 height;101 102	/* Analog crop rectangle. */103	struct v4l2_rect crop;104 105	/* Horizontal timining size */106	u32 llp;107 108	/* Default vertical timining size */109	u32 fll_def;110 111	/* Min vertical timining size */112	u32 fll_min;113 114	/* Link frequency needed for this resolution */115	u32 link_freq_index;116 117	/* Sensor register settings for this resolution */118	const struct hi556_reg_list reg_list;119};120 121#define to_hi556(_sd) container_of(_sd, struct hi556, sd)122 123//SENSOR_INITIALIZATION124static const struct hi556_reg mipi_data_rate_874mbps[] = {125	{0x0e00, 0x0102},126	{0x0e02, 0x0102},127	{0x0e0c, 0x0100},128	{0x2000, 0x7400},129	{0x2002, 0x001c},130	{0x2004, 0x0242},131	{0x2006, 0x0942},132	{0x2008, 0x7007},133	{0x200a, 0x0fd9},134	{0x200c, 0x0259},135	{0x200e, 0x7008},136	{0x2010, 0x160e},137	{0x2012, 0x0047},138	{0x2014, 0x2118},139	{0x2016, 0x0041},140	{0x2018, 0x00d8},141	{0x201a, 0x0145},142	{0x201c, 0x0006},143	{0x201e, 0x0181},144	{0x2020, 0x13cc},145	{0x2022, 0x2057},146	{0x2024, 0x7001},147	{0x2026, 0x0fca},148	{0x2028, 0x00cb},149	{0x202a, 0x009f},150	{0x202c, 0x7002},151	{0x202e, 0x13cc},152	{0x2030, 0x019b},153	{0x2032, 0x014d},154	{0x2034, 0x2987},155	{0x2036, 0x2766},156	{0x2038, 0x0020},157	{0x203a, 0x2060},158	{0x203c, 0x0e5d},159	{0x203e, 0x181d},160	{0x2040, 0x2066},161	{0x2042, 0x20c4},162	{0x2044, 0x5000},163	{0x2046, 0x0005},164	{0x2048, 0x0000},165	{0x204a, 0x01db},166	{0x204c, 0x025a},167	{0x204e, 0x00c0},168	{0x2050, 0x0005},169	{0x2052, 0x0006},170	{0x2054, 0x0ad9},171	{0x2056, 0x0259},172	{0x2058, 0x0618},173	{0x205a, 0x0258},174	{0x205c, 0x2266},175	{0x205e, 0x20c8},176	{0x2060, 0x2060},177	{0x2062, 0x707b},178	{0x2064, 0x0fdd},179	{0x2066, 0x81b8},180	{0x2068, 0x5040},181	{0x206a, 0x0020},182	{0x206c, 0x5060},183	{0x206e, 0x3143},184	{0x2070, 0x5081},185	{0x2072, 0x025c},186	{0x2074, 0x7800},187	{0x2076, 0x7400},188	{0x2078, 0x001c},189	{0x207a, 0x0242},190	{0x207c, 0x0942},191	{0x207e, 0x0bd9},192	{0x2080, 0x0259},193	{0x2082, 0x7008},194	{0x2084, 0x160e},195	{0x2086, 0x0047},196	{0x2088, 0x2118},197	{0x208a, 0x0041},198	{0x208c, 0x00d8},199	{0x208e, 0x0145},200	{0x2090, 0x0006},201	{0x2092, 0x0181},202	{0x2094, 0x13cc},203	{0x2096, 0x2057},204	{0x2098, 0x7001},205	{0x209a, 0x0fca},206	{0x209c, 0x00cb},207	{0x209e, 0x009f},208	{0x20a0, 0x7002},209	{0x20a2, 0x13cc},210	{0x20a4, 0x019b},211	{0x20a6, 0x014d},212	{0x20a8, 0x2987},213	{0x20aa, 0x2766},214	{0x20ac, 0x0020},215	{0x20ae, 0x2060},216	{0x20b0, 0x0e5d},217	{0x20b2, 0x181d},218	{0x20b4, 0x2066},219	{0x20b6, 0x20c4},220	{0x20b8, 0x50a0},221	{0x20ba, 0x0005},222	{0x20bc, 0x0000},223	{0x20be, 0x01db},224	{0x20c0, 0x025a},225	{0x20c2, 0x00c0},226	{0x20c4, 0x0005},227	{0x20c6, 0x0006},228	{0x20c8, 0x0ad9},229	{0x20ca, 0x0259},230	{0x20cc, 0x0618},231	{0x20ce, 0x0258},232	{0x20d0, 0x2266},233	{0x20d2, 0x20c8},234	{0x20d4, 0x2060},235	{0x20d6, 0x707b},236	{0x20d8, 0x0fdd},237	{0x20da, 0x86b8},238	{0x20dc, 0x50e0},239	{0x20de, 0x0020},240	{0x20e0, 0x5100},241	{0x20e2, 0x3143},242	{0x20e4, 0x5121},243	{0x20e6, 0x7800},244	{0x20e8, 0x3140},245	{0x20ea, 0x01c4},246	{0x20ec, 0x01c1},247	{0x20ee, 0x01c0},248	{0x20f0, 0x01c4},249	{0x20f2, 0x2700},250	{0x20f4, 0x3d40},251	{0x20f6, 0x7800},252	{0x20f8, 0xffff},253	{0x27fe, 0xe000},254	{0x3000, 0x60f8},255	{0x3002, 0x187f},256	{0x3004, 0x7060},257	{0x3006, 0x0114},258	{0x3008, 0x60b0},259	{0x300a, 0x1473},260	{0x300c, 0x0013},261	{0x300e, 0x140f},262	{0x3010, 0x0040},263	{0x3012, 0x100f},264	{0x3014, 0x60f8},265	{0x3016, 0x187f},266	{0x3018, 0x7060},267	{0x301a, 0x0114},268	{0x301c, 0x60b0},269	{0x301e, 0x1473},270	{0x3020, 0x0013},271	{0x3022, 0x140f},272	{0x3024, 0x0040},273	{0x3026, 0x000f},274 275	{0x0b00, 0x0000},276	{0x0b02, 0x0045},277	{0x0b04, 0xb405},278	{0x0b06, 0xc403},279	{0x0b08, 0x0081},280	{0x0b0a, 0x8252},281	{0x0b0c, 0xf814},282	{0x0b0e, 0xc618},283	{0x0b10, 0xa828},284	{0x0b12, 0x004c},285	{0x0b14, 0x4068},286	{0x0b16, 0x0000},287	{0x0f30, 0x5b15},288	{0x0f32, 0x7067},289	{0x0954, 0x0009},290	{0x0956, 0x0000},291	{0x0958, 0xbb80},292	{0x095a, 0x5140},293	{0x0c00, 0x1110},294	{0x0c02, 0x0011},295	{0x0c04, 0x0000},296	{0x0c06, 0x0200},297	{0x0c10, 0x0040},298	{0x0c12, 0x0040},299	{0x0c14, 0x0040},300	{0x0c16, 0x0040},301	{0x0a10, 0x4000},302	{0x3068, 0xf800},303	{0x306a, 0xf876},304	{0x006c, 0x0000},305	{0x005e, 0x0200},306	{0x000e, 0x0100},307	{0x0e0a, 0x0001},308	{0x004a, 0x0100},309	{0x004c, 0x0000},310	{0x004e, 0x0100},311	{0x000c, 0x0022},312	{0x0008, 0x0b00},313	{0x005a, 0x0202},314	{0x0012, 0x000e},315	{0x0018, 0x0a33},316	{0x0022, 0x0008},317	{0x0028, 0x0017},318	{0x0024, 0x0028},319	{0x002a, 0x002d},320	{0x0026, 0x0030},321	{0x002c, 0x07c9},322	{0x002e, 0x1111},323	{0x0030, 0x1111},324	{0x0032, 0x1111},325	{0x0006, 0x07bc},326	{0x0a22, 0x0000},327	{0x0a12, 0x0a20},328	{0x0a14, 0x0798},329	{0x003e, 0x0000},330	{0x0074, 0x080e},331	{0x0070, 0x0407},332	{0x0002, 0x0000},333	{0x0a02, 0x0100},334	{0x0a24, 0x0100},335	{0x0046, 0x0000},336	{0x0076, 0x0000},337	{0x0060, 0x0000},338	{0x0062, 0x0530},339	{0x0064, 0x0500},340	{0x0066, 0x0530},341	{0x0068, 0x0500},342	{0x0122, 0x0300},343	{0x015a, 0xff08},344	{0x0804, 0x0300},345	{0x0806, 0x0100},346	{0x005c, 0x0102},347	{0x0a1a, 0x0800},348};349 350static const struct hi556_reg mode_2592x1944_regs[] = {351	{0x0a00, 0x0000},352	{0x0b0a, 0x8252},353	{0x0f30, 0x5b15},354	{0x0f32, 0x7067},355	{0x004a, 0x0100},356	{0x004c, 0x0000},357	{0x004e, 0x0100},358	{0x000c, 0x0022},359	{0x0008, 0x0b00},360	{0x005a, 0x0202},361	{0x0012, 0x000e},362	{0x0018, 0x0a33},363	{0x0022, 0x0008},364	{0x0028, 0x0017},365	{0x0024, 0x0028},366	{0x002a, 0x002d},367	{0x0026, 0x0030},368	{0x002c, 0x07c9},369	{0x002e, 0x1111},370	{0x0030, 0x1111},371	{0x0032, 0x1111},372	{0x0006, 0x0814},373	{0x0a22, 0x0000},374	{0x0a12, 0x0a20},375	{0x0a14, 0x0798},376	{0x003e, 0x0000},377	{0x0074, 0x0812},378	{0x0070, 0x0409},379	{0x0804, 0x0300},380	{0x0806, 0x0100},381	{0x0a04, 0x014a},382	{0x090c, 0x0fdc},383	{0x090e, 0x002d},384 385	{0x0902, 0x4319},386	{0x0914, 0xc10a},387	{0x0916, 0x071f},388	{0x0918, 0x0408},389	{0x091a, 0x0c0d},390	{0x091c, 0x0f09},391	{0x091e, 0x0a00},392	{0x0958, 0xbb80},393};394 395static const struct hi556_reg mode_2592x1444_regs[] = {396	{0x0a00, 0x0000},397	{0x0b0a, 0x8252},398	{0x0f30, 0xe545},399	{0x0f32, 0x7067},400	{0x004a, 0x0100},401	{0x004c, 0x0000},402	{0x000c, 0x0022},403	{0x0008, 0x0b00},404	{0x005a, 0x0202},405	{0x0012, 0x000e},406	{0x0018, 0x0a33},407	{0x0022, 0x0008},408	{0x0028, 0x0017},409	{0x0024, 0x0122},410	{0x002a, 0x0127},411	{0x0026, 0x012a},412	{0x002c, 0x06cf},413	{0x002e, 0x1111},414	{0x0030, 0x1111},415	{0x0032, 0x1111},416	{0x0006, 0x0821},417	{0x0a22, 0x0000},418	{0x0a12, 0x0a20},419	{0x0a14, 0x05a4},420	{0x003e, 0x0000},421	{0x0074, 0x081f},422	{0x0070, 0x040f},423	{0x0804, 0x0300},424	{0x0806, 0x0100},425	{0x0a04, 0x014a},426	{0x090c, 0x0fdc},427	{0x090e, 0x002d},428	{0x0902, 0x4319},429	{0x0914, 0xc10a},430	{0x0916, 0x071f},431	{0x0918, 0x0408},432	{0x091a, 0x0c0d},433	{0x091c, 0x0f09},434	{0x091e, 0x0a00},435	{0x0958, 0xbb80},436};437 438static const struct hi556_reg mode_1296x972_regs[] = {439	{0x0a00, 0x0000},440	{0x0b0a, 0x8259},441	{0x0f30, 0x5b15},442	{0x0f32, 0x7167},443	{0x004a, 0x0100},444	{0x004c, 0x0000},445	{0x004e, 0x0100},446	{0x000c, 0x0122},447	{0x0008, 0x0b00},448	{0x005a, 0x0404},449	{0x0012, 0x000c},450	{0x0018, 0x0a33},451	{0x0022, 0x0008},452	{0x0028, 0x0017},453	{0x0024, 0x0022},454	{0x002a, 0x002b},455	{0x0026, 0x0030},456	{0x002c, 0x07c9},457	{0x002e, 0x3311},458	{0x0030, 0x3311},459	{0x0032, 0x3311},460	{0x0006, 0x0814},461	{0x0a22, 0x0000},462	{0x0a12, 0x0510},463	{0x0a14, 0x03cc},464	{0x003e, 0x0000},465	{0x0074, 0x0812},466	{0x0070, 0x0409},467	{0x0804, 0x0308},468	{0x0806, 0x0100},469	{0x0a04, 0x016a},470	{0x090e, 0x0010},471	{0x090c, 0x09c0},472 473	{0x0902, 0x4319},474	{0x0914, 0xc106},475	{0x0916, 0x040e},476	{0x0918, 0x0304},477	{0x091a, 0x0708},478	{0x091c, 0x0e06},479	{0x091e, 0x0300},480	{0x0958, 0xbb80},481};482 483static const struct hi556_reg mode_1296x722_regs[] = {484	{0x0a00, 0x0000},485	{0x0b0a, 0x8259},486	{0x0f30, 0x5b15},487	{0x0f32, 0x7167},488	{0x004a, 0x0100},489	{0x004c, 0x0000},490	{0x004e, 0x0100},491	{0x000c, 0x0122},492	{0x0008, 0x0b00},493	{0x005a, 0x0404},494	{0x0012, 0x000c},495	{0x0018, 0x0a33},496	{0x0022, 0x0008},497	{0x0028, 0x0017},498	{0x0024, 0x0022},499	{0x002a, 0x002b},500	{0x0026, 0x012a},501	{0x002c, 0x06cf},502	{0x002e, 0x3311},503	{0x0030, 0x3311},504	{0x0032, 0x3311},505	{0x0006, 0x0814},506	{0x0a22, 0x0000},507	{0x0a12, 0x0510},508	{0x0a14, 0x02d2},509	{0x003e, 0x0000},510	{0x0074, 0x0812},511	{0x0070, 0x0409},512	{0x0804, 0x0308},513	{0x0806, 0x0100},514	{0x0a04, 0x016a},515	{0x090c, 0x09c0},516	{0x090e, 0x0010},517	{0x0902, 0x4319},518	{0x0914, 0xc106},519	{0x0916, 0x040e},520	{0x0918, 0x0304},521	{0x091a, 0x0708},522	{0x091c, 0x0e06},523	{0x091e, 0x0300},524	{0x0958, 0xbb80},525};526 527static const char * const hi556_test_pattern_menu[] = {528	"Disabled",529	"Solid Colour",530	"100% Colour Bars",531	"Fade To Grey Colour Bars",532	"PN9",533	"Gradient Horizontal",534	"Gradient Vertical",535	"Check Board",536	"Slant Pattern",537};538 539static const s64 link_freq_menu_items[] = {540	HI556_LINK_FREQ_437MHZ,541};542 543static const struct hi556_link_freq_config link_freq_configs[] = {544	[HI556_LINK_FREQ_437MHZ_INDEX] = {545		.reg_list = {546			.num_of_regs = ARRAY_SIZE(mipi_data_rate_874mbps),547			.regs = mipi_data_rate_874mbps,548		}549	}550};551 552static const struct hi556_mode supported_modes[] = {553	{554		.width = HI556_PIXEL_ARRAY_WIDTH,555		.height = HI556_PIXEL_ARRAY_HEIGHT,556		.crop = {557			.left = HI556_PIXEL_ARRAY_LEFT,558			.top = HI556_PIXEL_ARRAY_TOP,559			.width = HI556_PIXEL_ARRAY_WIDTH,560			.height = HI556_PIXEL_ARRAY_HEIGHT561		},562		.fll_def = HI556_FLL_30FPS,563		.fll_min = HI556_FLL_30FPS_MIN,564		.llp = 0x0b00,565		.reg_list = {566			.num_of_regs = ARRAY_SIZE(mode_2592x1944_regs),567			.regs = mode_2592x1944_regs,568		},569		.link_freq_index = HI556_LINK_FREQ_437MHZ_INDEX,570	},571	{572		.width = HI556_PIXEL_ARRAY_WIDTH,573		.height = 1444,574		.crop = {575			.left = HI556_PIXEL_ARRAY_LEFT,576			.top = 250,577			.width = HI556_PIXEL_ARRAY_WIDTH,578			.height = 1444579		},580		.fll_def = 0x821,581		.fll_min = 0x821,582		.llp = 0x0b00,583		.reg_list = {584			.num_of_regs = ARRAY_SIZE(mode_2592x1444_regs),585			.regs = mode_2592x1444_regs,586		},587		.link_freq_index = HI556_LINK_FREQ_437MHZ_INDEX,588	},589	{590		.width = 1296,591		.height = 972,592		.crop = {593			.left = HI556_PIXEL_ARRAY_LEFT,594			.top = HI556_PIXEL_ARRAY_TOP,595			.width = HI556_PIXEL_ARRAY_WIDTH,596			.height = HI556_PIXEL_ARRAY_HEIGHT597		},598		.fll_def = HI556_FLL_30FPS,599		.fll_min = HI556_FLL_30FPS_MIN,600		.llp = 0x0b00,601		.reg_list = {602			.num_of_regs = ARRAY_SIZE(mode_1296x972_regs),603			.regs = mode_1296x972_regs,604		},605		.link_freq_index = HI556_LINK_FREQ_437MHZ_INDEX,606	},607	{608		.width = 1296,609		.height = 722,610		.crop = {611			.left = HI556_PIXEL_ARRAY_LEFT,612			.top = 250,613			.width = HI556_PIXEL_ARRAY_WIDTH,614			.height = 1444615		},616		.fll_def = HI556_FLL_30FPS,617		.fll_min = HI556_FLL_30FPS_MIN,618		.llp = 0x0b00,619		.reg_list = {620			.num_of_regs = ARRAY_SIZE(mode_1296x722_regs),621			.regs = mode_1296x722_regs,622		},623		.link_freq_index = HI556_LINK_FREQ_437MHZ_INDEX,624	},625};626 627struct hi556 {628	struct v4l2_subdev sd;629	struct media_pad pad;630	struct v4l2_ctrl_handler ctrl_handler;631 632	/* V4L2 Controls */633	struct v4l2_ctrl *link_freq;634	struct v4l2_ctrl *pixel_rate;635	struct v4l2_ctrl *vblank;636	struct v4l2_ctrl *hblank;637	struct v4l2_ctrl *exposure;638 639	/* GPIOs, clocks, etc. */640	struct gpio_desc *reset_gpio;641	struct clk *clk;642	struct regulator *avdd;643 644	/* Current mode */645	const struct hi556_mode *cur_mode;646 647	/* To serialize asynchronus callbacks */648	struct mutex mutex;649 650	/* True if the device has been identified */651	bool identified;652};653 654static u64 to_pixel_rate(u32 f_index)655{656	u64 pixel_rate = link_freq_menu_items[f_index] * 2 * HI556_DATA_LANES;657 658	do_div(pixel_rate, HI556_RGB_DEPTH);659 660	return pixel_rate;661}662 663static int hi556_read_reg(struct hi556 *hi556, u16 reg, u16 len, u32 *val)664{665	struct i2c_client *client = v4l2_get_subdevdata(&hi556->sd);666	struct i2c_msg msgs[2];667	u8 addr_buf[2];668	u8 data_buf[4] = {0};669	int ret;670 671	if (len > 4)672		return -EINVAL;673 674	put_unaligned_be16(reg, addr_buf);675	msgs[0].addr = client->addr;676	msgs[0].flags = 0;677	msgs[0].len = sizeof(addr_buf);678	msgs[0].buf = addr_buf;679	msgs[1].addr = client->addr;680	msgs[1].flags = I2C_M_RD;681	msgs[1].len = len;682	msgs[1].buf = &data_buf[4 - len];683 684	ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));685	if (ret != ARRAY_SIZE(msgs))686		return -EIO;687 688	*val = get_unaligned_be32(data_buf);689 690	return 0;691}692 693static int hi556_write_reg(struct hi556 *hi556, u16 reg, u16 len, u32 val)694{695	struct i2c_client *client = v4l2_get_subdevdata(&hi556->sd);696	u8 buf[6];697 698	if (len > 4)699		return -EINVAL;700 701	put_unaligned_be16(reg, buf);702	put_unaligned_be32(val << 8 * (4 - len), buf + 2);703	if (i2c_master_send(client, buf, len + 2) != len + 2)704		return -EIO;705 706	return 0;707}708 709static int hi556_write_reg_list(struct hi556 *hi556,710				const struct hi556_reg_list *r_list)711{712	struct i2c_client *client = v4l2_get_subdevdata(&hi556->sd);713	unsigned int i;714	int ret;715 716	for (i = 0; i < r_list->num_of_regs; i++) {717		ret = hi556_write_reg(hi556, r_list->regs[i].address,718				      HI556_REG_VALUE_16BIT,719				      r_list->regs[i].val);720		if (ret) {721			dev_err_ratelimited(&client->dev,722					    "failed to write reg 0x%4.4x. error = %d",723					    r_list->regs[i].address, ret);724			return ret;725		}726	}727 728	return 0;729}730 731static int hi556_update_digital_gain(struct hi556 *hi556, u32 d_gain)732{733	int ret;734 735	ret = hi556_write_reg(hi556, HI556_REG_MWB_GR_GAIN,736			      HI556_REG_VALUE_16BIT, d_gain);737	if (ret)738		return ret;739 740	ret = hi556_write_reg(hi556, HI556_REG_MWB_GB_GAIN,741			      HI556_REG_VALUE_16BIT, d_gain);742	if (ret)743		return ret;744 745	ret = hi556_write_reg(hi556, HI556_REG_MWB_R_GAIN,746			      HI556_REG_VALUE_16BIT, d_gain);747	if (ret)748		return ret;749 750	return hi556_write_reg(hi556, HI556_REG_MWB_B_GAIN,751			       HI556_REG_VALUE_16BIT, d_gain);752}753 754static int hi556_test_pattern(struct hi556 *hi556, u32 pattern)755{756	int ret;757	u32 val;758 759	if (pattern) {760		ret = hi556_read_reg(hi556, HI556_REG_ISP,761				     HI556_REG_VALUE_08BIT, &val);762		if (ret)763			return ret;764 765		ret = hi556_write_reg(hi556, HI556_REG_ISP,766				      HI556_REG_VALUE_08BIT,767				      val | HI556_REG_ISP_TPG_EN);768		if (ret)769			return ret;770	}771 772	return hi556_write_reg(hi556, HI556_REG_TEST_PATTERN,773			       HI556_REG_VALUE_08BIT, pattern);774}775 776static int hi556_set_ctrl(struct v4l2_ctrl *ctrl)777{778	struct hi556 *hi556 = container_of(ctrl->handler,779					     struct hi556, ctrl_handler);780	struct i2c_client *client = v4l2_get_subdevdata(&hi556->sd);781	s64 exposure_max;782	int ret = 0;783 784	/* Propagate change of current control to all related controls */785	if (ctrl->id == V4L2_CID_VBLANK) {786		/* Update max exposure while meeting expected vblanking */787		exposure_max = hi556->cur_mode->height + ctrl->val -788			       HI556_EXPOSURE_MAX_MARGIN;789		__v4l2_ctrl_modify_range(hi556->exposure,790					 hi556->exposure->minimum,791					 exposure_max, hi556->exposure->step,792					 exposure_max);793	}794 795	/* V4L2 controls values will be applied only when power is already up */796	if (!pm_runtime_get_if_in_use(&client->dev))797		return 0;798 799	switch (ctrl->id) {800	case V4L2_CID_ANALOGUE_GAIN:801		ret = hi556_write_reg(hi556, HI556_REG_ANALOG_GAIN,802				      HI556_REG_VALUE_16BIT, ctrl->val);803		break;804 805	case V4L2_CID_DIGITAL_GAIN:806		ret = hi556_update_digital_gain(hi556, ctrl->val);807		break;808 809	case V4L2_CID_EXPOSURE:810		ret = hi556_write_reg(hi556, HI556_REG_EXPOSURE,811				      HI556_REG_VALUE_16BIT, ctrl->val);812		break;813 814	case V4L2_CID_VBLANK:815		/* Update FLL that meets expected vertical blanking */816		ret = hi556_write_reg(hi556, HI556_REG_FLL,817				      HI556_REG_VALUE_16BIT,818				      hi556->cur_mode->height + ctrl->val);819		break;820 821	case V4L2_CID_TEST_PATTERN:822		ret = hi556_test_pattern(hi556, ctrl->val);823		break;824 825	default:826		ret = -EINVAL;827		break;828	}829 830	pm_runtime_put(&client->dev);831 832	return ret;833}834 835static const struct v4l2_ctrl_ops hi556_ctrl_ops = {836	.s_ctrl = hi556_set_ctrl,837};838 839static int hi556_init_controls(struct hi556 *hi556)840{841	struct v4l2_ctrl_handler *ctrl_hdlr;842	s64 exposure_max, h_blank;843	int ret;844 845	ctrl_hdlr = &hi556->ctrl_handler;846	ret = v4l2_ctrl_handler_init(ctrl_hdlr, 8);847	if (ret)848		return ret;849 850	ctrl_hdlr->lock = &hi556->mutex;851	hi556->link_freq = v4l2_ctrl_new_int_menu(ctrl_hdlr, &hi556_ctrl_ops,852						  V4L2_CID_LINK_FREQ,853					ARRAY_SIZE(link_freq_menu_items) - 1,854					0, link_freq_menu_items);855	if (hi556->link_freq)856		hi556->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;857 858	hi556->pixel_rate = v4l2_ctrl_new_std859			    (ctrl_hdlr, &hi556_ctrl_ops,860			     V4L2_CID_PIXEL_RATE, 0,861			     to_pixel_rate(HI556_LINK_FREQ_437MHZ_INDEX),862			     1,863			     to_pixel_rate(HI556_LINK_FREQ_437MHZ_INDEX));864	hi556->vblank = v4l2_ctrl_new_std(ctrl_hdlr, &hi556_ctrl_ops,865					  V4L2_CID_VBLANK,866					  hi556->cur_mode->fll_min -867					  hi556->cur_mode->height,868					  HI556_FLL_MAX -869					  hi556->cur_mode->height, 1,870					  hi556->cur_mode->fll_def -871					  hi556->cur_mode->height);872 873	h_blank = hi556->cur_mode->llp - hi556->cur_mode->width;874 875	hi556->hblank = v4l2_ctrl_new_std(ctrl_hdlr, &hi556_ctrl_ops,876					  V4L2_CID_HBLANK, h_blank, h_blank, 1,877					  h_blank);878	if (hi556->hblank)879		hi556->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;880 881	v4l2_ctrl_new_std(ctrl_hdlr, &hi556_ctrl_ops, V4L2_CID_ANALOGUE_GAIN,882			  HI556_ANAL_GAIN_MIN, HI556_ANAL_GAIN_MAX,883			  HI556_ANAL_GAIN_STEP, HI556_ANAL_GAIN_MIN);884	v4l2_ctrl_new_std(ctrl_hdlr, &hi556_ctrl_ops, V4L2_CID_DIGITAL_GAIN,885			  HI556_DGTL_GAIN_MIN, HI556_DGTL_GAIN_MAX,886			  HI556_DGTL_GAIN_STEP, HI556_DGTL_GAIN_DEFAULT);887	exposure_max = hi556->cur_mode->fll_def - HI556_EXPOSURE_MAX_MARGIN;888	hi556->exposure = v4l2_ctrl_new_std(ctrl_hdlr, &hi556_ctrl_ops,889					    V4L2_CID_EXPOSURE,890					    HI556_EXPOSURE_MIN, exposure_max,891					    HI556_EXPOSURE_STEP,892					    exposure_max);893	v4l2_ctrl_new_std_menu_items(ctrl_hdlr, &hi556_ctrl_ops,894				     V4L2_CID_TEST_PATTERN,895				     ARRAY_SIZE(hi556_test_pattern_menu) - 1,896				     0, 0, hi556_test_pattern_menu);897	if (ctrl_hdlr->error)898		return ctrl_hdlr->error;899 900	hi556->sd.ctrl_handler = ctrl_hdlr;901 902	return 0;903}904 905static void hi556_assign_pad_format(const struct hi556_mode *mode,906				    struct v4l2_mbus_framefmt *fmt)907{908	fmt->width = mode->width;909	fmt->height = mode->height;910	fmt->code = MEDIA_BUS_FMT_SGRBG10_1X10;911	fmt->field = V4L2_FIELD_NONE;912}913 914static int hi556_identify_module(struct hi556 *hi556)915{916	struct i2c_client *client = v4l2_get_subdevdata(&hi556->sd);917	int ret;918	u32 val;919 920	if (hi556->identified)921		return 0;922 923	ret = hi556_read_reg(hi556, HI556_REG_CHIP_ID,924			     HI556_REG_VALUE_16BIT, &val);925	if (ret)926		return ret;927 928	if (val != HI556_CHIP_ID) {929		dev_err(&client->dev, "chip id mismatch: %x!=%x",930			HI556_CHIP_ID, val);931		return -ENXIO;932	}933 934	hi556->identified = true;935 936	return 0;937}938 939static const struct v4l2_rect *940__hi556_get_pad_crop(struct hi556 *hi556,941		     struct v4l2_subdev_state *sd_state,942		     unsigned int pad, enum v4l2_subdev_format_whence which)943{944	switch (which) {945	case V4L2_SUBDEV_FORMAT_TRY:946		return v4l2_subdev_state_get_crop(sd_state, pad);947	case V4L2_SUBDEV_FORMAT_ACTIVE:948		return &hi556->cur_mode->crop;949	}950 951	return NULL;952}953 954static int hi556_get_selection(struct v4l2_subdev *sd,955			       struct v4l2_subdev_state *sd_state,956			       struct v4l2_subdev_selection *sel)957{958	switch (sel->target) {959	case V4L2_SEL_TGT_CROP: {960		struct hi556 *hi556 = to_hi556(sd);961 962		mutex_lock(&hi556->mutex);963		sel->r = *__hi556_get_pad_crop(hi556, sd_state, sel->pad,964						sel->which);965		mutex_unlock(&hi556->mutex);966 967		return 0;968	}969 970	case V4L2_SEL_TGT_NATIVE_SIZE:971		sel->r.top = 0;972		sel->r.left = 0;973		sel->r.width = HI556_NATIVE_WIDTH;974		sel->r.height = HI556_NATIVE_HEIGHT;975 976		return 0;977 978	case V4L2_SEL_TGT_CROP_DEFAULT:979	case V4L2_SEL_TGT_CROP_BOUNDS:980		sel->r.top = HI556_PIXEL_ARRAY_TOP;981		sel->r.left = HI556_PIXEL_ARRAY_LEFT;982		sel->r.width = HI556_PIXEL_ARRAY_WIDTH;983		sel->r.height = HI556_PIXEL_ARRAY_HEIGHT;984 985		return 0;986	}987 988	return -EINVAL;989}990 991static int hi556_start_streaming(struct hi556 *hi556)992{993	struct i2c_client *client = v4l2_get_subdevdata(&hi556->sd);994	const struct hi556_reg_list *reg_list;995	int link_freq_index, ret;996 997	ret = hi556_identify_module(hi556);998	if (ret)999		return ret;1000 1001	link_freq_index = hi556->cur_mode->link_freq_index;1002	reg_list = &link_freq_configs[link_freq_index].reg_list;1003	ret = hi556_write_reg_list(hi556, reg_list);1004	if (ret) {1005		dev_err(&client->dev, "failed to set plls");1006		return ret;1007	}1008 1009	reg_list = &hi556->cur_mode->reg_list;1010	ret = hi556_write_reg_list(hi556, reg_list);1011	if (ret) {1012		dev_err(&client->dev, "failed to set mode");1013		return ret;1014	}1015 1016	ret = __v4l2_ctrl_handler_setup(hi556->sd.ctrl_handler);1017	if (ret)1018		return ret;1019 1020	ret = hi556_write_reg(hi556, HI556_REG_MODE_SELECT,1021			      HI556_REG_VALUE_16BIT, HI556_MODE_STREAMING);1022 1023	if (ret) {1024		dev_err(&client->dev, "failed to set stream");1025		return ret;1026	}1027 1028	return 0;1029}1030 1031static void hi556_stop_streaming(struct hi556 *hi556)1032{1033	struct i2c_client *client = v4l2_get_subdevdata(&hi556->sd);1034 1035	if (hi556_write_reg(hi556, HI556_REG_MODE_SELECT,1036			    HI556_REG_VALUE_16BIT, HI556_MODE_STANDBY))1037		dev_err(&client->dev, "failed to set stream");1038}1039 1040static int hi556_set_stream(struct v4l2_subdev *sd, int enable)1041{1042	struct hi556 *hi556 = to_hi556(sd);1043	struct i2c_client *client = v4l2_get_subdevdata(sd);1044	int ret = 0;1045 1046	mutex_lock(&hi556->mutex);1047	if (enable) {1048		ret = pm_runtime_resume_and_get(&client->dev);1049		if (ret < 0) {1050			mutex_unlock(&hi556->mutex);1051			return ret;1052		}1053 1054		ret = hi556_start_streaming(hi556);1055		if (ret) {1056			enable = 0;1057			hi556_stop_streaming(hi556);1058			pm_runtime_put(&client->dev);1059		}1060	} else {1061		hi556_stop_streaming(hi556);1062		pm_runtime_put(&client->dev);1063	}1064 1065	mutex_unlock(&hi556->mutex);1066 1067	return ret;1068}1069 1070static int hi556_set_format(struct v4l2_subdev *sd,1071			    struct v4l2_subdev_state *sd_state,1072			    struct v4l2_subdev_format *fmt)1073{1074	struct hi556 *hi556 = to_hi556(sd);1075	const struct hi556_mode *mode;1076	s32 vblank_def, h_blank;1077 1078	mode = v4l2_find_nearest_size(supported_modes,1079				      ARRAY_SIZE(supported_modes), width,1080				      height, fmt->format.width,1081				      fmt->format.height);1082 1083	mutex_lock(&hi556->mutex);1084	hi556_assign_pad_format(mode, &fmt->format);1085	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {1086		*v4l2_subdev_state_get_format(sd_state, fmt->pad) = fmt->format;1087	} else {1088		hi556->cur_mode = mode;1089		__v4l2_ctrl_s_ctrl(hi556->link_freq, mode->link_freq_index);1090		__v4l2_ctrl_s_ctrl_int64(hi556->pixel_rate,1091					 to_pixel_rate(mode->link_freq_index));1092 1093		/* Update limits and set FPS to default */1094		vblank_def = mode->fll_def - mode->height;1095		__v4l2_ctrl_modify_range(hi556->vblank,1096					 mode->fll_min - mode->height,1097					 HI556_FLL_MAX - mode->height, 1,1098					 vblank_def);1099		__v4l2_ctrl_s_ctrl(hi556->vblank, vblank_def);1100 1101		h_blank = hi556->cur_mode->llp - hi556->cur_mode->width;1102 1103		__v4l2_ctrl_modify_range(hi556->hblank, h_blank, h_blank, 1,1104					 h_blank);1105	}1106 1107	mutex_unlock(&hi556->mutex);1108 1109	return 0;1110}1111 1112static int hi556_get_format(struct v4l2_subdev *sd,1113			    struct v4l2_subdev_state *sd_state,1114			    struct v4l2_subdev_format *fmt)1115{1116	struct hi556 *hi556 = to_hi556(sd);1117 1118	mutex_lock(&hi556->mutex);1119	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY)1120		fmt->format = *v4l2_subdev_state_get_format(sd_state,1121							    fmt->pad);1122	else1123		hi556_assign_pad_format(hi556->cur_mode, &fmt->format);1124 1125	mutex_unlock(&hi556->mutex);1126 1127	return 0;1128}1129 1130static int hi556_enum_mbus_code(struct v4l2_subdev *sd,1131				struct v4l2_subdev_state *sd_state,1132				struct v4l2_subdev_mbus_code_enum *code)1133{1134	if (code->index > 0)1135		return -EINVAL;1136 1137	code->code = MEDIA_BUS_FMT_SGRBG10_1X10;1138 1139	return 0;1140}1141 1142static int hi556_enum_frame_size(struct v4l2_subdev *sd,1143				 struct v4l2_subdev_state *sd_state,1144				 struct v4l2_subdev_frame_size_enum *fse)1145{1146	if (fse->index >= ARRAY_SIZE(supported_modes))1147		return -EINVAL;1148 1149	if (fse->code != MEDIA_BUS_FMT_SGRBG10_1X10)1150		return -EINVAL;1151 1152	fse->min_width = supported_modes[fse->index].width;1153	fse->max_width = fse->min_width;1154	fse->min_height = supported_modes[fse->index].height;1155	fse->max_height = fse->min_height;1156 1157	return 0;1158}1159 1160static int hi556_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)1161{1162	struct hi556 *hi556 = to_hi556(sd);1163	struct v4l2_rect *try_crop;1164 1165	mutex_lock(&hi556->mutex);1166	hi556_assign_pad_format(&supported_modes[0],1167				v4l2_subdev_state_get_format(fh->state, 0));1168 1169	/* Initialize try_crop rectangle. */1170	try_crop = v4l2_subdev_state_get_crop(fh->state, 0);1171	try_crop->top = HI556_PIXEL_ARRAY_TOP;1172	try_crop->left = HI556_PIXEL_ARRAY_LEFT;1173	try_crop->width = HI556_PIXEL_ARRAY_WIDTH;1174	try_crop->height = HI556_PIXEL_ARRAY_HEIGHT;1175 1176	mutex_unlock(&hi556->mutex);1177 1178	return 0;1179}1180 1181static const struct v4l2_subdev_video_ops hi556_video_ops = {1182	.s_stream = hi556_set_stream,1183};1184 1185static const struct v4l2_subdev_pad_ops hi556_pad_ops = {1186	.set_fmt = hi556_set_format,1187	.get_fmt = hi556_get_format,1188	.get_selection = hi556_get_selection,1189	.enum_mbus_code = hi556_enum_mbus_code,1190	.enum_frame_size = hi556_enum_frame_size,1191};1192 1193static const struct v4l2_subdev_ops hi556_subdev_ops = {1194	.video = &hi556_video_ops,1195	.pad = &hi556_pad_ops,1196};1197 1198static const struct media_entity_operations hi556_subdev_entity_ops = {1199	.link_validate = v4l2_subdev_link_validate,1200};1201 1202static const struct v4l2_subdev_internal_ops hi556_internal_ops = {1203	.open = hi556_open,1204};1205 1206static int hi556_check_hwcfg(struct device *dev)1207{1208	struct fwnode_handle *ep;1209	struct fwnode_handle *fwnode = dev_fwnode(dev);1210	struct v4l2_fwnode_endpoint bus_cfg = {1211		.bus_type = V4L2_MBUS_CSI2_DPHY1212	};1213	u32 mclk;1214	int ret = 0;1215	unsigned int i, j;1216 1217	/*1218	 * Sometimes the fwnode graph is initialized by the bridge driver,1219	 * wait for this.1220	 */1221	ep = fwnode_graph_get_next_endpoint(fwnode, NULL);1222	if (!ep)1223		return -EPROBE_DEFER;1224 1225	ret = v4l2_fwnode_endpoint_alloc_parse(ep, &bus_cfg);1226	fwnode_handle_put(ep);1227	if (ret)1228		return ret;1229 1230	ret = fwnode_property_read_u32(fwnode, "clock-frequency", &mclk);1231	if (ret) {1232		dev_err(dev, "can't get clock frequency");1233		return ret;1234	}1235 1236	if (mclk != HI556_MCLK) {1237		dev_err(dev, "external clock %d is not supported", mclk);1238		return -EINVAL;1239	}1240 1241	if (bus_cfg.bus.mipi_csi2.num_data_lanes != 2) {1242		dev_err(dev, "number of CSI2 data lanes %d is not supported",1243			bus_cfg.bus.mipi_csi2.num_data_lanes);1244		ret = -EINVAL;1245		goto check_hwcfg_error;1246	}1247 1248	if (!bus_cfg.nr_of_link_frequencies) {1249		dev_err(dev, "no link frequencies defined");1250		ret = -EINVAL;1251		goto check_hwcfg_error;1252	}1253 1254	for (i = 0; i < ARRAY_SIZE(link_freq_menu_items); i++) {1255		for (j = 0; j < bus_cfg.nr_of_link_frequencies; j++) {1256			if (link_freq_menu_items[i] ==1257				bus_cfg.link_frequencies[j])1258				break;1259		}1260 1261		if (j == bus_cfg.nr_of_link_frequencies) {1262			dev_err(dev, "no link frequency %lld supported",1263				link_freq_menu_items[i]);1264			ret = -EINVAL;1265			goto check_hwcfg_error;1266		}1267	}1268 1269check_hwcfg_error:1270	v4l2_fwnode_endpoint_free(&bus_cfg);1271 1272	return ret;1273}1274 1275static void hi556_remove(struct i2c_client *client)1276{1277	struct v4l2_subdev *sd = i2c_get_clientdata(client);1278	struct hi556 *hi556 = to_hi556(sd);1279 1280	v4l2_async_unregister_subdev(sd);1281	media_entity_cleanup(&sd->entity);1282	v4l2_ctrl_handler_free(sd->ctrl_handler);1283	pm_runtime_disable(&client->dev);1284	mutex_destroy(&hi556->mutex);1285}1286 1287static int hi556_suspend(struct device *dev)1288{1289	struct v4l2_subdev *sd = dev_get_drvdata(dev);1290	struct hi556 *hi556 = to_hi556(sd);1291	int ret;1292 1293	gpiod_set_value_cansleep(hi556->reset_gpio, 1);1294 1295	ret = regulator_disable(hi556->avdd);1296	if (ret) {1297		dev_err(dev, "failed to disable avdd: %d\n", ret);1298		gpiod_set_value_cansleep(hi556->reset_gpio, 0);1299		return ret;1300	}1301 1302	clk_disable_unprepare(hi556->clk);1303	return 0;1304}1305 1306static int hi556_resume(struct device *dev)1307{1308	struct v4l2_subdev *sd = dev_get_drvdata(dev);1309	struct hi556 *hi556 = to_hi556(sd);1310	int ret;1311 1312	ret = clk_prepare_enable(hi556->clk);1313	if (ret)1314		return ret;1315 1316	ret = regulator_enable(hi556->avdd);1317	if (ret) {1318		dev_err(dev, "failed to enable avdd: %d\n", ret);1319		clk_disable_unprepare(hi556->clk);1320		return ret;1321	}1322 1323	gpiod_set_value_cansleep(hi556->reset_gpio, 0);1324	usleep_range(5000, 5500);1325	return 0;1326}1327 1328static int hi556_probe(struct i2c_client *client)1329{1330	struct hi556 *hi556;1331	bool full_power;1332	int ret;1333 1334	ret = hi556_check_hwcfg(&client->dev);1335	if (ret) {1336		dev_err(&client->dev, "failed to check HW configuration: %d",1337			ret);1338		return ret;1339	}1340 1341	hi556 = devm_kzalloc(&client->dev, sizeof(*hi556), GFP_KERNEL);1342	if (!hi556)1343		return -ENOMEM;1344 1345	v4l2_i2c_subdev_init(&hi556->sd, client, &hi556_subdev_ops);1346 1347	hi556->reset_gpio = devm_gpiod_get_optional(&client->dev, "reset",1348						    GPIOD_OUT_HIGH);1349	if (IS_ERR(hi556->reset_gpio))1350		return dev_err_probe(&client->dev, PTR_ERR(hi556->reset_gpio),1351				     "failed to get reset GPIO\n");1352 1353	hi556->clk = devm_clk_get_optional(&client->dev, "clk");1354	if (IS_ERR(hi556->clk))1355		return dev_err_probe(&client->dev, PTR_ERR(hi556->clk),1356				     "failed to get clock\n");1357 1358	/* The regulator core will provide a "dummy" regulator if necessary */1359	hi556->avdd = devm_regulator_get(&client->dev, "avdd");1360	if (IS_ERR(hi556->avdd))1361		return dev_err_probe(&client->dev, PTR_ERR(hi556->avdd),1362				     "failed to get avdd regulator\n");1363 1364	full_power = acpi_dev_state_d0(&client->dev);1365	if (full_power) {1366		/* Ensure non ACPI managed resources are enabled */1367		ret = hi556_resume(&client->dev);1368		if (ret)1369			return dev_err_probe(&client->dev, ret,1370					     "failed to power on sensor\n");1371 1372		ret = hi556_identify_module(hi556);1373		if (ret) {1374			dev_err(&client->dev, "failed to find sensor: %d", ret);1375			goto probe_error_power_off;1376		}1377	}1378 1379	mutex_init(&hi556->mutex);1380	hi556->cur_mode = &supported_modes[0];1381	ret = hi556_init_controls(hi556);1382	if (ret) {1383		dev_err(&client->dev, "failed to init controls: %d", ret);1384		goto probe_error_v4l2_ctrl_handler_free;1385	}1386 1387	hi556->sd.internal_ops = &hi556_internal_ops;1388	hi556->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;1389	hi556->sd.entity.ops = &hi556_subdev_entity_ops;1390	hi556->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;1391	hi556->pad.flags = MEDIA_PAD_FL_SOURCE;1392	ret = media_entity_pads_init(&hi556->sd.entity, 1, &hi556->pad);1393	if (ret) {1394		dev_err(&client->dev, "failed to init entity pads: %d", ret);1395		goto probe_error_v4l2_ctrl_handler_free;1396	}1397 1398	ret = v4l2_async_register_subdev_sensor(&hi556->sd);1399	if (ret < 0) {1400		dev_err(&client->dev, "failed to register V4L2 subdev: %d",1401			ret);1402		goto probe_error_media_entity_cleanup;1403	}1404 1405	/* Set the device's state to active if it's in D0 state. */1406	if (full_power)1407		pm_runtime_set_active(&client->dev);1408	pm_runtime_enable(&client->dev);1409	pm_runtime_idle(&client->dev);1410 1411	return 0;1412 1413probe_error_media_entity_cleanup:1414	media_entity_cleanup(&hi556->sd.entity);1415 1416probe_error_v4l2_ctrl_handler_free:1417	v4l2_ctrl_handler_free(hi556->sd.ctrl_handler);1418	mutex_destroy(&hi556->mutex);1419 1420probe_error_power_off:1421	if (full_power)1422		hi556_suspend(&client->dev);1423 1424	return ret;1425}1426 1427static DEFINE_RUNTIME_DEV_PM_OPS(hi556_pm_ops, hi556_suspend, hi556_resume,1428				 NULL);1429 1430#ifdef CONFIG_ACPI1431static const struct acpi_device_id hi556_acpi_ids[] = {1432	{"INT3537"},1433	{}1434};1435 1436MODULE_DEVICE_TABLE(acpi, hi556_acpi_ids);1437#endif1438 1439static struct i2c_driver hi556_i2c_driver = {1440	.driver = {1441		.name = "hi556",1442		.acpi_match_table = ACPI_PTR(hi556_acpi_ids),1443		.pm = pm_sleep_ptr(&hi556_pm_ops),1444	},1445	.probe = hi556_probe,1446	.remove = hi556_remove,1447	.flags = I2C_DRV_ACPI_WAIVE_D0_PROBE,1448};1449 1450module_i2c_driver(hi556_i2c_driver);1451 1452MODULE_AUTHOR("Shawn Tu");1453MODULE_DESCRIPTION("Hynix HI556 sensor driver");1454MODULE_LICENSE("GPL v2");1455