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

m5602_ov7660.c (12442B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * Driver for the ov7660 sensor
      4 *
      5 * Copyright (C) 2009 Erik Andrén
      6 * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project.
      7 * Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br>
      8 *
      9 * Portions of code to USB interface and ALi driver software,
     10 * Copyright (c) 2006 Willem Duinker
     11 * v4l2 interface modeled after the V4L2 driver
     12 * for SN9C10x PC Camera Controllers
     13 */
     14
     15#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
     16
     17#include "m5602_ov7660.h"
     18
     19static int ov7660_s_ctrl(struct v4l2_ctrl *ctrl);
     20static void ov7660_dump_registers(struct sd *sd);
     21
     22static const unsigned char preinit_ov7660[][4] = {
     23	{BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02},
     24	{BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0},
     25	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
     26	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
     27	{BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
     28	{BRIDGE, M5602_XB_SENSOR_TYPE, 0x0d},
     29	{BRIDGE, M5602_XB_SENSOR_CTRL, 0x00},
     30	{BRIDGE, M5602_XB_GPIO_DIR, 0x03},
     31	{BRIDGE, M5602_XB_GPIO_DIR, 0x03},
     32	{BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
     33	{BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
     34
     35	{SENSOR, OV7660_OFON, 0x0c},
     36	{SENSOR, OV7660_COM2, 0x11},
     37	{SENSOR, OV7660_COM7, 0x05},
     38
     39	{BRIDGE, M5602_XB_GPIO_DIR, 0x01},
     40	{BRIDGE, M5602_XB_GPIO_DAT, 0x04},
     41	{BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
     42	{BRIDGE, M5602_XB_GPIO_DIR_H, 0x06},
     43	{BRIDGE, M5602_XB_GPIO_DAT_H, 0x00},
     44	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x08},
     45	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
     46	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
     47	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
     48	{BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
     49	{BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
     50	{BRIDGE, M5602_XB_GPIO_DIR, 0x05},
     51	{BRIDGE, M5602_XB_GPIO_DAT, 0x00},
     52	{BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
     53	{BRIDGE, M5602_XB_GPIO_EN_L, 0x00}
     54};
     55
     56static const unsigned char init_ov7660[][4] = {
     57	{BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02},
     58	{BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0},
     59	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
     60	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
     61	{BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
     62	{BRIDGE, M5602_XB_SENSOR_TYPE, 0x0d},
     63	{BRIDGE, M5602_XB_SENSOR_CTRL, 0x00},
     64	{BRIDGE, M5602_XB_GPIO_DIR, 0x01},
     65	{BRIDGE, M5602_XB_GPIO_DIR, 0x01},
     66	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
     67	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
     68	{BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
     69	{BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
     70	{BRIDGE, M5602_XB_GPIO_DIR, 0x05},
     71	{BRIDGE, M5602_XB_GPIO_DAT, 0x00},
     72	{BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
     73	{BRIDGE, M5602_XB_GPIO_EN_L, 0x00},
     74	{SENSOR, OV7660_COM7, 0x80},
     75	{SENSOR, OV7660_CLKRC, 0x80},
     76	{SENSOR, OV7660_COM9, 0x4c},
     77	{SENSOR, OV7660_OFON, 0x43},
     78	{SENSOR, OV7660_COM12, 0x28},
     79	{SENSOR, OV7660_COM8, 0x00},
     80	{SENSOR, OV7660_COM10, 0x40},
     81	{SENSOR, OV7660_HSTART, 0x0c},
     82	{SENSOR, OV7660_HSTOP, 0x61},
     83	{SENSOR, OV7660_HREF, 0xa4},
     84	{SENSOR, OV7660_PSHFT, 0x0b},
     85	{SENSOR, OV7660_VSTART, 0x01},
     86	{SENSOR, OV7660_VSTOP, 0x7a},
     87	{SENSOR, OV7660_VSTOP, 0x00},
     88	{SENSOR, OV7660_COM7, 0x05},
     89	{SENSOR, OV7660_COM6, 0x42},
     90	{SENSOR, OV7660_BBIAS, 0x94},
     91	{SENSOR, OV7660_GbBIAS, 0x94},
     92	{SENSOR, OV7660_RSVD29, 0x94},
     93	{SENSOR, OV7660_RBIAS, 0x94},
     94	{SENSOR, OV7660_COM1, 0x00},
     95	{SENSOR, OV7660_AECH, 0x00},
     96	{SENSOR, OV7660_AECHH, 0x00},
     97	{SENSOR, OV7660_ADC, 0x05},
     98	{SENSOR, OV7660_COM13, 0x00},
     99	{SENSOR, OV7660_RSVDA1, 0x23},
    100	{SENSOR, OV7660_TSLB, 0x0d},
    101	{SENSOR, OV7660_HV, 0x80},
    102	{SENSOR, OV7660_LCC1, 0x00},
    103	{SENSOR, OV7660_LCC2, 0x00},
    104	{SENSOR, OV7660_LCC3, 0x10},
    105	{SENSOR, OV7660_LCC4, 0x40},
    106	{SENSOR, OV7660_LCC5, 0x01},
    107
    108	{SENSOR, OV7660_AECH, 0x20},
    109	{SENSOR, OV7660_COM1, 0x00},
    110	{SENSOR, OV7660_OFON, 0x0c},
    111	{SENSOR, OV7660_COM2, 0x11},
    112	{SENSOR, OV7660_COM7, 0x05},
    113	{BRIDGE, M5602_XB_GPIO_DIR, 0x01},
    114	{BRIDGE, M5602_XB_GPIO_DAT, 0x04},
    115	{BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
    116	{BRIDGE, M5602_XB_GPIO_DIR_H, 0x06},
    117	{BRIDGE, M5602_XB_GPIO_DAT_H, 0x00},
    118	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x08},
    119	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
    120	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
    121	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
    122	{BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
    123	{BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
    124	{BRIDGE, M5602_XB_GPIO_DIR, 0x05},
    125	{BRIDGE, M5602_XB_GPIO_DAT, 0x00},
    126	{BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
    127	{BRIDGE, M5602_XB_GPIO_EN_L, 0x00},
    128	{SENSOR, OV7660_AECH, 0x5f},
    129	{SENSOR, OV7660_COM1, 0x03},
    130	{SENSOR, OV7660_OFON, 0x0c},
    131	{SENSOR, OV7660_COM2, 0x11},
    132	{SENSOR, OV7660_COM7, 0x05},
    133	{BRIDGE, M5602_XB_GPIO_DIR, 0x01},
    134	{BRIDGE, M5602_XB_GPIO_DAT, 0x04},
    135	{BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
    136	{BRIDGE, M5602_XB_GPIO_DIR_H, 0x06},
    137	{BRIDGE, M5602_XB_GPIO_DAT_H, 0x00},
    138	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x08},
    139	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
    140	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
    141	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
    142	{BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
    143	{BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
    144	{BRIDGE, M5602_XB_GPIO_DIR, 0x05},
    145	{BRIDGE, M5602_XB_GPIO_DAT, 0x00},
    146	{BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
    147	{BRIDGE, M5602_XB_GPIO_EN_L, 0x00},
    148
    149	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06},
    150	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
    151	{BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
    152	{BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
    153	{BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81},
    154	{BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82},
    155	{BRIDGE, M5602_XB_SIG_INI, 0x01},
    156	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
    157	{BRIDGE, M5602_XB_VSYNC_PARA, 0x08},
    158	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
    159	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
    160	{BRIDGE, M5602_XB_VSYNC_PARA, 0x01},
    161	{BRIDGE, M5602_XB_VSYNC_PARA, 0xec},
    162	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
    163	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
    164	{BRIDGE, M5602_XB_SIG_INI, 0x00},
    165	{BRIDGE, M5602_XB_SIG_INI, 0x02},
    166	{BRIDGE, M5602_XB_HSYNC_PARA, 0x00},
    167	{BRIDGE, M5602_XB_HSYNC_PARA, 0x27},
    168	{BRIDGE, M5602_XB_HSYNC_PARA, 0x02},
    169	{BRIDGE, M5602_XB_HSYNC_PARA, 0xa7},
    170	{BRIDGE, M5602_XB_SIG_INI, 0x00},
    171	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
    172	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
    173};
    174
    175static struct v4l2_pix_format ov7660_modes[] = {
    176	{
    177		640,
    178		480,
    179		V4L2_PIX_FMT_SBGGR8,
    180		V4L2_FIELD_NONE,
    181		.sizeimage =
    182			640 * 480,
    183		.bytesperline = 640,
    184		.colorspace = V4L2_COLORSPACE_SRGB,
    185		.priv = 0
    186	}
    187};
    188
    189static const struct v4l2_ctrl_ops ov7660_ctrl_ops = {
    190	.s_ctrl = ov7660_s_ctrl,
    191};
    192
    193int ov7660_probe(struct sd *sd)
    194{
    195	int err = 0, i;
    196	u8 prod_id = 0, ver_id = 0;
    197
    198	if (force_sensor) {
    199		if (force_sensor == OV7660_SENSOR) {
    200			pr_info("Forcing an %s sensor\n", ov7660.name);
    201			goto sensor_found;
    202		}
    203		/* If we want to force another sensor,
    204		don't try to probe this one */
    205		return -ENODEV;
    206	}
    207
    208	/* Do the preinit */
    209	for (i = 0; i < ARRAY_SIZE(preinit_ov7660) && !err; i++) {
    210		u8 data[2];
    211
    212		if (preinit_ov7660[i][0] == BRIDGE) {
    213			err = m5602_write_bridge(sd,
    214				preinit_ov7660[i][1],
    215				preinit_ov7660[i][2]);
    216		} else {
    217			data[0] = preinit_ov7660[i][2];
    218			err = m5602_write_sensor(sd,
    219				preinit_ov7660[i][1], data, 1);
    220		}
    221	}
    222	if (err < 0)
    223		return err;
    224
    225	if (m5602_read_sensor(sd, OV7660_PID, &prod_id, 1))
    226		return -ENODEV;
    227
    228	if (m5602_read_sensor(sd, OV7660_VER, &ver_id, 1))
    229		return -ENODEV;
    230
    231	pr_info("Sensor reported 0x%x%x\n", prod_id, ver_id);
    232
    233	if ((prod_id == 0x76) && (ver_id == 0x60)) {
    234		pr_info("Detected a ov7660 sensor\n");
    235		goto sensor_found;
    236	}
    237	return -ENODEV;
    238
    239sensor_found:
    240	sd->gspca_dev.cam.cam_mode = ov7660_modes;
    241	sd->gspca_dev.cam.nmodes = ARRAY_SIZE(ov7660_modes);
    242
    243	return 0;
    244}
    245
    246int ov7660_init(struct sd *sd)
    247{
    248	int i, err;
    249
    250	/* Init the sensor */
    251	for (i = 0; i < ARRAY_SIZE(init_ov7660); i++) {
    252		u8 data[2];
    253
    254		if (init_ov7660[i][0] == BRIDGE) {
    255			err = m5602_write_bridge(sd,
    256				init_ov7660[i][1],
    257				init_ov7660[i][2]);
    258		} else {
    259			data[0] = init_ov7660[i][2];
    260			err = m5602_write_sensor(sd,
    261				init_ov7660[i][1], data, 1);
    262		}
    263		if (err < 0)
    264			return err;
    265	}
    266
    267	if (dump_sensor)
    268		ov7660_dump_registers(sd);
    269
    270	return 0;
    271}
    272
    273int ov7660_init_controls(struct sd *sd)
    274{
    275	struct v4l2_ctrl_handler *hdl = &sd->gspca_dev.ctrl_handler;
    276
    277	sd->gspca_dev.vdev.ctrl_handler = hdl;
    278	v4l2_ctrl_handler_init(hdl, 6);
    279
    280	v4l2_ctrl_new_std(hdl, &ov7660_ctrl_ops, V4L2_CID_AUTO_WHITE_BALANCE,
    281			  0, 1, 1, 1);
    282	v4l2_ctrl_new_std_menu(hdl, &ov7660_ctrl_ops,
    283			  V4L2_CID_EXPOSURE_AUTO, 1, 0, V4L2_EXPOSURE_AUTO);
    284
    285	sd->autogain = v4l2_ctrl_new_std(hdl, &ov7660_ctrl_ops,
    286					 V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
    287	sd->gain = v4l2_ctrl_new_std(hdl, &ov7660_ctrl_ops, V4L2_CID_GAIN, 0,
    288				     255, 1, OV7660_DEFAULT_GAIN);
    289
    290	sd->hflip = v4l2_ctrl_new_std(hdl, &ov7660_ctrl_ops, V4L2_CID_HFLIP,
    291				      0, 1, 1, 0);
    292	sd->vflip = v4l2_ctrl_new_std(hdl, &ov7660_ctrl_ops, V4L2_CID_VFLIP,
    293				      0, 1, 1, 0);
    294
    295	if (hdl->error) {
    296		pr_err("Could not initialize controls\n");
    297		return hdl->error;
    298	}
    299
    300	v4l2_ctrl_auto_cluster(2, &sd->autogain, 0, false);
    301	v4l2_ctrl_cluster(2, &sd->hflip);
    302
    303	return 0;
    304}
    305
    306int ov7660_start(struct sd *sd)
    307{
    308	return 0;
    309}
    310
    311int ov7660_stop(struct sd *sd)
    312{
    313	return 0;
    314}
    315
    316void ov7660_disconnect(struct sd *sd)
    317{
    318	ov7660_stop(sd);
    319
    320	sd->sensor = NULL;
    321}
    322
    323static int ov7660_set_gain(struct gspca_dev *gspca_dev, __s32 val)
    324{
    325	int err;
    326	u8 i2c_data = val;
    327	struct sd *sd = (struct sd *) gspca_dev;
    328
    329	gspca_dbg(gspca_dev, D_CONF, "Setting gain to %d\n", val);
    330
    331	err = m5602_write_sensor(sd, OV7660_GAIN, &i2c_data, 1);
    332	return err;
    333}
    334
    335static int ov7660_set_auto_white_balance(struct gspca_dev *gspca_dev,
    336					 __s32 val)
    337{
    338	int err;
    339	u8 i2c_data;
    340	struct sd *sd = (struct sd *) gspca_dev;
    341
    342	gspca_dbg(gspca_dev, D_CONF, "Set auto white balance to %d\n", val);
    343
    344	err = m5602_read_sensor(sd, OV7660_COM8, &i2c_data, 1);
    345	if (err < 0)
    346		return err;
    347
    348	i2c_data = ((i2c_data & 0xfd) | ((val & 0x01) << 1));
    349	err = m5602_write_sensor(sd, OV7660_COM8, &i2c_data, 1);
    350
    351	return err;
    352}
    353
    354static int ov7660_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val)
    355{
    356	int err;
    357	u8 i2c_data;
    358	struct sd *sd = (struct sd *) gspca_dev;
    359
    360	gspca_dbg(gspca_dev, D_CONF, "Set auto gain control to %d\n", val);
    361
    362	err = m5602_read_sensor(sd, OV7660_COM8, &i2c_data, 1);
    363	if (err < 0)
    364		return err;
    365
    366	i2c_data = ((i2c_data & 0xfb) | ((val & 0x01) << 2));
    367
    368	return m5602_write_sensor(sd, OV7660_COM8, &i2c_data, 1);
    369}
    370
    371static int ov7660_set_auto_exposure(struct gspca_dev *gspca_dev,
    372				    __s32 val)
    373{
    374	int err;
    375	u8 i2c_data;
    376	struct sd *sd = (struct sd *) gspca_dev;
    377
    378	gspca_dbg(gspca_dev, D_CONF, "Set auto exposure control to %d\n", val);
    379
    380	err = m5602_read_sensor(sd, OV7660_COM8, &i2c_data, 1);
    381	if (err < 0)
    382		return err;
    383
    384	val = (val == V4L2_EXPOSURE_AUTO);
    385	i2c_data = ((i2c_data & 0xfe) | ((val & 0x01) << 0));
    386
    387	return m5602_write_sensor(sd, OV7660_COM8, &i2c_data, 1);
    388}
    389
    390static int ov7660_set_hvflip(struct gspca_dev *gspca_dev)
    391{
    392	int err;
    393	u8 i2c_data;
    394	struct sd *sd = (struct sd *) gspca_dev;
    395
    396	gspca_dbg(gspca_dev, D_CONF, "Set hvflip to %d, %d\n",
    397		  sd->hflip->val, sd->vflip->val);
    398
    399	i2c_data = (sd->hflip->val << 5) | (sd->vflip->val << 4);
    400
    401	err = m5602_write_sensor(sd, OV7660_MVFP, &i2c_data, 1);
    402
    403	return err;
    404}
    405
    406static int ov7660_s_ctrl(struct v4l2_ctrl *ctrl)
    407{
    408	struct gspca_dev *gspca_dev =
    409		container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
    410	struct sd *sd = (struct sd *) gspca_dev;
    411	int err;
    412
    413	if (!gspca_dev->streaming)
    414		return 0;
    415
    416	switch (ctrl->id) {
    417	case V4L2_CID_AUTO_WHITE_BALANCE:
    418		err = ov7660_set_auto_white_balance(gspca_dev, ctrl->val);
    419		break;
    420	case V4L2_CID_EXPOSURE_AUTO:
    421		err = ov7660_set_auto_exposure(gspca_dev, ctrl->val);
    422		break;
    423	case V4L2_CID_AUTOGAIN:
    424		err = ov7660_set_auto_gain(gspca_dev, ctrl->val);
    425		if (err || ctrl->val)
    426			return err;
    427		err = ov7660_set_gain(gspca_dev, sd->gain->val);
    428		break;
    429	case V4L2_CID_HFLIP:
    430		err = ov7660_set_hvflip(gspca_dev);
    431		break;
    432	default:
    433		return -EINVAL;
    434	}
    435
    436	return err;
    437}
    438
    439static void ov7660_dump_registers(struct sd *sd)
    440{
    441	int address;
    442	pr_info("Dumping the ov7660 register state\n");
    443	for (address = 0; address < 0xa9; address++) {
    444		u8 value;
    445		m5602_read_sensor(sd, address, &value, 1);
    446		pr_info("register 0x%x contains 0x%x\n", address, value);
    447	}
    448
    449	pr_info("ov7660 register state dump complete\n");
    450
    451	pr_info("Probing for which registers that are read/write\n");
    452	for (address = 0; address < 0xff; address++) {
    453		u8 old_value, ctrl_value;
    454		u8 test_value[2] = {0xff, 0xff};
    455
    456		m5602_read_sensor(sd, address, &old_value, 1);
    457		m5602_write_sensor(sd, address, test_value, 1);
    458		m5602_read_sensor(sd, address, &ctrl_value, 1);
    459
    460		if (ctrl_value == test_value[0])
    461			pr_info("register 0x%x is writeable\n", address);
    462		else
    463			pr_info("register 0x%x is read only\n", address);
    464
    465		/* Restore original value */
    466		m5602_write_sensor(sd, address, &old_value, 1);
    467	}
    468}