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

ov9640.c (19377B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * OmniVision OV96xx Camera Driver
      4 *
      5 * Copyright (C) 2009 Marek Vasut <marek.vasut@gmail.com>
      6 *
      7 * Based on ov772x camera driver:
      8 *
      9 * Copyright (C) 2008 Renesas Solutions Corp.
     10 * Kuninori Morimoto <morimoto.kuninori@renesas.com>
     11 *
     12 * Based on ov7670 and soc_camera_platform driver,
     13 * transition from soc_camera to pxa_camera based on mt9m111
     14 *
     15 * Copyright 2006-7 Jonathan Corbet <corbet@lwn.net>
     16 * Copyright (C) 2008 Magnus Damm
     17 * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>
     18 */
     19
     20#include <linux/clk.h>
     21#include <linux/init.h>
     22#include <linux/module.h>
     23#include <linux/i2c.h>
     24#include <linux/slab.h>
     25#include <linux/delay.h>
     26#include <linux/v4l2-mediabus.h>
     27#include <linux/videodev2.h>
     28
     29#include <media/v4l2-async.h>
     30#include <media/v4l2-common.h>
     31#include <media/v4l2-ctrls.h>
     32#include <media/v4l2-device.h>
     33#include <media/v4l2-event.h>
     34
     35#include <linux/gpio/consumer.h>
     36
     37#include "ov9640.h"
     38
     39#define to_ov9640_sensor(sd)	container_of(sd, struct ov9640_priv, subdev)
     40
     41/* default register setup */
     42static const struct ov9640_reg ov9640_regs_dflt[] = {
     43	{ OV9640_COM5,	OV9640_COM5_SYSCLK | OV9640_COM5_LONGEXP },
     44	{ OV9640_COM6,	OV9640_COM6_OPT_BLC | OV9640_COM6_ADBLC_BIAS |
     45			OV9640_COM6_FMT_RST | OV9640_COM6_ADBLC_OPTEN },
     46	{ OV9640_PSHFT,	OV9640_PSHFT_VAL(0x01) },
     47	{ OV9640_ACOM,	OV9640_ACOM_2X_ANALOG | OV9640_ACOM_RSVD },
     48	{ OV9640_TSLB,	OV9640_TSLB_YUYV_UYVY },
     49	{ OV9640_COM16,	OV9640_COM16_RB_AVG },
     50
     51	/* Gamma curve P */
     52	{ 0x6c, 0x40 },	{ 0x6d, 0x30 },	{ 0x6e, 0x4b },	{ 0x6f, 0x60 },
     53	{ 0x70, 0x70 },	{ 0x71, 0x70 },	{ 0x72, 0x70 },	{ 0x73, 0x70 },
     54	{ 0x74, 0x60 },	{ 0x75, 0x60 },	{ 0x76, 0x50 },	{ 0x77, 0x48 },
     55	{ 0x78, 0x3a },	{ 0x79, 0x2e },	{ 0x7a, 0x28 },	{ 0x7b, 0x22 },
     56
     57	/* Gamma curve T */
     58	{ 0x7c, 0x04 },	{ 0x7d, 0x07 },	{ 0x7e, 0x10 },	{ 0x7f, 0x28 },
     59	{ 0x80, 0x36 },	{ 0x81, 0x44 },	{ 0x82, 0x52 },	{ 0x83, 0x60 },
     60	{ 0x84, 0x6c },	{ 0x85, 0x78 },	{ 0x86, 0x8c },	{ 0x87, 0x9e },
     61	{ 0x88, 0xbb },	{ 0x89, 0xd2 },	{ 0x8a, 0xe6 },
     62};
     63
     64/* Configurations
     65 * NOTE: for YUV, alter the following registers:
     66 *		COM12 |= OV9640_COM12_YUV_AVG
     67 *
     68 *	 for RGB, alter the following registers:
     69 *		COM7  |= OV9640_COM7_RGB
     70 *		COM13 |= OV9640_COM13_RGB_AVG
     71 *		COM15 |= proper RGB color encoding mode
     72 */
     73static const struct ov9640_reg ov9640_regs_qqcif[] = {
     74	{ OV9640_CLKRC,	OV9640_CLKRC_DPLL_EN | OV9640_CLKRC_DIV(0x0f) },
     75	{ OV9640_COM1,	OV9640_COM1_QQFMT | OV9640_COM1_HREF_2SKIP },
     76	{ OV9640_COM4,	OV9640_COM4_QQ_VP | OV9640_COM4_RSVD },
     77	{ OV9640_COM7,	OV9640_COM7_QCIF },
     78	{ OV9640_COM12,	OV9640_COM12_RSVD },
     79	{ OV9640_COM13,	OV9640_COM13_GAMMA_RAW | OV9640_COM13_MATRIX_EN },
     80	{ OV9640_COM15,	OV9640_COM15_OR_10F0 },
     81};
     82
     83static const struct ov9640_reg ov9640_regs_qqvga[] = {
     84	{ OV9640_CLKRC,	OV9640_CLKRC_DPLL_EN | OV9640_CLKRC_DIV(0x07) },
     85	{ OV9640_COM1,	OV9640_COM1_QQFMT | OV9640_COM1_HREF_2SKIP },
     86	{ OV9640_COM4,	OV9640_COM4_QQ_VP | OV9640_COM4_RSVD },
     87	{ OV9640_COM7,	OV9640_COM7_QVGA },
     88	{ OV9640_COM12,	OV9640_COM12_RSVD },
     89	{ OV9640_COM13,	OV9640_COM13_GAMMA_RAW | OV9640_COM13_MATRIX_EN },
     90	{ OV9640_COM15,	OV9640_COM15_OR_10F0 },
     91};
     92
     93static const struct ov9640_reg ov9640_regs_qcif[] = {
     94	{ OV9640_CLKRC,	OV9640_CLKRC_DPLL_EN | OV9640_CLKRC_DIV(0x07) },
     95	{ OV9640_COM4,	OV9640_COM4_QQ_VP | OV9640_COM4_RSVD },
     96	{ OV9640_COM7,	OV9640_COM7_QCIF },
     97	{ OV9640_COM12,	OV9640_COM12_RSVD },
     98	{ OV9640_COM13,	OV9640_COM13_GAMMA_RAW | OV9640_COM13_MATRIX_EN },
     99	{ OV9640_COM15,	OV9640_COM15_OR_10F0 },
    100};
    101
    102static const struct ov9640_reg ov9640_regs_qvga[] = {
    103	{ OV9640_CLKRC,	OV9640_CLKRC_DPLL_EN | OV9640_CLKRC_DIV(0x03) },
    104	{ OV9640_COM4,	OV9640_COM4_QQ_VP | OV9640_COM4_RSVD },
    105	{ OV9640_COM7,	OV9640_COM7_QVGA },
    106	{ OV9640_COM12,	OV9640_COM12_RSVD },
    107	{ OV9640_COM13,	OV9640_COM13_GAMMA_RAW | OV9640_COM13_MATRIX_EN },
    108	{ OV9640_COM15,	OV9640_COM15_OR_10F0 },
    109};
    110
    111static const struct ov9640_reg ov9640_regs_cif[] = {
    112	{ OV9640_CLKRC,	OV9640_CLKRC_DPLL_EN | OV9640_CLKRC_DIV(0x03) },
    113	{ OV9640_COM3,	OV9640_COM3_VP },
    114	{ OV9640_COM7,	OV9640_COM7_CIF },
    115	{ OV9640_COM12,	OV9640_COM12_RSVD },
    116	{ OV9640_COM13,	OV9640_COM13_GAMMA_RAW | OV9640_COM13_MATRIX_EN },
    117	{ OV9640_COM15,	OV9640_COM15_OR_10F0 },
    118};
    119
    120static const struct ov9640_reg ov9640_regs_vga[] = {
    121	{ OV9640_CLKRC,	OV9640_CLKRC_DPLL_EN | OV9640_CLKRC_DIV(0x01) },
    122	{ OV9640_COM3,	OV9640_COM3_VP },
    123	{ OV9640_COM7,	OV9640_COM7_VGA },
    124	{ OV9640_COM12,	OV9640_COM12_RSVD },
    125	{ OV9640_COM13,	OV9640_COM13_GAMMA_RAW | OV9640_COM13_MATRIX_EN },
    126	{ OV9640_COM15,	OV9640_COM15_OR_10F0 },
    127};
    128
    129static const struct ov9640_reg ov9640_regs_sxga[] = {
    130	{ OV9640_CLKRC,	OV9640_CLKRC_DPLL_EN | OV9640_CLKRC_DIV(0x01) },
    131	{ OV9640_COM3,	OV9640_COM3_VP },
    132	{ OV9640_COM7,	0 },
    133	{ OV9640_COM12,	OV9640_COM12_RSVD },
    134	{ OV9640_COM13,	OV9640_COM13_GAMMA_RAW | OV9640_COM13_MATRIX_EN },
    135	{ OV9640_COM15,	OV9640_COM15_OR_10F0 },
    136};
    137
    138static const struct ov9640_reg ov9640_regs_yuv[] = {
    139	{ OV9640_MTX1,	0x58 },
    140	{ OV9640_MTX2,	0x48 },
    141	{ OV9640_MTX3,	0x10 },
    142	{ OV9640_MTX4,	0x28 },
    143	{ OV9640_MTX5,	0x48 },
    144	{ OV9640_MTX6,	0x70 },
    145	{ OV9640_MTX7,	0x40 },
    146	{ OV9640_MTX8,	0x40 },
    147	{ OV9640_MTX9,	0x40 },
    148	{ OV9640_MTXS,	0x0f },
    149};
    150
    151static const struct ov9640_reg ov9640_regs_rgb[] = {
    152	{ OV9640_MTX1,	0x71 },
    153	{ OV9640_MTX2,	0x3e },
    154	{ OV9640_MTX3,	0x0c },
    155	{ OV9640_MTX4,	0x33 },
    156	{ OV9640_MTX5,	0x72 },
    157	{ OV9640_MTX6,	0x00 },
    158	{ OV9640_MTX7,	0x2b },
    159	{ OV9640_MTX8,	0x66 },
    160	{ OV9640_MTX9,	0xd2 },
    161	{ OV9640_MTXS,	0x65 },
    162};
    163
    164static const u32 ov9640_codes[] = {
    165	MEDIA_BUS_FMT_UYVY8_2X8,
    166	MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE,
    167	MEDIA_BUS_FMT_RGB565_2X8_LE,
    168};
    169
    170/* read a register */
    171static int ov9640_reg_read(struct i2c_client *client, u8 reg, u8 *val)
    172{
    173	int ret;
    174	u8 data = reg;
    175	struct i2c_msg msg = {
    176		.addr	= client->addr,
    177		.flags	= 0,
    178		.len	= 1,
    179		.buf	= &data,
    180	};
    181
    182	ret = i2c_transfer(client->adapter, &msg, 1);
    183	if (ret < 0)
    184		goto err;
    185
    186	msg.flags = I2C_M_RD;
    187	ret = i2c_transfer(client->adapter, &msg, 1);
    188	if (ret < 0)
    189		goto err;
    190
    191	*val = data;
    192	return 0;
    193
    194err:
    195	dev_err(&client->dev, "Failed reading register 0x%02x!\n", reg);
    196	return ret;
    197}
    198
    199/* write a register */
    200static int ov9640_reg_write(struct i2c_client *client, u8 reg, u8 val)
    201{
    202	int ret;
    203	u8 _val;
    204	unsigned char data[2] = { reg, val };
    205	struct i2c_msg msg = {
    206		.addr	= client->addr,
    207		.flags	= 0,
    208		.len	= 2,
    209		.buf	= data,
    210	};
    211
    212	ret = i2c_transfer(client->adapter, &msg, 1);
    213	if (ret < 0) {
    214		dev_err(&client->dev, "Failed writing register 0x%02x!\n", reg);
    215		return ret;
    216	}
    217
    218	/* we have to read the register back ... no idea why, maybe HW bug */
    219	ret = ov9640_reg_read(client, reg, &_val);
    220	if (ret)
    221		dev_err(&client->dev,
    222			"Failed reading back register 0x%02x!\n", reg);
    223
    224	return 0;
    225}
    226
    227
    228/* Read a register, alter its bits, write it back */
    229static int ov9640_reg_rmw(struct i2c_client *client, u8 reg, u8 set, u8 unset)
    230{
    231	u8 val;
    232	int ret;
    233
    234	ret = ov9640_reg_read(client, reg, &val);
    235	if (ret) {
    236		dev_err(&client->dev,
    237			"[Read]-Modify-Write of register %02x failed!\n", reg);
    238		return ret;
    239	}
    240
    241	val |= set;
    242	val &= ~unset;
    243
    244	ret = ov9640_reg_write(client, reg, val);
    245	if (ret)
    246		dev_err(&client->dev,
    247			"Read-Modify-[Write] of register %02x failed!\n", reg);
    248
    249	return ret;
    250}
    251
    252/* Soft reset the camera. This has nothing to do with the RESET pin! */
    253static int ov9640_reset(struct i2c_client *client)
    254{
    255	int ret;
    256
    257	ret = ov9640_reg_write(client, OV9640_COM7, OV9640_COM7_SCCB_RESET);
    258	if (ret)
    259		dev_err(&client->dev,
    260			"An error occurred while entering soft reset!\n");
    261
    262	return ret;
    263}
    264
    265/* Start/Stop streaming from the device */
    266static int ov9640_s_stream(struct v4l2_subdev *sd, int enable)
    267{
    268	return 0;
    269}
    270
    271/* Set status of additional camera capabilities */
    272static int ov9640_s_ctrl(struct v4l2_ctrl *ctrl)
    273{
    274	struct ov9640_priv *priv = container_of(ctrl->handler,
    275						struct ov9640_priv, hdl);
    276	struct i2c_client *client = v4l2_get_subdevdata(&priv->subdev);
    277
    278	switch (ctrl->id) {
    279	case V4L2_CID_VFLIP:
    280		if (ctrl->val)
    281			return ov9640_reg_rmw(client, OV9640_MVFP,
    282					      OV9640_MVFP_V, 0);
    283		return ov9640_reg_rmw(client, OV9640_MVFP, 0, OV9640_MVFP_V);
    284	case V4L2_CID_HFLIP:
    285		if (ctrl->val)
    286			return ov9640_reg_rmw(client, OV9640_MVFP,
    287					      OV9640_MVFP_H, 0);
    288		return ov9640_reg_rmw(client, OV9640_MVFP, 0, OV9640_MVFP_H);
    289	}
    290
    291	return -EINVAL;
    292}
    293
    294#ifdef CONFIG_VIDEO_ADV_DEBUG
    295static int ov9640_get_register(struct v4l2_subdev *sd,
    296				struct v4l2_dbg_register *reg)
    297{
    298	struct i2c_client *client = v4l2_get_subdevdata(sd);
    299	int ret;
    300	u8 val;
    301
    302	if (reg->reg & ~0xff)
    303		return -EINVAL;
    304
    305	reg->size = 1;
    306
    307	ret = ov9640_reg_read(client, reg->reg, &val);
    308	if (ret)
    309		return ret;
    310
    311	reg->val = (__u64)val;
    312
    313	return 0;
    314}
    315
    316static int ov9640_set_register(struct v4l2_subdev *sd,
    317				const struct v4l2_dbg_register *reg)
    318{
    319	struct i2c_client *client = v4l2_get_subdevdata(sd);
    320
    321	if (reg->reg & ~0xff || reg->val & ~0xff)
    322		return -EINVAL;
    323
    324	return ov9640_reg_write(client, reg->reg, reg->val);
    325}
    326#endif
    327
    328static int ov9640_s_power(struct v4l2_subdev *sd, int on)
    329{
    330	struct ov9640_priv *priv = to_ov9640_sensor(sd);
    331	int ret = 0;
    332
    333	if (on) {
    334		gpiod_set_value(priv->gpio_power, 1);
    335		usleep_range(1000, 2000);
    336		ret = clk_prepare_enable(priv->clk);
    337		usleep_range(1000, 2000);
    338		gpiod_set_value(priv->gpio_reset, 0);
    339	} else {
    340		gpiod_set_value(priv->gpio_reset, 1);
    341		usleep_range(1000, 2000);
    342		clk_disable_unprepare(priv->clk);
    343		usleep_range(1000, 2000);
    344		gpiod_set_value(priv->gpio_power, 0);
    345	}
    346
    347	return ret;
    348}
    349
    350/* select nearest higher resolution for capture */
    351static void ov9640_res_roundup(u32 *width, u32 *height)
    352{
    353	unsigned int i;
    354	enum { QQCIF, QQVGA, QCIF, QVGA, CIF, VGA, SXGA };
    355	static const u32 res_x[] = { 88, 160, 176, 320, 352, 640, 1280 };
    356	static const u32 res_y[] = { 72, 120, 144, 240, 288, 480, 960 };
    357
    358	for (i = 0; i < ARRAY_SIZE(res_x); i++) {
    359		if (res_x[i] >= *width && res_y[i] >= *height) {
    360			*width = res_x[i];
    361			*height = res_y[i];
    362			return;
    363		}
    364	}
    365
    366	*width = res_x[SXGA];
    367	*height = res_y[SXGA];
    368}
    369
    370/* Prepare necessary register changes depending on color encoding */
    371static void ov9640_alter_regs(u32 code,
    372			      struct ov9640_reg_alt *alt)
    373{
    374	switch (code) {
    375	default:
    376	case MEDIA_BUS_FMT_UYVY8_2X8:
    377		alt->com12	= OV9640_COM12_YUV_AVG;
    378		alt->com13	= OV9640_COM13_Y_DELAY_EN |
    379					OV9640_COM13_YUV_DLY(0x01);
    380		break;
    381	case MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE:
    382		alt->com7	= OV9640_COM7_RGB;
    383		alt->com13	= OV9640_COM13_RGB_AVG;
    384		alt->com15	= OV9640_COM15_RGB_555;
    385		break;
    386	case MEDIA_BUS_FMT_RGB565_2X8_LE:
    387		alt->com7	= OV9640_COM7_RGB;
    388		alt->com13	= OV9640_COM13_RGB_AVG;
    389		alt->com15	= OV9640_COM15_RGB_565;
    390		break;
    391	}
    392}
    393
    394/* Setup registers according to resolution and color encoding */
    395static int ov9640_write_regs(struct i2c_client *client, u32 width,
    396		u32 code, struct ov9640_reg_alt *alts)
    397{
    398	const struct ov9640_reg	*ov9640_regs, *matrix_regs;
    399	unsigned int		ov9640_regs_len, matrix_regs_len;
    400	unsigned int		i;
    401	int			ret;
    402	u8			val;
    403
    404	/* select register configuration for given resolution */
    405	switch (width) {
    406	case W_QQCIF:
    407		ov9640_regs	= ov9640_regs_qqcif;
    408		ov9640_regs_len	= ARRAY_SIZE(ov9640_regs_qqcif);
    409		break;
    410	case W_QQVGA:
    411		ov9640_regs	= ov9640_regs_qqvga;
    412		ov9640_regs_len	= ARRAY_SIZE(ov9640_regs_qqvga);
    413		break;
    414	case W_QCIF:
    415		ov9640_regs	= ov9640_regs_qcif;
    416		ov9640_regs_len	= ARRAY_SIZE(ov9640_regs_qcif);
    417		break;
    418	case W_QVGA:
    419		ov9640_regs	= ov9640_regs_qvga;
    420		ov9640_regs_len	= ARRAY_SIZE(ov9640_regs_qvga);
    421		break;
    422	case W_CIF:
    423		ov9640_regs	= ov9640_regs_cif;
    424		ov9640_regs_len	= ARRAY_SIZE(ov9640_regs_cif);
    425		break;
    426	case W_VGA:
    427		ov9640_regs	= ov9640_regs_vga;
    428		ov9640_regs_len	= ARRAY_SIZE(ov9640_regs_vga);
    429		break;
    430	case W_SXGA:
    431		ov9640_regs	= ov9640_regs_sxga;
    432		ov9640_regs_len	= ARRAY_SIZE(ov9640_regs_sxga);
    433		break;
    434	default:
    435		dev_err(&client->dev, "Failed to select resolution!\n");
    436		return -EINVAL;
    437	}
    438
    439	/* select color matrix configuration for given color encoding */
    440	if (code == MEDIA_BUS_FMT_UYVY8_2X8) {
    441		matrix_regs	= ov9640_regs_yuv;
    442		matrix_regs_len	= ARRAY_SIZE(ov9640_regs_yuv);
    443	} else {
    444		matrix_regs	= ov9640_regs_rgb;
    445		matrix_regs_len	= ARRAY_SIZE(ov9640_regs_rgb);
    446	}
    447
    448	/* write register settings into the module */
    449	for (i = 0; i < ov9640_regs_len; i++) {
    450		val = ov9640_regs[i].val;
    451
    452		switch (ov9640_regs[i].reg) {
    453		case OV9640_COM7:
    454			val |= alts->com7;
    455			break;
    456		case OV9640_COM12:
    457			val |= alts->com12;
    458			break;
    459		case OV9640_COM13:
    460			val |= alts->com13;
    461			break;
    462		case OV9640_COM15:
    463			val |= alts->com15;
    464			break;
    465		}
    466
    467		ret = ov9640_reg_write(client, ov9640_regs[i].reg, val);
    468		if (ret)
    469			return ret;
    470	}
    471
    472	/* write color matrix configuration into the module */
    473	for (i = 0; i < matrix_regs_len; i++) {
    474		ret = ov9640_reg_write(client, matrix_regs[i].reg,
    475				       matrix_regs[i].val);
    476		if (ret)
    477			return ret;
    478	}
    479
    480	return 0;
    481}
    482
    483/* program default register values */
    484static int ov9640_prog_dflt(struct i2c_client *client)
    485{
    486	unsigned int i;
    487	int ret;
    488
    489	for (i = 0; i < ARRAY_SIZE(ov9640_regs_dflt); i++) {
    490		ret = ov9640_reg_write(client, ov9640_regs_dflt[i].reg,
    491				       ov9640_regs_dflt[i].val);
    492		if (ret)
    493			return ret;
    494	}
    495
    496	/* wait for the changes to actually happen, 140ms are not enough yet */
    497	msleep(150);
    498
    499	return 0;
    500}
    501
    502/* set the format we will capture in */
    503static int ov9640_s_fmt(struct v4l2_subdev *sd,
    504			struct v4l2_mbus_framefmt *mf)
    505{
    506	struct i2c_client *client = v4l2_get_subdevdata(sd);
    507	struct ov9640_reg_alt alts = {0};
    508	int ret;
    509
    510	ov9640_alter_regs(mf->code, &alts);
    511
    512	ov9640_reset(client);
    513
    514	ret = ov9640_prog_dflt(client);
    515	if (ret)
    516		return ret;
    517
    518	return ov9640_write_regs(client, mf->width, mf->code, &alts);
    519}
    520
    521static int ov9640_set_fmt(struct v4l2_subdev *sd,
    522		struct v4l2_subdev_state *sd_state,
    523		struct v4l2_subdev_format *format)
    524{
    525	struct v4l2_mbus_framefmt *mf = &format->format;
    526
    527	if (format->pad)
    528		return -EINVAL;
    529
    530	ov9640_res_roundup(&mf->width, &mf->height);
    531
    532	mf->field = V4L2_FIELD_NONE;
    533
    534	switch (mf->code) {
    535	case MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE:
    536	case MEDIA_BUS_FMT_RGB565_2X8_LE:
    537		mf->colorspace = V4L2_COLORSPACE_SRGB;
    538		break;
    539	default:
    540		mf->code = MEDIA_BUS_FMT_UYVY8_2X8;
    541		fallthrough;
    542	case MEDIA_BUS_FMT_UYVY8_2X8:
    543		mf->colorspace = V4L2_COLORSPACE_JPEG;
    544		break;
    545	}
    546
    547	if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE)
    548		return ov9640_s_fmt(sd, mf);
    549
    550	sd_state->pads->try_fmt = *mf;
    551
    552	return 0;
    553}
    554
    555static int ov9640_enum_mbus_code(struct v4l2_subdev *sd,
    556		struct v4l2_subdev_state *sd_state,
    557		struct v4l2_subdev_mbus_code_enum *code)
    558{
    559	if (code->pad || code->index >= ARRAY_SIZE(ov9640_codes))
    560		return -EINVAL;
    561
    562	code->code = ov9640_codes[code->index];
    563
    564	return 0;
    565}
    566
    567static int ov9640_get_selection(struct v4l2_subdev *sd,
    568		struct v4l2_subdev_state *sd_state,
    569		struct v4l2_subdev_selection *sel)
    570{
    571	if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
    572		return -EINVAL;
    573
    574	sel->r.left = 0;
    575	sel->r.top = 0;
    576	switch (sel->target) {
    577	case V4L2_SEL_TGT_CROP_BOUNDS:
    578	case V4L2_SEL_TGT_CROP:
    579		sel->r.width = W_SXGA;
    580		sel->r.height = H_SXGA;
    581		return 0;
    582	default:
    583		return -EINVAL;
    584	}
    585}
    586
    587static int ov9640_video_probe(struct i2c_client *client)
    588{
    589	struct v4l2_subdev *sd = i2c_get_clientdata(client);
    590	struct ov9640_priv *priv = to_ov9640_sensor(sd);
    591	u8		pid, ver, midh, midl;
    592	const char	*devname;
    593	int		ret;
    594
    595	ret = ov9640_s_power(&priv->subdev, 1);
    596	if (ret < 0)
    597		return ret;
    598
    599	/*
    600	 * check and show product ID and manufacturer ID
    601	 */
    602
    603	ret = ov9640_reg_read(client, OV9640_PID, &pid);
    604	if (!ret)
    605		ret = ov9640_reg_read(client, OV9640_VER, &ver);
    606	if (!ret)
    607		ret = ov9640_reg_read(client, OV9640_MIDH, &midh);
    608	if (!ret)
    609		ret = ov9640_reg_read(client, OV9640_MIDL, &midl);
    610	if (ret)
    611		goto done;
    612
    613	switch (VERSION(pid, ver)) {
    614	case OV9640_V2:
    615		devname		= "ov9640";
    616		priv->revision	= 2;
    617		break;
    618	case OV9640_V3:
    619		devname		= "ov9640";
    620		priv->revision	= 3;
    621		break;
    622	default:
    623		dev_err(&client->dev, "Product ID error %x:%x\n", pid, ver);
    624		ret = -ENODEV;
    625		goto done;
    626	}
    627
    628	dev_info(&client->dev, "%s Product ID %0x:%0x Manufacturer ID %x:%x\n",
    629		 devname, pid, ver, midh, midl);
    630
    631	ret = v4l2_ctrl_handler_setup(&priv->hdl);
    632
    633done:
    634	ov9640_s_power(&priv->subdev, 0);
    635	return ret;
    636}
    637
    638static const struct v4l2_ctrl_ops ov9640_ctrl_ops = {
    639	.s_ctrl = ov9640_s_ctrl,
    640};
    641
    642static const struct v4l2_subdev_core_ops ov9640_core_ops = {
    643#ifdef CONFIG_VIDEO_ADV_DEBUG
    644	.g_register		= ov9640_get_register,
    645	.s_register		= ov9640_set_register,
    646#endif
    647	.s_power		= ov9640_s_power,
    648};
    649
    650/* Request bus settings on camera side */
    651static int ov9640_get_mbus_config(struct v4l2_subdev *sd,
    652				  unsigned int pad,
    653				  struct v4l2_mbus_config *cfg)
    654{
    655	cfg->type = V4L2_MBUS_PARALLEL;
    656	cfg->bus.parallel.flags = V4L2_MBUS_PCLK_SAMPLE_RISING |
    657				  V4L2_MBUS_MASTER |
    658				  V4L2_MBUS_VSYNC_ACTIVE_HIGH |
    659				  V4L2_MBUS_HSYNC_ACTIVE_HIGH |
    660				  V4L2_MBUS_DATA_ACTIVE_HIGH;
    661
    662	return 0;
    663}
    664
    665static const struct v4l2_subdev_video_ops ov9640_video_ops = {
    666	.s_stream	= ov9640_s_stream,
    667};
    668
    669static const struct v4l2_subdev_pad_ops ov9640_pad_ops = {
    670	.enum_mbus_code = ov9640_enum_mbus_code,
    671	.get_selection	= ov9640_get_selection,
    672	.set_fmt	= ov9640_set_fmt,
    673	.get_mbus_config = ov9640_get_mbus_config,
    674};
    675
    676static const struct v4l2_subdev_ops ov9640_subdev_ops = {
    677	.core	= &ov9640_core_ops,
    678	.video	= &ov9640_video_ops,
    679	.pad	= &ov9640_pad_ops,
    680};
    681
    682/*
    683 * i2c_driver function
    684 */
    685static int ov9640_probe(struct i2c_client *client,
    686			const struct i2c_device_id *did)
    687{
    688	struct ov9640_priv *priv;
    689	int ret;
    690
    691	priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL);
    692	if (!priv)
    693		return -ENOMEM;
    694
    695	priv->gpio_power = devm_gpiod_get(&client->dev, "Camera power",
    696					  GPIOD_OUT_LOW);
    697	if (IS_ERR(priv->gpio_power)) {
    698		ret = PTR_ERR(priv->gpio_power);
    699		return ret;
    700	}
    701
    702	priv->gpio_reset = devm_gpiod_get(&client->dev, "Camera reset",
    703					  GPIOD_OUT_HIGH);
    704	if (IS_ERR(priv->gpio_reset)) {
    705		ret = PTR_ERR(priv->gpio_reset);
    706		return ret;
    707	}
    708
    709	v4l2_i2c_subdev_init(&priv->subdev, client, &ov9640_subdev_ops);
    710
    711	v4l2_ctrl_handler_init(&priv->hdl, 2);
    712	v4l2_ctrl_new_std(&priv->hdl, &ov9640_ctrl_ops,
    713			  V4L2_CID_VFLIP, 0, 1, 1, 0);
    714	v4l2_ctrl_new_std(&priv->hdl, &ov9640_ctrl_ops,
    715			  V4L2_CID_HFLIP, 0, 1, 1, 0);
    716
    717	if (priv->hdl.error) {
    718		ret = priv->hdl.error;
    719		goto ectrlinit;
    720	}
    721
    722	priv->subdev.ctrl_handler = &priv->hdl;
    723
    724	priv->clk = devm_clk_get(&client->dev, "mclk");
    725	if (IS_ERR(priv->clk)) {
    726		ret = PTR_ERR(priv->clk);
    727		goto ectrlinit;
    728	}
    729
    730	ret = ov9640_video_probe(client);
    731	if (ret)
    732		goto ectrlinit;
    733
    734	priv->subdev.dev = &client->dev;
    735	ret = v4l2_async_register_subdev(&priv->subdev);
    736	if (ret)
    737		goto ectrlinit;
    738
    739	return 0;
    740
    741ectrlinit:
    742	v4l2_ctrl_handler_free(&priv->hdl);
    743
    744	return ret;
    745}
    746
    747static int ov9640_remove(struct i2c_client *client)
    748{
    749	struct v4l2_subdev *sd = i2c_get_clientdata(client);
    750	struct ov9640_priv *priv = to_ov9640_sensor(sd);
    751
    752	v4l2_async_unregister_subdev(&priv->subdev);
    753	v4l2_ctrl_handler_free(&priv->hdl);
    754
    755	return 0;
    756}
    757
    758static const struct i2c_device_id ov9640_id[] = {
    759	{ "ov9640", 0 },
    760	{ }
    761};
    762MODULE_DEVICE_TABLE(i2c, ov9640_id);
    763
    764static struct i2c_driver ov9640_i2c_driver = {
    765	.driver = {
    766		.name = "ov9640",
    767	},
    768	.probe    = ov9640_probe,
    769	.remove   = ov9640_remove,
    770	.id_table = ov9640_id,
    771};
    772
    773module_i2c_driver(ov9640_i2c_driver);
    774
    775MODULE_DESCRIPTION("OmniVision OV96xx CMOS Image Sensor driver");
    776MODULE_AUTHOR("Marek Vasut <marek.vasut@gmail.com>");
    777MODULE_LICENSE("GPL v2");