// SPDX-License-Identifier: GPL-2.0
/*
* Driver for RJ54N1CB0C CMOS Image Sensor from Sharp
*
* Copyright (C) 2018, Jacopo Mondi <jacopo@jmondi.org>
*
* Copyright (C) 2009, Guennadi Liakhovetski <g.liakhovetski@gmx.de>
*/
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/gpio/consumer.h>
#include <linux/i2c.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/v4l2-mediabus.h>
#include <linux/videodev2.h>
#include <media/i2c/rj54n1cb0c.h>
#include <media/v4l2-device.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-subdev.h>
#define RJ54N1_DEV_CODE 0x0400
#define RJ54N1_DEV_CODE2 0x0401
#define RJ54N1_OUT_SEL 0x0403
#define RJ54N1_XY_OUTPUT_SIZE_S_H 0x0404
#define RJ54N1_X_OUTPUT_SIZE_S_L 0x0405
#define RJ54N1_Y_OUTPUT_SIZE_S_L 0x0406
#define RJ54N1_XY_OUTPUT_SIZE_P_H 0x0407
#define RJ54N1_X_OUTPUT_SIZE_P_L 0x0408
#define RJ54N1_Y_OUTPUT_SIZE_P_L 0x0409
#define RJ54N1_LINE_LENGTH_PCK_S_H 0x040a
#define RJ54N1_LINE_LENGTH_PCK_S_L 0x040b
#define RJ54N1_LINE_LENGTH_PCK_P_H 0x040c
#define RJ54N1_LINE_LENGTH_PCK_P_L 0x040d
#define RJ54N1_RESIZE_N 0x040e
#define RJ54N1_RESIZE_N_STEP 0x040f
#define RJ54N1_RESIZE_STEP 0x0410
#define RJ54N1_RESIZE_HOLD_H 0x0411
#define RJ54N1_RESIZE_HOLD_L 0x0412
#define RJ54N1_H_OBEN_OFS 0x0413
#define RJ54N1_V_OBEN_OFS 0x0414
#define RJ54N1_RESIZE_CONTROL 0x0415
#define RJ54N1_STILL_CONTROL 0x0417
#define RJ54N1_INC_USE_SEL_H 0x0425
#define RJ54N1_INC_USE_SEL_L 0x0426
#define RJ54N1_MIRROR_STILL_MODE 0x0427
#define RJ54N1_INIT_START 0x0428
#define RJ54N1_SCALE_1_2_LEV 0x0429
#define RJ54N1_SCALE_4_LEV 0x042a
#define RJ54N1_Y_GAIN 0x04d8
#define RJ54N1_APT_GAIN_UP 0x04fa
#define RJ54N1_RA_SEL_UL 0x0530
#define RJ54N1_BYTE_SWAP 0x0531
#define RJ54N1_OUT_SIGPO 0x053b
#define RJ54N1_WB_SEL_WEIGHT_I 0x054e
#define RJ54N1_BIT8_WB 0x0569
#define RJ54N1_HCAPS_WB 0x056a
#define RJ54N1_VCAPS_WB 0x056b
#define RJ54N1_HCAPE_WB 0x056c
#define RJ54N1_VCAPE_WB 0x056d
#define RJ54N1_EXPOSURE_CONTROL 0x058c
#define RJ54N1_FRAME_LENGTH_S_H 0x0595
#define RJ54N1_FRAME_LENGTH_S_L 0x0596
#define RJ54N1_FRAME_LENGTH_P_H 0x0597
#define RJ54N1_FRAME_LENGTH_P_L 0x0598
#define RJ54N1_PEAK_H 0x05b7
#define RJ54N1_PEAK_50 0x05b8
#define RJ54N1_PEAK_60 0x05b9
#define RJ54N1_PEAK_DIFF 0x05ba
#define RJ54N1_IOC 0x05ef
#define RJ54N1_TG_BYPASS 0x0700
#define RJ54N1_PLL_L 0x0701
#define RJ54N1_PLL_N 0x0702
#define RJ54N1_PLL_EN 0x0704
#define RJ54N1_RATIO_TG 0x0706
#define RJ54N1_RATIO_T 0x0707
#define RJ54N1_RATIO_R 0x0708
#define RJ54N1_RAMP_TGCLK_EN 0x0709
#define RJ54N1_OCLK_DSP 0x0710
#define RJ54N1_RATIO_OP 0x0711
#define RJ54N1_RATIO_O 0x0712
#define RJ54N1_OCLK_SEL_EN 0x0713
#define RJ54N1_CLK_RST 0x0717
#define RJ54N1_RESET_STANDBY 0x0718
#define RJ54N1_FWFLG 0x07fe
#define E_EXCLK (1 << 7)
#define SOFT_STDBY (1 << 4)
#define SEN_RSTX (1 << 2)
#define TG_RSTX (1 << 1)
#define DSP_RSTX (1 << 0)
#define RESIZE_HOLD_SEL (1 << 2)
#define RESIZE_GO (1 << 1)
/*
* When cropping, the camera automatically centers the cropped region, there
* doesn't seem to be a way to specify an explicit location of the rectangle.
*/
#define RJ54N1_COLUMN_SKIP 0
#define RJ54N1_ROW_SKIP 0
#define RJ54N1_MAX_WIDTH 1600
#define RJ54N1_MAX_HEIGHT 1200
#define PLL_L 2
#define PLL_N 0x31
/* I2C addresses: 0x50, 0x51, 0x60, 0x61 */
/* RJ54N1CB0C has only one fixed colorspace per pixelcode */
struct rj54n1_datafmt