xref: /OK3568_Linux_fs/kernel/drivers/media/i2c/smiapp/smiapp.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0-only */
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * drivers/media/i2c/smiapp/smiapp.h
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * Generic driver for SMIA/SMIA++ compliant camera modules
6*4882a593Smuzhiyun  *
7*4882a593Smuzhiyun  * Copyright (C) 2010--2012 Nokia Corporation
8*4882a593Smuzhiyun  * Contact: Sakari Ailus <sakari.ailus@iki.fi>
9*4882a593Smuzhiyun  */
10*4882a593Smuzhiyun 
11*4882a593Smuzhiyun #ifndef __SMIAPP_PRIV_H_
12*4882a593Smuzhiyun #define __SMIAPP_PRIV_H_
13*4882a593Smuzhiyun 
14*4882a593Smuzhiyun #include <linux/mutex.h>
15*4882a593Smuzhiyun #include <media/v4l2-ctrls.h>
16*4882a593Smuzhiyun #include <media/v4l2-subdev.h>
17*4882a593Smuzhiyun 
18*4882a593Smuzhiyun #include "smiapp-pll.h"
19*4882a593Smuzhiyun #include "smiapp-reg.h"
20*4882a593Smuzhiyun #include "smiapp-regs.h"
21*4882a593Smuzhiyun #include "smiapp-quirk.h"
22*4882a593Smuzhiyun 
23*4882a593Smuzhiyun /*
24*4882a593Smuzhiyun  * Standard SMIA++ constants
25*4882a593Smuzhiyun  */
26*4882a593Smuzhiyun #define SMIA_VERSION_1			10
27*4882a593Smuzhiyun #define SMIAPP_VERSION_0_8		8 /* Draft 0.8 */
28*4882a593Smuzhiyun #define SMIAPP_VERSION_0_9		9 /* Draft 0.9 */
29*4882a593Smuzhiyun #define SMIAPP_VERSION_1		10
30*4882a593Smuzhiyun 
31*4882a593Smuzhiyun #define SMIAPP_PROFILE_0		0
32*4882a593Smuzhiyun #define SMIAPP_PROFILE_1		1
33*4882a593Smuzhiyun #define SMIAPP_PROFILE_2		2
34*4882a593Smuzhiyun 
35*4882a593Smuzhiyun #define SMIAPP_NVM_PAGE_SIZE		64	/* bytes */
36*4882a593Smuzhiyun 
37*4882a593Smuzhiyun #define SMIAPP_RESET_DELAY_CLOCKS	2400
38*4882a593Smuzhiyun #define SMIAPP_RESET_DELAY(clk)				\
39*4882a593Smuzhiyun 	(1000 +	(SMIAPP_RESET_DELAY_CLOCKS * 1000	\
40*4882a593Smuzhiyun 		 + (clk) / 1000 - 1) / ((clk) / 1000))
41*4882a593Smuzhiyun 
42*4882a593Smuzhiyun #define SMIAPP_COLOUR_COMPONENTS	4
43*4882a593Smuzhiyun 
44*4882a593Smuzhiyun #define SMIAPP_NAME		"smiapp"
45*4882a593Smuzhiyun 
46*4882a593Smuzhiyun #define SMIAPP_DFL_I2C_ADDR	(0x20 >> 1) /* Default I2C Address */
47*4882a593Smuzhiyun #define SMIAPP_ALT_I2C_ADDR	(0x6e >> 1) /* Alternate I2C Address */
48*4882a593Smuzhiyun 
49*4882a593Smuzhiyun /*
50*4882a593Smuzhiyun  * Sometimes due to board layout considerations the camera module can be
51*4882a593Smuzhiyun  * mounted rotated. The typical rotation used is 180 degrees which can be
52*4882a593Smuzhiyun  * corrected by giving a default H-FLIP and V-FLIP in the sensor readout.
53*4882a593Smuzhiyun  * FIXME: rotation also changes the bayer pattern.
54*4882a593Smuzhiyun  */
55*4882a593Smuzhiyun enum smiapp_module_board_orient {
56*4882a593Smuzhiyun 	SMIAPP_MODULE_BOARD_ORIENT_0 = 0,
57*4882a593Smuzhiyun 	SMIAPP_MODULE_BOARD_ORIENT_180,
58*4882a593Smuzhiyun };
59*4882a593Smuzhiyun 
60*4882a593Smuzhiyun struct smiapp_flash_strobe_parms {
61*4882a593Smuzhiyun 	u8 mode;
62*4882a593Smuzhiyun 	u32 strobe_width_high_us;
63*4882a593Smuzhiyun 	u16 strobe_delay;
64*4882a593Smuzhiyun 	u16 stobe_start_point;
65*4882a593Smuzhiyun 	u8 trigger;
66*4882a593Smuzhiyun };
67*4882a593Smuzhiyun 
68*4882a593Smuzhiyun struct smiapp_hwconfig {
69*4882a593Smuzhiyun 	/*
70*4882a593Smuzhiyun 	 * Change the cci address if i2c_addr_alt is set.
71*4882a593Smuzhiyun 	 * Both default and alternate cci addr need to be present
72*4882a593Smuzhiyun 	 */
73*4882a593Smuzhiyun 	unsigned short i2c_addr_dfl;	/* Default i2c addr */
74*4882a593Smuzhiyun 	unsigned short i2c_addr_alt;	/* Alternate i2c addr */
75*4882a593Smuzhiyun 
76*4882a593Smuzhiyun 	uint32_t ext_clk;		/* sensor external clk */
77*4882a593Smuzhiyun 
78*4882a593Smuzhiyun 	unsigned int lanes;		/* Number of CSI-2 lanes */
79*4882a593Smuzhiyun 	uint32_t csi_signalling_mode;	/* SMIAPP_CSI_SIGNALLING_MODE_* */
80*4882a593Smuzhiyun 	uint64_t *op_sys_clock;
81*4882a593Smuzhiyun 
82*4882a593Smuzhiyun 	enum smiapp_module_board_orient module_board_orient;
83*4882a593Smuzhiyun 
84*4882a593Smuzhiyun 	struct smiapp_flash_strobe_parms *strobe_setup;
85*4882a593Smuzhiyun };
86*4882a593Smuzhiyun 
87*4882a593Smuzhiyun #include "smiapp-limits.h"
88*4882a593Smuzhiyun 
89*4882a593Smuzhiyun struct smiapp_quirk;
90*4882a593Smuzhiyun 
91*4882a593Smuzhiyun #define SMIAPP_MODULE_IDENT_FLAG_REV_LE		(1 << 0)
92*4882a593Smuzhiyun 
93*4882a593Smuzhiyun struct smiapp_module_ident {
94*4882a593Smuzhiyun 	u8 manufacturer_id;
95*4882a593Smuzhiyun 	u16 model_id;
96*4882a593Smuzhiyun 	u8 revision_number_major;
97*4882a593Smuzhiyun 
98*4882a593Smuzhiyun 	u8 flags;
99*4882a593Smuzhiyun 
100*4882a593Smuzhiyun 	char *name;
101*4882a593Smuzhiyun 	const struct smiapp_quirk *quirk;
102*4882a593Smuzhiyun };
103*4882a593Smuzhiyun 
104*4882a593Smuzhiyun struct smiapp_module_info {
105*4882a593Smuzhiyun 	u32 manufacturer_id;
106*4882a593Smuzhiyun 	u32 model_id;
107*4882a593Smuzhiyun 	u32 revision_number_major;
108*4882a593Smuzhiyun 	u32 revision_number_minor;
109*4882a593Smuzhiyun 
110*4882a593Smuzhiyun 	u32 module_year;
111*4882a593Smuzhiyun 	u32 module_month;
112*4882a593Smuzhiyun 	u32 module_day;
113*4882a593Smuzhiyun 
114*4882a593Smuzhiyun 	u32 sensor_manufacturer_id;
115*4882a593Smuzhiyun 	u32 sensor_model_id;
116*4882a593Smuzhiyun 	u32 sensor_revision_number;
117*4882a593Smuzhiyun 	u32 sensor_firmware_version;
118*4882a593Smuzhiyun 
119*4882a593Smuzhiyun 	u32 smia_version;
120*4882a593Smuzhiyun 	u32 smiapp_version;
121*4882a593Smuzhiyun 
122*4882a593Smuzhiyun 	u32 smiapp_profile;
123*4882a593Smuzhiyun 
124*4882a593Smuzhiyun 	char *name;
125*4882a593Smuzhiyun 	const struct smiapp_quirk *quirk;
126*4882a593Smuzhiyun };
127*4882a593Smuzhiyun 
128*4882a593Smuzhiyun #define SMIAPP_IDENT_FQ(manufacturer, model, rev, fl, _name, _quirk)	\
129*4882a593Smuzhiyun 	{ .manufacturer_id = manufacturer,				\
130*4882a593Smuzhiyun 	  .model_id = model,						\
131*4882a593Smuzhiyun 	  .revision_number_major = rev,					\
132*4882a593Smuzhiyun 	  .flags = fl,							\
133*4882a593Smuzhiyun 	  .name = _name,						\
134*4882a593Smuzhiyun 	  .quirk = _quirk, }
135*4882a593Smuzhiyun 
136*4882a593Smuzhiyun #define SMIAPP_IDENT_LQ(manufacturer, model, rev, _name, _quirk)	\
137*4882a593Smuzhiyun 	{ .manufacturer_id = manufacturer,				\
138*4882a593Smuzhiyun 	  .model_id = model,						\
139*4882a593Smuzhiyun 	  .revision_number_major = rev,					\
140*4882a593Smuzhiyun 	  .flags = SMIAPP_MODULE_IDENT_FLAG_REV_LE,			\
141*4882a593Smuzhiyun 	  .name = _name,						\
142*4882a593Smuzhiyun 	  .quirk = _quirk, }
143*4882a593Smuzhiyun 
144*4882a593Smuzhiyun #define SMIAPP_IDENT_L(manufacturer, model, rev, _name)			\
145*4882a593Smuzhiyun 	{ .manufacturer_id = manufacturer,				\
146*4882a593Smuzhiyun 	  .model_id = model,						\
147*4882a593Smuzhiyun 	  .revision_number_major = rev,					\
148*4882a593Smuzhiyun 	  .flags = SMIAPP_MODULE_IDENT_FLAG_REV_LE,			\
149*4882a593Smuzhiyun 	  .name = _name, }
150*4882a593Smuzhiyun 
151*4882a593Smuzhiyun #define SMIAPP_IDENT_Q(manufacturer, model, rev, _name, _quirk)		\
152*4882a593Smuzhiyun 	{ .manufacturer_id = manufacturer,				\
153*4882a593Smuzhiyun 	  .model_id = model,						\
154*4882a593Smuzhiyun 	  .revision_number_major = rev,					\
155*4882a593Smuzhiyun 	  .flags = 0,							\
156*4882a593Smuzhiyun 	  .name = _name,						\
157*4882a593Smuzhiyun 	  .quirk = _quirk, }
158*4882a593Smuzhiyun 
159*4882a593Smuzhiyun #define SMIAPP_IDENT(manufacturer, model, rev, _name)			\
160*4882a593Smuzhiyun 	{ .manufacturer_id = manufacturer,				\
161*4882a593Smuzhiyun 	  .model_id = model,						\
162*4882a593Smuzhiyun 	  .revision_number_major = rev,					\
163*4882a593Smuzhiyun 	  .flags = 0,							\
164*4882a593Smuzhiyun 	  .name = _name, }
165*4882a593Smuzhiyun 
166*4882a593Smuzhiyun struct smiapp_reg_limits {
167*4882a593Smuzhiyun 	u32 addr;
168*4882a593Smuzhiyun 	char *what;
169*4882a593Smuzhiyun };
170*4882a593Smuzhiyun 
171*4882a593Smuzhiyun extern struct smiapp_reg_limits smiapp_reg_limits[];
172*4882a593Smuzhiyun 
173*4882a593Smuzhiyun struct smiapp_csi_data_format {
174*4882a593Smuzhiyun 	u32 code;
175*4882a593Smuzhiyun 	u8 width;
176*4882a593Smuzhiyun 	u8 compressed;
177*4882a593Smuzhiyun 	u8 pixel_order;
178*4882a593Smuzhiyun };
179*4882a593Smuzhiyun 
180*4882a593Smuzhiyun #define SMIAPP_SUBDEVS			3
181*4882a593Smuzhiyun 
182*4882a593Smuzhiyun #define SMIAPP_PA_PAD_SRC		0
183*4882a593Smuzhiyun #define SMIAPP_PAD_SINK			0
184*4882a593Smuzhiyun #define SMIAPP_PAD_SRC			1
185*4882a593Smuzhiyun #define SMIAPP_PADS			2
186*4882a593Smuzhiyun 
187*4882a593Smuzhiyun struct smiapp_binning_subtype {
188*4882a593Smuzhiyun 	u8 horizontal:4;
189*4882a593Smuzhiyun 	u8 vertical:4;
190*4882a593Smuzhiyun } __packed;
191*4882a593Smuzhiyun 
192*4882a593Smuzhiyun struct smiapp_subdev {
193*4882a593Smuzhiyun 	struct v4l2_subdev sd;
194*4882a593Smuzhiyun 	struct media_pad pads[SMIAPP_PADS];
195*4882a593Smuzhiyun 	struct v4l2_rect sink_fmt;
196*4882a593Smuzhiyun 	struct v4l2_rect crop[SMIAPP_PADS];
197*4882a593Smuzhiyun 	struct v4l2_rect compose; /* compose on sink */
198*4882a593Smuzhiyun 	unsigned short sink_pad;
199*4882a593Smuzhiyun 	unsigned short source_pad;
200*4882a593Smuzhiyun 	int npads;
201*4882a593Smuzhiyun 	struct smiapp_sensor *sensor;
202*4882a593Smuzhiyun 	struct v4l2_ctrl_handler ctrl_handler;
203*4882a593Smuzhiyun };
204*4882a593Smuzhiyun 
205*4882a593Smuzhiyun /*
206*4882a593Smuzhiyun  * struct smiapp_sensor - Main device structure
207*4882a593Smuzhiyun  */
208*4882a593Smuzhiyun struct smiapp_sensor {
209*4882a593Smuzhiyun 	/*
210*4882a593Smuzhiyun 	 * "mutex" is used to serialise access to all fields here
211*4882a593Smuzhiyun 	 * except v4l2_ctrls at the end of the struct. "mutex" is also
212*4882a593Smuzhiyun 	 * used to serialise access to file handle specific
213*4882a593Smuzhiyun 	 * information.
214*4882a593Smuzhiyun 	 */
215*4882a593Smuzhiyun 	struct mutex mutex;
216*4882a593Smuzhiyun 	struct smiapp_subdev ssds[SMIAPP_SUBDEVS];
217*4882a593Smuzhiyun 	u32 ssds_used;
218*4882a593Smuzhiyun 	struct smiapp_subdev *src;
219*4882a593Smuzhiyun 	struct smiapp_subdev *binner;
220*4882a593Smuzhiyun 	struct smiapp_subdev *scaler;
221*4882a593Smuzhiyun 	struct smiapp_subdev *pixel_array;
222*4882a593Smuzhiyun 	struct smiapp_hwconfig *hwcfg;
223*4882a593Smuzhiyun 	struct regulator *vana;
224*4882a593Smuzhiyun 	struct clk *ext_clk;
225*4882a593Smuzhiyun 	struct gpio_desc *xshutdown;
226*4882a593Smuzhiyun 	u32 limits[SMIAPP_LIMIT_LAST];
227*4882a593Smuzhiyun 	u8 nbinning_subtypes;
228*4882a593Smuzhiyun 	struct smiapp_binning_subtype binning_subtypes[SMIAPP_BINNING_SUBTYPES];
229*4882a593Smuzhiyun 	u32 mbus_frame_fmts;
230*4882a593Smuzhiyun 	const struct smiapp_csi_data_format *csi_format;
231*4882a593Smuzhiyun 	const struct smiapp_csi_data_format *internal_csi_format;
232*4882a593Smuzhiyun 	u32 default_mbus_frame_fmts;
233*4882a593Smuzhiyun 	int default_pixel_order;
234*4882a593Smuzhiyun 
235*4882a593Smuzhiyun 	u8 binning_horizontal;
236*4882a593Smuzhiyun 	u8 binning_vertical;
237*4882a593Smuzhiyun 
238*4882a593Smuzhiyun 	u8 scale_m;
239*4882a593Smuzhiyun 	u8 scaling_mode;
240*4882a593Smuzhiyun 
241*4882a593Smuzhiyun 	u8 hvflip_inv_mask; /* H/VFLIP inversion due to sensor orientation */
242*4882a593Smuzhiyun 	u8 frame_skip;
243*4882a593Smuzhiyun 	u16 embedded_start; /* embedded data start line */
244*4882a593Smuzhiyun 	u16 embedded_end;
245*4882a593Smuzhiyun 	u16 image_start; /* image data start line */
246*4882a593Smuzhiyun 	u16 visible_pixel_start; /* start pixel of the visible image */
247*4882a593Smuzhiyun 
248*4882a593Smuzhiyun 	bool streaming;
249*4882a593Smuzhiyun 	bool dev_init_done;
250*4882a593Smuzhiyun 	u8 compressed_min_bpp;
251*4882a593Smuzhiyun 
252*4882a593Smuzhiyun 	struct smiapp_module_info minfo;
253*4882a593Smuzhiyun 
254*4882a593Smuzhiyun 	struct smiapp_pll pll;
255*4882a593Smuzhiyun 
256*4882a593Smuzhiyun 	/* Is a default format supported for a given BPP? */
257*4882a593Smuzhiyun 	unsigned long *valid_link_freqs;
258*4882a593Smuzhiyun 
259*4882a593Smuzhiyun 	/* Pixel array controls */
260*4882a593Smuzhiyun 	struct v4l2_ctrl *analog_gain;
261*4882a593Smuzhiyun 	struct v4l2_ctrl *exposure;
262*4882a593Smuzhiyun 	struct v4l2_ctrl *hflip;
263*4882a593Smuzhiyun 	struct v4l2_ctrl *vflip;
264*4882a593Smuzhiyun 	struct v4l2_ctrl *vblank;
265*4882a593Smuzhiyun 	struct v4l2_ctrl *hblank;
266*4882a593Smuzhiyun 	struct v4l2_ctrl *pixel_rate_parray;
267*4882a593Smuzhiyun 	/* src controls */
268*4882a593Smuzhiyun 	struct v4l2_ctrl *link_freq;
269*4882a593Smuzhiyun 	struct v4l2_ctrl *pixel_rate_csi;
270*4882a593Smuzhiyun 	/* test pattern colour components */
271*4882a593Smuzhiyun 	struct v4l2_ctrl *test_data[SMIAPP_COLOUR_COMPONENTS];
272*4882a593Smuzhiyun };
273*4882a593Smuzhiyun 
274*4882a593Smuzhiyun #define to_smiapp_subdev(_sd)				\
275*4882a593Smuzhiyun 	container_of(_sd, struct smiapp_subdev, sd)
276*4882a593Smuzhiyun 
277*4882a593Smuzhiyun #define to_smiapp_sensor(_sd)	\
278*4882a593Smuzhiyun 	(to_smiapp_subdev(_sd)->sensor)
279*4882a593Smuzhiyun 
280*4882a593Smuzhiyun #endif /* __SMIAPP_PRIV_H_ */
281