cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

s5k5baf.c (51577B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * Driver for Samsung S5K5BAF UXGA 1/5" 2M CMOS Image Sensor
      4 * with embedded SoC ISP.
      5 *
      6 * Copyright (C) 2013, Samsung Electronics Co., Ltd.
      7 * Andrzej Hajda <a.hajda@samsung.com>
      8 *
      9 * Based on S5K6AA driver authored by Sylwester Nawrocki
     10 * Copyright (C) 2013, Samsung Electronics Co., Ltd.
     11 */
     12
     13#include <linux/clk.h>
     14#include <linux/delay.h>
     15#include <linux/firmware.h>
     16#include <linux/gpio.h>
     17#include <linux/i2c.h>
     18#include <linux/media.h>
     19#include <linux/module.h>
     20#include <linux/of_gpio.h>
     21#include <linux/of_graph.h>
     22#include <linux/regulator/consumer.h>
     23#include <linux/slab.h>
     24
     25#include <media/media-entity.h>
     26#include <media/v4l2-ctrls.h>
     27#include <media/v4l2-device.h>
     28#include <media/v4l2-subdev.h>
     29#include <media/v4l2-mediabus.h>
     30#include <media/v4l2-fwnode.h>
     31
     32static int debug;
     33module_param(debug, int, 0644);
     34
     35#define S5K5BAF_DRIVER_NAME		"s5k5baf"
     36#define S5K5BAF_DEFAULT_MCLK_FREQ	24000000U
     37#define S5K5BAF_CLK_NAME		"mclk"
     38
     39#define S5K5BAF_FW_FILENAME		"s5k5baf-cfg.bin"
     40#define S5K5BAF_FW_TAG			"SF00"
     41#define S5K5BAG_FW_TAG_LEN		2
     42#define S5K5BAG_FW_MAX_COUNT		16
     43
     44#define S5K5BAF_CIS_WIDTH		1600
     45#define S5K5BAF_CIS_HEIGHT		1200
     46#define S5K5BAF_WIN_WIDTH_MIN		8
     47#define S5K5BAF_WIN_HEIGHT_MIN		8
     48#define S5K5BAF_GAIN_RED_DEF		127
     49#define S5K5BAF_GAIN_GREEN_DEF		95
     50#define S5K5BAF_GAIN_BLUE_DEF		180
     51/* Default number of MIPI CSI-2 data lanes used */
     52#define S5K5BAF_DEF_NUM_LANES		1
     53
     54#define AHB_MSB_ADDR_PTR		0xfcfc
     55
     56/*
     57 * Register interface pages (the most significant word of the address)
     58 */
     59#define PAGE_IF_HW			0xd000
     60#define PAGE_IF_SW			0x7000
     61
     62/*
     63 * H/W register Interface (PAGE_IF_HW)
     64 */
     65#define REG_SW_LOAD_COMPLETE		0x0014
     66#define REG_CMDWR_PAGE			0x0028
     67#define REG_CMDWR_ADDR			0x002a
     68#define REG_CMDRD_PAGE			0x002c
     69#define REG_CMDRD_ADDR			0x002e
     70#define REG_CMD_BUF			0x0f12
     71#define REG_SET_HOST_INT		0x1000
     72#define REG_CLEAR_HOST_INT		0x1030
     73#define REG_PATTERN_SET			0x3100
     74#define REG_PATTERN_WIDTH		0x3118
     75#define REG_PATTERN_HEIGHT		0x311a
     76#define REG_PATTERN_PARAM		0x311c
     77
     78/*
     79 * S/W register interface (PAGE_IF_SW)
     80 */
     81
     82/* Firmware revision information */
     83#define REG_FW_APIVER			0x012e
     84#define  S5K5BAF_FW_APIVER		0x0001
     85#define REG_FW_REVISION			0x0130
     86#define REG_FW_SENSOR_ID		0x0152
     87
     88/* Initialization parameters */
     89/* Master clock frequency in KHz */
     90#define REG_I_INCLK_FREQ_L		0x01b8
     91#define REG_I_INCLK_FREQ_H		0x01ba
     92#define  MIN_MCLK_FREQ_KHZ		6000U
     93#define  MAX_MCLK_FREQ_KHZ		48000U
     94#define REG_I_USE_NPVI_CLOCKS		0x01c6
     95#define  NPVI_CLOCKS			1
     96#define REG_I_USE_NMIPI_CLOCKS		0x01c8
     97#define  NMIPI_CLOCKS			1
     98#define REG_I_BLOCK_INTERNAL_PLL_CALC	0x01ca
     99
    100/* Clock configurations, n = 0..2. REG_I_* frequency unit is 4 kHz. */
    101#define REG_I_OPCLK_4KHZ(n)		((n) * 6 + 0x01cc)
    102#define REG_I_MIN_OUTRATE_4KHZ(n)	((n) * 6 + 0x01ce)
    103#define REG_I_MAX_OUTRATE_4KHZ(n)	((n) * 6 + 0x01d0)
    104#define  SCLK_PVI_FREQ			24000
    105#define  SCLK_MIPI_FREQ			48000
    106#define  PCLK_MIN_FREQ			6000
    107#define  PCLK_MAX_FREQ			48000
    108#define REG_I_USE_REGS_API		0x01de
    109#define REG_I_INIT_PARAMS_UPDATED	0x01e0
    110#define REG_I_ERROR_INFO		0x01e2
    111
    112/* General purpose parameters */
    113#define REG_USER_BRIGHTNESS		0x01e4
    114#define REG_USER_CONTRAST		0x01e6
    115#define REG_USER_SATURATION		0x01e8
    116#define REG_USER_SHARPBLUR		0x01ea
    117
    118#define REG_G_SPEC_EFFECTS		0x01ee
    119#define REG_G_ENABLE_PREV		0x01f0
    120#define REG_G_ENABLE_PREV_CHG		0x01f2
    121#define REG_G_NEW_CFG_SYNC		0x01f8
    122#define REG_G_PREVREQ_IN_WIDTH		0x01fa
    123#define REG_G_PREVREQ_IN_HEIGHT		0x01fc
    124#define REG_G_PREVREQ_IN_XOFFS		0x01fe
    125#define REG_G_PREVREQ_IN_YOFFS		0x0200
    126#define REG_G_PREVZOOM_IN_WIDTH		0x020a
    127#define REG_G_PREVZOOM_IN_HEIGHT	0x020c
    128#define REG_G_PREVZOOM_IN_XOFFS		0x020e
    129#define REG_G_PREVZOOM_IN_YOFFS		0x0210
    130#define REG_G_INPUTS_CHANGE_REQ		0x021a
    131#define REG_G_ACTIVE_PREV_CFG		0x021c
    132#define REG_G_PREV_CFG_CHG		0x021e
    133#define REG_G_PREV_OPEN_AFTER_CH	0x0220
    134#define REG_G_PREV_CFG_ERROR		0x0222
    135#define  CFG_ERROR_RANGE		0x0b
    136#define REG_G_PREV_CFG_BYPASS_CHANGED	0x022a
    137#define REG_G_ACTUAL_P_FR_TIME		0x023a
    138#define REG_G_ACTUAL_P_OUT_RATE		0x023c
    139#define REG_G_ACTUAL_C_FR_TIME		0x023e
    140#define REG_G_ACTUAL_C_OUT_RATE		0x0240
    141
    142/* Preview control section. n = 0...4. */
    143#define PREG(n, x)			((n) * 0x26 + x)
    144#define REG_P_OUT_WIDTH(n)		PREG(n, 0x0242)
    145#define REG_P_OUT_HEIGHT(n)		PREG(n, 0x0244)
    146#define REG_P_FMT(n)			PREG(n, 0x0246)
    147#define REG_P_MAX_OUT_RATE(n)		PREG(n, 0x0248)
    148#define REG_P_MIN_OUT_RATE(n)		PREG(n, 0x024a)
    149#define REG_P_PVI_MASK(n)		PREG(n, 0x024c)
    150#define  PVI_MASK_MIPI			0x52
    151#define REG_P_CLK_INDEX(n)		PREG(n, 0x024e)
    152#define  CLK_PVI_INDEX			0
    153#define  CLK_MIPI_INDEX			NPVI_CLOCKS
    154#define REG_P_FR_RATE_TYPE(n)		PREG(n, 0x0250)
    155#define  FR_RATE_DYNAMIC		0
    156#define  FR_RATE_FIXED			1
    157#define  FR_RATE_FIXED_ACCURATE		2
    158#define REG_P_FR_RATE_Q_TYPE(n)		PREG(n, 0x0252)
    159#define  FR_RATE_Q_DYNAMIC		0
    160#define  FR_RATE_Q_BEST_FRRATE		1 /* Binning enabled */
    161#define  FR_RATE_Q_BEST_QUALITY		2 /* Binning disabled */
    162/* Frame period in 0.1 ms units */
    163#define REG_P_MAX_FR_TIME(n)		PREG(n, 0x0254)
    164#define REG_P_MIN_FR_TIME(n)		PREG(n, 0x0256)
    165#define  S5K5BAF_MIN_FR_TIME		333  /* x100 us */
    166#define  S5K5BAF_MAX_FR_TIME		6500 /* x100 us */
    167/* The below 5 registers are for "device correction" values */
    168#define REG_P_SATURATION(n)		PREG(n, 0x0258)
    169#define REG_P_SHARP_BLUR(n)		PREG(n, 0x025a)
    170#define REG_P_GLAMOUR(n)		PREG(n, 0x025c)
    171#define REG_P_COLORTEMP(n)		PREG(n, 0x025e)
    172#define REG_P_GAMMA_INDEX(n)		PREG(n, 0x0260)
    173#define REG_P_PREV_MIRROR(n)		PREG(n, 0x0262)
    174#define REG_P_CAP_MIRROR(n)		PREG(n, 0x0264)
    175#define REG_P_CAP_ROTATION(n)		PREG(n, 0x0266)
    176
    177/* Extended image property controls */
    178/* Exposure time in 10 us units */
    179#define REG_SF_USR_EXPOSURE_L		0x03bc
    180#define REG_SF_USR_EXPOSURE_H		0x03be
    181#define REG_SF_USR_EXPOSURE_CHG		0x03c0
    182#define REG_SF_USR_TOT_GAIN		0x03c2
    183#define REG_SF_USR_TOT_GAIN_CHG		0x03c4
    184#define REG_SF_RGAIN			0x03c6
    185#define REG_SF_RGAIN_CHG		0x03c8
    186#define REG_SF_GGAIN			0x03ca
    187#define REG_SF_GGAIN_CHG		0x03cc
    188#define REG_SF_BGAIN			0x03ce
    189#define REG_SF_BGAIN_CHG		0x03d0
    190#define REG_SF_WBGAIN_CHG		0x03d2
    191#define REG_SF_FLICKER_QUANT		0x03d4
    192#define REG_SF_FLICKER_QUANT_CHG	0x03d6
    193
    194/* Output interface (parallel/MIPI) setup */
    195#define REG_OIF_EN_MIPI_LANES		0x03f2
    196#define REG_OIF_EN_PACKETS		0x03f4
    197#define  EN_PACKETS_CSI2		0xc3
    198#define REG_OIF_CFG_CHG			0x03f6
    199
    200/* Auto-algorithms enable mask */
    201#define REG_DBG_AUTOALG_EN		0x03f8
    202#define  AALG_ALL_EN			BIT(0)
    203#define  AALG_AE_EN			BIT(1)
    204#define  AALG_DIVLEI_EN			BIT(2)
    205#define  AALG_WB_EN			BIT(3)
    206#define  AALG_USE_WB_FOR_ISP		BIT(4)
    207#define  AALG_FLICKER_EN		BIT(5)
    208#define  AALG_FIT_EN			BIT(6)
    209#define  AALG_WRHW_EN			BIT(7)
    210
    211/* Pointers to color correction matrices */
    212#define REG_PTR_CCM_HORIZON		0x06d0
    213#define REG_PTR_CCM_INCANDESCENT	0x06d4
    214#define REG_PTR_CCM_WARM_WHITE		0x06d8
    215#define REG_PTR_CCM_COOL_WHITE		0x06dc
    216#define REG_PTR_CCM_DL50		0x06e0
    217#define REG_PTR_CCM_DL65		0x06e4
    218#define REG_PTR_CCM_OUTDOOR		0x06ec
    219
    220#define REG_ARR_CCM(n)			(0x2800 + 36 * (n))
    221
    222static const char * const s5k5baf_supply_names[] = {
    223	"vdda",		/* Analog power supply 2.8V (2.6V to 3.0V) */
    224	"vddreg",	/* Regulator input power supply 1.8V (1.7V to 1.9V)
    225			   or 2.8V (2.6V to 3.0) */
    226	"vddio",	/* I/O power supply 1.8V (1.65V to 1.95V)
    227			   or 2.8V (2.5V to 3.1V) */
    228};
    229#define S5K5BAF_NUM_SUPPLIES ARRAY_SIZE(s5k5baf_supply_names)
    230
    231struct s5k5baf_gpio {
    232	int gpio;
    233	int level;
    234};
    235
    236enum s5k5baf_gpio_id {
    237	STBY,
    238	RSET,
    239	NUM_GPIOS,
    240};
    241
    242#define PAD_CIS 0
    243#define PAD_OUT 1
    244#define NUM_CIS_PADS 1
    245#define NUM_ISP_PADS 2
    246
    247struct s5k5baf_pixfmt {
    248	u32 code;
    249	u32 colorspace;
    250	/* REG_P_FMT(x) register value */
    251	u16 reg_p_fmt;
    252};
    253
    254struct s5k5baf_ctrls {
    255	struct v4l2_ctrl_handler handler;
    256	struct { /* Auto / manual white balance cluster */
    257		struct v4l2_ctrl *awb;
    258		struct v4l2_ctrl *gain_red;
    259		struct v4l2_ctrl *gain_blue;
    260	};
    261	struct { /* Mirror cluster */
    262		struct v4l2_ctrl *hflip;
    263		struct v4l2_ctrl *vflip;
    264	};
    265	struct { /* Auto exposure / manual exposure and gain cluster */
    266		struct v4l2_ctrl *auto_exp;
    267		struct v4l2_ctrl *exposure;
    268		struct v4l2_ctrl *gain;
    269	};
    270};
    271
    272enum {
    273	S5K5BAF_FW_ID_PATCH,
    274	S5K5BAF_FW_ID_CCM,
    275	S5K5BAF_FW_ID_CIS,
    276};
    277
    278struct s5k5baf_fw {
    279	u16 count;
    280	struct {
    281		u16 id;
    282		u16 offset;
    283	} seq[];
    284};
    285
    286struct s5k5baf {
    287	struct s5k5baf_gpio gpios[NUM_GPIOS];
    288	enum v4l2_mbus_type bus_type;
    289	u8 nlanes;
    290	struct regulator_bulk_data supplies[S5K5BAF_NUM_SUPPLIES];
    291
    292	struct clk *clock;
    293	u32 mclk_frequency;
    294
    295	struct s5k5baf_fw *fw;
    296
    297	struct v4l2_subdev cis_sd;
    298	struct media_pad cis_pad;
    299
    300	struct v4l2_subdev sd;
    301	struct media_pad pads[NUM_ISP_PADS];
    302
    303	/* protects the struct members below */
    304	struct mutex lock;
    305
    306	int error;
    307
    308	struct v4l2_rect crop_sink;
    309	struct v4l2_rect compose;
    310	struct v4l2_rect crop_source;
    311	/* index to s5k5baf_formats array */
    312	int pixfmt;
    313	/* actual frame interval in 100us */
    314	u16 fiv;
    315	/* requested frame interval in 100us */
    316	u16 req_fiv;
    317	/* cache for REG_DBG_AUTOALG_EN register */
    318	u16 auto_alg;
    319
    320	struct s5k5baf_ctrls ctrls;
    321
    322	unsigned int streaming:1;
    323	unsigned int apply_cfg:1;
    324	unsigned int apply_crop:1;
    325	unsigned int valid_auto_alg:1;
    326	unsigned int power;
    327};
    328
    329static const struct s5k5baf_pixfmt s5k5baf_formats[] = {
    330	{ MEDIA_BUS_FMT_VYUY8_2X8,	V4L2_COLORSPACE_JPEG,	5 },
    331	/* range 16-240 */
    332	{ MEDIA_BUS_FMT_VYUY8_2X8,	V4L2_COLORSPACE_REC709,	6 },
    333	{ MEDIA_BUS_FMT_RGB565_2X8_BE,	V4L2_COLORSPACE_JPEG,	0 },
    334};
    335
    336static struct v4l2_rect s5k5baf_cis_rect = {
    337	0, 0, S5K5BAF_CIS_WIDTH, S5K5BAF_CIS_HEIGHT
    338};
    339
    340/* Setfile contains set of I2C command sequences. Each sequence has its ID.
    341 * setfile format:
    342 *	u8 magic[4];
    343 *	u16 count;		number of sequences
    344 *	struct {
    345 *		u16 id;		sequence id
    346 *		u16 offset;	sequence offset in data array
    347 *	} seq[count];
    348 *	u16 data[*];		array containing sequences
    349 *
    350 */
    351static int s5k5baf_fw_parse(struct device *dev, struct s5k5baf_fw **fw,
    352			    size_t count, const __le16 *data)
    353{
    354	struct s5k5baf_fw *f;
    355	u16 *d, i, *end;
    356	int ret;
    357
    358	if (count < S5K5BAG_FW_TAG_LEN + 1) {
    359		dev_err(dev, "firmware file too short (%zu)\n", count);
    360		return -EINVAL;
    361	}
    362
    363	ret = memcmp(data, S5K5BAF_FW_TAG, S5K5BAG_FW_TAG_LEN * sizeof(u16));
    364	if (ret != 0) {
    365		dev_err(dev, "invalid firmware magic number\n");
    366		return -EINVAL;
    367	}
    368
    369	data += S5K5BAG_FW_TAG_LEN;
    370	count -= S5K5BAG_FW_TAG_LEN;
    371
    372	d = devm_kcalloc(dev, count, sizeof(u16), GFP_KERNEL);
    373	if (!d)
    374		return -ENOMEM;
    375
    376	for (i = 0; i < count; ++i)
    377		d[i] = le16_to_cpu(data[i]);
    378
    379	f = (struct s5k5baf_fw *)d;
    380	if (count < 1 + 2 * f->count) {
    381		dev_err(dev, "invalid firmware header (count=%d size=%zu)\n",
    382			f->count, 2 * (count + S5K5BAG_FW_TAG_LEN));
    383		return -EINVAL;
    384	}
    385	end = d + count;
    386	d += 1 + 2 * f->count;
    387
    388	for (i = 0; i < f->count; ++i) {
    389		if (f->seq[i].offset + d <= end)
    390			continue;
    391		dev_err(dev, "invalid firmware header (seq=%d)\n", i);
    392		return -EINVAL;
    393	}
    394
    395	*fw = f;
    396
    397	return 0;
    398}
    399
    400static inline struct v4l2_subdev *ctrl_to_sd(struct v4l2_ctrl *ctrl)
    401{
    402	return &container_of(ctrl->handler, struct s5k5baf, ctrls.handler)->sd;
    403}
    404
    405static inline bool s5k5baf_is_cis_subdev(struct v4l2_subdev *sd)
    406{
    407	return sd->entity.function == MEDIA_ENT_F_CAM_SENSOR;
    408}
    409
    410static inline struct s5k5baf *to_s5k5baf(struct v4l2_subdev *sd)
    411{
    412	if (s5k5baf_is_cis_subdev(sd))
    413		return container_of(sd, struct s5k5baf, cis_sd);
    414	else
    415		return container_of(sd, struct s5k5baf, sd);
    416}
    417
    418static u16 s5k5baf_i2c_read(struct s5k5baf *state, u16 addr)
    419{
    420	struct i2c_client *c = v4l2_get_subdevdata(&state->sd);
    421	__be16 w, r;
    422	u16 res;
    423	struct i2c_msg msg[] = {
    424		{ .addr = c->addr, .flags = 0,
    425		  .len = 2, .buf = (u8 *)&w },
    426		{ .addr = c->addr, .flags = I2C_M_RD,
    427		  .len = 2, .buf = (u8 *)&r },
    428	};
    429	int ret;
    430
    431	if (state->error)
    432		return 0;
    433
    434	w = cpu_to_be16(addr);
    435	ret = i2c_transfer(c->adapter, msg, 2);
    436	res = be16_to_cpu(r);
    437
    438	v4l2_dbg(3, debug, c, "i2c_read: 0x%04x : 0x%04x\n", addr, res);
    439
    440	if (ret != 2) {
    441		v4l2_err(c, "i2c_read: error during transfer (%d)\n", ret);
    442		state->error = ret;
    443	}
    444	return res;
    445}
    446
    447static void s5k5baf_i2c_write(struct s5k5baf *state, u16 addr, u16 val)
    448{
    449	u8 buf[4] = { addr >> 8, addr & 0xFF, val >> 8, val & 0xFF };
    450	struct i2c_client *c = v4l2_get_subdevdata(&state->sd);
    451	int ret;
    452
    453	if (state->error)
    454		return;
    455
    456	ret = i2c_master_send(c, buf, 4);
    457	v4l2_dbg(3, debug, c, "i2c_write: 0x%04x : 0x%04x\n", addr, val);
    458
    459	if (ret != 4) {
    460		v4l2_err(c, "i2c_write: error during transfer (%d)\n", ret);
    461		state->error = ret;
    462	}
    463}
    464
    465static u16 s5k5baf_read(struct s5k5baf *state, u16 addr)
    466{
    467	s5k5baf_i2c_write(state, REG_CMDRD_ADDR, addr);
    468	return s5k5baf_i2c_read(state, REG_CMD_BUF);
    469}
    470
    471static void s5k5baf_write(struct s5k5baf *state, u16 addr, u16 val)
    472{
    473	s5k5baf_i2c_write(state, REG_CMDWR_ADDR, addr);
    474	s5k5baf_i2c_write(state, REG_CMD_BUF, val);
    475}
    476
    477static void s5k5baf_write_arr_seq(struct s5k5baf *state, u16 addr,
    478				  u16 count, const u16 *seq)
    479{
    480	struct i2c_client *c = v4l2_get_subdevdata(&state->sd);
    481	__be16 buf[65];
    482
    483	s5k5baf_i2c_write(state, REG_CMDWR_ADDR, addr);
    484	if (state->error)
    485		return;
    486
    487	v4l2_dbg(3, debug, c, "i2c_write_seq(count=%d): %*ph\n", count,
    488		 min(2 * count, 64), seq);
    489
    490	buf[0] = cpu_to_be16(REG_CMD_BUF);
    491
    492	while (count > 0) {
    493		int n = min_t(int, count, ARRAY_SIZE(buf) - 1);
    494		int ret, i;
    495
    496		for (i = 1; i <= n; ++i)
    497			buf[i] = cpu_to_be16(*seq++);
    498
    499		i *= 2;
    500		ret = i2c_master_send(c, (char *)buf, i);
    501		if (ret != i) {
    502			v4l2_err(c, "i2c_write_seq: error during transfer (%d)\n", ret);
    503			state->error = ret;
    504			break;
    505		}
    506
    507		count -= n;
    508	}
    509}
    510
    511#define s5k5baf_write_seq(state, addr, seq...) \
    512	s5k5baf_write_arr_seq(state, addr, sizeof((char[]){ seq }), \
    513			      (const u16 []){ seq })
    514
    515/* add items count at the beginning of the list */
    516#define NSEQ(seq...) sizeof((char[]){ seq }), seq
    517
    518/*
    519 * s5k5baf_write_nseq() - Writes sequences of values to sensor memory via i2c
    520 * @nseq: sequence of u16 words in format:
    521 *	(N, address, value[1]...value[N-1])*,0
    522 * Ex.:
    523 *	u16 seq[] = { NSEQ(0x4000, 1, 1), NSEQ(0x4010, 640, 480), 0 };
    524 *	ret = s5k5baf_write_nseq(c, seq);
    525 */
    526static void s5k5baf_write_nseq(struct s5k5baf *state, const u16 *nseq)
    527{
    528	int count;
    529
    530	while ((count = *nseq++)) {
    531		u16 addr = *nseq++;
    532		--count;
    533
    534		s5k5baf_write_arr_seq(state, addr, count, nseq);
    535		nseq += count;
    536	}
    537}
    538
    539static void s5k5baf_synchronize(struct s5k5baf *state, int timeout, u16 addr)
    540{
    541	unsigned long end = jiffies + msecs_to_jiffies(timeout);
    542	u16 reg;
    543
    544	s5k5baf_write(state, addr, 1);
    545	do {
    546		reg = s5k5baf_read(state, addr);
    547		if (state->error || !reg)
    548			return;
    549		usleep_range(5000, 10000);
    550	} while (time_is_after_jiffies(end));
    551
    552	v4l2_err(&state->sd, "timeout on register synchronize (%#x)\n", addr);
    553	state->error = -ETIMEDOUT;
    554}
    555
    556static u16 *s5k5baf_fw_get_seq(struct s5k5baf *state, u16 seq_id)
    557{
    558	struct s5k5baf_fw *fw = state->fw;
    559	u16 *data;
    560	int i;
    561
    562	if (fw == NULL)
    563		return NULL;
    564
    565	data = &fw->seq[0].id + 2 * fw->count;
    566
    567	for (i = 0; i < fw->count; ++i) {
    568		if (fw->seq[i].id == seq_id)
    569			return data + fw->seq[i].offset;
    570	}
    571
    572	return NULL;
    573}
    574
    575static void s5k5baf_hw_patch(struct s5k5baf *state)
    576{
    577	u16 *seq = s5k5baf_fw_get_seq(state, S5K5BAF_FW_ID_PATCH);
    578
    579	if (seq)
    580		s5k5baf_write_nseq(state, seq);
    581}
    582
    583static void s5k5baf_hw_set_clocks(struct s5k5baf *state)
    584{
    585	unsigned long mclk = state->mclk_frequency / 1000;
    586	u16 status;
    587	static const u16 nseq_clk_cfg[] = {
    588		NSEQ(REG_I_USE_NPVI_CLOCKS,
    589		  NPVI_CLOCKS, NMIPI_CLOCKS, 0,
    590		  SCLK_PVI_FREQ / 4, PCLK_MIN_FREQ / 4, PCLK_MAX_FREQ / 4,
    591		  SCLK_MIPI_FREQ / 4, PCLK_MIN_FREQ / 4, PCLK_MAX_FREQ / 4),
    592		NSEQ(REG_I_USE_REGS_API, 1),
    593		0
    594	};
    595
    596	s5k5baf_write_seq(state, REG_I_INCLK_FREQ_L, mclk & 0xffff, mclk >> 16);
    597	s5k5baf_write_nseq(state, nseq_clk_cfg);
    598
    599	s5k5baf_synchronize(state, 250, REG_I_INIT_PARAMS_UPDATED);
    600	status = s5k5baf_read(state, REG_I_ERROR_INFO);
    601	if (!state->error && status) {
    602		v4l2_err(&state->sd, "error configuring PLL (%d)\n", status);
    603		state->error = -EINVAL;
    604	}
    605}
    606
    607/* set custom color correction matrices for various illuminations */
    608static void s5k5baf_hw_set_ccm(struct s5k5baf *state)
    609{
    610	u16 *seq = s5k5baf_fw_get_seq(state, S5K5BAF_FW_ID_CCM);
    611
    612	if (seq)
    613		s5k5baf_write_nseq(state, seq);
    614}
    615
    616/* CIS sensor tuning, based on undocumented android driver code */
    617static void s5k5baf_hw_set_cis(struct s5k5baf *state)
    618{
    619	u16 *seq = s5k5baf_fw_get_seq(state, S5K5BAF_FW_ID_CIS);
    620
    621	if (!seq)
    622		return;
    623
    624	s5k5baf_i2c_write(state, REG_CMDWR_PAGE, PAGE_IF_HW);
    625	s5k5baf_write_nseq(state, seq);
    626	s5k5baf_i2c_write(state, REG_CMDWR_PAGE, PAGE_IF_SW);
    627}
    628
    629static void s5k5baf_hw_sync_cfg(struct s5k5baf *state)
    630{
    631	s5k5baf_write(state, REG_G_PREV_CFG_CHG, 1);
    632	if (state->apply_crop) {
    633		s5k5baf_write(state, REG_G_INPUTS_CHANGE_REQ, 1);
    634		s5k5baf_write(state, REG_G_PREV_CFG_BYPASS_CHANGED, 1);
    635	}
    636	s5k5baf_synchronize(state, 500, REG_G_NEW_CFG_SYNC);
    637}
    638/* Set horizontal and vertical image flipping */
    639static void s5k5baf_hw_set_mirror(struct s5k5baf *state)
    640{
    641	u16 flip = state->ctrls.vflip->val | (state->ctrls.vflip->val << 1);
    642
    643	s5k5baf_write(state, REG_P_PREV_MIRROR(0), flip);
    644	if (state->streaming)
    645		s5k5baf_hw_sync_cfg(state);
    646}
    647
    648static void s5k5baf_hw_set_alg(struct s5k5baf *state, u16 alg, bool enable)
    649{
    650	u16 cur_alg, new_alg;
    651
    652	if (!state->valid_auto_alg)
    653		cur_alg = s5k5baf_read(state, REG_DBG_AUTOALG_EN);
    654	else
    655		cur_alg = state->auto_alg;
    656
    657	new_alg = enable ? (cur_alg | alg) : (cur_alg & ~alg);
    658
    659	if (new_alg != cur_alg)
    660		s5k5baf_write(state, REG_DBG_AUTOALG_EN, new_alg);
    661
    662	if (state->error)
    663		return;
    664
    665	state->valid_auto_alg = 1;
    666	state->auto_alg = new_alg;
    667}
    668
    669/* Configure auto/manual white balance and R/G/B gains */
    670static void s5k5baf_hw_set_awb(struct s5k5baf *state, int awb)
    671{
    672	struct s5k5baf_ctrls *ctrls = &state->ctrls;
    673
    674	if (!awb)
    675		s5k5baf_write_seq(state, REG_SF_RGAIN,
    676				  ctrls->gain_red->val, 1,
    677				  S5K5BAF_GAIN_GREEN_DEF, 1,
    678				  ctrls->gain_blue->val, 1,
    679				  1);
    680
    681	s5k5baf_hw_set_alg(state, AALG_WB_EN, awb);
    682}
    683
    684/* Program FW with exposure time, 'exposure' in us units */
    685static void s5k5baf_hw_set_user_exposure(struct s5k5baf *state, int exposure)
    686{
    687	unsigned int time = exposure / 10;
    688
    689	s5k5baf_write_seq(state, REG_SF_USR_EXPOSURE_L,
    690			  time & 0xffff, time >> 16, 1);
    691}
    692
    693static void s5k5baf_hw_set_user_gain(struct s5k5baf *state, int gain)
    694{
    695	s5k5baf_write_seq(state, REG_SF_USR_TOT_GAIN, gain, 1);
    696}
    697
    698/* Set auto/manual exposure and total gain */
    699static void s5k5baf_hw_set_auto_exposure(struct s5k5baf *state, int value)
    700{
    701	if (value == V4L2_EXPOSURE_AUTO) {
    702		s5k5baf_hw_set_alg(state, AALG_AE_EN | AALG_DIVLEI_EN, true);
    703	} else {
    704		unsigned int exp_time = state->ctrls.exposure->val;
    705
    706		s5k5baf_hw_set_user_exposure(state, exp_time);
    707		s5k5baf_hw_set_user_gain(state, state->ctrls.gain->val);
    708		s5k5baf_hw_set_alg(state, AALG_AE_EN | AALG_DIVLEI_EN, false);
    709	}
    710}
    711
    712static void s5k5baf_hw_set_anti_flicker(struct s5k5baf *state, int v)
    713{
    714	if (v == V4L2_CID_POWER_LINE_FREQUENCY_AUTO) {
    715		s5k5baf_hw_set_alg(state, AALG_FLICKER_EN, true);
    716	} else {
    717		/* The V4L2_CID_LINE_FREQUENCY control values match
    718		 * the register values */
    719		s5k5baf_write_seq(state, REG_SF_FLICKER_QUANT, v, 1);
    720		s5k5baf_hw_set_alg(state, AALG_FLICKER_EN, false);
    721	}
    722}
    723
    724static void s5k5baf_hw_set_colorfx(struct s5k5baf *state, int val)
    725{
    726	static const u16 colorfx[] = {
    727		[V4L2_COLORFX_NONE] = 0,
    728		[V4L2_COLORFX_BW] = 1,
    729		[V4L2_COLORFX_NEGATIVE] = 2,
    730		[V4L2_COLORFX_SEPIA] = 3,
    731		[V4L2_COLORFX_SKY_BLUE] = 4,
    732		[V4L2_COLORFX_SKETCH] = 5,
    733	};
    734
    735	s5k5baf_write(state, REG_G_SPEC_EFFECTS, colorfx[val]);
    736}
    737
    738static int s5k5baf_find_pixfmt(struct v4l2_mbus_framefmt *mf)
    739{
    740	int i, c = -1;
    741
    742	for (i = 0; i < ARRAY_SIZE(s5k5baf_formats); i++) {
    743		if (mf->colorspace != s5k5baf_formats[i].colorspace)
    744			continue;
    745		if (mf->code == s5k5baf_formats[i].code)
    746			return i;
    747		if (c < 0)
    748			c = i;
    749	}
    750	return (c < 0) ? 0 : c;
    751}
    752
    753static int s5k5baf_clear_error(struct s5k5baf *state)
    754{
    755	int ret = state->error;
    756
    757	state->error = 0;
    758	return ret;
    759}
    760
    761static int s5k5baf_hw_set_video_bus(struct s5k5baf *state)
    762{
    763	u16 en_pkts;
    764
    765	if (state->bus_type == V4L2_MBUS_CSI2_DPHY)
    766		en_pkts = EN_PACKETS_CSI2;
    767	else
    768		en_pkts = 0;
    769
    770	s5k5baf_write_seq(state, REG_OIF_EN_MIPI_LANES,
    771			  state->nlanes, en_pkts, 1);
    772
    773	return s5k5baf_clear_error(state);
    774}
    775
    776static u16 s5k5baf_get_cfg_error(struct s5k5baf *state)
    777{
    778	u16 err = s5k5baf_read(state, REG_G_PREV_CFG_ERROR);
    779	if (err)
    780		s5k5baf_write(state, REG_G_PREV_CFG_ERROR, 0);
    781	return err;
    782}
    783
    784static void s5k5baf_hw_set_fiv(struct s5k5baf *state, u16 fiv)
    785{
    786	s5k5baf_write(state, REG_P_MAX_FR_TIME(0), fiv);
    787	s5k5baf_hw_sync_cfg(state);
    788}
    789
    790static void s5k5baf_hw_find_min_fiv(struct s5k5baf *state)
    791{
    792	u16 err, fiv;
    793	int n;
    794
    795	fiv = s5k5baf_read(state,  REG_G_ACTUAL_P_FR_TIME);
    796	if (state->error)
    797		return;
    798
    799	for (n = 5; n > 0; --n) {
    800		s5k5baf_hw_set_fiv(state, fiv);
    801		err = s5k5baf_get_cfg_error(state);
    802		if (state->error)
    803			return;
    804		switch (err) {
    805		case CFG_ERROR_RANGE:
    806			++fiv;
    807			break;
    808		case 0:
    809			state->fiv = fiv;
    810			v4l2_info(&state->sd,
    811				  "found valid frame interval: %d00us\n", fiv);
    812			return;
    813		default:
    814			v4l2_err(&state->sd,
    815				 "error setting frame interval: %d\n", err);
    816			state->error = -EINVAL;
    817		}
    818	}
    819	v4l2_err(&state->sd, "cannot find correct frame interval\n");
    820	state->error = -ERANGE;
    821}
    822
    823static void s5k5baf_hw_validate_cfg(struct s5k5baf *state)
    824{
    825	u16 err;
    826
    827	err = s5k5baf_get_cfg_error(state);
    828	if (state->error)
    829		return;
    830
    831	switch (err) {
    832	case 0:
    833		state->apply_cfg = 1;
    834		return;
    835	case CFG_ERROR_RANGE:
    836		s5k5baf_hw_find_min_fiv(state);
    837		if (!state->error)
    838			state->apply_cfg = 1;
    839		return;
    840	default:
    841		v4l2_err(&state->sd,
    842			 "error setting format: %d\n", err);
    843		state->error = -EINVAL;
    844	}
    845}
    846
    847static void s5k5baf_rescale(struct v4l2_rect *r, const struct v4l2_rect *v,
    848			    const struct v4l2_rect *n,
    849			    const struct v4l2_rect *d)
    850{
    851	r->left = v->left * n->width / d->width;
    852	r->top = v->top * n->height / d->height;
    853	r->width = v->width * n->width / d->width;
    854	r->height = v->height * n->height / d->height;
    855}
    856
    857static int s5k5baf_hw_set_crop_rects(struct s5k5baf *state)
    858{
    859	struct v4l2_rect *p, r;
    860	u16 err;
    861	int ret;
    862
    863	p = &state->crop_sink;
    864	s5k5baf_write_seq(state, REG_G_PREVREQ_IN_WIDTH, p->width, p->height,
    865			  p->left, p->top);
    866
    867	s5k5baf_rescale(&r, &state->crop_source, &state->crop_sink,
    868			&state->compose);
    869	s5k5baf_write_seq(state, REG_G_PREVZOOM_IN_WIDTH, r.width, r.height,
    870			  r.left, r.top);
    871
    872	s5k5baf_synchronize(state, 500, REG_G_INPUTS_CHANGE_REQ);
    873	s5k5baf_synchronize(state, 500, REG_G_PREV_CFG_BYPASS_CHANGED);
    874	err = s5k5baf_get_cfg_error(state);
    875	ret = s5k5baf_clear_error(state);
    876	if (ret < 0)
    877		return ret;
    878
    879	switch (err) {
    880	case 0:
    881		break;
    882	case CFG_ERROR_RANGE:
    883		/* retry crop with frame interval set to max */
    884		s5k5baf_hw_set_fiv(state, S5K5BAF_MAX_FR_TIME);
    885		err = s5k5baf_get_cfg_error(state);
    886		ret = s5k5baf_clear_error(state);
    887		if (ret < 0)
    888			return ret;
    889		if (err) {
    890			v4l2_err(&state->sd,
    891				 "crop error on max frame interval: %d\n", err);
    892			state->error = -EINVAL;
    893		}
    894		s5k5baf_hw_set_fiv(state, state->req_fiv);
    895		s5k5baf_hw_validate_cfg(state);
    896		break;
    897	default:
    898		v4l2_err(&state->sd, "crop error: %d\n", err);
    899		return -EINVAL;
    900	}
    901
    902	if (!state->apply_cfg)
    903		return 0;
    904
    905	p = &state->crop_source;
    906	s5k5baf_write_seq(state, REG_P_OUT_WIDTH(0), p->width, p->height);
    907	s5k5baf_hw_set_fiv(state, state->req_fiv);
    908	s5k5baf_hw_validate_cfg(state);
    909
    910	return s5k5baf_clear_error(state);
    911}
    912
    913static void s5k5baf_hw_set_config(struct s5k5baf *state)
    914{
    915	u16 reg_fmt = s5k5baf_formats[state->pixfmt].reg_p_fmt;
    916	struct v4l2_rect *r = &state->crop_source;
    917
    918	s5k5baf_write_seq(state, REG_P_OUT_WIDTH(0),
    919			  r->width, r->height, reg_fmt,
    920			  PCLK_MAX_FREQ >> 2, PCLK_MIN_FREQ >> 2,
    921			  PVI_MASK_MIPI, CLK_MIPI_INDEX,
    922			  FR_RATE_FIXED, FR_RATE_Q_DYNAMIC,
    923			  state->req_fiv, S5K5BAF_MIN_FR_TIME);
    924	s5k5baf_hw_sync_cfg(state);
    925	s5k5baf_hw_validate_cfg(state);
    926}
    927
    928
    929static void s5k5baf_hw_set_test_pattern(struct s5k5baf *state, int id)
    930{
    931	s5k5baf_i2c_write(state, REG_PATTERN_WIDTH, 800);
    932	s5k5baf_i2c_write(state, REG_PATTERN_HEIGHT, 511);
    933	s5k5baf_i2c_write(state, REG_PATTERN_PARAM, 0);
    934	s5k5baf_i2c_write(state, REG_PATTERN_SET, id);
    935}
    936
    937static void s5k5baf_gpio_assert(struct s5k5baf *state, int id)
    938{
    939	struct s5k5baf_gpio *gpio = &state->gpios[id];
    940
    941	gpio_set_value(gpio->gpio, gpio->level);
    942}
    943
    944static void s5k5baf_gpio_deassert(struct s5k5baf *state, int id)
    945{
    946	struct s5k5baf_gpio *gpio = &state->gpios[id];
    947
    948	gpio_set_value(gpio->gpio, !gpio->level);
    949}
    950
    951static int s5k5baf_power_on(struct s5k5baf *state)
    952{
    953	int ret;
    954
    955	ret = regulator_bulk_enable(S5K5BAF_NUM_SUPPLIES, state->supplies);
    956	if (ret < 0)
    957		goto err;
    958
    959	ret = clk_set_rate(state->clock, state->mclk_frequency);
    960	if (ret < 0)
    961		goto err_reg_dis;
    962
    963	ret = clk_prepare_enable(state->clock);
    964	if (ret < 0)
    965		goto err_reg_dis;
    966
    967	v4l2_dbg(1, debug, &state->sd, "clock frequency: %ld\n",
    968		 clk_get_rate(state->clock));
    969
    970	s5k5baf_gpio_deassert(state, STBY);
    971	usleep_range(50, 100);
    972	s5k5baf_gpio_deassert(state, RSET);
    973	return 0;
    974
    975err_reg_dis:
    976	regulator_bulk_disable(S5K5BAF_NUM_SUPPLIES, state->supplies);
    977err:
    978	v4l2_err(&state->sd, "%s() failed (%d)\n", __func__, ret);
    979	return ret;
    980}
    981
    982static int s5k5baf_power_off(struct s5k5baf *state)
    983{
    984	int ret;
    985
    986	state->streaming = 0;
    987	state->apply_cfg = 0;
    988	state->apply_crop = 0;
    989
    990	s5k5baf_gpio_assert(state, RSET);
    991	s5k5baf_gpio_assert(state, STBY);
    992
    993	if (!IS_ERR(state->clock))
    994		clk_disable_unprepare(state->clock);
    995
    996	ret = regulator_bulk_disable(S5K5BAF_NUM_SUPPLIES,
    997					state->supplies);
    998	if (ret < 0)
    999		v4l2_err(&state->sd, "failed to disable regulators\n");
   1000
   1001	return 0;
   1002}
   1003
   1004static void s5k5baf_hw_init(struct s5k5baf *state)
   1005{
   1006	s5k5baf_i2c_write(state, AHB_MSB_ADDR_PTR, PAGE_IF_HW);
   1007	s5k5baf_i2c_write(state, REG_CLEAR_HOST_INT, 0);
   1008	s5k5baf_i2c_write(state, REG_SW_LOAD_COMPLETE, 1);
   1009	s5k5baf_i2c_write(state, REG_CMDRD_PAGE, PAGE_IF_SW);
   1010	s5k5baf_i2c_write(state, REG_CMDWR_PAGE, PAGE_IF_SW);
   1011}
   1012
   1013/*
   1014 * V4L2 subdev core and video operations
   1015 */
   1016
   1017static void s5k5baf_initialize_data(struct s5k5baf *state)
   1018{
   1019	state->pixfmt = 0;
   1020	state->req_fiv = 10000 / 15;
   1021	state->fiv = state->req_fiv;
   1022	state->valid_auto_alg = 0;
   1023}
   1024
   1025static int s5k5baf_load_setfile(struct s5k5baf *state)
   1026{
   1027	struct i2c_client *c = v4l2_get_subdevdata(&state->sd);
   1028	const struct firmware *fw;
   1029	int ret;
   1030
   1031	ret = request_firmware(&fw, S5K5BAF_FW_FILENAME, &c->dev);
   1032	if (ret < 0) {
   1033		dev_warn(&c->dev, "firmware file (%s) not loaded\n",
   1034			 S5K5BAF_FW_FILENAME);
   1035		return ret;
   1036	}
   1037
   1038	ret = s5k5baf_fw_parse(&c->dev, &state->fw, fw->size / 2,
   1039			       (__le16 *)fw->data);
   1040
   1041	release_firmware(fw);
   1042
   1043	return ret;
   1044}
   1045
   1046static int s5k5baf_set_power(struct v4l2_subdev *sd, int on)
   1047{
   1048	struct s5k5baf *state = to_s5k5baf(sd);
   1049	int ret = 0;
   1050
   1051	mutex_lock(&state->lock);
   1052
   1053	if (state->power != !on)
   1054		goto out;
   1055
   1056	if (on) {
   1057		if (state->fw == NULL)
   1058			s5k5baf_load_setfile(state);
   1059
   1060		s5k5baf_initialize_data(state);
   1061		ret = s5k5baf_power_on(state);
   1062		if (ret < 0)
   1063			goto out;
   1064
   1065		s5k5baf_hw_init(state);
   1066		s5k5baf_hw_patch(state);
   1067		s5k5baf_i2c_write(state, REG_SET_HOST_INT, 1);
   1068		s5k5baf_hw_set_clocks(state);
   1069
   1070		ret = s5k5baf_hw_set_video_bus(state);
   1071		if (ret < 0)
   1072			goto out;
   1073
   1074		s5k5baf_hw_set_cis(state);
   1075		s5k5baf_hw_set_ccm(state);
   1076
   1077		ret = s5k5baf_clear_error(state);
   1078		if (!ret)
   1079			state->power++;
   1080	} else {
   1081		s5k5baf_power_off(state);
   1082		state->power--;
   1083	}
   1084
   1085out:
   1086	mutex_unlock(&state->lock);
   1087
   1088	if (!ret && on)
   1089		ret = v4l2_ctrl_handler_setup(&state->ctrls.handler);
   1090
   1091	return ret;
   1092}
   1093
   1094static void s5k5baf_hw_set_stream(struct s5k5baf *state, int enable)
   1095{
   1096	s5k5baf_write_seq(state, REG_G_ENABLE_PREV, enable, 1);
   1097}
   1098
   1099static int s5k5baf_s_stream(struct v4l2_subdev *sd, int on)
   1100{
   1101	struct s5k5baf *state = to_s5k5baf(sd);
   1102	int ret;
   1103
   1104	mutex_lock(&state->lock);
   1105
   1106	if (state->streaming == !!on) {
   1107		ret = 0;
   1108		goto out;
   1109	}
   1110
   1111	if (on) {
   1112		s5k5baf_hw_set_config(state);
   1113		ret = s5k5baf_hw_set_crop_rects(state);
   1114		if (ret < 0)
   1115			goto out;
   1116		s5k5baf_hw_set_stream(state, 1);
   1117		s5k5baf_i2c_write(state, 0xb0cc, 0x000b);
   1118	} else {
   1119		s5k5baf_hw_set_stream(state, 0);
   1120	}
   1121	ret = s5k5baf_clear_error(state);
   1122	if (!ret)
   1123		state->streaming = !state->streaming;
   1124
   1125out:
   1126	mutex_unlock(&state->lock);
   1127
   1128	return ret;
   1129}
   1130
   1131static int s5k5baf_g_frame_interval(struct v4l2_subdev *sd,
   1132				   struct v4l2_subdev_frame_interval *fi)
   1133{
   1134	struct s5k5baf *state = to_s5k5baf(sd);
   1135
   1136	mutex_lock(&state->lock);
   1137	fi->interval.numerator = state->fiv;
   1138	fi->interval.denominator = 10000;
   1139	mutex_unlock(&state->lock);
   1140
   1141	return 0;
   1142}
   1143
   1144static void s5k5baf_set_frame_interval(struct s5k5baf *state,
   1145				       struct v4l2_subdev_frame_interval *fi)
   1146{
   1147	struct v4l2_fract *i = &fi->interval;
   1148
   1149	if (fi->interval.denominator == 0)
   1150		state->req_fiv = S5K5BAF_MAX_FR_TIME;
   1151	else
   1152		state->req_fiv = clamp_t(u32,
   1153					 i->numerator * 10000 / i->denominator,
   1154					 S5K5BAF_MIN_FR_TIME,
   1155					 S5K5BAF_MAX_FR_TIME);
   1156
   1157	state->fiv = state->req_fiv;
   1158	if (state->apply_cfg) {
   1159		s5k5baf_hw_set_fiv(state, state->req_fiv);
   1160		s5k5baf_hw_validate_cfg(state);
   1161	}
   1162	*i = (struct v4l2_fract){ state->fiv, 10000 };
   1163	if (state->fiv == state->req_fiv)
   1164		v4l2_info(&state->sd, "frame interval changed to %d00us\n",
   1165			  state->fiv);
   1166}
   1167
   1168static int s5k5baf_s_frame_interval(struct v4l2_subdev *sd,
   1169				   struct v4l2_subdev_frame_interval *fi)
   1170{
   1171	struct s5k5baf *state = to_s5k5baf(sd);
   1172
   1173	mutex_lock(&state->lock);
   1174	s5k5baf_set_frame_interval(state, fi);
   1175	mutex_unlock(&state->lock);
   1176	return 0;
   1177}
   1178
   1179/*
   1180 * V4L2 subdev pad level and video operations
   1181 */
   1182static int s5k5baf_enum_frame_interval(struct v4l2_subdev *sd,
   1183			      struct v4l2_subdev_state *sd_state,
   1184			      struct v4l2_subdev_frame_interval_enum *fie)
   1185{
   1186	if (fie->index > S5K5BAF_MAX_FR_TIME - S5K5BAF_MIN_FR_TIME ||
   1187	    fie->pad != PAD_CIS)
   1188		return -EINVAL;
   1189
   1190	v4l_bound_align_image(&fie->width, S5K5BAF_WIN_WIDTH_MIN,
   1191			      S5K5BAF_CIS_WIDTH, 1,
   1192			      &fie->height, S5K5BAF_WIN_HEIGHT_MIN,
   1193			      S5K5BAF_CIS_HEIGHT, 1, 0);
   1194
   1195	fie->interval.numerator = S5K5BAF_MIN_FR_TIME + fie->index;
   1196	fie->interval.denominator = 10000;
   1197
   1198	return 0;
   1199}
   1200
   1201static int s5k5baf_enum_mbus_code(struct v4l2_subdev *sd,
   1202				 struct v4l2_subdev_state *sd_state,
   1203				 struct v4l2_subdev_mbus_code_enum *code)
   1204{
   1205	if (code->pad == PAD_CIS) {
   1206		if (code->index > 0)
   1207			return -EINVAL;
   1208		code->code = MEDIA_BUS_FMT_FIXED;
   1209		return 0;
   1210	}
   1211
   1212	if (code->index >= ARRAY_SIZE(s5k5baf_formats))
   1213		return -EINVAL;
   1214
   1215	code->code = s5k5baf_formats[code->index].code;
   1216	return 0;
   1217}
   1218
   1219static int s5k5baf_enum_frame_size(struct v4l2_subdev *sd,
   1220				  struct v4l2_subdev_state *sd_state,
   1221				  struct v4l2_subdev_frame_size_enum *fse)
   1222{
   1223	int i;
   1224
   1225	if (fse->index > 0)
   1226		return -EINVAL;
   1227
   1228	if (fse->pad == PAD_CIS) {
   1229		fse->code = MEDIA_BUS_FMT_FIXED;
   1230		fse->min_width = S5K5BAF_CIS_WIDTH;
   1231		fse->max_width = S5K5BAF_CIS_WIDTH;
   1232		fse->min_height = S5K5BAF_CIS_HEIGHT;
   1233		fse->max_height = S5K5BAF_CIS_HEIGHT;
   1234		return 0;
   1235	}
   1236
   1237	i = ARRAY_SIZE(s5k5baf_formats);
   1238	while (--i)
   1239		if (fse->code == s5k5baf_formats[i].code)
   1240			break;
   1241	fse->code = s5k5baf_formats[i].code;
   1242	fse->min_width = S5K5BAF_WIN_WIDTH_MIN;
   1243	fse->max_width = S5K5BAF_CIS_WIDTH;
   1244	fse->max_height = S5K5BAF_WIN_HEIGHT_MIN;
   1245	fse->min_height = S5K5BAF_CIS_HEIGHT;
   1246
   1247	return 0;
   1248}
   1249
   1250static void s5k5baf_try_cis_format(struct v4l2_mbus_framefmt *mf)
   1251{
   1252	mf->width = S5K5BAF_CIS_WIDTH;
   1253	mf->height = S5K5BAF_CIS_HEIGHT;
   1254	mf->code = MEDIA_BUS_FMT_FIXED;
   1255	mf->colorspace = V4L2_COLORSPACE_JPEG;
   1256	mf->field = V4L2_FIELD_NONE;
   1257}
   1258
   1259static int s5k5baf_try_isp_format(struct v4l2_mbus_framefmt *mf)
   1260{
   1261	int pixfmt;
   1262
   1263	v4l_bound_align_image(&mf->width, S5K5BAF_WIN_WIDTH_MIN,
   1264			      S5K5BAF_CIS_WIDTH, 1,
   1265			      &mf->height, S5K5BAF_WIN_HEIGHT_MIN,
   1266			      S5K5BAF_CIS_HEIGHT, 1, 0);
   1267
   1268	pixfmt = s5k5baf_find_pixfmt(mf);
   1269
   1270	mf->colorspace = s5k5baf_formats[pixfmt].colorspace;
   1271	mf->code = s5k5baf_formats[pixfmt].code;
   1272	mf->field = V4L2_FIELD_NONE;
   1273
   1274	return pixfmt;
   1275}
   1276
   1277static int s5k5baf_get_fmt(struct v4l2_subdev *sd,
   1278			   struct v4l2_subdev_state *sd_state,
   1279			   struct v4l2_subdev_format *fmt)
   1280{
   1281	struct s5k5baf *state = to_s5k5baf(sd);
   1282	const struct s5k5baf_pixfmt *pixfmt;
   1283	struct v4l2_mbus_framefmt *mf;
   1284
   1285	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
   1286		mf = v4l2_subdev_get_try_format(sd, sd_state, fmt->pad);
   1287		fmt->format = *mf;
   1288		return 0;
   1289	}
   1290
   1291	mf = &fmt->format;
   1292	if (fmt->pad == PAD_CIS) {
   1293		s5k5baf_try_cis_format(mf);
   1294		return 0;
   1295	}
   1296	mf->field = V4L2_FIELD_NONE;
   1297	mutex_lock(&state->lock);
   1298	pixfmt = &s5k5baf_formats[state->pixfmt];
   1299	mf->width = state->crop_source.width;
   1300	mf->height = state->crop_source.height;
   1301	mf->code = pixfmt->code;
   1302	mf->colorspace = pixfmt->colorspace;
   1303	mutex_unlock(&state->lock);
   1304
   1305	return 0;
   1306}
   1307
   1308static int s5k5baf_set_fmt(struct v4l2_subdev *sd,
   1309			   struct v4l2_subdev_state *sd_state,
   1310			   struct v4l2_subdev_format *fmt)
   1311{
   1312	struct v4l2_mbus_framefmt *mf = &fmt->format;
   1313	struct s5k5baf *state = to_s5k5baf(sd);
   1314	const struct s5k5baf_pixfmt *pixfmt;
   1315	int ret = 0;
   1316
   1317	mf->field = V4L2_FIELD_NONE;
   1318
   1319	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
   1320		*v4l2_subdev_get_try_format(sd, sd_state, fmt->pad) = *mf;
   1321		return 0;
   1322	}
   1323
   1324	if (fmt->pad == PAD_CIS) {
   1325		s5k5baf_try_cis_format(mf);
   1326		return 0;
   1327	}
   1328
   1329	mutex_lock(&state->lock);
   1330
   1331	if (state->streaming) {
   1332		mutex_unlock(&state->lock);
   1333		return -EBUSY;
   1334	}
   1335
   1336	state->pixfmt = s5k5baf_try_isp_format(mf);
   1337	pixfmt = &s5k5baf_formats[state->pixfmt];
   1338	mf->code = pixfmt->code;
   1339	mf->colorspace = pixfmt->colorspace;
   1340	mf->width = state->crop_source.width;
   1341	mf->height = state->crop_source.height;
   1342
   1343	mutex_unlock(&state->lock);
   1344	return ret;
   1345}
   1346
   1347enum selection_rect { R_CIS, R_CROP_SINK, R_COMPOSE, R_CROP_SOURCE, R_INVALID };
   1348
   1349static enum selection_rect s5k5baf_get_sel_rect(u32 pad, u32 target)
   1350{
   1351	switch (target) {
   1352	case V4L2_SEL_TGT_CROP_BOUNDS:
   1353		return pad ? R_COMPOSE : R_CIS;
   1354	case V4L2_SEL_TGT_CROP:
   1355		return pad ? R_CROP_SOURCE : R_CROP_SINK;
   1356	case V4L2_SEL_TGT_COMPOSE_BOUNDS:
   1357		return pad ? R_INVALID : R_CROP_SINK;
   1358	case V4L2_SEL_TGT_COMPOSE:
   1359		return pad ? R_INVALID : R_COMPOSE;
   1360	default:
   1361		return R_INVALID;
   1362	}
   1363}
   1364
   1365static int s5k5baf_is_bound_target(u32 target)
   1366{
   1367	return target == V4L2_SEL_TGT_CROP_BOUNDS ||
   1368		target == V4L2_SEL_TGT_COMPOSE_BOUNDS;
   1369}
   1370
   1371static int s5k5baf_get_selection(struct v4l2_subdev *sd,
   1372				 struct v4l2_subdev_state *sd_state,
   1373				 struct v4l2_subdev_selection *sel)
   1374{
   1375	enum selection_rect rtype;
   1376	struct s5k5baf *state = to_s5k5baf(sd);
   1377
   1378	rtype = s5k5baf_get_sel_rect(sel->pad, sel->target);
   1379
   1380	switch (rtype) {
   1381	case R_INVALID:
   1382		return -EINVAL;
   1383	case R_CIS:
   1384		sel->r = s5k5baf_cis_rect;
   1385		return 0;
   1386	default:
   1387		break;
   1388	}
   1389
   1390	if (sel->which == V4L2_SUBDEV_FORMAT_TRY) {
   1391		if (rtype == R_COMPOSE)
   1392			sel->r = *v4l2_subdev_get_try_compose(sd, sd_state,
   1393							      sel->pad);
   1394		else
   1395			sel->r = *v4l2_subdev_get_try_crop(sd, sd_state,
   1396							   sel->pad);
   1397		return 0;
   1398	}
   1399
   1400	mutex_lock(&state->lock);
   1401	switch (rtype) {
   1402	case R_CROP_SINK:
   1403		sel->r = state->crop_sink;
   1404		break;
   1405	case R_COMPOSE:
   1406		sel->r = state->compose;
   1407		break;
   1408	case R_CROP_SOURCE:
   1409		sel->r = state->crop_source;
   1410		break;
   1411	default:
   1412		break;
   1413	}
   1414	if (s5k5baf_is_bound_target(sel->target)) {
   1415		sel->r.left = 0;
   1416		sel->r.top = 0;
   1417	}
   1418	mutex_unlock(&state->lock);
   1419
   1420	return 0;
   1421}
   1422
   1423/* bounds range [start, start+len) to [0, max) and aligns to 2 */
   1424static void s5k5baf_bound_range(u32 *start, u32 *len, u32 max)
   1425{
   1426	if (*len > max)
   1427		*len = max;
   1428	if (*start + *len > max)
   1429		*start = max - *len;
   1430	*start &= ~1;
   1431	*len &= ~1;
   1432	if (*len < S5K5BAF_WIN_WIDTH_MIN)
   1433		*len = S5K5BAF_WIN_WIDTH_MIN;
   1434}
   1435
   1436static void s5k5baf_bound_rect(struct v4l2_rect *r, u32 width, u32 height)
   1437{
   1438	s5k5baf_bound_range(&r->left, &r->width, width);
   1439	s5k5baf_bound_range(&r->top, &r->height, height);
   1440}
   1441
   1442static void s5k5baf_set_rect_and_adjust(struct v4l2_rect **rects,
   1443					enum selection_rect first,
   1444					struct v4l2_rect *v)
   1445{
   1446	struct v4l2_rect *r, *br;
   1447	enum selection_rect i = first;
   1448
   1449	*rects[first] = *v;
   1450	do {
   1451		r = rects[i];
   1452		br = rects[i - 1];
   1453		s5k5baf_bound_rect(r, br->width, br->height);
   1454	} while (++i != R_INVALID);
   1455	*v = *rects[first];
   1456}
   1457
   1458static bool s5k5baf_cmp_rect(const struct v4l2_rect *r1,
   1459			     const struct v4l2_rect *r2)
   1460{
   1461	return !memcmp(r1, r2, sizeof(*r1));
   1462}
   1463
   1464static int s5k5baf_set_selection(struct v4l2_subdev *sd,
   1465				 struct v4l2_subdev_state *sd_state,
   1466				 struct v4l2_subdev_selection *sel)
   1467{
   1468	static enum selection_rect rtype;
   1469	struct s5k5baf *state = to_s5k5baf(sd);
   1470	struct v4l2_rect **rects;
   1471	int ret = 0;
   1472
   1473	rtype = s5k5baf_get_sel_rect(sel->pad, sel->target);
   1474	if (rtype == R_INVALID || s5k5baf_is_bound_target(sel->target))
   1475		return -EINVAL;
   1476
   1477	/* allow only scaling on compose */
   1478	if (rtype == R_COMPOSE) {
   1479		sel->r.left = 0;
   1480		sel->r.top = 0;
   1481	}
   1482
   1483	if (sel->which == V4L2_SUBDEV_FORMAT_TRY) {
   1484		rects = (struct v4l2_rect * []) {
   1485				&s5k5baf_cis_rect,
   1486				v4l2_subdev_get_try_crop(sd, sd_state,
   1487							 PAD_CIS),
   1488				v4l2_subdev_get_try_compose(sd, sd_state,
   1489							    PAD_CIS),
   1490				v4l2_subdev_get_try_crop(sd, sd_state,
   1491							 PAD_OUT)
   1492			};
   1493		s5k5baf_set_rect_and_adjust(rects, rtype, &sel->r);
   1494		return 0;
   1495	}
   1496
   1497	rects = (struct v4l2_rect * []) {
   1498			&s5k5baf_cis_rect,
   1499			&state->crop_sink,
   1500			&state->compose,
   1501			&state->crop_source
   1502		};
   1503	mutex_lock(&state->lock);
   1504	if (state->streaming) {
   1505		/* adjust sel->r to avoid output resolution change */
   1506		if (rtype < R_CROP_SOURCE) {
   1507			if (sel->r.width < state->crop_source.width)
   1508				sel->r.width = state->crop_source.width;
   1509			if (sel->r.height < state->crop_source.height)
   1510				sel->r.height = state->crop_source.height;
   1511		} else {
   1512			sel->r.width = state->crop_source.width;
   1513			sel->r.height = state->crop_source.height;
   1514		}
   1515	}
   1516	s5k5baf_set_rect_and_adjust(rects, rtype, &sel->r);
   1517	if (!s5k5baf_cmp_rect(&state->crop_sink, &s5k5baf_cis_rect) ||
   1518	    !s5k5baf_cmp_rect(&state->compose, &s5k5baf_cis_rect))
   1519		state->apply_crop = 1;
   1520	if (state->streaming)
   1521		ret = s5k5baf_hw_set_crop_rects(state);
   1522	mutex_unlock(&state->lock);
   1523
   1524	return ret;
   1525}
   1526
   1527static const struct v4l2_subdev_pad_ops s5k5baf_cis_pad_ops = {
   1528	.enum_mbus_code		= s5k5baf_enum_mbus_code,
   1529	.enum_frame_size	= s5k5baf_enum_frame_size,
   1530	.get_fmt		= s5k5baf_get_fmt,
   1531	.set_fmt		= s5k5baf_set_fmt,
   1532};
   1533
   1534static const struct v4l2_subdev_pad_ops s5k5baf_pad_ops = {
   1535	.enum_mbus_code		= s5k5baf_enum_mbus_code,
   1536	.enum_frame_size	= s5k5baf_enum_frame_size,
   1537	.enum_frame_interval	= s5k5baf_enum_frame_interval,
   1538	.get_fmt		= s5k5baf_get_fmt,
   1539	.set_fmt		= s5k5baf_set_fmt,
   1540	.get_selection		= s5k5baf_get_selection,
   1541	.set_selection		= s5k5baf_set_selection,
   1542};
   1543
   1544static const struct v4l2_subdev_video_ops s5k5baf_video_ops = {
   1545	.g_frame_interval	= s5k5baf_g_frame_interval,
   1546	.s_frame_interval	= s5k5baf_s_frame_interval,
   1547	.s_stream		= s5k5baf_s_stream,
   1548};
   1549
   1550/*
   1551 * V4L2 subdev controls
   1552 */
   1553
   1554static int s5k5baf_s_ctrl(struct v4l2_ctrl *ctrl)
   1555{
   1556	struct v4l2_subdev *sd = ctrl_to_sd(ctrl);
   1557	struct s5k5baf *state = to_s5k5baf(sd);
   1558	int ret;
   1559
   1560	v4l2_dbg(1, debug, sd, "ctrl: %s, value: %d\n", ctrl->name, ctrl->val);
   1561
   1562	mutex_lock(&state->lock);
   1563
   1564	if (state->power == 0)
   1565		goto unlock;
   1566
   1567	switch (ctrl->id) {
   1568	case V4L2_CID_AUTO_WHITE_BALANCE:
   1569		s5k5baf_hw_set_awb(state, ctrl->val);
   1570		break;
   1571
   1572	case V4L2_CID_BRIGHTNESS:
   1573		s5k5baf_write(state, REG_USER_BRIGHTNESS, ctrl->val);
   1574		break;
   1575
   1576	case V4L2_CID_COLORFX:
   1577		s5k5baf_hw_set_colorfx(state, ctrl->val);
   1578		break;
   1579
   1580	case V4L2_CID_CONTRAST:
   1581		s5k5baf_write(state, REG_USER_CONTRAST, ctrl->val);
   1582		break;
   1583
   1584	case V4L2_CID_EXPOSURE_AUTO:
   1585		s5k5baf_hw_set_auto_exposure(state, ctrl->val);
   1586		break;
   1587
   1588	case V4L2_CID_HFLIP:
   1589		s5k5baf_hw_set_mirror(state);
   1590		break;
   1591
   1592	case V4L2_CID_POWER_LINE_FREQUENCY:
   1593		s5k5baf_hw_set_anti_flicker(state, ctrl->val);
   1594		break;
   1595
   1596	case V4L2_CID_SATURATION:
   1597		s5k5baf_write(state, REG_USER_SATURATION, ctrl->val);
   1598		break;
   1599
   1600	case V4L2_CID_SHARPNESS:
   1601		s5k5baf_write(state, REG_USER_SHARPBLUR, ctrl->val);
   1602		break;
   1603
   1604	case V4L2_CID_WHITE_BALANCE_TEMPERATURE:
   1605		s5k5baf_write(state, REG_P_COLORTEMP(0), ctrl->val);
   1606		if (state->apply_cfg)
   1607			s5k5baf_hw_sync_cfg(state);
   1608		break;
   1609
   1610	case V4L2_CID_TEST_PATTERN:
   1611		s5k5baf_hw_set_test_pattern(state, ctrl->val);
   1612		break;
   1613	}
   1614unlock:
   1615	ret = s5k5baf_clear_error(state);
   1616	mutex_unlock(&state->lock);
   1617	return ret;
   1618}
   1619
   1620static const struct v4l2_ctrl_ops s5k5baf_ctrl_ops = {
   1621	.s_ctrl	= s5k5baf_s_ctrl,
   1622};
   1623
   1624static const char * const s5k5baf_test_pattern_menu[] = {
   1625	"Disabled",
   1626	"Blank",
   1627	"Bars",
   1628	"Gradients",
   1629	"Textile",
   1630	"Textile2",
   1631	"Squares"
   1632};
   1633
   1634static int s5k5baf_initialize_ctrls(struct s5k5baf *state)
   1635{
   1636	const struct v4l2_ctrl_ops *ops = &s5k5baf_ctrl_ops;
   1637	struct s5k5baf_ctrls *ctrls = &state->ctrls;
   1638	struct v4l2_ctrl_handler *hdl = &ctrls->handler;
   1639	int ret;
   1640
   1641	ret = v4l2_ctrl_handler_init(hdl, 16);
   1642	if (ret < 0) {
   1643		v4l2_err(&state->sd, "cannot init ctrl handler (%d)\n", ret);
   1644		return ret;
   1645	}
   1646
   1647	/* Auto white balance cluster */
   1648	ctrls->awb = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_AUTO_WHITE_BALANCE,
   1649				       0, 1, 1, 1);
   1650	ctrls->gain_red = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_RED_BALANCE,
   1651					    0, 255, 1, S5K5BAF_GAIN_RED_DEF);
   1652	ctrls->gain_blue = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_BLUE_BALANCE,
   1653					     0, 255, 1, S5K5BAF_GAIN_BLUE_DEF);
   1654	v4l2_ctrl_auto_cluster(3, &ctrls->awb, 0, false);
   1655
   1656	ctrls->hflip = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_HFLIP, 0, 1, 1, 0);
   1657	ctrls->vflip = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_VFLIP, 0, 1, 1, 0);
   1658	v4l2_ctrl_cluster(2, &ctrls->hflip);
   1659
   1660	ctrls->auto_exp = v4l2_ctrl_new_std_menu(hdl, ops,
   1661				V4L2_CID_EXPOSURE_AUTO,
   1662				V4L2_EXPOSURE_MANUAL, 0, V4L2_EXPOSURE_AUTO);
   1663	/* Exposure time: x 1 us */
   1664	ctrls->exposure = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_EXPOSURE,
   1665					    0, 6000000U, 1, 100000U);
   1666	/* Total gain: 256 <=> 1x */
   1667	ctrls->gain = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_GAIN,
   1668					0, 256, 1, 256);
   1669	v4l2_ctrl_auto_cluster(3, &ctrls->auto_exp, 0, false);
   1670
   1671	v4l2_ctrl_new_std_menu(hdl, ops, V4L2_CID_POWER_LINE_FREQUENCY,
   1672			       V4L2_CID_POWER_LINE_FREQUENCY_AUTO, 0,
   1673			       V4L2_CID_POWER_LINE_FREQUENCY_AUTO);
   1674
   1675	v4l2_ctrl_new_std_menu(hdl, ops, V4L2_CID_COLORFX,
   1676			       V4L2_COLORFX_SKY_BLUE, ~0x6f, V4L2_COLORFX_NONE);
   1677
   1678	v4l2_ctrl_new_std(hdl, ops, V4L2_CID_WHITE_BALANCE_TEMPERATURE,
   1679			  0, 256, 1, 0);
   1680
   1681	v4l2_ctrl_new_std(hdl, ops, V4L2_CID_SATURATION, -127, 127, 1, 0);
   1682	v4l2_ctrl_new_std(hdl, ops, V4L2_CID_BRIGHTNESS, -127, 127, 1, 0);
   1683	v4l2_ctrl_new_std(hdl, ops, V4L2_CID_CONTRAST, -127, 127, 1, 0);
   1684	v4l2_ctrl_new_std(hdl, ops, V4L2_CID_SHARPNESS, -127, 127, 1, 0);
   1685
   1686	v4l2_ctrl_new_std_menu_items(hdl, ops, V4L2_CID_TEST_PATTERN,
   1687				     ARRAY_SIZE(s5k5baf_test_pattern_menu) - 1,
   1688				     0, 0, s5k5baf_test_pattern_menu);
   1689
   1690	if (hdl->error) {
   1691		v4l2_err(&state->sd, "error creating controls (%d)\n",
   1692			 hdl->error);
   1693		ret = hdl->error;
   1694		v4l2_ctrl_handler_free(hdl);
   1695		return ret;
   1696	}
   1697
   1698	state->sd.ctrl_handler = hdl;
   1699	return 0;
   1700}
   1701
   1702/*
   1703 * V4L2 subdev internal operations
   1704 */
   1705static int s5k5baf_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
   1706{
   1707	struct v4l2_mbus_framefmt *mf;
   1708
   1709	mf = v4l2_subdev_get_try_format(sd, fh->state, PAD_CIS);
   1710	s5k5baf_try_cis_format(mf);
   1711
   1712	if (s5k5baf_is_cis_subdev(sd))
   1713		return 0;
   1714
   1715	mf = v4l2_subdev_get_try_format(sd, fh->state, PAD_OUT);
   1716	mf->colorspace = s5k5baf_formats[0].colorspace;
   1717	mf->code = s5k5baf_formats[0].code;
   1718	mf->width = s5k5baf_cis_rect.width;
   1719	mf->height = s5k5baf_cis_rect.height;
   1720	mf->field = V4L2_FIELD_NONE;
   1721
   1722	*v4l2_subdev_get_try_crop(sd, fh->state, PAD_CIS) = s5k5baf_cis_rect;
   1723	*v4l2_subdev_get_try_compose(sd, fh->state, PAD_CIS) = s5k5baf_cis_rect;
   1724	*v4l2_subdev_get_try_crop(sd, fh->state, PAD_OUT) = s5k5baf_cis_rect;
   1725
   1726	return 0;
   1727}
   1728
   1729static int s5k5baf_check_fw_revision(struct s5k5baf *state)
   1730{
   1731	u16 api_ver = 0, fw_rev = 0, s_id = 0;
   1732	int ret;
   1733
   1734	api_ver = s5k5baf_read(state, REG_FW_APIVER);
   1735	fw_rev = s5k5baf_read(state, REG_FW_REVISION) & 0xff;
   1736	s_id = s5k5baf_read(state, REG_FW_SENSOR_ID);
   1737	ret = s5k5baf_clear_error(state);
   1738	if (ret < 0)
   1739		return ret;
   1740
   1741	v4l2_info(&state->sd, "FW API=%#x, revision=%#x sensor_id=%#x\n",
   1742		  api_ver, fw_rev, s_id);
   1743
   1744	if (api_ver != S5K5BAF_FW_APIVER) {
   1745		v4l2_err(&state->sd, "FW API version not supported\n");
   1746		return -ENODEV;
   1747	}
   1748
   1749	return 0;
   1750}
   1751
   1752static int s5k5baf_registered(struct v4l2_subdev *sd)
   1753{
   1754	struct s5k5baf *state = to_s5k5baf(sd);
   1755	int ret;
   1756
   1757	ret = v4l2_device_register_subdev(sd->v4l2_dev, &state->cis_sd);
   1758	if (ret < 0)
   1759		v4l2_err(sd, "failed to register subdev %s\n",
   1760			 state->cis_sd.name);
   1761	else
   1762		ret = media_create_pad_link(&state->cis_sd.entity, PAD_CIS,
   1763					       &state->sd.entity, PAD_CIS,
   1764					       MEDIA_LNK_FL_IMMUTABLE |
   1765					       MEDIA_LNK_FL_ENABLED);
   1766	return ret;
   1767}
   1768
   1769static void s5k5baf_unregistered(struct v4l2_subdev *sd)
   1770{
   1771	struct s5k5baf *state = to_s5k5baf(sd);
   1772	v4l2_device_unregister_subdev(&state->cis_sd);
   1773}
   1774
   1775static const struct v4l2_subdev_ops s5k5baf_cis_subdev_ops = {
   1776	.pad	= &s5k5baf_cis_pad_ops,
   1777};
   1778
   1779static const struct v4l2_subdev_internal_ops s5k5baf_cis_subdev_internal_ops = {
   1780	.open = s5k5baf_open,
   1781};
   1782
   1783static const struct v4l2_subdev_internal_ops s5k5baf_subdev_internal_ops = {
   1784	.registered = s5k5baf_registered,
   1785	.unregistered = s5k5baf_unregistered,
   1786	.open = s5k5baf_open,
   1787};
   1788
   1789static const struct v4l2_subdev_core_ops s5k5baf_core_ops = {
   1790	.s_power = s5k5baf_set_power,
   1791	.log_status = v4l2_ctrl_subdev_log_status,
   1792};
   1793
   1794static const struct v4l2_subdev_ops s5k5baf_subdev_ops = {
   1795	.core = &s5k5baf_core_ops,
   1796	.pad = &s5k5baf_pad_ops,
   1797	.video = &s5k5baf_video_ops,
   1798};
   1799
   1800static int s5k5baf_configure_gpios(struct s5k5baf *state)
   1801{
   1802	static const char * const name[] = { "S5K5BAF_STBY", "S5K5BAF_RST" };
   1803	struct i2c_client *c = v4l2_get_subdevdata(&state->sd);
   1804	struct s5k5baf_gpio *g = state->gpios;
   1805	int ret, i;
   1806
   1807	for (i = 0; i < NUM_GPIOS; ++i) {
   1808		int flags = GPIOF_DIR_OUT;
   1809		if (g[i].level)
   1810			flags |= GPIOF_INIT_HIGH;
   1811		ret = devm_gpio_request_one(&c->dev, g[i].gpio, flags, name[i]);
   1812		if (ret < 0) {
   1813			v4l2_err(c, "failed to request gpio %s\n", name[i]);
   1814			return ret;
   1815		}
   1816	}
   1817	return 0;
   1818}
   1819
   1820static int s5k5baf_parse_gpios(struct s5k5baf_gpio *gpios, struct device *dev)
   1821{
   1822	static const char * const names[] = {
   1823		"stbyn-gpios",
   1824		"rstn-gpios",
   1825	};
   1826	struct device_node *node = dev->of_node;
   1827	enum of_gpio_flags flags;
   1828	int ret, i;
   1829
   1830	for (i = 0; i < NUM_GPIOS; ++i) {
   1831		ret = of_get_named_gpio_flags(node, names[i], 0, &flags);
   1832		if (ret < 0) {
   1833			dev_err(dev, "no %s GPIO pin provided\n", names[i]);
   1834			return ret;
   1835		}
   1836		gpios[i].gpio = ret;
   1837		gpios[i].level = !(flags & OF_GPIO_ACTIVE_LOW);
   1838	}
   1839
   1840	return 0;
   1841}
   1842
   1843static int s5k5baf_parse_device_node(struct s5k5baf *state, struct device *dev)
   1844{
   1845	struct device_node *node = dev->of_node;
   1846	struct device_node *node_ep;
   1847	struct v4l2_fwnode_endpoint ep = { .bus_type = 0 };
   1848	int ret;
   1849
   1850	if (!node) {
   1851		dev_err(dev, "no device-tree node provided\n");
   1852		return -EINVAL;
   1853	}
   1854
   1855	ret = of_property_read_u32(node, "clock-frequency",
   1856				   &state->mclk_frequency);
   1857	if (ret < 0) {
   1858		state->mclk_frequency = S5K5BAF_DEFAULT_MCLK_FREQ;
   1859		dev_info(dev, "using default %u Hz clock frequency\n",
   1860			 state->mclk_frequency);
   1861	}
   1862
   1863	ret = s5k5baf_parse_gpios(state->gpios, dev);
   1864	if (ret < 0)
   1865		return ret;
   1866
   1867	node_ep = of_graph_get_next_endpoint(node, NULL);
   1868	if (!node_ep) {
   1869		dev_err(dev, "no endpoint defined at node %pOF\n", node);
   1870		return -EINVAL;
   1871	}
   1872
   1873	ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(node_ep), &ep);
   1874	of_node_put(node_ep);
   1875	if (ret)
   1876		return ret;
   1877
   1878	state->bus_type = ep.bus_type;
   1879
   1880	switch (state->bus_type) {
   1881	case V4L2_MBUS_CSI2_DPHY:
   1882		state->nlanes = ep.bus.mipi_csi2.num_data_lanes;
   1883		break;
   1884	case V4L2_MBUS_PARALLEL:
   1885		break;
   1886	default:
   1887		dev_err(dev, "unsupported bus in endpoint defined at node %pOF\n",
   1888			node);
   1889		return -EINVAL;
   1890	}
   1891
   1892	return 0;
   1893}
   1894
   1895static int s5k5baf_configure_subdevs(struct s5k5baf *state,
   1896				     struct i2c_client *c)
   1897{
   1898	struct v4l2_subdev *sd;
   1899	int ret;
   1900
   1901	sd = &state->cis_sd;
   1902	v4l2_subdev_init(sd, &s5k5baf_cis_subdev_ops);
   1903	sd->owner = THIS_MODULE;
   1904	v4l2_set_subdevdata(sd, state);
   1905	snprintf(sd->name, sizeof(sd->name), "S5K5BAF-CIS %d-%04x",
   1906		 i2c_adapter_id(c->adapter), c->addr);
   1907
   1908	sd->internal_ops = &s5k5baf_cis_subdev_internal_ops;
   1909	sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
   1910
   1911	state->cis_pad.flags = MEDIA_PAD_FL_SOURCE;
   1912	sd->entity.function = MEDIA_ENT_F_CAM_SENSOR;
   1913	ret = media_entity_pads_init(&sd->entity, NUM_CIS_PADS, &state->cis_pad);
   1914	if (ret < 0)
   1915		goto err;
   1916
   1917	sd = &state->sd;
   1918	v4l2_i2c_subdev_init(sd, c, &s5k5baf_subdev_ops);
   1919	snprintf(sd->name, sizeof(sd->name), "S5K5BAF-ISP %d-%04x",
   1920		 i2c_adapter_id(c->adapter), c->addr);
   1921
   1922	sd->internal_ops = &s5k5baf_subdev_internal_ops;
   1923	sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
   1924
   1925	state->pads[PAD_CIS].flags = MEDIA_PAD_FL_SINK;
   1926	state->pads[PAD_OUT].flags = MEDIA_PAD_FL_SOURCE;
   1927	sd->entity.function = MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN;
   1928	ret = media_entity_pads_init(&sd->entity, NUM_ISP_PADS, state->pads);
   1929
   1930	if (!ret)
   1931		return 0;
   1932
   1933	media_entity_cleanup(&state->cis_sd.entity);
   1934err:
   1935	dev_err(&c->dev, "cannot init media entity %s\n", sd->name);
   1936	return ret;
   1937}
   1938
   1939static int s5k5baf_configure_regulators(struct s5k5baf *state)
   1940{
   1941	struct i2c_client *c = v4l2_get_subdevdata(&state->sd);
   1942	int ret;
   1943	int i;
   1944
   1945	for (i = 0; i < S5K5BAF_NUM_SUPPLIES; i++)
   1946		state->supplies[i].supply = s5k5baf_supply_names[i];
   1947
   1948	ret = devm_regulator_bulk_get(&c->dev, S5K5BAF_NUM_SUPPLIES,
   1949				      state->supplies);
   1950	if (ret < 0)
   1951		v4l2_err(c, "failed to get regulators\n");
   1952	return ret;
   1953}
   1954
   1955static int s5k5baf_probe(struct i2c_client *c)
   1956{
   1957	struct s5k5baf *state;
   1958	int ret;
   1959
   1960	state = devm_kzalloc(&c->dev, sizeof(*state), GFP_KERNEL);
   1961	if (!state)
   1962		return -ENOMEM;
   1963
   1964	mutex_init(&state->lock);
   1965	state->crop_sink = s5k5baf_cis_rect;
   1966	state->compose = s5k5baf_cis_rect;
   1967	state->crop_source = s5k5baf_cis_rect;
   1968
   1969	ret = s5k5baf_parse_device_node(state, &c->dev);
   1970	if (ret < 0)
   1971		return ret;
   1972
   1973	ret = s5k5baf_configure_subdevs(state, c);
   1974	if (ret < 0)
   1975		return ret;
   1976
   1977	ret = s5k5baf_configure_gpios(state);
   1978	if (ret < 0)
   1979		goto err_me;
   1980
   1981	ret = s5k5baf_configure_regulators(state);
   1982	if (ret < 0)
   1983		goto err_me;
   1984
   1985	state->clock = devm_clk_get(state->sd.dev, S5K5BAF_CLK_NAME);
   1986	if (IS_ERR(state->clock)) {
   1987		ret = -EPROBE_DEFER;
   1988		goto err_me;
   1989	}
   1990
   1991	ret = s5k5baf_power_on(state);
   1992	if (ret < 0) {
   1993		ret = -EPROBE_DEFER;
   1994		goto err_me;
   1995	}
   1996	s5k5baf_hw_init(state);
   1997	ret = s5k5baf_check_fw_revision(state);
   1998
   1999	s5k5baf_power_off(state);
   2000	if (ret < 0)
   2001		goto err_me;
   2002
   2003	ret = s5k5baf_initialize_ctrls(state);
   2004	if (ret < 0)
   2005		goto err_me;
   2006
   2007	ret = v4l2_async_register_subdev(&state->sd);
   2008	if (ret < 0)
   2009		goto err_ctrl;
   2010
   2011	return 0;
   2012
   2013err_ctrl:
   2014	v4l2_ctrl_handler_free(state->sd.ctrl_handler);
   2015err_me:
   2016	media_entity_cleanup(&state->sd.entity);
   2017	media_entity_cleanup(&state->cis_sd.entity);
   2018	return ret;
   2019}
   2020
   2021static int s5k5baf_remove(struct i2c_client *c)
   2022{
   2023	struct v4l2_subdev *sd = i2c_get_clientdata(c);
   2024	struct s5k5baf *state = to_s5k5baf(sd);
   2025
   2026	v4l2_async_unregister_subdev(sd);
   2027	v4l2_ctrl_handler_free(sd->ctrl_handler);
   2028	media_entity_cleanup(&sd->entity);
   2029
   2030	sd = &state->cis_sd;
   2031	v4l2_device_unregister_subdev(sd);
   2032	media_entity_cleanup(&sd->entity);
   2033
   2034	return 0;
   2035}
   2036
   2037static const struct i2c_device_id s5k5baf_id[] = {
   2038	{ S5K5BAF_DRIVER_NAME, 0 },
   2039	{ },
   2040};
   2041MODULE_DEVICE_TABLE(i2c, s5k5baf_id);
   2042
   2043static const struct of_device_id s5k5baf_of_match[] = {
   2044	{ .compatible = "samsung,s5k5baf" },
   2045	{ }
   2046};
   2047MODULE_DEVICE_TABLE(of, s5k5baf_of_match);
   2048
   2049static struct i2c_driver s5k5baf_i2c_driver = {
   2050	.driver = {
   2051		.of_match_table = s5k5baf_of_match,
   2052		.name = S5K5BAF_DRIVER_NAME
   2053	},
   2054	.probe_new	= s5k5baf_probe,
   2055	.remove		= s5k5baf_remove,
   2056	.id_table	= s5k5baf_id,
   2057};
   2058
   2059module_i2c_driver(s5k5baf_i2c_driver);
   2060
   2061MODULE_DESCRIPTION("Samsung S5K5BAF(X) UXGA camera driver");
   2062MODULE_AUTHOR("Andrzej Hajda <a.hajda@samsung.com>");
   2063MODULE_LICENSE("GPL v2");