18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * drivers/media/i2c/smiapp/smiapp.h
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * Generic driver for SMIA/SMIA++ compliant camera modules
68c2ecf20Sopenharmony_ci *
78c2ecf20Sopenharmony_ci * Copyright (C) 2010--2012 Nokia Corporation
88c2ecf20Sopenharmony_ci * Contact: Sakari Ailus <sakari.ailus@iki.fi>
98c2ecf20Sopenharmony_ci */
108c2ecf20Sopenharmony_ci
118c2ecf20Sopenharmony_ci#ifndef __SMIAPP_PRIV_H_
128c2ecf20Sopenharmony_ci#define __SMIAPP_PRIV_H_
138c2ecf20Sopenharmony_ci
148c2ecf20Sopenharmony_ci#include <linux/mutex.h>
158c2ecf20Sopenharmony_ci#include <media/v4l2-ctrls.h>
168c2ecf20Sopenharmony_ci#include <media/v4l2-subdev.h>
178c2ecf20Sopenharmony_ci
188c2ecf20Sopenharmony_ci#include "smiapp-pll.h"
198c2ecf20Sopenharmony_ci#include "smiapp-reg.h"
208c2ecf20Sopenharmony_ci#include "smiapp-regs.h"
218c2ecf20Sopenharmony_ci#include "smiapp-quirk.h"
228c2ecf20Sopenharmony_ci
238c2ecf20Sopenharmony_ci/*
248c2ecf20Sopenharmony_ci * Standard SMIA++ constants
258c2ecf20Sopenharmony_ci */
268c2ecf20Sopenharmony_ci#define SMIA_VERSION_1			10
278c2ecf20Sopenharmony_ci#define SMIAPP_VERSION_0_8		8 /* Draft 0.8 */
288c2ecf20Sopenharmony_ci#define SMIAPP_VERSION_0_9		9 /* Draft 0.9 */
298c2ecf20Sopenharmony_ci#define SMIAPP_VERSION_1		10
308c2ecf20Sopenharmony_ci
318c2ecf20Sopenharmony_ci#define SMIAPP_PROFILE_0		0
328c2ecf20Sopenharmony_ci#define SMIAPP_PROFILE_1		1
338c2ecf20Sopenharmony_ci#define SMIAPP_PROFILE_2		2
348c2ecf20Sopenharmony_ci
358c2ecf20Sopenharmony_ci#define SMIAPP_NVM_PAGE_SIZE		64	/* bytes */
368c2ecf20Sopenharmony_ci
378c2ecf20Sopenharmony_ci#define SMIAPP_RESET_DELAY_CLOCKS	2400
388c2ecf20Sopenharmony_ci#define SMIAPP_RESET_DELAY(clk)				\
398c2ecf20Sopenharmony_ci	(1000 +	(SMIAPP_RESET_DELAY_CLOCKS * 1000	\
408c2ecf20Sopenharmony_ci		 + (clk) / 1000 - 1) / ((clk) / 1000))
418c2ecf20Sopenharmony_ci
428c2ecf20Sopenharmony_ci#define SMIAPP_COLOUR_COMPONENTS	4
438c2ecf20Sopenharmony_ci
448c2ecf20Sopenharmony_ci#define SMIAPP_NAME		"smiapp"
458c2ecf20Sopenharmony_ci
468c2ecf20Sopenharmony_ci#define SMIAPP_DFL_I2C_ADDR	(0x20 >> 1) /* Default I2C Address */
478c2ecf20Sopenharmony_ci#define SMIAPP_ALT_I2C_ADDR	(0x6e >> 1) /* Alternate I2C Address */
488c2ecf20Sopenharmony_ci
498c2ecf20Sopenharmony_ci/*
508c2ecf20Sopenharmony_ci * Sometimes due to board layout considerations the camera module can be
518c2ecf20Sopenharmony_ci * mounted rotated. The typical rotation used is 180 degrees which can be
528c2ecf20Sopenharmony_ci * corrected by giving a default H-FLIP and V-FLIP in the sensor readout.
538c2ecf20Sopenharmony_ci * FIXME: rotation also changes the bayer pattern.
548c2ecf20Sopenharmony_ci */
558c2ecf20Sopenharmony_cienum smiapp_module_board_orient {
568c2ecf20Sopenharmony_ci	SMIAPP_MODULE_BOARD_ORIENT_0 = 0,
578c2ecf20Sopenharmony_ci	SMIAPP_MODULE_BOARD_ORIENT_180,
588c2ecf20Sopenharmony_ci};
598c2ecf20Sopenharmony_ci
608c2ecf20Sopenharmony_cistruct smiapp_flash_strobe_parms {
618c2ecf20Sopenharmony_ci	u8 mode;
628c2ecf20Sopenharmony_ci	u32 strobe_width_high_us;
638c2ecf20Sopenharmony_ci	u16 strobe_delay;
648c2ecf20Sopenharmony_ci	u16 stobe_start_point;
658c2ecf20Sopenharmony_ci	u8 trigger;
668c2ecf20Sopenharmony_ci};
678c2ecf20Sopenharmony_ci
688c2ecf20Sopenharmony_cistruct smiapp_hwconfig {
698c2ecf20Sopenharmony_ci	/*
708c2ecf20Sopenharmony_ci	 * Change the cci address if i2c_addr_alt is set.
718c2ecf20Sopenharmony_ci	 * Both default and alternate cci addr need to be present
728c2ecf20Sopenharmony_ci	 */
738c2ecf20Sopenharmony_ci	unsigned short i2c_addr_dfl;	/* Default i2c addr */
748c2ecf20Sopenharmony_ci	unsigned short i2c_addr_alt;	/* Alternate i2c addr */
758c2ecf20Sopenharmony_ci
768c2ecf20Sopenharmony_ci	uint32_t ext_clk;		/* sensor external clk */
778c2ecf20Sopenharmony_ci
788c2ecf20Sopenharmony_ci	unsigned int lanes;		/* Number of CSI-2 lanes */
798c2ecf20Sopenharmony_ci	uint32_t csi_signalling_mode;	/* SMIAPP_CSI_SIGNALLING_MODE_* */
808c2ecf20Sopenharmony_ci	uint64_t *op_sys_clock;
818c2ecf20Sopenharmony_ci
828c2ecf20Sopenharmony_ci	enum smiapp_module_board_orient module_board_orient;
838c2ecf20Sopenharmony_ci
848c2ecf20Sopenharmony_ci	struct smiapp_flash_strobe_parms *strobe_setup;
858c2ecf20Sopenharmony_ci};
868c2ecf20Sopenharmony_ci
878c2ecf20Sopenharmony_ci#include "smiapp-limits.h"
888c2ecf20Sopenharmony_ci
898c2ecf20Sopenharmony_cistruct smiapp_quirk;
908c2ecf20Sopenharmony_ci
918c2ecf20Sopenharmony_ci#define SMIAPP_MODULE_IDENT_FLAG_REV_LE		(1 << 0)
928c2ecf20Sopenharmony_ci
938c2ecf20Sopenharmony_cistruct smiapp_module_ident {
948c2ecf20Sopenharmony_ci	u8 manufacturer_id;
958c2ecf20Sopenharmony_ci	u16 model_id;
968c2ecf20Sopenharmony_ci	u8 revision_number_major;
978c2ecf20Sopenharmony_ci
988c2ecf20Sopenharmony_ci	u8 flags;
998c2ecf20Sopenharmony_ci
1008c2ecf20Sopenharmony_ci	char *name;
1018c2ecf20Sopenharmony_ci	const struct smiapp_quirk *quirk;
1028c2ecf20Sopenharmony_ci};
1038c2ecf20Sopenharmony_ci
1048c2ecf20Sopenharmony_cistruct smiapp_module_info {
1058c2ecf20Sopenharmony_ci	u32 manufacturer_id;
1068c2ecf20Sopenharmony_ci	u32 model_id;
1078c2ecf20Sopenharmony_ci	u32 revision_number_major;
1088c2ecf20Sopenharmony_ci	u32 revision_number_minor;
1098c2ecf20Sopenharmony_ci
1108c2ecf20Sopenharmony_ci	u32 module_year;
1118c2ecf20Sopenharmony_ci	u32 module_month;
1128c2ecf20Sopenharmony_ci	u32 module_day;
1138c2ecf20Sopenharmony_ci
1148c2ecf20Sopenharmony_ci	u32 sensor_manufacturer_id;
1158c2ecf20Sopenharmony_ci	u32 sensor_model_id;
1168c2ecf20Sopenharmony_ci	u32 sensor_revision_number;
1178c2ecf20Sopenharmony_ci	u32 sensor_firmware_version;
1188c2ecf20Sopenharmony_ci
1198c2ecf20Sopenharmony_ci	u32 smia_version;
1208c2ecf20Sopenharmony_ci	u32 smiapp_version;
1218c2ecf20Sopenharmony_ci
1228c2ecf20Sopenharmony_ci	u32 smiapp_profile;
1238c2ecf20Sopenharmony_ci
1248c2ecf20Sopenharmony_ci	char *name;
1258c2ecf20Sopenharmony_ci	const struct smiapp_quirk *quirk;
1268c2ecf20Sopenharmony_ci};
1278c2ecf20Sopenharmony_ci
1288c2ecf20Sopenharmony_ci#define SMIAPP_IDENT_FQ(manufacturer, model, rev, fl, _name, _quirk)	\
1298c2ecf20Sopenharmony_ci	{ .manufacturer_id = manufacturer,				\
1308c2ecf20Sopenharmony_ci	  .model_id = model,						\
1318c2ecf20Sopenharmony_ci	  .revision_number_major = rev,					\
1328c2ecf20Sopenharmony_ci	  .flags = fl,							\
1338c2ecf20Sopenharmony_ci	  .name = _name,						\
1348c2ecf20Sopenharmony_ci	  .quirk = _quirk, }
1358c2ecf20Sopenharmony_ci
1368c2ecf20Sopenharmony_ci#define SMIAPP_IDENT_LQ(manufacturer, model, rev, _name, _quirk)	\
1378c2ecf20Sopenharmony_ci	{ .manufacturer_id = manufacturer,				\
1388c2ecf20Sopenharmony_ci	  .model_id = model,						\
1398c2ecf20Sopenharmony_ci	  .revision_number_major = rev,					\
1408c2ecf20Sopenharmony_ci	  .flags = SMIAPP_MODULE_IDENT_FLAG_REV_LE,			\
1418c2ecf20Sopenharmony_ci	  .name = _name,						\
1428c2ecf20Sopenharmony_ci	  .quirk = _quirk, }
1438c2ecf20Sopenharmony_ci
1448c2ecf20Sopenharmony_ci#define SMIAPP_IDENT_L(manufacturer, model, rev, _name)			\
1458c2ecf20Sopenharmony_ci	{ .manufacturer_id = manufacturer,				\
1468c2ecf20Sopenharmony_ci	  .model_id = model,						\
1478c2ecf20Sopenharmony_ci	  .revision_number_major = rev,					\
1488c2ecf20Sopenharmony_ci	  .flags = SMIAPP_MODULE_IDENT_FLAG_REV_LE,			\
1498c2ecf20Sopenharmony_ci	  .name = _name, }
1508c2ecf20Sopenharmony_ci
1518c2ecf20Sopenharmony_ci#define SMIAPP_IDENT_Q(manufacturer, model, rev, _name, _quirk)		\
1528c2ecf20Sopenharmony_ci	{ .manufacturer_id = manufacturer,				\
1538c2ecf20Sopenharmony_ci	  .model_id = model,						\
1548c2ecf20Sopenharmony_ci	  .revision_number_major = rev,					\
1558c2ecf20Sopenharmony_ci	  .flags = 0,							\
1568c2ecf20Sopenharmony_ci	  .name = _name,						\
1578c2ecf20Sopenharmony_ci	  .quirk = _quirk, }
1588c2ecf20Sopenharmony_ci
1598c2ecf20Sopenharmony_ci#define SMIAPP_IDENT(manufacturer, model, rev, _name)			\
1608c2ecf20Sopenharmony_ci	{ .manufacturer_id = manufacturer,				\
1618c2ecf20Sopenharmony_ci	  .model_id = model,						\
1628c2ecf20Sopenharmony_ci	  .revision_number_major = rev,					\
1638c2ecf20Sopenharmony_ci	  .flags = 0,							\
1648c2ecf20Sopenharmony_ci	  .name = _name, }
1658c2ecf20Sopenharmony_ci
1668c2ecf20Sopenharmony_cistruct smiapp_reg_limits {
1678c2ecf20Sopenharmony_ci	u32 addr;
1688c2ecf20Sopenharmony_ci	char *what;
1698c2ecf20Sopenharmony_ci};
1708c2ecf20Sopenharmony_ci
1718c2ecf20Sopenharmony_ciextern struct smiapp_reg_limits smiapp_reg_limits[];
1728c2ecf20Sopenharmony_ci
1738c2ecf20Sopenharmony_cistruct smiapp_csi_data_format {
1748c2ecf20Sopenharmony_ci	u32 code;
1758c2ecf20Sopenharmony_ci	u8 width;
1768c2ecf20Sopenharmony_ci	u8 compressed;
1778c2ecf20Sopenharmony_ci	u8 pixel_order;
1788c2ecf20Sopenharmony_ci};
1798c2ecf20Sopenharmony_ci
1808c2ecf20Sopenharmony_ci#define SMIAPP_SUBDEVS			3
1818c2ecf20Sopenharmony_ci
1828c2ecf20Sopenharmony_ci#define SMIAPP_PA_PAD_SRC		0
1838c2ecf20Sopenharmony_ci#define SMIAPP_PAD_SINK			0
1848c2ecf20Sopenharmony_ci#define SMIAPP_PAD_SRC			1
1858c2ecf20Sopenharmony_ci#define SMIAPP_PADS			2
1868c2ecf20Sopenharmony_ci
1878c2ecf20Sopenharmony_cistruct smiapp_binning_subtype {
1888c2ecf20Sopenharmony_ci	u8 horizontal:4;
1898c2ecf20Sopenharmony_ci	u8 vertical:4;
1908c2ecf20Sopenharmony_ci} __packed;
1918c2ecf20Sopenharmony_ci
1928c2ecf20Sopenharmony_cistruct smiapp_subdev {
1938c2ecf20Sopenharmony_ci	struct v4l2_subdev sd;
1948c2ecf20Sopenharmony_ci	struct media_pad pads[SMIAPP_PADS];
1958c2ecf20Sopenharmony_ci	struct v4l2_rect sink_fmt;
1968c2ecf20Sopenharmony_ci	struct v4l2_rect crop[SMIAPP_PADS];
1978c2ecf20Sopenharmony_ci	struct v4l2_rect compose; /* compose on sink */
1988c2ecf20Sopenharmony_ci	unsigned short sink_pad;
1998c2ecf20Sopenharmony_ci	unsigned short source_pad;
2008c2ecf20Sopenharmony_ci	int npads;
2018c2ecf20Sopenharmony_ci	struct smiapp_sensor *sensor;
2028c2ecf20Sopenharmony_ci	struct v4l2_ctrl_handler ctrl_handler;
2038c2ecf20Sopenharmony_ci};
2048c2ecf20Sopenharmony_ci
2058c2ecf20Sopenharmony_ci/*
2068c2ecf20Sopenharmony_ci * struct smiapp_sensor - Main device structure
2078c2ecf20Sopenharmony_ci */
2088c2ecf20Sopenharmony_cistruct smiapp_sensor {
2098c2ecf20Sopenharmony_ci	/*
2108c2ecf20Sopenharmony_ci	 * "mutex" is used to serialise access to all fields here
2118c2ecf20Sopenharmony_ci	 * except v4l2_ctrls at the end of the struct. "mutex" is also
2128c2ecf20Sopenharmony_ci	 * used to serialise access to file handle specific
2138c2ecf20Sopenharmony_ci	 * information.
2148c2ecf20Sopenharmony_ci	 */
2158c2ecf20Sopenharmony_ci	struct mutex mutex;
2168c2ecf20Sopenharmony_ci	struct smiapp_subdev ssds[SMIAPP_SUBDEVS];
2178c2ecf20Sopenharmony_ci	u32 ssds_used;
2188c2ecf20Sopenharmony_ci	struct smiapp_subdev *src;
2198c2ecf20Sopenharmony_ci	struct smiapp_subdev *binner;
2208c2ecf20Sopenharmony_ci	struct smiapp_subdev *scaler;
2218c2ecf20Sopenharmony_ci	struct smiapp_subdev *pixel_array;
2228c2ecf20Sopenharmony_ci	struct smiapp_hwconfig *hwcfg;
2238c2ecf20Sopenharmony_ci	struct regulator *vana;
2248c2ecf20Sopenharmony_ci	struct clk *ext_clk;
2258c2ecf20Sopenharmony_ci	struct gpio_desc *xshutdown;
2268c2ecf20Sopenharmony_ci	u32 limits[SMIAPP_LIMIT_LAST];
2278c2ecf20Sopenharmony_ci	u8 nbinning_subtypes;
2288c2ecf20Sopenharmony_ci	struct smiapp_binning_subtype binning_subtypes[SMIAPP_BINNING_SUBTYPES];
2298c2ecf20Sopenharmony_ci	u32 mbus_frame_fmts;
2308c2ecf20Sopenharmony_ci	const struct smiapp_csi_data_format *csi_format;
2318c2ecf20Sopenharmony_ci	const struct smiapp_csi_data_format *internal_csi_format;
2328c2ecf20Sopenharmony_ci	u32 default_mbus_frame_fmts;
2338c2ecf20Sopenharmony_ci	int default_pixel_order;
2348c2ecf20Sopenharmony_ci
2358c2ecf20Sopenharmony_ci	u8 binning_horizontal;
2368c2ecf20Sopenharmony_ci	u8 binning_vertical;
2378c2ecf20Sopenharmony_ci
2388c2ecf20Sopenharmony_ci	u8 scale_m;
2398c2ecf20Sopenharmony_ci	u8 scaling_mode;
2408c2ecf20Sopenharmony_ci
2418c2ecf20Sopenharmony_ci	u8 hvflip_inv_mask; /* H/VFLIP inversion due to sensor orientation */
2428c2ecf20Sopenharmony_ci	u8 frame_skip;
2438c2ecf20Sopenharmony_ci	u16 embedded_start; /* embedded data start line */
2448c2ecf20Sopenharmony_ci	u16 embedded_end;
2458c2ecf20Sopenharmony_ci	u16 image_start; /* image data start line */
2468c2ecf20Sopenharmony_ci	u16 visible_pixel_start; /* start pixel of the visible image */
2478c2ecf20Sopenharmony_ci
2488c2ecf20Sopenharmony_ci	bool streaming;
2498c2ecf20Sopenharmony_ci	bool dev_init_done;
2508c2ecf20Sopenharmony_ci	u8 compressed_min_bpp;
2518c2ecf20Sopenharmony_ci
2528c2ecf20Sopenharmony_ci	struct smiapp_module_info minfo;
2538c2ecf20Sopenharmony_ci
2548c2ecf20Sopenharmony_ci	struct smiapp_pll pll;
2558c2ecf20Sopenharmony_ci
2568c2ecf20Sopenharmony_ci	/* Is a default format supported for a given BPP? */
2578c2ecf20Sopenharmony_ci	unsigned long *valid_link_freqs;
2588c2ecf20Sopenharmony_ci
2598c2ecf20Sopenharmony_ci	/* Pixel array controls */
2608c2ecf20Sopenharmony_ci	struct v4l2_ctrl *analog_gain;
2618c2ecf20Sopenharmony_ci	struct v4l2_ctrl *exposure;
2628c2ecf20Sopenharmony_ci	struct v4l2_ctrl *hflip;
2638c2ecf20Sopenharmony_ci	struct v4l2_ctrl *vflip;
2648c2ecf20Sopenharmony_ci	struct v4l2_ctrl *vblank;
2658c2ecf20Sopenharmony_ci	struct v4l2_ctrl *hblank;
2668c2ecf20Sopenharmony_ci	struct v4l2_ctrl *pixel_rate_parray;
2678c2ecf20Sopenharmony_ci	/* src controls */
2688c2ecf20Sopenharmony_ci	struct v4l2_ctrl *link_freq;
2698c2ecf20Sopenharmony_ci	struct v4l2_ctrl *pixel_rate_csi;
2708c2ecf20Sopenharmony_ci	/* test pattern colour components */
2718c2ecf20Sopenharmony_ci	struct v4l2_ctrl *test_data[SMIAPP_COLOUR_COMPONENTS];
2728c2ecf20Sopenharmony_ci};
2738c2ecf20Sopenharmony_ci
2748c2ecf20Sopenharmony_ci#define to_smiapp_subdev(_sd)				\
2758c2ecf20Sopenharmony_ci	container_of(_sd, struct smiapp_subdev, sd)
2768c2ecf20Sopenharmony_ci
2778c2ecf20Sopenharmony_ci#define to_smiapp_sensor(_sd)	\
2788c2ecf20Sopenharmony_ci	(to_smiapp_subdev(_sd)->sensor)
2798c2ecf20Sopenharmony_ci
2808c2ecf20Sopenharmony_ci#endif /* __SMIAPP_PRIV_H_ */
281