1233 lines · c
1// SPDX-License-Identifier: GPL-2.02// Copyright (c) 2022 Intel Corporation.3 4#include <linux/unaligned.h>5#include <linux/acpi.h>6#include <linux/clk.h>7#include <linux/delay.h>8#include <linux/gpio/consumer.h>9#include <linux/i2c.h>10#include <linux/module.h>11#include <linux/pm_runtime.h>12#include <linux/regulator/consumer.h>13#include <media/v4l2-ctrls.h>14#include <media/v4l2-device.h>15#include <media/v4l2-fwnode.h>16 17#define OG01A1B_REG_VALUE_08BIT 118#define OG01A1B_REG_VALUE_16BIT 219#define OG01A1B_REG_VALUE_24BIT 320 21#define OG01A1B_LINK_FREQ_500MHZ 500000000ULL22#define OG01A1B_SCLK 120000000LL23#define OG01A1B_MCLK 1920000024#define OG01A1B_DATA_LANES 225#define OG01A1B_RGB_DEPTH 1026 27#define OG01A1B_REG_CHIP_ID 0x300a28#define OG01A1B_CHIP_ID 0x47014129 30#define OG01A1B_REG_MODE_SELECT 0x010031#define OG01A1B_MODE_STANDBY 0x0032#define OG01A1B_MODE_STREAMING 0x0133 34/* vertical-timings from sensor */35#define OG01A1B_REG_VTS 0x380e36#define OG01A1B_VTS_120FPS 0x049837#define OG01A1B_VTS_120FPS_MIN 0x049838#define OG01A1B_VTS_MAX 0x7fff39 40/* horizontal-timings from sensor */41#define OG01A1B_REG_HTS 0x380c42 43/* Exposure controls from sensor */44#define OG01A1B_REG_EXPOSURE 0x350145#define OG01A1B_EXPOSURE_MIN 146#define OG01A1B_EXPOSURE_MAX_MARGIN 1447#define OG01A1B_EXPOSURE_STEP 148 49/* Analog gain controls from sensor */50#define OG01A1B_REG_ANALOG_GAIN 0x350851#define OG01A1B_ANAL_GAIN_MIN 1652#define OG01A1B_ANAL_GAIN_MAX 248 /* Max = 15.5x */53#define OG01A1B_ANAL_GAIN_STEP 154 55/* Digital gain controls from sensor */56#define OG01A1B_REG_DIG_GAIN 0x350a57#define OG01A1B_DGTL_GAIN_MIN 102458#define OG01A1B_DGTL_GAIN_MAX 16384 /* Max = 16x */59#define OG01A1B_DGTL_GAIN_STEP 160#define OG01A1B_DGTL_GAIN_DEFAULT 102461 62/* Group Access */63#define OG01A1B_REG_GROUP_ACCESS 0x320864#define OG01A1B_GROUP_HOLD_START 0x065#define OG01A1B_GROUP_HOLD_END 0x1066#define OG01A1B_GROUP_HOLD_LAUNCH 0xa067 68/* Test Pattern Control */69#define OG01A1B_REG_TEST_PATTERN 0x510070#define OG01A1B_TEST_PATTERN_ENABLE BIT(7)71#define OG01A1B_TEST_PATTERN_BAR_SHIFT 272 73#define to_og01a1b(_sd) container_of(_sd, struct og01a1b, sd)74 75enum {76 OG01A1B_LINK_FREQ_1000MBPS,77};78 79struct og01a1b_reg {80 u16 address;81 u8 val;82};83 84struct og01a1b_reg_list {85 u32 num_of_regs;86 const struct og01a1b_reg *regs;87};88 89struct og01a1b_link_freq_config {90 const struct og01a1b_reg_list reg_list;91};92 93struct og01a1b_mode {94 /* Frame width in pixels */95 u32 width;96 97 /* Frame height in pixels */98 u32 height;99 100 /* Horizontal timining size */101 u32 hts;102 103 /* Default vertical timining size */104 u32 vts_def;105 106 /* Min vertical timining size */107 u32 vts_min;108 109 /* Link frequency needed for this resolution */110 u32 link_freq_index;111 112 /* Sensor register settings for this resolution */113 const struct og01a1b_reg_list reg_list;114};115 116static const struct og01a1b_reg mipi_data_rate_1000mbps[] = {117 {0x0103, 0x01},118 {0x0303, 0x02},119 {0x0304, 0x00},120 {0x0305, 0xd2},121 {0x0323, 0x02},122 {0x0324, 0x01},123 {0x0325, 0x77},124};125 126static const struct og01a1b_reg mode_1280x1024_regs[] = {127 {0x0300, 0x0a},128 {0x0301, 0x29},129 {0x0302, 0x31},130 {0x0303, 0x02},131 {0x0304, 0x00},132 {0x0305, 0xd2},133 {0x0306, 0x00},134 {0x0307, 0x01},135 {0x0308, 0x02},136 {0x0309, 0x00},137 {0x0310, 0x00},138 {0x0311, 0x00},139 {0x0312, 0x07},140 {0x0313, 0x00},141 {0x0314, 0x00},142 {0x0315, 0x00},143 {0x0320, 0x02},144 {0x0321, 0x01},145 {0x0322, 0x01},146 {0x0323, 0x02},147 {0x0324, 0x01},148 {0x0325, 0x77},149 {0x0326, 0xce},150 {0x0327, 0x04},151 {0x0329, 0x02},152 {0x032a, 0x04},153 {0x032b, 0x04},154 {0x032c, 0x02},155 {0x032d, 0x01},156 {0x032e, 0x00},157 {0x300d, 0x02},158 {0x300e, 0x04},159 {0x3021, 0x08},160 {0x301e, 0x03},161 {0x3103, 0x00},162 {0x3106, 0x08},163 {0x3107, 0x40},164 {0x3216, 0x01},165 {0x3217, 0x00},166 {0x3218, 0xc0},167 {0x3219, 0x55},168 {0x3500, 0x00},169 {0x3501, 0x04},170 {0x3502, 0x8a},171 {0x3506, 0x01},172 {0x3507, 0x72},173 {0x3508, 0x01},174 {0x3509, 0x00},175 {0x350a, 0x01},176 {0x350b, 0x00},177 {0x350c, 0x00},178 {0x3541, 0x00},179 {0x3542, 0x40},180 {0x3605, 0xe0},181 {0x3606, 0x41},182 {0x3614, 0x20},183 {0x3620, 0x0b},184 {0x3630, 0x07},185 {0x3636, 0xa0},186 {0x3637, 0xf9},187 {0x3638, 0x09},188 {0x3639, 0x38},189 {0x363f, 0x09},190 {0x3640, 0x17},191 {0x3662, 0x04},192 {0x3665, 0x80},193 {0x3670, 0x68},194 {0x3674, 0x00},195 {0x3677, 0x3f},196 {0x3679, 0x00},197 {0x369f, 0x19},198 {0x36a0, 0x03},199 {0x36a2, 0x19},200 {0x36a3, 0x03},201 {0x370d, 0x66},202 {0x370f, 0x00},203 {0x3710, 0x03},204 {0x3715, 0x03},205 {0x3716, 0x03},206 {0x3717, 0x06},207 {0x3733, 0x00},208 {0x3778, 0x00},209 {0x37a8, 0x0f},210 {0x37a9, 0x01},211 {0x37aa, 0x07},212 {0x37bd, 0x1c},213 {0x37c1, 0x2f},214 {0x37c3, 0x09},215 {0x37c8, 0x1d},216 {0x37ca, 0x30},217 {0x37df, 0x00},218 {0x3800, 0x00},219 {0x3801, 0x00},220 {0x3802, 0x00},221 {0x3803, 0x00},222 {0x3804, 0x05},223 {0x3805, 0x0f},224 {0x3806, 0x04},225 {0x3807, 0x0f},226 {0x3808, 0x05},227 {0x3809, 0x00},228 {0x380a, 0x04},229 {0x380b, 0x00},230 {0x380c, 0x03},231 {0x380d, 0x50},232 {0x380e, 0x04},233 {0x380f, 0x98},234 {0x3810, 0x00},235 {0x3811, 0x08},236 {0x3812, 0x00},237 {0x3813, 0x08},238 {0x3814, 0x11},239 {0x3815, 0x11},240 {0x3820, 0x40},241 {0x3821, 0x04},242 {0x3826, 0x00},243 {0x3827, 0x00},244 {0x382a, 0x08},245 {0x382b, 0x52},246 {0x382d, 0xba},247 {0x383d, 0x14},248 {0x384a, 0xa2},249 {0x3866, 0x0e},250 {0x3867, 0x07},251 {0x3884, 0x00},252 {0x3885, 0x08},253 {0x3893, 0x68},254 {0x3894, 0x2a},255 {0x3898, 0x00},256 {0x3899, 0x31},257 {0x389a, 0x04},258 {0x389b, 0x00},259 {0x389c, 0x0b},260 {0x389d, 0xad},261 {0x389f, 0x08},262 {0x38a0, 0x00},263 {0x38a1, 0x00},264 {0x38a8, 0x70},265 {0x38ac, 0xea},266 {0x38b2, 0x00},267 {0x38b3, 0x08},268 {0x38bc, 0x20},269 {0x38c4, 0x0c},270 {0x38c5, 0x3a},271 {0x38c7, 0x3a},272 {0x38e1, 0xc0},273 {0x38ec, 0x3c},274 {0x38f0, 0x09},275 {0x38f1, 0x6f},276 {0x38fe, 0x3c},277 {0x391e, 0x00},278 {0x391f, 0x00},279 {0x3920, 0xa5},280 {0x3921, 0x00},281 {0x3922, 0x00},282 {0x3923, 0x00},283 {0x3924, 0x05},284 {0x3925, 0x00},285 {0x3926, 0x00},286 {0x3927, 0x00},287 {0x3928, 0x1a},288 {0x3929, 0x01},289 {0x392a, 0xb4},290 {0x392b, 0x00},291 {0x392c, 0x10},292 {0x392f, 0x40},293 {0x4000, 0xcf},294 {0x4003, 0x40},295 {0x4008, 0x00},296 {0x4009, 0x07},297 {0x400a, 0x02},298 {0x400b, 0x54},299 {0x400c, 0x00},300 {0x400d, 0x07},301 {0x4010, 0xc0},302 {0x4012, 0x02},303 {0x4014, 0x04},304 {0x4015, 0x04},305 {0x4017, 0x02},306 {0x4042, 0x01},307 {0x4306, 0x04},308 {0x4307, 0x12},309 {0x4509, 0x00},310 {0x450b, 0x83},311 {0x4604, 0x68},312 {0x4608, 0x0a},313 {0x4700, 0x06},314 {0x4800, 0x64},315 {0x481b, 0x3c},316 {0x4825, 0x32},317 {0x4833, 0x18},318 {0x4837, 0x0f},319 {0x4850, 0x40},320 {0x4860, 0x00},321 {0x4861, 0xec},322 {0x4864, 0x00},323 {0x4883, 0x00},324 {0x4888, 0x90},325 {0x4889, 0x05},326 {0x488b, 0x04},327 {0x4f00, 0x04},328 {0x4f10, 0x04},329 {0x4f21, 0x01},330 {0x4f22, 0x40},331 {0x4f23, 0x44},332 {0x4f24, 0x51},333 {0x4f25, 0x41},334 {0x5000, 0x1f},335 {0x500a, 0x00},336 {0x5100, 0x00},337 {0x5111, 0x20},338 {0x3020, 0x20},339 {0x3613, 0x03},340 {0x38c9, 0x02},341 {0x5304, 0x01},342 {0x3620, 0x08},343 {0x3639, 0x58},344 {0x363a, 0x10},345 {0x3674, 0x04},346 {0x3780, 0xff},347 {0x3781, 0xff},348 {0x3782, 0x00},349 {0x3783, 0x01},350 {0x3798, 0xa3},351 {0x37aa, 0x10},352 {0x38a8, 0xf0},353 {0x38c4, 0x09},354 {0x38c5, 0xb0},355 {0x38df, 0x80},356 {0x38ff, 0x05},357 {0x4010, 0xf1},358 {0x4011, 0x70},359 {0x3667, 0x80},360 {0x4d00, 0x4a},361 {0x4d01, 0x18},362 {0x4d02, 0xbb},363 {0x4d03, 0xde},364 {0x4d04, 0x93},365 {0x4d05, 0xff},366 {0x4d09, 0x0a},367 {0x37aa, 0x16},368 {0x3606, 0x42},369 {0x3605, 0x00},370 {0x36a2, 0x17},371 {0x300d, 0x0a},372 {0x4d00, 0x4d},373 {0x4d01, 0x95},374 {0x3d8C, 0x70},375 {0x3d8d, 0xE9},376 {0x5300, 0x00},377 {0x5301, 0x10},378 {0x5302, 0x00},379 {0x5303, 0xE3},380 {0x3d88, 0x00},381 {0x3d89, 0x10},382 {0x3d8a, 0x00},383 {0x3d8b, 0xE3},384 {0x4f22, 0x00},385};386 387static const char * const og01a1b_test_pattern_menu[] = {388 "Disabled",389 "Standard Color Bar",390 "Top-Bottom Darker Color Bar",391 "Right-Left Darker Color Bar",392 "Bottom-Top Darker Color Bar"393};394 395static const s64 link_freq_menu_items[] = {396 OG01A1B_LINK_FREQ_500MHZ,397};398 399static const struct og01a1b_link_freq_config link_freq_configs[] = {400 [OG01A1B_LINK_FREQ_1000MBPS] = {401 .reg_list = {402 .num_of_regs = ARRAY_SIZE(mipi_data_rate_1000mbps),403 .regs = mipi_data_rate_1000mbps,404 }405 }406};407 408static const struct og01a1b_mode supported_modes[] = {409 {410 .width = 1280,411 .height = 1024,412 .hts = 848,413 .vts_def = OG01A1B_VTS_120FPS,414 .vts_min = OG01A1B_VTS_120FPS_MIN,415 .reg_list = {416 .num_of_regs = ARRAY_SIZE(mode_1280x1024_regs),417 .regs = mode_1280x1024_regs,418 },419 .link_freq_index = OG01A1B_LINK_FREQ_1000MBPS,420 },421};422 423struct og01a1b {424 struct clk *xvclk;425 struct gpio_desc *reset_gpio;426 struct regulator *avdd;427 struct regulator *dovdd;428 struct regulator *dvdd;429 430 struct v4l2_subdev sd;431 struct media_pad pad;432 struct v4l2_ctrl_handler ctrl_handler;433 434 /* V4L2 Controls */435 struct v4l2_ctrl *link_freq;436 struct v4l2_ctrl *pixel_rate;437 struct v4l2_ctrl *vblank;438 struct v4l2_ctrl *hblank;439 struct v4l2_ctrl *exposure;440 441 /* Current mode */442 const struct og01a1b_mode *cur_mode;443 444 /* To serialize asynchronus callbacks */445 struct mutex mutex;446};447 448static u64 to_pixel_rate(u32 f_index)449{450 u64 pixel_rate = link_freq_menu_items[f_index] * 2 * OG01A1B_DATA_LANES;451 452 do_div(pixel_rate, OG01A1B_RGB_DEPTH);453 454 return pixel_rate;455}456 457static u64 to_pixels_per_line(u32 hts, u32 f_index)458{459 u64 ppl = hts * to_pixel_rate(f_index);460 461 do_div(ppl, OG01A1B_SCLK);462 463 return ppl;464}465 466static int og01a1b_read_reg(struct og01a1b *og01a1b, u16 reg, u16 len, u32 *val)467{468 struct i2c_client *client = v4l2_get_subdevdata(&og01a1b->sd);469 struct i2c_msg msgs[2];470 u8 addr_buf[2];471 u8 data_buf[4] = {0};472 int ret;473 474 if (len > 4)475 return -EINVAL;476 477 put_unaligned_be16(reg, addr_buf);478 msgs[0].addr = client->addr;479 msgs[0].flags = 0;480 msgs[0].len = sizeof(addr_buf);481 msgs[0].buf = addr_buf;482 msgs[1].addr = client->addr;483 msgs[1].flags = I2C_M_RD;484 msgs[1].len = len;485 msgs[1].buf = &data_buf[4 - len];486 487 ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));488 if (ret != ARRAY_SIZE(msgs))489 return -EIO;490 491 *val = get_unaligned_be32(data_buf);492 493 return 0;494}495 496static int og01a1b_write_reg(struct og01a1b *og01a1b, u16 reg, u16 len, u32 val)497{498 struct i2c_client *client = v4l2_get_subdevdata(&og01a1b->sd);499 u8 buf[6];500 501 if (len > 4)502 return -EINVAL;503 504 put_unaligned_be16(reg, buf);505 put_unaligned_be32(val << 8 * (4 - len), buf + 2);506 if (i2c_master_send(client, buf, len + 2) != len + 2)507 return -EIO;508 509 return 0;510}511 512static int og01a1b_write_reg_list(struct og01a1b *og01a1b,513 const struct og01a1b_reg_list *r_list)514{515 struct i2c_client *client = v4l2_get_subdevdata(&og01a1b->sd);516 unsigned int i;517 int ret;518 519 for (i = 0; i < r_list->num_of_regs; i++) {520 ret = og01a1b_write_reg(og01a1b, r_list->regs[i].address, 1,521 r_list->regs[i].val);522 if (ret) {523 dev_err_ratelimited(&client->dev,524 "failed to write reg 0x%4.4x. error = %d",525 r_list->regs[i].address, ret);526 return ret;527 }528 }529 530 return 0;531}532 533static int og01a1b_test_pattern(struct og01a1b *og01a1b, u32 pattern)534{535 if (pattern)536 pattern = (pattern - 1) << OG01A1B_TEST_PATTERN_BAR_SHIFT |537 OG01A1B_TEST_PATTERN_ENABLE;538 539 return og01a1b_write_reg(og01a1b, OG01A1B_REG_TEST_PATTERN,540 OG01A1B_REG_VALUE_08BIT, pattern);541}542 543static int og01a1b_set_ctrl(struct v4l2_ctrl *ctrl)544{545 struct og01a1b *og01a1b = container_of(ctrl->handler,546 struct og01a1b, ctrl_handler);547 struct i2c_client *client = v4l2_get_subdevdata(&og01a1b->sd);548 s64 exposure_max;549 int ret = 0;550 551 /* Propagate change of current control to all related controls */552 if (ctrl->id == V4L2_CID_VBLANK) {553 /* Update max exposure while meeting expected vblanking */554 exposure_max = og01a1b->cur_mode->height + ctrl->val -555 OG01A1B_EXPOSURE_MAX_MARGIN;556 __v4l2_ctrl_modify_range(og01a1b->exposure,557 og01a1b->exposure->minimum,558 exposure_max, og01a1b->exposure->step,559 exposure_max);560 }561 562 /* V4L2 controls values will be applied only when power is already up */563 if (!pm_runtime_get_if_in_use(&client->dev))564 return 0;565 566 switch (ctrl->id) {567 case V4L2_CID_ANALOGUE_GAIN:568 ret = og01a1b_write_reg(og01a1b, OG01A1B_REG_ANALOG_GAIN,569 OG01A1B_REG_VALUE_16BIT,570 ctrl->val << 4);571 break;572 573 case V4L2_CID_DIGITAL_GAIN:574 ret = og01a1b_write_reg(og01a1b, OG01A1B_REG_DIG_GAIN,575 OG01A1B_REG_VALUE_24BIT,576 ctrl->val << 6);577 break;578 579 case V4L2_CID_EXPOSURE:580 ret = og01a1b_write_reg(og01a1b, OG01A1B_REG_EXPOSURE,581 OG01A1B_REG_VALUE_16BIT, ctrl->val);582 break;583 584 case V4L2_CID_VBLANK:585 ret = og01a1b_write_reg(og01a1b, OG01A1B_REG_VTS,586 OG01A1B_REG_VALUE_16BIT,587 og01a1b->cur_mode->height + ctrl->val);588 break;589 590 case V4L2_CID_TEST_PATTERN:591 ret = og01a1b_test_pattern(og01a1b, ctrl->val);592 break;593 594 default:595 ret = -EINVAL;596 break;597 }598 599 pm_runtime_put(&client->dev);600 601 return ret;602}603 604static const struct v4l2_ctrl_ops og01a1b_ctrl_ops = {605 .s_ctrl = og01a1b_set_ctrl,606};607 608static int og01a1b_init_controls(struct og01a1b *og01a1b)609{610 struct v4l2_ctrl_handler *ctrl_hdlr;611 s64 exposure_max, h_blank;612 int ret;613 614 ctrl_hdlr = &og01a1b->ctrl_handler;615 ret = v4l2_ctrl_handler_init(ctrl_hdlr, 8);616 if (ret)617 return ret;618 619 ctrl_hdlr->lock = &og01a1b->mutex;620 og01a1b->link_freq = v4l2_ctrl_new_int_menu(ctrl_hdlr,621 &og01a1b_ctrl_ops,622 V4L2_CID_LINK_FREQ,623 ARRAY_SIZE624 (link_freq_menu_items) - 1,625 0, link_freq_menu_items);626 if (og01a1b->link_freq)627 og01a1b->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;628 629 og01a1b->pixel_rate = v4l2_ctrl_new_std(ctrl_hdlr, &og01a1b_ctrl_ops,630 V4L2_CID_PIXEL_RATE, 0,631 to_pixel_rate632 (OG01A1B_LINK_FREQ_1000MBPS),633 1,634 to_pixel_rate635 (OG01A1B_LINK_FREQ_1000MBPS));636 og01a1b->vblank = v4l2_ctrl_new_std(ctrl_hdlr, &og01a1b_ctrl_ops,637 V4L2_CID_VBLANK,638 og01a1b->cur_mode->vts_min -639 og01a1b->cur_mode->height,640 OG01A1B_VTS_MAX -641 og01a1b->cur_mode->height, 1,642 og01a1b->cur_mode->vts_def -643 og01a1b->cur_mode->height);644 h_blank = to_pixels_per_line(og01a1b->cur_mode->hts,645 og01a1b->cur_mode->link_freq_index) -646 og01a1b->cur_mode->width;647 og01a1b->hblank = v4l2_ctrl_new_std(ctrl_hdlr, &og01a1b_ctrl_ops,648 V4L2_CID_HBLANK, h_blank, h_blank,649 1, h_blank);650 if (og01a1b->hblank)651 og01a1b->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;652 653 v4l2_ctrl_new_std(ctrl_hdlr, &og01a1b_ctrl_ops, V4L2_CID_ANALOGUE_GAIN,654 OG01A1B_ANAL_GAIN_MIN, OG01A1B_ANAL_GAIN_MAX,655 OG01A1B_ANAL_GAIN_STEP, OG01A1B_ANAL_GAIN_MIN);656 v4l2_ctrl_new_std(ctrl_hdlr, &og01a1b_ctrl_ops, V4L2_CID_DIGITAL_GAIN,657 OG01A1B_DGTL_GAIN_MIN, OG01A1B_DGTL_GAIN_MAX,658 OG01A1B_DGTL_GAIN_STEP, OG01A1B_DGTL_GAIN_DEFAULT);659 exposure_max = (og01a1b->cur_mode->vts_def -660 OG01A1B_EXPOSURE_MAX_MARGIN);661 og01a1b->exposure = v4l2_ctrl_new_std(ctrl_hdlr, &og01a1b_ctrl_ops,662 V4L2_CID_EXPOSURE,663 OG01A1B_EXPOSURE_MIN,664 exposure_max,665 OG01A1B_EXPOSURE_STEP,666 exposure_max);667 v4l2_ctrl_new_std_menu_items(ctrl_hdlr, &og01a1b_ctrl_ops,668 V4L2_CID_TEST_PATTERN,669 ARRAY_SIZE(og01a1b_test_pattern_menu) - 1,670 0, 0, og01a1b_test_pattern_menu);671 672 if (ctrl_hdlr->error)673 return ctrl_hdlr->error;674 675 og01a1b->sd.ctrl_handler = ctrl_hdlr;676 677 return 0;678}679 680static void og01a1b_update_pad_format(const struct og01a1b_mode *mode,681 struct v4l2_mbus_framefmt *fmt)682{683 fmt->width = mode->width;684 fmt->height = mode->height;685 fmt->code = MEDIA_BUS_FMT_SGRBG10_1X10;686 fmt->field = V4L2_FIELD_NONE;687}688 689static int og01a1b_start_streaming(struct og01a1b *og01a1b)690{691 struct i2c_client *client = v4l2_get_subdevdata(&og01a1b->sd);692 const struct og01a1b_reg_list *reg_list;693 int link_freq_index, ret;694 695 link_freq_index = og01a1b->cur_mode->link_freq_index;696 reg_list = &link_freq_configs[link_freq_index].reg_list;697 698 ret = og01a1b_write_reg_list(og01a1b, reg_list);699 if (ret) {700 dev_err(&client->dev, "failed to set plls");701 return ret;702 }703 704 reg_list = &og01a1b->cur_mode->reg_list;705 ret = og01a1b_write_reg_list(og01a1b, reg_list);706 if (ret) {707 dev_err(&client->dev, "failed to set mode");708 return ret;709 }710 711 ret = __v4l2_ctrl_handler_setup(og01a1b->sd.ctrl_handler);712 if (ret)713 return ret;714 715 ret = og01a1b_write_reg(og01a1b, OG01A1B_REG_MODE_SELECT,716 OG01A1B_REG_VALUE_08BIT,717 OG01A1B_MODE_STREAMING);718 if (ret) {719 dev_err(&client->dev, "failed to set stream");720 return ret;721 }722 723 return 0;724}725 726static void og01a1b_stop_streaming(struct og01a1b *og01a1b)727{728 struct i2c_client *client = v4l2_get_subdevdata(&og01a1b->sd);729 730 if (og01a1b_write_reg(og01a1b, OG01A1B_REG_MODE_SELECT,731 OG01A1B_REG_VALUE_08BIT, OG01A1B_MODE_STANDBY))732 dev_err(&client->dev, "failed to set stream");733}734 735static int og01a1b_set_stream(struct v4l2_subdev *sd, int enable)736{737 struct og01a1b *og01a1b = to_og01a1b(sd);738 struct i2c_client *client = v4l2_get_subdevdata(sd);739 int ret = 0;740 741 mutex_lock(&og01a1b->mutex);742 if (enable) {743 ret = pm_runtime_resume_and_get(&client->dev);744 if (ret) {745 mutex_unlock(&og01a1b->mutex);746 return ret;747 }748 749 ret = og01a1b_start_streaming(og01a1b);750 if (ret) {751 enable = 0;752 og01a1b_stop_streaming(og01a1b);753 pm_runtime_put(&client->dev);754 }755 } else {756 og01a1b_stop_streaming(og01a1b);757 pm_runtime_put(&client->dev);758 }759 760 mutex_unlock(&og01a1b->mutex);761 762 return ret;763}764 765static int og01a1b_set_format(struct v4l2_subdev *sd,766 struct v4l2_subdev_state *sd_state,767 struct v4l2_subdev_format *fmt)768{769 struct og01a1b *og01a1b = to_og01a1b(sd);770 const struct og01a1b_mode *mode;771 s32 vblank_def, h_blank;772 773 mode = v4l2_find_nearest_size(supported_modes,774 ARRAY_SIZE(supported_modes), width,775 height, fmt->format.width,776 fmt->format.height);777 778 mutex_lock(&og01a1b->mutex);779 og01a1b_update_pad_format(mode, &fmt->format);780 if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {781 *v4l2_subdev_state_get_format(sd_state, fmt->pad) = fmt->format;782 } else {783 og01a1b->cur_mode = mode;784 __v4l2_ctrl_s_ctrl(og01a1b->link_freq, mode->link_freq_index);785 __v4l2_ctrl_s_ctrl_int64(og01a1b->pixel_rate,786 to_pixel_rate(mode->link_freq_index));787 788 /* Update limits and set FPS to default */789 vblank_def = mode->vts_def - mode->height;790 __v4l2_ctrl_modify_range(og01a1b->vblank,791 mode->vts_min - mode->height,792 OG01A1B_VTS_MAX - mode->height, 1,793 vblank_def);794 __v4l2_ctrl_s_ctrl(og01a1b->vblank, vblank_def);795 h_blank = to_pixels_per_line(mode->hts, mode->link_freq_index) -796 mode->width;797 __v4l2_ctrl_modify_range(og01a1b->hblank, h_blank, h_blank, 1,798 h_blank);799 }800 801 mutex_unlock(&og01a1b->mutex);802 803 return 0;804}805 806static int og01a1b_get_format(struct v4l2_subdev *sd,807 struct v4l2_subdev_state *sd_state,808 struct v4l2_subdev_format *fmt)809{810 struct og01a1b *og01a1b = to_og01a1b(sd);811 812 mutex_lock(&og01a1b->mutex);813 if (fmt->which == V4L2_SUBDEV_FORMAT_TRY)814 fmt->format = *v4l2_subdev_state_get_format(sd_state,815 fmt->pad);816 else817 og01a1b_update_pad_format(og01a1b->cur_mode, &fmt->format);818 819 mutex_unlock(&og01a1b->mutex);820 821 return 0;822}823 824static int og01a1b_enum_mbus_code(struct v4l2_subdev *sd,825 struct v4l2_subdev_state *sd_state,826 struct v4l2_subdev_mbus_code_enum *code)827{828 if (code->index > 0)829 return -EINVAL;830 831 code->code = MEDIA_BUS_FMT_SGRBG10_1X10;832 833 return 0;834}835 836static int og01a1b_enum_frame_size(struct v4l2_subdev *sd,837 struct v4l2_subdev_state *sd_state,838 struct v4l2_subdev_frame_size_enum *fse)839{840 if (fse->index >= ARRAY_SIZE(supported_modes))841 return -EINVAL;842 843 if (fse->code != MEDIA_BUS_FMT_SGRBG10_1X10)844 return -EINVAL;845 846 fse->min_width = supported_modes[fse->index].width;847 fse->max_width = fse->min_width;848 fse->min_height = supported_modes[fse->index].height;849 fse->max_height = fse->min_height;850 851 return 0;852}853 854static int og01a1b_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)855{856 struct og01a1b *og01a1b = to_og01a1b(sd);857 858 mutex_lock(&og01a1b->mutex);859 og01a1b_update_pad_format(&supported_modes[0],860 v4l2_subdev_state_get_format(fh->state, 0));861 mutex_unlock(&og01a1b->mutex);862 863 return 0;864}865 866static const struct v4l2_subdev_video_ops og01a1b_video_ops = {867 .s_stream = og01a1b_set_stream,868};869 870static const struct v4l2_subdev_pad_ops og01a1b_pad_ops = {871 .set_fmt = og01a1b_set_format,872 .get_fmt = og01a1b_get_format,873 .enum_mbus_code = og01a1b_enum_mbus_code,874 .enum_frame_size = og01a1b_enum_frame_size,875};876 877static const struct v4l2_subdev_ops og01a1b_subdev_ops = {878 .video = &og01a1b_video_ops,879 .pad = &og01a1b_pad_ops,880};881 882static const struct media_entity_operations og01a1b_subdev_entity_ops = {883 .link_validate = v4l2_subdev_link_validate,884};885 886static const struct v4l2_subdev_internal_ops og01a1b_internal_ops = {887 .open = og01a1b_open,888};889 890static int og01a1b_identify_module(struct og01a1b *og01a1b)891{892 struct i2c_client *client = v4l2_get_subdevdata(&og01a1b->sd);893 int ret;894 u32 val;895 896 ret = og01a1b_read_reg(og01a1b, OG01A1B_REG_CHIP_ID,897 OG01A1B_REG_VALUE_24BIT, &val);898 if (ret)899 return ret;900 901 if (val != OG01A1B_CHIP_ID) {902 dev_err(&client->dev, "chip id mismatch: %x!=%x",903 OG01A1B_CHIP_ID, val);904 return -ENXIO;905 }906 907 return 0;908}909 910static int og01a1b_check_hwcfg(struct og01a1b *og01a1b)911{912 struct i2c_client *client = v4l2_get_subdevdata(&og01a1b->sd);913 struct device *dev = &client->dev;914 struct fwnode_handle *ep;915 struct fwnode_handle *fwnode = dev_fwnode(dev);916 struct v4l2_fwnode_endpoint bus_cfg = {917 .bus_type = V4L2_MBUS_CSI2_DPHY918 };919 u32 mclk;920 int ret;921 unsigned int i, j;922 923 if (!fwnode)924 return -ENXIO;925 926 ret = fwnode_property_read_u32(fwnode, "clock-frequency", &mclk);927 if (ret) {928 if (!og01a1b->xvclk) {929 dev_err(dev, "can't get clock frequency");930 return ret;931 }932 933 mclk = clk_get_rate(og01a1b->xvclk);934 }935 936 if (mclk != OG01A1B_MCLK) {937 dev_err(dev, "external clock %d is not supported", mclk);938 return -EINVAL;939 }940 941 ep = fwnode_graph_get_next_endpoint(fwnode, NULL);942 if (!ep)943 return -ENXIO;944 945 ret = v4l2_fwnode_endpoint_alloc_parse(ep, &bus_cfg);946 fwnode_handle_put(ep);947 if (ret)948 return ret;949 950 if (bus_cfg.bus.mipi_csi2.num_data_lanes != OG01A1B_DATA_LANES) {951 dev_err(dev, "number of CSI2 data lanes %d is not supported",952 bus_cfg.bus.mipi_csi2.num_data_lanes);953 ret = -EINVAL;954 goto check_hwcfg_error;955 }956 957 if (!bus_cfg.nr_of_link_frequencies) {958 dev_err(dev, "no link frequencies defined");959 ret = -EINVAL;960 goto check_hwcfg_error;961 }962 963 for (i = 0; i < ARRAY_SIZE(link_freq_menu_items); i++) {964 for (j = 0; j < bus_cfg.nr_of_link_frequencies; j++) {965 if (link_freq_menu_items[i] ==966 bus_cfg.link_frequencies[j])967 break;968 }969 970 if (j == bus_cfg.nr_of_link_frequencies) {971 dev_err(dev, "no link frequency %lld supported",972 link_freq_menu_items[i]);973 ret = -EINVAL;974 goto check_hwcfg_error;975 }976 }977 978check_hwcfg_error:979 v4l2_fwnode_endpoint_free(&bus_cfg);980 981 return ret;982}983 984/* Power/clock management functions */985static int og01a1b_power_on(struct device *dev)986{987 unsigned long delay = DIV_ROUND_UP(8192UL * USEC_PER_SEC, OG01A1B_MCLK);988 struct v4l2_subdev *sd = dev_get_drvdata(dev);989 struct og01a1b *og01a1b = to_og01a1b(sd);990 int ret;991 992 if (og01a1b->avdd) {993 ret = regulator_enable(og01a1b->avdd);994 if (ret)995 return ret;996 }997 998 if (og01a1b->dovdd) {999 ret = regulator_enable(og01a1b->dovdd);1000 if (ret)1001 goto avdd_disable;1002 }1003 1004 if (og01a1b->dvdd) {1005 ret = regulator_enable(og01a1b->dvdd);1006 if (ret)1007 goto dovdd_disable;1008 }1009 1010 ret = clk_prepare_enable(og01a1b->xvclk);1011 if (ret)1012 goto dvdd_disable;1013 1014 gpiod_set_value_cansleep(og01a1b->reset_gpio, 0);1015 1016 if (og01a1b->reset_gpio)1017 usleep_range(5 * USEC_PER_MSEC, 6 * USEC_PER_MSEC);1018 else if (og01a1b->xvclk)1019 usleep_range(delay, 2 * delay);1020 1021 return 0;1022 1023dvdd_disable:1024 if (og01a1b->dvdd)1025 regulator_disable(og01a1b->dvdd);1026dovdd_disable:1027 if (og01a1b->dovdd)1028 regulator_disable(og01a1b->dovdd);1029avdd_disable:1030 if (og01a1b->avdd)1031 regulator_disable(og01a1b->avdd);1032 1033 return ret;1034}1035 1036static int og01a1b_power_off(struct device *dev)1037{1038 unsigned long delay = DIV_ROUND_UP(512 * USEC_PER_SEC, OG01A1B_MCLK);1039 struct v4l2_subdev *sd = dev_get_drvdata(dev);1040 struct og01a1b *og01a1b = to_og01a1b(sd);1041 1042 if (og01a1b->xvclk)1043 usleep_range(delay, 2 * delay);1044 1045 clk_disable_unprepare(og01a1b->xvclk);1046 1047 gpiod_set_value_cansleep(og01a1b->reset_gpio, 1);1048 1049 if (og01a1b->dvdd)1050 regulator_disable(og01a1b->dvdd);1051 1052 if (og01a1b->dovdd)1053 regulator_disable(og01a1b->dovdd);1054 1055 if (og01a1b->avdd)1056 regulator_disable(og01a1b->avdd);1057 1058 return 0;1059}1060 1061static void og01a1b_remove(struct i2c_client *client)1062{1063 struct v4l2_subdev *sd = i2c_get_clientdata(client);1064 struct og01a1b *og01a1b = to_og01a1b(sd);1065 1066 v4l2_async_unregister_subdev(sd);1067 media_entity_cleanup(&sd->entity);1068 v4l2_ctrl_handler_free(sd->ctrl_handler);1069 pm_runtime_disable(&client->dev);1070 mutex_destroy(&og01a1b->mutex);1071}1072 1073static int og01a1b_probe(struct i2c_client *client)1074{1075 struct og01a1b *og01a1b;1076 int ret;1077 1078 og01a1b = devm_kzalloc(&client->dev, sizeof(*og01a1b), GFP_KERNEL);1079 if (!og01a1b)1080 return -ENOMEM;1081 1082 v4l2_i2c_subdev_init(&og01a1b->sd, client, &og01a1b_subdev_ops);1083 1084 og01a1b->xvclk = devm_clk_get_optional(&client->dev, NULL);1085 if (IS_ERR(og01a1b->xvclk)) {1086 ret = PTR_ERR(og01a1b->xvclk);1087 dev_err(&client->dev, "failed to get xvclk clock: %d\n", ret);1088 return ret;1089 }1090 1091 ret = og01a1b_check_hwcfg(og01a1b);1092 if (ret) {1093 dev_err(&client->dev, "failed to check HW configuration: %d",1094 ret);1095 return ret;1096 }1097 1098 og01a1b->reset_gpio = devm_gpiod_get_optional(&client->dev, "reset",1099 GPIOD_OUT_LOW);1100 if (IS_ERR(og01a1b->reset_gpio)) {1101 dev_err(&client->dev, "cannot get reset GPIO\n");1102 return PTR_ERR(og01a1b->reset_gpio);1103 }1104 1105 og01a1b->avdd = devm_regulator_get_optional(&client->dev, "avdd");1106 if (IS_ERR(og01a1b->avdd)) {1107 ret = PTR_ERR(og01a1b->avdd);1108 if (ret != -ENODEV) {1109 dev_err_probe(&client->dev, ret,1110 "Failed to get 'avdd' regulator\n");1111 return ret;1112 }1113 1114 og01a1b->avdd = NULL;1115 }1116 1117 og01a1b->dovdd = devm_regulator_get_optional(&client->dev, "dovdd");1118 if (IS_ERR(og01a1b->dovdd)) {1119 ret = PTR_ERR(og01a1b->dovdd);1120 if (ret != -ENODEV) {1121 dev_err_probe(&client->dev, ret,1122 "Failed to get 'dovdd' regulator\n");1123 return ret;1124 }1125 1126 og01a1b->dovdd = NULL;1127 }1128 1129 og01a1b->dvdd = devm_regulator_get_optional(&client->dev, "dvdd");1130 if (IS_ERR(og01a1b->dvdd)) {1131 ret = PTR_ERR(og01a1b->dvdd);1132 if (ret != -ENODEV) {1133 dev_err_probe(&client->dev, ret,1134 "Failed to get 'dvdd' regulator\n");1135 return ret;1136 }1137 1138 og01a1b->dvdd = NULL;1139 }1140 1141 /* The sensor must be powered on to read the CHIP_ID register */1142 ret = og01a1b_power_on(&client->dev);1143 if (ret)1144 return ret;1145 1146 ret = og01a1b_identify_module(og01a1b);1147 if (ret) {1148 dev_err(&client->dev, "failed to find sensor: %d", ret);1149 goto power_off;1150 }1151 1152 mutex_init(&og01a1b->mutex);1153 og01a1b->cur_mode = &supported_modes[0];1154 ret = og01a1b_init_controls(og01a1b);1155 if (ret) {1156 dev_err(&client->dev, "failed to init controls: %d", ret);1157 goto probe_error_v4l2_ctrl_handler_free;1158 }1159 1160 og01a1b->sd.internal_ops = &og01a1b_internal_ops;1161 og01a1b->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;1162 og01a1b->sd.entity.ops = &og01a1b_subdev_entity_ops;1163 og01a1b->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;1164 og01a1b->pad.flags = MEDIA_PAD_FL_SOURCE;1165 ret = media_entity_pads_init(&og01a1b->sd.entity, 1, &og01a1b->pad);1166 if (ret) {1167 dev_err(&client->dev, "failed to init entity pads: %d", ret);1168 goto probe_error_v4l2_ctrl_handler_free;1169 }1170 1171 ret = v4l2_async_register_subdev_sensor(&og01a1b->sd);1172 if (ret < 0) {1173 dev_err(&client->dev, "failed to register V4L2 subdev: %d",1174 ret);1175 goto probe_error_media_entity_cleanup;1176 }1177 1178 /* Enable runtime PM and turn off the device */1179 pm_runtime_set_active(&client->dev);1180 pm_runtime_enable(&client->dev);1181 pm_runtime_idle(&client->dev);1182 1183 return 0;1184 1185probe_error_media_entity_cleanup:1186 media_entity_cleanup(&og01a1b->sd.entity);1187 1188probe_error_v4l2_ctrl_handler_free:1189 v4l2_ctrl_handler_free(og01a1b->sd.ctrl_handler);1190 mutex_destroy(&og01a1b->mutex);1191 1192power_off:1193 og01a1b_power_off(&client->dev);1194 1195 return ret;1196}1197 1198static const struct dev_pm_ops og01a1b_pm_ops = {1199 SET_RUNTIME_PM_OPS(og01a1b_power_off, og01a1b_power_on, NULL)1200};1201 1202#ifdef CONFIG_ACPI1203static const struct acpi_device_id og01a1b_acpi_ids[] = {1204 {"OVTI01AC"},1205 {}1206};1207 1208MODULE_DEVICE_TABLE(acpi, og01a1b_acpi_ids);1209#endif1210 1211static const struct of_device_id og01a1b_of_match[] = {1212 { .compatible = "ovti,og01a1b" },1213 { /* sentinel */ }1214};1215MODULE_DEVICE_TABLE(of, og01a1b_of_match);1216 1217static struct i2c_driver og01a1b_i2c_driver = {1218 .driver = {1219 .name = "og01a1b",1220 .pm = &og01a1b_pm_ops,1221 .acpi_match_table = ACPI_PTR(og01a1b_acpi_ids),1222 .of_match_table = og01a1b_of_match,1223 },1224 .probe = og01a1b_probe,1225 .remove = og01a1b_remove,1226};1227 1228module_i2c_driver(og01a1b_i2c_driver);1229 1230MODULE_AUTHOR("Shawn Tu");1231MODULE_DESCRIPTION("OmniVision OG01A1B sensor driver");1232MODULE_LICENSE("GPL v2");1233