^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Driver for MT9P031 CMOS Image Sensor from Aptina
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2011, Laurent Pinchart <laurent.pinchart@ideasonboard.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (C) 2011, Javier Martin <javier.martin@vista-silicon.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Copyright (C) 2011, Guennadi Liakhovetski <g.liakhovetski@gmx.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Based on the MT9V032 driver and Bastian Hecht's code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/gpio/consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/i2c.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/log2.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/of_graph.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/pm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/regulator/consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/videodev2.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <media/i2c/mt9p031.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <media/v4l2-async.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <media/v4l2-ctrls.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <media/v4l2-device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <media/v4l2-subdev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include "aptina-pll.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define MT9P031_PIXEL_ARRAY_WIDTH 2752
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define MT9P031_PIXEL_ARRAY_HEIGHT 2004
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define MT9P031_CHIP_VERSION 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define MT9P031_CHIP_VERSION_VALUE 0x1801
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define MT9P031_ROW_START 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define MT9P031_ROW_START_MIN 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define MT9P031_ROW_START_MAX 2004
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define MT9P031_ROW_START_DEF 54
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define MT9P031_COLUMN_START 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define MT9P031_COLUMN_START_MIN 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define MT9P031_COLUMN_START_MAX 2750
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define MT9P031_COLUMN_START_DEF 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define MT9P031_WINDOW_HEIGHT 0x03
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define MT9P031_WINDOW_HEIGHT_MIN 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define MT9P031_WINDOW_HEIGHT_MAX 2006
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define MT9P031_WINDOW_HEIGHT_DEF 1944
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define MT9P031_WINDOW_WIDTH 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define MT9P031_WINDOW_WIDTH_MIN 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define MT9P031_WINDOW_WIDTH_MAX 2752
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define MT9P031_WINDOW_WIDTH_DEF 2592
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define MT9P031_HORIZONTAL_BLANK 0x05
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define MT9P031_HORIZONTAL_BLANK_MIN 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define MT9P031_HORIZONTAL_BLANK_MAX 4095
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define MT9P031_VERTICAL_BLANK 0x06
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define MT9P031_VERTICAL_BLANK_MIN 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #define MT9P031_VERTICAL_BLANK_MAX 4096
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define MT9P031_VERTICAL_BLANK_DEF 26
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define MT9P031_OUTPUT_CONTROL 0x07
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define MT9P031_OUTPUT_CONTROL_CEN 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define MT9P031_OUTPUT_CONTROL_SYN 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define MT9P031_OUTPUT_CONTROL_DEF 0x1f82
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #define MT9P031_SHUTTER_WIDTH_UPPER 0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #define MT9P031_SHUTTER_WIDTH_LOWER 0x09
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #define MT9P031_SHUTTER_WIDTH_MIN 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #define MT9P031_SHUTTER_WIDTH_MAX 1048575
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #define MT9P031_SHUTTER_WIDTH_DEF 1943
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define MT9P031_PLL_CONTROL 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define MT9P031_PLL_CONTROL_PWROFF 0x0050
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define MT9P031_PLL_CONTROL_PWRON 0x0051
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #define MT9P031_PLL_CONTROL_USEPLL 0x0052
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #define MT9P031_PLL_CONFIG_1 0x11
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #define MT9P031_PLL_CONFIG_2 0x12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #define MT9P031_PIXEL_CLOCK_CONTROL 0x0a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #define MT9P031_PIXEL_CLOCK_INVERT (1 << 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #define MT9P031_PIXEL_CLOCK_SHIFT(n) ((n) << 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #define MT9P031_PIXEL_CLOCK_DIVIDE(n) ((n) << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #define MT9P031_RESTART 0x0b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #define MT9P031_FRAME_PAUSE_RESTART (1 << 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) #define MT9P031_FRAME_RESTART (1 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #define MT9P031_SHUTTER_DELAY 0x0c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) #define MT9P031_RST 0x0d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) #define MT9P031_RST_ENABLE 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) #define MT9P031_RST_DISABLE 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) #define MT9P031_READ_MODE_1 0x1e
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) #define MT9P031_READ_MODE_2 0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) #define MT9P031_READ_MODE_2_ROW_MIR (1 << 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) #define MT9P031_READ_MODE_2_COL_MIR (1 << 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) #define MT9P031_READ_MODE_2_ROW_BLC (1 << 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) #define MT9P031_ROW_ADDRESS_MODE 0x22
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) #define MT9P031_COLUMN_ADDRESS_MODE 0x23
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) #define MT9P031_GLOBAL_GAIN 0x35
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) #define MT9P031_GLOBAL_GAIN_MIN 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) #define MT9P031_GLOBAL_GAIN_MAX 1024
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) #define MT9P031_GLOBAL_GAIN_DEF 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) #define MT9P031_GLOBAL_GAIN_MULT (1 << 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) #define MT9P031_ROW_BLACK_TARGET 0x49
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) #define MT9P031_ROW_BLACK_DEF_OFFSET 0x4b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) #define MT9P031_GREEN1_OFFSET 0x60
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) #define MT9P031_GREEN2_OFFSET 0x61
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) #define MT9P031_BLACK_LEVEL_CALIBRATION 0x62
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) #define MT9P031_BLC_MANUAL_BLC (1 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) #define MT9P031_RED_OFFSET 0x63
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) #define MT9P031_BLUE_OFFSET 0x64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) #define MT9P031_TEST_PATTERN 0xa0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) #define MT9P031_TEST_PATTERN_SHIFT 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) #define MT9P031_TEST_PATTERN_ENABLE (1 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) #define MT9P031_TEST_PATTERN_DISABLE (0 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) #define MT9P031_TEST_PATTERN_GREEN 0xa1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) #define MT9P031_TEST_PATTERN_RED 0xa2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) #define MT9P031_TEST_PATTERN_BLUE 0xa3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) enum mt9p031_model {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) MT9P031_MODEL_COLOR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) MT9P031_MODEL_MONOCHROME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) struct mt9p031 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) struct v4l2_subdev subdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) struct media_pad pad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) struct v4l2_rect crop; /* Sensor window */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) struct v4l2_mbus_framefmt format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) struct mt9p031_platform_data *pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) struct mutex power_lock; /* lock to protect power_count */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) int power_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) struct clk *clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) struct regulator_bulk_data regulators[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) enum mt9p031_model model;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) struct aptina_pll pll;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) unsigned int clk_div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) bool use_pll;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) struct gpio_desc *reset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) struct v4l2_ctrl_handler ctrls;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) struct v4l2_ctrl *blc_auto;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) struct v4l2_ctrl *blc_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) /* Registers cache */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) u16 output_control;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) u16 mode2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) static struct mt9p031 *to_mt9p031(struct v4l2_subdev *sd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) return container_of(sd, struct mt9p031, subdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) static int mt9p031_read(struct i2c_client *client, u8 reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) return i2c_smbus_read_word_swapped(client, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) static int mt9p031_write(struct i2c_client *client, u8 reg, u16 data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) return i2c_smbus_write_word_swapped(client, reg, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) static int mt9p031_set_output_control(struct mt9p031 *mt9p031, u16 clear,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) u16 set)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) struct i2c_client *client = v4l2_get_subdevdata(&mt9p031->subdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) u16 value = (mt9p031->output_control & ~clear) | set;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) ret = mt9p031_write(client, MT9P031_OUTPUT_CONTROL, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) mt9p031->output_control = value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) static int mt9p031_set_mode2(struct mt9p031 *mt9p031, u16 clear, u16 set)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) struct i2c_client *client = v4l2_get_subdevdata(&mt9p031->subdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) u16 value = (mt9p031->mode2 & ~clear) | set;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) ret = mt9p031_write(client, MT9P031_READ_MODE_2, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) mt9p031->mode2 = value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) static int mt9p031_reset(struct mt9p031 *mt9p031)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) struct i2c_client *client = v4l2_get_subdevdata(&mt9p031->subdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) /* Disable chip output, synchronous option update */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) ret = mt9p031_write(client, MT9P031_RST, MT9P031_RST_ENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) ret = mt9p031_write(client, MT9P031_RST, MT9P031_RST_DISABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) ret = mt9p031_write(client, MT9P031_PIXEL_CLOCK_CONTROL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) MT9P031_PIXEL_CLOCK_DIVIDE(mt9p031->clk_div));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) return mt9p031_set_output_control(mt9p031, MT9P031_OUTPUT_CONTROL_CEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) static int mt9p031_clk_setup(struct mt9p031 *mt9p031)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) static const struct aptina_pll_limits limits = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) .ext_clock_min = 6000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) .ext_clock_max = 27000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) .int_clock_min = 2000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) .int_clock_max = 13500000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) .out_clock_min = 180000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) .out_clock_max = 360000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) .pix_clock_max = 96000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) .n_min = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) .n_max = 64,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) .m_min = 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) .m_max = 255,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) .p1_min = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) .p1_max = 128,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) struct i2c_client *client = v4l2_get_subdevdata(&mt9p031->subdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) struct mt9p031_platform_data *pdata = mt9p031->pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) mt9p031->clk = devm_clk_get(&client->dev, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) if (IS_ERR(mt9p031->clk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) return PTR_ERR(mt9p031->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) ret = clk_set_rate(mt9p031->clk, pdata->ext_freq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) /* If the external clock frequency is out of bounds for the PLL use the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) * pixel clock divider only and disable the PLL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) if (pdata->ext_freq > limits.ext_clock_max) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) unsigned int div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) div = DIV_ROUND_UP(pdata->ext_freq, pdata->target_freq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) div = roundup_pow_of_two(div) / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) mt9p031->clk_div = min_t(unsigned int, div, 64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) mt9p031->use_pll = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) mt9p031->pll.ext_clock = pdata->ext_freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) mt9p031->pll.pix_clock = pdata->target_freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) mt9p031->use_pll = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) return aptina_pll_calculate(&client->dev, &limits, &mt9p031->pll);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) static int mt9p031_pll_enable(struct mt9p031 *mt9p031)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) struct i2c_client *client = v4l2_get_subdevdata(&mt9p031->subdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) if (!mt9p031->use_pll)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) ret = mt9p031_write(client, MT9P031_PLL_CONTROL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) MT9P031_PLL_CONTROL_PWRON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) ret = mt9p031_write(client, MT9P031_PLL_CONFIG_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) (mt9p031->pll.m << 8) | (mt9p031->pll.n - 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) ret = mt9p031_write(client, MT9P031_PLL_CONFIG_2, mt9p031->pll.p1 - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) usleep_range(1000, 2000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) ret = mt9p031_write(client, MT9P031_PLL_CONTROL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) MT9P031_PLL_CONTROL_PWRON |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) MT9P031_PLL_CONTROL_USEPLL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) static inline int mt9p031_pll_disable(struct mt9p031 *mt9p031)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) struct i2c_client *client = v4l2_get_subdevdata(&mt9p031->subdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) if (!mt9p031->use_pll)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) return mt9p031_write(client, MT9P031_PLL_CONTROL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) MT9P031_PLL_CONTROL_PWROFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) static int mt9p031_power_on(struct mt9p031 *mt9p031)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) /* Ensure RESET_BAR is active */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) if (mt9p031->reset) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) gpiod_set_value(mt9p031->reset, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) usleep_range(1000, 2000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) /* Bring up the supplies */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) ret = regulator_bulk_enable(ARRAY_SIZE(mt9p031->regulators),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) mt9p031->regulators);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) /* Enable clock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) if (mt9p031->clk) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) ret = clk_prepare_enable(mt9p031->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) regulator_bulk_disable(ARRAY_SIZE(mt9p031->regulators),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) mt9p031->regulators);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) /* Now RESET_BAR must be high */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) if (mt9p031->reset) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) gpiod_set_value(mt9p031->reset, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) usleep_range(1000, 2000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) static void mt9p031_power_off(struct mt9p031 *mt9p031)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) if (mt9p031->reset) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) gpiod_set_value(mt9p031->reset, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) usleep_range(1000, 2000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) regulator_bulk_disable(ARRAY_SIZE(mt9p031->regulators),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) mt9p031->regulators);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) if (mt9p031->clk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) clk_disable_unprepare(mt9p031->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) static int __mt9p031_set_power(struct mt9p031 *mt9p031, bool on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) struct i2c_client *client = v4l2_get_subdevdata(&mt9p031->subdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) if (!on) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) mt9p031_power_off(mt9p031);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) ret = mt9p031_power_on(mt9p031);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) ret = mt9p031_reset(mt9p031);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) dev_err(&client->dev, "Failed to reset the camera\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) return v4l2_ctrl_handler_setup(&mt9p031->ctrls);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) /* -----------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) * V4L2 subdev video operations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) static int mt9p031_set_params(struct mt9p031 *mt9p031)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) struct i2c_client *client = v4l2_get_subdevdata(&mt9p031->subdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) struct v4l2_mbus_framefmt *format = &mt9p031->format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) const struct v4l2_rect *crop = &mt9p031->crop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) unsigned int hblank;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) unsigned int vblank;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) unsigned int xskip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) unsigned int yskip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) unsigned int xbin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) unsigned int ybin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) /* Windows position and size.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) * TODO: Make sure the start coordinates and window size match the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) * skipping, binning and mirroring (see description of registers 2 and 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) * in table 13, and Binning section on page 41).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) ret = mt9p031_write(client, MT9P031_COLUMN_START, crop->left);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) ret = mt9p031_write(client, MT9P031_ROW_START, crop->top);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) ret = mt9p031_write(client, MT9P031_WINDOW_WIDTH, crop->width - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) ret = mt9p031_write(client, MT9P031_WINDOW_HEIGHT, crop->height - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) /* Row and column binning and skipping. Use the maximum binning value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) * compatible with the skipping settings.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) xskip = DIV_ROUND_CLOSEST(crop->width, format->width);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) yskip = DIV_ROUND_CLOSEST(crop->height, format->height);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) xbin = 1 << (ffs(xskip) - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) ybin = 1 << (ffs(yskip) - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) ret = mt9p031_write(client, MT9P031_COLUMN_ADDRESS_MODE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) ((xbin - 1) << 4) | (xskip - 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) ret = mt9p031_write(client, MT9P031_ROW_ADDRESS_MODE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) ((ybin - 1) << 4) | (yskip - 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) /* Blanking - use minimum value for horizontal blanking and default
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) * value for vertical blanking.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) hblank = 346 * ybin + 64 + (80 >> min_t(unsigned int, xbin, 3));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) vblank = MT9P031_VERTICAL_BLANK_DEF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) ret = mt9p031_write(client, MT9P031_HORIZONTAL_BLANK, hblank - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) ret = mt9p031_write(client, MT9P031_VERTICAL_BLANK, vblank - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) static int mt9p031_s_stream(struct v4l2_subdev *subdev, int enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) struct mt9p031 *mt9p031 = to_mt9p031(subdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) struct i2c_client *client = v4l2_get_subdevdata(subdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) if (!enable) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) /* enable pause restart */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) val = MT9P031_FRAME_PAUSE_RESTART;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) ret = mt9p031_write(client, MT9P031_RESTART, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) /* enable restart + keep pause restart set */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) val |= MT9P031_FRAME_RESTART;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) ret = mt9p031_write(client, MT9P031_RESTART, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) /* Stop sensor readout */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) ret = mt9p031_set_output_control(mt9p031,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) MT9P031_OUTPUT_CONTROL_CEN, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) return mt9p031_pll_disable(mt9p031);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) ret = mt9p031_set_params(mt9p031);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) /* Switch to master "normal" mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) ret = mt9p031_set_output_control(mt9p031, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) MT9P031_OUTPUT_CONTROL_CEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) * - clear pause restart
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) * - don't clear restart as clearing restart manually can cause
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) * undefined behavior
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) val = MT9P031_FRAME_RESTART;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) ret = mt9p031_write(client, MT9P031_RESTART, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) return mt9p031_pll_enable(mt9p031);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) static int mt9p031_enum_mbus_code(struct v4l2_subdev *subdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) struct v4l2_subdev_pad_config *cfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) struct v4l2_subdev_mbus_code_enum *code)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) struct mt9p031 *mt9p031 = to_mt9p031(subdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) if (code->pad || code->index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) code->code = mt9p031->format.code;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) static int mt9p031_enum_frame_size(struct v4l2_subdev *subdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) struct v4l2_subdev_pad_config *cfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) struct v4l2_subdev_frame_size_enum *fse)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) struct mt9p031 *mt9p031 = to_mt9p031(subdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) if (fse->index >= 8 || fse->code != mt9p031->format.code)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) fse->min_width = MT9P031_WINDOW_WIDTH_DEF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) / min_t(unsigned int, 7, fse->index + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) fse->max_width = fse->min_width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) fse->min_height = MT9P031_WINDOW_HEIGHT_DEF / (fse->index + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) fse->max_height = fse->min_height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) static struct v4l2_mbus_framefmt *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) __mt9p031_get_pad_format(struct mt9p031 *mt9p031, struct v4l2_subdev_pad_config *cfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) unsigned int pad, u32 which)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) switch (which) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) case V4L2_SUBDEV_FORMAT_TRY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) return v4l2_subdev_get_try_format(&mt9p031->subdev, cfg, pad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) case V4L2_SUBDEV_FORMAT_ACTIVE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) return &mt9p031->format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) static struct v4l2_rect *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) __mt9p031_get_pad_crop(struct mt9p031 *mt9p031, struct v4l2_subdev_pad_config *cfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) unsigned int pad, u32 which)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) switch (which) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) case V4L2_SUBDEV_FORMAT_TRY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) return v4l2_subdev_get_try_crop(&mt9p031->subdev, cfg, pad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) case V4L2_SUBDEV_FORMAT_ACTIVE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) return &mt9p031->crop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) static int mt9p031_get_format(struct v4l2_subdev *subdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) struct v4l2_subdev_pad_config *cfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) struct v4l2_subdev_format *fmt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) struct mt9p031 *mt9p031 = to_mt9p031(subdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) fmt->format = *__mt9p031_get_pad_format(mt9p031, cfg, fmt->pad,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) fmt->which);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) static int mt9p031_set_format(struct v4l2_subdev *subdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) struct v4l2_subdev_pad_config *cfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) struct v4l2_subdev_format *format)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) struct mt9p031 *mt9p031 = to_mt9p031(subdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) struct v4l2_mbus_framefmt *__format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) struct v4l2_rect *__crop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) unsigned int width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) unsigned int height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) unsigned int hratio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) unsigned int vratio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) __crop = __mt9p031_get_pad_crop(mt9p031, cfg, format->pad,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) format->which);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) /* Clamp the width and height to avoid dividing by zero. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) width = clamp_t(unsigned int, ALIGN(format->format.width, 2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) max_t(unsigned int, __crop->width / 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) MT9P031_WINDOW_WIDTH_MIN),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) __crop->width);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) height = clamp_t(unsigned int, ALIGN(format->format.height, 2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) max_t(unsigned int, __crop->height / 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) MT9P031_WINDOW_HEIGHT_MIN),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) __crop->height);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) hratio = DIV_ROUND_CLOSEST(__crop->width, width);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) vratio = DIV_ROUND_CLOSEST(__crop->height, height);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) __format = __mt9p031_get_pad_format(mt9p031, cfg, format->pad,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) format->which);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) __format->width = __crop->width / hratio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) __format->height = __crop->height / vratio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) format->format = *__format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) static int mt9p031_get_selection(struct v4l2_subdev *subdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) struct v4l2_subdev_pad_config *cfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) struct v4l2_subdev_selection *sel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) struct mt9p031 *mt9p031 = to_mt9p031(subdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) if (sel->target != V4L2_SEL_TGT_CROP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) sel->r = *__mt9p031_get_pad_crop(mt9p031, cfg, sel->pad, sel->which);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) static int mt9p031_set_selection(struct v4l2_subdev *subdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) struct v4l2_subdev_pad_config *cfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) struct v4l2_subdev_selection *sel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) struct mt9p031 *mt9p031 = to_mt9p031(subdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) struct v4l2_mbus_framefmt *__format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) struct v4l2_rect *__crop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) struct v4l2_rect rect;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) if (sel->target != V4L2_SEL_TGT_CROP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) /* Clamp the crop rectangle boundaries and align them to a multiple of 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) * pixels to ensure a GRBG Bayer pattern.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) rect.left = clamp(ALIGN(sel->r.left, 2), MT9P031_COLUMN_START_MIN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) MT9P031_COLUMN_START_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) rect.top = clamp(ALIGN(sel->r.top, 2), MT9P031_ROW_START_MIN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) MT9P031_ROW_START_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) rect.width = clamp_t(unsigned int, ALIGN(sel->r.width, 2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) MT9P031_WINDOW_WIDTH_MIN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) MT9P031_WINDOW_WIDTH_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) rect.height = clamp_t(unsigned int, ALIGN(sel->r.height, 2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) MT9P031_WINDOW_HEIGHT_MIN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) MT9P031_WINDOW_HEIGHT_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) rect.width = min_t(unsigned int, rect.width,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) MT9P031_PIXEL_ARRAY_WIDTH - rect.left);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) rect.height = min_t(unsigned int, rect.height,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) MT9P031_PIXEL_ARRAY_HEIGHT - rect.top);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) __crop = __mt9p031_get_pad_crop(mt9p031, cfg, sel->pad, sel->which);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) if (rect.width != __crop->width || rect.height != __crop->height) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) /* Reset the output image size if the crop rectangle size has
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) * been modified.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) __format = __mt9p031_get_pad_format(mt9p031, cfg, sel->pad,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) sel->which);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) __format->width = rect.width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) __format->height = rect.height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) *__crop = rect;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) sel->r = rect;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) /* -----------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) * V4L2 subdev control operations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) #define V4L2_CID_BLC_AUTO (V4L2_CID_USER_BASE | 0x1002)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) #define V4L2_CID_BLC_TARGET_LEVEL (V4L2_CID_USER_BASE | 0x1003)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) #define V4L2_CID_BLC_ANALOG_OFFSET (V4L2_CID_USER_BASE | 0x1004)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) #define V4L2_CID_BLC_DIGITAL_OFFSET (V4L2_CID_USER_BASE | 0x1005)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) static int mt9p031_restore_blc(struct mt9p031 *mt9p031)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) struct i2c_client *client = v4l2_get_subdevdata(&mt9p031->subdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) if (mt9p031->blc_auto->cur.val != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) ret = mt9p031_set_mode2(mt9p031, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) MT9P031_READ_MODE_2_ROW_BLC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) if (mt9p031->blc_offset->cur.val != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) ret = mt9p031_write(client, MT9P031_ROW_BLACK_TARGET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) mt9p031->blc_offset->cur.val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) static int mt9p031_s_ctrl(struct v4l2_ctrl *ctrl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) struct mt9p031 *mt9p031 =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) container_of(ctrl->handler, struct mt9p031, ctrls);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) struct i2c_client *client = v4l2_get_subdevdata(&mt9p031->subdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) u16 data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) if (ctrl->flags & V4L2_CTRL_FLAG_INACTIVE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) switch (ctrl->id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) case V4L2_CID_EXPOSURE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) ret = mt9p031_write(client, MT9P031_SHUTTER_WIDTH_UPPER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) (ctrl->val >> 16) & 0xffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) return mt9p031_write(client, MT9P031_SHUTTER_WIDTH_LOWER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) ctrl->val & 0xffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) case V4L2_CID_GAIN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) /* Gain is controlled by 2 analog stages and a digital stage.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) * Valid values for the 3 stages are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) * Stage Min Max Step
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) * ------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) * First analog stage x1 x2 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) * Second analog stage x1 x4 0.125
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) * Digital stage x1 x16 0.125
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) * To minimize noise, the gain stages should be used in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) * second analog stage, first analog stage, digital stage order.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) * Gain from a previous stage should be pushed to its maximum
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) * value before the next stage is used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) if (ctrl->val <= 32) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) data = ctrl->val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) } else if (ctrl->val <= 64) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) ctrl->val &= ~1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) data = (1 << 6) | (ctrl->val >> 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) ctrl->val &= ~7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) data = ((ctrl->val - 64) << 5) | (1 << 6) | 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) return mt9p031_write(client, MT9P031_GLOBAL_GAIN, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) case V4L2_CID_HFLIP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) if (ctrl->val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) return mt9p031_set_mode2(mt9p031,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) 0, MT9P031_READ_MODE_2_COL_MIR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) return mt9p031_set_mode2(mt9p031,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) MT9P031_READ_MODE_2_COL_MIR, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) case V4L2_CID_VFLIP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) if (ctrl->val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) return mt9p031_set_mode2(mt9p031,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) 0, MT9P031_READ_MODE_2_ROW_MIR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) return mt9p031_set_mode2(mt9p031,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) MT9P031_READ_MODE_2_ROW_MIR, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) case V4L2_CID_TEST_PATTERN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) /* The digital side of the Black Level Calibration function must
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) * be disabled when generating a test pattern to avoid artifacts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) * in the image. Activate (deactivate) the BLC-related controls
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) * when the test pattern is enabled (disabled).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) v4l2_ctrl_activate(mt9p031->blc_auto, ctrl->val == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) v4l2_ctrl_activate(mt9p031->blc_offset, ctrl->val == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) if (!ctrl->val) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) /* Restore the BLC settings. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) ret = mt9p031_restore_blc(mt9p031);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) return mt9p031_write(client, MT9P031_TEST_PATTERN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) MT9P031_TEST_PATTERN_DISABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) ret = mt9p031_write(client, MT9P031_TEST_PATTERN_GREEN, 0x05a0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) ret = mt9p031_write(client, MT9P031_TEST_PATTERN_RED, 0x0a50);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) ret = mt9p031_write(client, MT9P031_TEST_PATTERN_BLUE, 0x0aa0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) /* Disable digital BLC when generating a test pattern. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) ret = mt9p031_set_mode2(mt9p031, MT9P031_READ_MODE_2_ROW_BLC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) ret = mt9p031_write(client, MT9P031_ROW_BLACK_DEF_OFFSET, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) return mt9p031_write(client, MT9P031_TEST_PATTERN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) ((ctrl->val - 1) << MT9P031_TEST_PATTERN_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) | MT9P031_TEST_PATTERN_ENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) case V4L2_CID_BLC_AUTO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) ret = mt9p031_set_mode2(mt9p031,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) ctrl->val ? 0 : MT9P031_READ_MODE_2_ROW_BLC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) ctrl->val ? MT9P031_READ_MODE_2_ROW_BLC : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) return mt9p031_write(client, MT9P031_BLACK_LEVEL_CALIBRATION,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) ctrl->val ? 0 : MT9P031_BLC_MANUAL_BLC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) case V4L2_CID_BLC_TARGET_LEVEL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) return mt9p031_write(client, MT9P031_ROW_BLACK_TARGET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) ctrl->val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) case V4L2_CID_BLC_ANALOG_OFFSET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) data = ctrl->val & ((1 << 9) - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) ret = mt9p031_write(client, MT9P031_GREEN1_OFFSET, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) ret = mt9p031_write(client, MT9P031_GREEN2_OFFSET, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) ret = mt9p031_write(client, MT9P031_RED_OFFSET, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) return mt9p031_write(client, MT9P031_BLUE_OFFSET, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) case V4L2_CID_BLC_DIGITAL_OFFSET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) return mt9p031_write(client, MT9P031_ROW_BLACK_DEF_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) ctrl->val & ((1 << 12) - 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) static const struct v4l2_ctrl_ops mt9p031_ctrl_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) .s_ctrl = mt9p031_s_ctrl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) static const char * const mt9p031_test_pattern_menu[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) "Disabled",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) "Color Field",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) "Horizontal Gradient",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) "Vertical Gradient",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) "Diagonal Gradient",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) "Classic Test Pattern",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) "Walking 1s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) "Monochrome Horizontal Bars",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) "Monochrome Vertical Bars",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) "Vertical Color Bars",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) static const struct v4l2_ctrl_config mt9p031_ctrls[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) .ops = &mt9p031_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) .id = V4L2_CID_BLC_AUTO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) .type = V4L2_CTRL_TYPE_BOOLEAN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) .name = "BLC, Auto",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) .min = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) .max = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) .step = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) .def = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) .flags = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) .ops = &mt9p031_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) .id = V4L2_CID_BLC_TARGET_LEVEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) .type = V4L2_CTRL_TYPE_INTEGER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) .name = "BLC Target Level",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) .min = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) .max = 4095,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) .step = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) .def = 168,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) .flags = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) .ops = &mt9p031_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) .id = V4L2_CID_BLC_ANALOG_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) .type = V4L2_CTRL_TYPE_INTEGER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) .name = "BLC Analog Offset",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) .min = -255,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) .max = 255,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) .step = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) .def = 32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) .flags = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) .ops = &mt9p031_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) .id = V4L2_CID_BLC_DIGITAL_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) .type = V4L2_CTRL_TYPE_INTEGER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) .name = "BLC Digital Offset",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) .min = -2048,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) .max = 2047,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) .step = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) .def = 40,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) .flags = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) /* -----------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) * V4L2 subdev core operations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) static int mt9p031_set_power(struct v4l2_subdev *subdev, int on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) struct mt9p031 *mt9p031 = to_mt9p031(subdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) mutex_lock(&mt9p031->power_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) /* If the power count is modified from 0 to != 0 or from != 0 to 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) * update the power state.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) if (mt9p031->power_count == !on) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) ret = __mt9p031_set_power(mt9p031, !!on);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) /* Update the power count. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) mt9p031->power_count += on ? 1 : -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) WARN_ON(mt9p031->power_count < 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) mutex_unlock(&mt9p031->power_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) /* -----------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) * V4L2 subdev internal operations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) static int mt9p031_registered(struct v4l2_subdev *subdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) struct i2c_client *client = v4l2_get_subdevdata(subdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) struct mt9p031 *mt9p031 = to_mt9p031(subdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) s32 data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) ret = mt9p031_power_on(mt9p031);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) dev_err(&client->dev, "MT9P031 power up failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) /* Read out the chip version register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) data = mt9p031_read(client, MT9P031_CHIP_VERSION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) mt9p031_power_off(mt9p031);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) if (data != MT9P031_CHIP_VERSION_VALUE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) dev_err(&client->dev, "MT9P031 not detected, wrong version "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) "0x%04x\n", data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) dev_info(&client->dev, "MT9P031 detected at address 0x%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) client->addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) static int mt9p031_open(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) struct mt9p031 *mt9p031 = to_mt9p031(subdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) struct v4l2_mbus_framefmt *format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) struct v4l2_rect *crop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) crop = v4l2_subdev_get_try_crop(subdev, fh->pad, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) crop->left = MT9P031_COLUMN_START_DEF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) crop->top = MT9P031_ROW_START_DEF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) crop->width = MT9P031_WINDOW_WIDTH_DEF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) crop->height = MT9P031_WINDOW_HEIGHT_DEF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) format = v4l2_subdev_get_try_format(subdev, fh->pad, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) if (mt9p031->model == MT9P031_MODEL_MONOCHROME)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) format->code = MEDIA_BUS_FMT_Y12_1X12;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) format->code = MEDIA_BUS_FMT_SGRBG12_1X12;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) format->width = MT9P031_WINDOW_WIDTH_DEF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) format->height = MT9P031_WINDOW_HEIGHT_DEF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) format->field = V4L2_FIELD_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) format->colorspace = V4L2_COLORSPACE_SRGB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) return mt9p031_set_power(subdev, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) static int mt9p031_close(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) return mt9p031_set_power(subdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) static const struct v4l2_subdev_core_ops mt9p031_subdev_core_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) .s_power = mt9p031_set_power,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) static const struct v4l2_subdev_video_ops mt9p031_subdev_video_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) .s_stream = mt9p031_s_stream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) static const struct v4l2_subdev_pad_ops mt9p031_subdev_pad_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) .enum_mbus_code = mt9p031_enum_mbus_code,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) .enum_frame_size = mt9p031_enum_frame_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) .get_fmt = mt9p031_get_format,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) .set_fmt = mt9p031_set_format,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) .get_selection = mt9p031_get_selection,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) .set_selection = mt9p031_set_selection,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) static const struct v4l2_subdev_ops mt9p031_subdev_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) .core = &mt9p031_subdev_core_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) .video = &mt9p031_subdev_video_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) .pad = &mt9p031_subdev_pad_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) static const struct v4l2_subdev_internal_ops mt9p031_subdev_internal_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) .registered = mt9p031_registered,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) .open = mt9p031_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) .close = mt9p031_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) /* -----------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) * Driver initialization and probing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) static struct mt9p031_platform_data *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) mt9p031_get_pdata(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) struct mt9p031_platform_data *pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) struct device_node *np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) return client->dev.platform_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) np = of_graph_get_next_endpoint(client->dev.of_node, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) if (!np)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) pdata = devm_kzalloc(&client->dev, sizeof(*pdata), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) if (!pdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) of_property_read_u32(np, "input-clock-frequency", &pdata->ext_freq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) of_property_read_u32(np, "pixel-clock-frequency", &pdata->target_freq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) of_node_put(np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) return pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) static int mt9p031_probe(struct i2c_client *client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) const struct i2c_device_id *did)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) struct mt9p031_platform_data *pdata = mt9p031_get_pdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) struct i2c_adapter *adapter = client->adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) struct mt9p031 *mt9p031;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) if (pdata == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) dev_err(&client->dev, "No platform data\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) dev_warn(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) "I2C-Adapter doesn't support I2C_FUNC_SMBUS_WORD\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) mt9p031 = devm_kzalloc(&client->dev, sizeof(*mt9p031), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) if (mt9p031 == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) mt9p031->pdata = pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) mt9p031->output_control = MT9P031_OUTPUT_CONTROL_DEF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) mt9p031->mode2 = MT9P031_READ_MODE_2_ROW_BLC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) mt9p031->model = did->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) mt9p031->regulators[0].supply = "vdd";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) mt9p031->regulators[1].supply = "vdd_io";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) mt9p031->regulators[2].supply = "vaa";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) ret = devm_regulator_bulk_get(&client->dev, 3, mt9p031->regulators);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) dev_err(&client->dev, "Unable to get regulators\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) mutex_init(&mt9p031->power_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) v4l2_ctrl_handler_init(&mt9p031->ctrls, ARRAY_SIZE(mt9p031_ctrls) + 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) v4l2_ctrl_new_std(&mt9p031->ctrls, &mt9p031_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) V4L2_CID_EXPOSURE, MT9P031_SHUTTER_WIDTH_MIN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) MT9P031_SHUTTER_WIDTH_MAX, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) MT9P031_SHUTTER_WIDTH_DEF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) v4l2_ctrl_new_std(&mt9p031->ctrls, &mt9p031_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) V4L2_CID_GAIN, MT9P031_GLOBAL_GAIN_MIN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) MT9P031_GLOBAL_GAIN_MAX, 1, MT9P031_GLOBAL_GAIN_DEF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) v4l2_ctrl_new_std(&mt9p031->ctrls, &mt9p031_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) V4L2_CID_HFLIP, 0, 1, 1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) v4l2_ctrl_new_std(&mt9p031->ctrls, &mt9p031_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) V4L2_CID_VFLIP, 0, 1, 1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) v4l2_ctrl_new_std(&mt9p031->ctrls, &mt9p031_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) V4L2_CID_PIXEL_RATE, pdata->target_freq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) pdata->target_freq, 1, pdata->target_freq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) v4l2_ctrl_new_std_menu_items(&mt9p031->ctrls, &mt9p031_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) V4L2_CID_TEST_PATTERN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) ARRAY_SIZE(mt9p031_test_pattern_menu) - 1, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) 0, mt9p031_test_pattern_menu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) for (i = 0; i < ARRAY_SIZE(mt9p031_ctrls); ++i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) v4l2_ctrl_new_custom(&mt9p031->ctrls, &mt9p031_ctrls[i], NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) mt9p031->subdev.ctrl_handler = &mt9p031->ctrls;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) if (mt9p031->ctrls.error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) printk(KERN_INFO "%s: control initialization error %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) __func__, mt9p031->ctrls.error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) ret = mt9p031->ctrls.error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) mt9p031->blc_auto = v4l2_ctrl_find(&mt9p031->ctrls, V4L2_CID_BLC_AUTO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) mt9p031->blc_offset = v4l2_ctrl_find(&mt9p031->ctrls,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) V4L2_CID_BLC_DIGITAL_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) v4l2_i2c_subdev_init(&mt9p031->subdev, client, &mt9p031_subdev_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) mt9p031->subdev.internal_ops = &mt9p031_subdev_internal_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) mt9p031->subdev.entity.function = MEDIA_ENT_F_CAM_SENSOR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) mt9p031->pad.flags = MEDIA_PAD_FL_SOURCE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) ret = media_entity_pads_init(&mt9p031->subdev.entity, 1, &mt9p031->pad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) mt9p031->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) mt9p031->crop.width = MT9P031_WINDOW_WIDTH_DEF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) mt9p031->crop.height = MT9P031_WINDOW_HEIGHT_DEF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) mt9p031->crop.left = MT9P031_COLUMN_START_DEF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) mt9p031->crop.top = MT9P031_ROW_START_DEF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) if (mt9p031->model == MT9P031_MODEL_MONOCHROME)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) mt9p031->format.code = MEDIA_BUS_FMT_Y12_1X12;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) mt9p031->format.code = MEDIA_BUS_FMT_SGRBG12_1X12;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) mt9p031->format.width = MT9P031_WINDOW_WIDTH_DEF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) mt9p031->format.height = MT9P031_WINDOW_HEIGHT_DEF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) mt9p031->format.field = V4L2_FIELD_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) mt9p031->format.colorspace = V4L2_COLORSPACE_SRGB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) mt9p031->reset = devm_gpiod_get_optional(&client->dev, "reset",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) GPIOD_OUT_HIGH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) ret = mt9p031_clk_setup(mt9p031);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) ret = v4l2_async_register_subdev(&mt9p031->subdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) v4l2_ctrl_handler_free(&mt9p031->ctrls);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) media_entity_cleanup(&mt9p031->subdev.entity);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) mutex_destroy(&mt9p031->power_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) static int mt9p031_remove(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) struct v4l2_subdev *subdev = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) struct mt9p031 *mt9p031 = to_mt9p031(subdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) v4l2_ctrl_handler_free(&mt9p031->ctrls);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) v4l2_async_unregister_subdev(subdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) media_entity_cleanup(&subdev->entity);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) mutex_destroy(&mt9p031->power_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) static const struct i2c_device_id mt9p031_id[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) { "mt9p031", MT9P031_MODEL_COLOR },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) { "mt9p031m", MT9P031_MODEL_MONOCHROME },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) MODULE_DEVICE_TABLE(i2c, mt9p031_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) #if IS_ENABLED(CONFIG_OF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) static const struct of_device_id mt9p031_of_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) { .compatible = "aptina,mt9p031", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) { .compatible = "aptina,mt9p031m", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) { /* sentinel */ },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) MODULE_DEVICE_TABLE(of, mt9p031_of_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) static struct i2c_driver mt9p031_i2c_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) .of_match_table = of_match_ptr(mt9p031_of_match),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) .name = "mt9p031",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) .probe = mt9p031_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) .remove = mt9p031_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) .id_table = mt9p031_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) module_i2c_driver(mt9p031_i2c_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) MODULE_DESCRIPTION("Aptina MT9P031 Camera driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) MODULE_AUTHOR("Bastian Hecht <hechtb@gmail.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) MODULE_LICENSE("GPL v2");