File Index
Files and directories
Sign in
FILE

imx208.c

File preview with syntax highlighting.

linux-6.19.14/drivers/media/i2c/imx208.c C
   1// SPDX-License-Identifier: GPL-2.0
   2// Copyright (C) 2021 Intel Corporation
   3
   4#include <linux/acpi.h>
   5#include <linux/clk.h>
   6#include <linux/delay.h>
   7#include <linux/i2c.h>
   8#include <linux/module.h>
   9#include <linux/pm_runtime.h>
  10#include <linux/unaligned.h>
  11
  12#include <media/v4l2-ctrls.h>
  13#include <media/v4l2-device.h>
  14
  15#define IMX208_REG_MODE_SELECT		0x0100
  16#define IMX208_MODE_STANDBY		0x00
  17#define IMX208_MODE_STREAMING		0x01
  18
  19/* Chip ID */
  20#define IMX208_REG_CHIP_ID		0x0000
  21#define IMX208_CHIP_ID			0x0208
  22
  23/* V_TIMING internal */
  24#define IMX208_REG_VTS			0x0340
  25#define IMX208_VTS_60FPS		0x0472
  26#define IMX208_VTS_BINNING		0x0239
  27#define IMX208_VTS_60FPS_MIN		0x0458
  28#define IMX208_VTS_BINNING_MIN		0x0230
  29#define IMX208_VTS_MAX			0xffff
  30
  31/* HBLANK control - read only */
  32#define IMX208_PPL_384MHZ		2248
  33#define IMX208_PPL_96MHZ		2248
  34
  35/* Exposure control */
  36#define IMX208_REG_EXPOSURE		0x0202
  37#define IMX208_EXPOSURE_MIN		4
  38#define IMX208_EXPOSURE_STEP		1
  39#define IMX208_EXPOSURE_DEFAULT		0x190
  40#define IMX208_EXPOSURE_MAX		65535
  41
  42/* Analog gain control */
  43#define IMX208_REG_ANALOG_GAIN		0x0204
  44#define IMX208_ANA_GAIN_MIN		0
  45#define IMX208_ANA_GAIN_MAX		0x00e0
  46#define IMX208_ANA_GAIN_STEP		1
  47#define IMX208_ANA_GAIN_DEFAULT		0x0
  48
  49/* Digital gain control */
  50#define IMX208_REG_GR_DIGITAL_GAIN	0x020e
  51#define IMX208_REG_R_DIGITAL_GAIN	0x0210
  52#define IMX208_REG_B_DIGITAL_GAIN	0x0212
  53#define IMX208_REG_GB_DIGITAL_GAIN	0x0214
  54#define IMX208_DIGITAL_GAIN_SHIFT	8
  55
  56/* Orientation */
  57#define IMX208_REG_ORIENTATION_CONTROL	0x0101
  58
  59/* Test Pattern Control */
  60#define IMX208_REG_TEST_PATTERN_MODE	0x0600
  61#define IMX208_TEST_PATTERN_DISABLE	0x0
  62#define IMX208_TEST_PATTERN_SOLID_COLOR	0x1
  63#define IMX208_TEST_PATTERN_COLOR_BARS	0x2
  64#define IMX208_TEST_PATTERN_GREY_COLOR	0x3
  65#define IMX208_TEST_PATTERN_PN9		0x4
  66#define IMX208_TEST_PATTERN_FIX_1	0x100
  67#define IMX208_TEST_PATTERN_FIX_2	0x101
  68#define IMX208_TEST_PATTERN_FIX_3	0x102
  69#define IMX208_TEST_PATTERN_FIX_4	0x103
  70#define IMX208_TEST_PATTERN_FIX_5	0x104
  71#define IMX208_TEST_PATTERN_FIX_6	0x105
  72
  73/* OTP Access */
  74#define IMX208_OTP_BASE			0x3500
  75#define IMX208_OTP_SIZE			40
  76
  77struct imx208_reg {
  78	u16 address;
  79	u8 val;
  80};
  81
  82struct imx208_reg_list {
  83	u32 num_of_regs;
  84	const struct imx208_reg *regs;
  85};
  86
  87/* Link frequency config */
  88struct imx208_link_freq_config {
  89	u32 pixels_per_line;
  90
  91	/* PLL registers for this link frequency */
  92	struct imx208_reg_list reg_list;
  93};
  94
  95/* Mode : resolution and related config&values */
  96struct imx208_mode {
  97	/* Frame width */
  98	u32 width;
  99	/* Frame height */
 100	u32 height;
 101
 102	/* V-timing */
 103	u32 vts_def;
 104	u32 vts_min;
 105
 106	/* Index of Link frequency config to be used */
 107	u32 link_freq_index;
 108	/* Default register values */
 109	struct imx208_reg_list reg_list;
 110};
 111
 112static const struct imx208_reg pll_ctrl_reg[] = {
 113	{0x0305, 0x02},
 114	{0x0307, 0x50},
 115	{0x303C, 0x3C},
 116};
 117
 118static const struct imx208_reg mode_1936x1096_60fps_regs[] = {
 119	{0x0340, 0x04},
 120	{0x0341, 0x72},
 121	{0x0342, 0x04},
 122	{0x0343, 0x64},
 123	{0x034C, 0x07},
 124	{0x034D, 0x90},
 125	{0x034E, 0x04},
 126	{0x034F, 0x48},
 127	{0x0381, 0x01},
 128	{0x0383, 0x01},
 129	{0x0385, 0x01},
 130	{0x0387, 0x01},
 131	{0x3048, 0x00},
 132	{0x3050, 0x01},
 133	{0x30D5, 0x00},
 134	{0x3301, 0x00},
 135	{0x3318, 0x62},
 136	{0x0202, 0x01},
 137	{0x0203, 0x90},
 138	{0x0205, 0x00},
 139};
 140
 141static const struct imx208_reg mode_968_548_60fps_regs[] = {
 142	{0x0340, 0x02},
 143	{0x0341, 0x39},
 144	{0x0342, 0x08},
 145	{0x0343, 0xC8},
 146	{0x034C, 0x03},
 147	{0x034D, 0xC8},
 148	{0x034E, 0x02},
 149	{0x034F, 0x24},
 150	{0x0381, 0x01},
 151	{0x0383, 0x03},
 152	{0x0385, 0x01},
 153	{0x0387, 0x03},
 154	{0x3048, 0x01},
 155	{0x3050, 0x02},
 156	{0x30D5, 0x03},
 157	{0x3301, 0x10},
 158	{0x3318, 0x75},
 159	{0x0202, 0x01},
 160	{0x0203, 0x90},
 161	{0x0205, 0x00},
 162};
 163
 164static const s64 imx208_discrete_digital_gain[] = {
 165	1, 2, 4, 8, 16,
 166};
 167
 168static const char * const imx208_test_pattern_menu[] = {
 169	"Disabled",
 170	"Solid Color",
 171	"100% Color Bar",
 172	"Fade to Grey Color Bar",
 173	"PN9",
 174	"Fixed Pattern1",
 175	"Fixed Pattern2",
 176	"Fixed Pattern3",
 177	"Fixed Pattern4",
 178	"Fixed Pattern5",
 179	"Fixed Pattern6"
 180};
 181
 182static const int imx208_test_pattern_val[] = {
 183	IMX208_TEST_PATTERN_DISABLE,
 184	IMX208_TEST_PATTERN_SOLID_COLOR,
 185	IMX208_TEST_PATTERN_COLOR_BARS,
 186	IMX208_TEST_PATTERN_GREY_COLOR,
 187	IMX208_TEST_PATTERN_PN9,
 188	IMX208_TEST_PATTERN_FIX_1,
 189	IMX208_TEST_PATTERN_FIX_2,
 190	IMX208_TEST_PATTERN_FIX_3,
 191	IMX208_TEST_PATTERN_FIX_4,
 192	IMX208_TEST_PATTERN_FIX_5,
 193	IMX208_TEST_PATTERN_FIX_6,
 194};
 195
 196/* Configurations for supported link frequencies */
 197#define IMX208_MHZ			(1000 * 1000ULL)
 198#define IMX208_LINK_FREQ_384MHZ		(384ULL * IMX208_MHZ)
 199#define IMX208_LINK_FREQ_96MHZ		(96ULL * IMX208_MHZ)
 200
 201#define IMX208_DATA_RATE_DOUBLE		2
 202#define IMX208_NUM_OF_LANES		2
 203#define IMX208_PIXEL_BITS		10
 204
 205enum {
 206	IMX208_LINK_FREQ_384MHZ_INDEX,
 207	IMX208_LINK_FREQ_96MHZ_INDEX,
 208};
 209
 210/*
 211 * pixel_rate = link_freq * data-rate * nr_of_lanes / bits_per_sample
 212 * data rate => double data rate; number of lanes => 2; bits per pixel => 10
 213 */
 214static u64 link_freq_to_pixel_rate(u64 f)
 215{
 216	f *= IMX208_DATA_RATE_DOUBLE * IMX208_NUM_OF_LANES;
 217	do_div(f, IMX208_PIXEL_BITS);
 218
 219	return f;
 220}
 221
 222/* Menu items for LINK_FREQ V4L2 control */
 223static const s64 link_freq_menu_items[] = {
 224	[IMX208_LINK_FREQ_384MHZ_INDEX] = IMX208_LINK_FREQ_384MHZ,
 225	[IMX208_LINK_FREQ_96MHZ_INDEX] = IMX208_LINK_FREQ_96MHZ,
 226};
 227
 228/* Link frequency configs */
 229static const struct imx208_link_freq_config link_freq_configs[] = {
 230	[IMX208_LINK_FREQ_384MHZ_INDEX] = {
 231		.pixels_per_line = IMX208_PPL_384MHZ,
 232		.reg_list = {
 233			.num_of_regs = ARRAY_SIZE(pll_ctrl_reg),
 234			.regs = pll_ctrl_reg,
 235		}
 236	},
 237	[IMX208_LINK_FREQ_96MHZ_INDEX] = {
 238		.pixels_per_line = IMX208_PPL_96MHZ,
 239		.reg_list = {
 240			.num_of_regs = ARRAY_SIZE(pll_ctrl_reg),
 241			.regs = pll_ctrl_reg,
 242		}
 243	},
 244};
 245
 246/* Mode configs */
 247static const struct imx208_mode supported_modes[] = {
 248	{
 249		.width = 1936,
 250		.height = 1096,
 251		.vts_def = IMX208_VTS_60FPS,
 252		.vts_min = IMX208_VTS_60FPS_MIN,
 253		.reg_list = {
 254			.num_of_regs = ARRAY_SIZE(mode_1936x1096_60fps_regs),
 255			.regs = mode_1936x1096_60fps_regs,
 256		},
 257		.link_freq_index = IMX208_LINK_FREQ_384MHZ_INDEX,
 258	},
 259	{
 260		.width = 968,
 261		.height = 548,
 262		.vts_def = IMX208_VTS_BINNING,
 263		.vts_min = IMX208_VTS_BINNING_MIN,
 264		.reg_list = {
 265			.num_of_regs = ARRAY_SIZE(mode_968_548_60fps_regs),
 266			.regs = mode_968_548_60fps_regs,
 267		},
 268		.link_freq_index = IMX208_LINK_FREQ_96MHZ_INDEX,
 269	},
 270};
 271
 272struct imx208 {
 273	struct device *dev;
 274	struct clk *clk;
 275
 276	struct v4l2_subdev sd;
 277	struct media_pad pad;
 278
 279	struct v4l2_ctrl_handler ctrl_handler;
 280	/* V4L2 Controls */
 281	struct v4l2_ctrl *link_freq;
 282	struct v4l2_ctrl *pixel_rate;
 283	struct v4l2_ctrl *vblank;
 284	struct v4l2_ctrl *hblank;
 285	struct v4l2_ctrl *vflip;
 286	struct v4l2_ctrl *hflip;
 287
 288	/* Current mode */
 289	const struct imx208_mode *cur_mode;
 290
 291	/*
 292	 * Mutex for serialized access:
 293	 * Protect sensor set pad format and start/stop streaming safely.
 294	 * Protect access to sensor v4l2 controls.
 295	 */
 296	struct mutex imx208_mx;
 297
 298	/* OTP data */
 299	bool otp_read;
 300	char otp_data[IMX208_OTP_SIZE];
 301
 302	/* True if the device has been identified */
 303	bool identified;
 304};
 305
 306static inline struct imx208 *to_imx208(struct v4l2_subdev *_sd)
 307{
 308	return container_of(_sd, struct imx208, sd);
 309}
 310
 311/* Get bayer order based on flip setting. */
 312static u32 imx208_get_format_code(struct imx208 *imx208)
 313{
 314	/*
 315	 * Only one bayer order is supported.
 316	 * It depends on the flip settings.
 317	 */
 318	static const u32 codes[2][2] = {
 319		{ MEDIA_BUS_FMT_SRGGB10_1X10, MEDIA_BUS_FMT_SGRBG10_1X10, },
 320		{ MEDIA_BUS_FMT_SGBRG10_1X10, MEDIA_BUS_FMT_SBGGR10_1X10, },
 321	};
 322
 323	return codes[imx208->vflip->val][imx208->hflip->val];
 324}
 325
 326/* Read registers up to 4 at a time */
 327static int imx208_read_reg(struct imx208 *imx208, u16 reg, u32 len, u32 *val)
 328{
 329	struct i2c_client *client = v4l2_get_subdevdata(&imx208->sd);
 330	struct i2c_msg msgs[2];
 331	u8 addr_buf[2] = { reg >> 8, reg & 0xff };
 332	u8 data_buf[4] = { 0, };
 333	int ret;
 334
 335	if (len > 4)
 336		return -EINVAL;
 337
 338	/* Write register address */
 339	msgs[0].addr = client->addr;
 340	msgs[0].flags = 0;
 341	msgs[0].len = ARRAY_SIZE(addr_buf);
 342	msgs[0].buf = addr_buf;
 343
 344	/* Read data from register */
 345	msgs[1].addr = client->addr;
 346	msgs[1].flags = I2C_M_RD;
 347	msgs[1].len = len;
 348	msgs[1].buf = &data_buf[4 - len];
 349
 350	ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
 351	if (ret != ARRAY_SIZE(msgs))
 352		return -EIO;
 353
 354	*val = get_unaligned_be32(data_buf);
 355
 356	return 0;
 357}
 358
 359/* Write registers up to 4 at a time */
 360static int imx208_write_reg(struct imx208 *imx208, u16 reg, u32 len, u32 val)
 361{
 362	struct i2c_client *client = v4l2_get_subdevdata(&imx208->sd);
 363	u8 buf[6];
 364
 365	if (len > 4)
 366		return -EINVAL;
 367
 368	put_unaligned_be16(reg, buf);
 369	put_unaligned_be32(val << (8 * (4 - len)), buf + 2);
 370	if (i2c_master_send(client, buf, len + 2) != len + 2)
 371		return -EIO;
 372
 373	return 0;
 374}
 375
 376/* Write a list of registers */
 377static int imx208_write_regs(struct imx208 *imx208,
 378			     const struct imx208_reg *regs, u32 len)
 379{
 380	unsigned int i;
 381	int ret;
 382
 383	for (i = 0; i < len; i++) {
 384		ret = imx208_write_reg(imx208, regs[i].address, 1,
 385				       regs[i].val);
 386		if (ret) {
 387			dev_err_ratelimited(imx208->dev,
 388					    "Failed to write reg 0x%4.4x. error = %d\n",
 389					    regs[i].address, ret);
 390
 391			return ret;
 392		}
 393	}
 394
 395	return 0;
 396}
 397
 398/* Open sub-device */
 399static int imx208_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
 400{
 401	struct v4l2_mbus_framefmt *try_fmt =
 402		v4l2_subdev_state_get_format(fh->state, 0);
 403
 404	/* Initialize try_fmt */
 405	try_fmt->width = supported_modes[0].width;
 406	try_fmt->height = supported_modes[0].height;
 407	try_fmt->code = MEDIA_BUS_FMT_SRGGB10_1X10;
 408	try_fmt->field = V4L2_FIELD_NONE;
 409
 410	return 0;
 411}
 412
 413static int imx208_update_digital_gain(struct imx208 *imx208, u32 len, u32 val)
 414{
 415	int ret;
 416
 417	val = imx208_discrete_digital_gain[val] << IMX208_DIGITAL_GAIN_SHIFT;
 418
 419	ret = imx208_write_reg(imx208, IMX208_REG_GR_DIGITAL_GAIN, 2, val);
 420	if (ret)
 421		return ret;
 422
 423	ret = imx208_write_reg(imx208, IMX208_REG_GB_DIGITAL_GAIN, 2, val);
 424	if (ret)
 425		return ret;
 426
 427	ret = imx208_write_reg(imx208, IMX208_REG_R_DIGITAL_GAIN, 2, val);
 428	if (ret)
 429		return ret;
 430
 431	return imx208_write_reg(imx208, IMX208_REG_B_DIGITAL_GAIN, 2, val);
 432}
 433
 434static int imx208_set_ctrl(struct v4l2_ctrl *ctrl)
 435{
 436	struct imx208 *imx208 =
 437		container_of(ctrl->handler, struct imx208, ctrl_handler);
 438	int ret;
 439
 440	/*
 441	 * Applying V4L2 control value only happens
 442	 * when power is up for streaming
 443	 */
 444	if (!pm_runtime_get_if_in_use(imx208->dev))
 445		return 0;
 446
 447	switch (ctrl->id) {
 448	case V4L2_CID_ANALOGUE_GAIN:
 449		ret = imx208_write_reg(imx208, IMX208_REG_ANALOG_GAIN,
 450				       2, ctrl->val);
 451		break;
 452	case V4L2_CID_EXPOSURE:
 453		ret = imx208_write_reg(imx208, IMX208_REG_EXPOSURE,
 454				       2, ctrl->val);
 455		break;
 456	case V4L2_CID_DIGITAL_GAIN:
 457		ret = imx208_update_digital_gain(imx208, 2, ctrl->val);
 458		break;
 459	case V4L2_CID_VBLANK:
 460		/* Update VTS that meets expected vertical blanking */
 461		ret = imx208_write_reg(imx208, IMX208_REG_VTS, 2,
 462				       imx208->cur_mode->height + ctrl->val);
 463		break;
 464	case V4L2_CID_TEST_PATTERN:
 465		ret = imx208_write_reg(imx208, IMX208_REG_TEST_PATTERN_MODE,
 466				       2, imx208_test_pattern_val[ctrl->val]);
 467		break;
 468	case V4L2_CID_HFLIP:
 469	case V4L2_CID_VFLIP:
 470		ret = imx208_write_reg(imx208, IMX208_REG_ORIENTATION_CONTROL,
 471				       1,
 472				       imx208->hflip->val |
 473				       imx208->vflip->val << 1);
 474		break;
 475	default:
 476		ret = -EINVAL;
 477		dev_err(imx208->dev,
 478			"ctrl(id:0x%x,val:0x%x) is not handled\n",
 479			ctrl->id, ctrl->val);
 480		break;
 481	}
 482
 483	pm_runtime_put(imx208->dev);
 484
 485	return ret;
 486}
 487
 488static const struct v4l2_ctrl_ops imx208_ctrl_ops = {
 489	.s_ctrl = imx208_set_ctrl,
 490};
 491
 492static const struct v4l2_ctrl_config imx208_digital_gain_control = {
 493	.ops = &imx208_ctrl_ops,
 494	.id = V4L2_CID_DIGITAL_GAIN,
 495	.name = "Digital Gain",
 496	.type = V4L2_CTRL_TYPE_INTEGER_MENU,
 497	.min = 0,
 498	.max = ARRAY_SIZE(imx208_discrete_digital_gain) - 1,
 499	.step = 0,
 500	.def = 0,
 501	.menu_skip_mask = 0,
 502	.qmenu_int = imx208_discrete_digital_gain,
 503};
 504
 505static int imx208_enum_mbus_code(struct v4l2_subdev *sd,
 506				 struct v4l2_subdev_state *sd_state,
 507				 struct v4l2_subdev_mbus_code_enum *code)
 508{
 509	struct imx208 *imx208 = to_imx208(sd);
 510
 511	if (code->index > 0)
 512		return -EINVAL;
 513
 514	code->code = imx208_get_format_code(imx208);
 515
 516	return 0;
 517}
 518
 519static int imx208_enum_frame_size(struct v4l2_subdev *sd,
 520				  struct v4l2_subdev_state *sd_state,
 521				  struct v4l2_subdev_frame_size_enum *fse)
 522{
 523	struct imx208 *imx208 = to_imx208(sd);
 524
 525	if (fse->index >= ARRAY_SIZE(supported_modes))
 526		return -EINVAL;
 527
 528	if (fse->code != imx208_get_format_code(imx208))
 529		return -EINVAL;
 530
 531	fse->min_width = supported_modes[fse->index].width;
 532	fse->max_width = fse->min_width;
 533	fse->min_height = supported_modes[fse->index].height;
 534	fse->max_height = fse->min_height;
 535
 536	return 0;
 537}
 538
 539static void imx208_mode_to_pad_format(struct imx208 *imx208,
 540				      const struct imx208_mode *mode,
 541				      struct v4l2_subdev_format *fmt)
 542{
 543	fmt->format.width = mode->width;
 544	fmt->format.height = mode->height;
 545	fmt->format.code = imx208_get_format_code(imx208);
 546	fmt->format.field = V4L2_FIELD_NONE;
 547}
 548
 549static int __imx208_get_pad_format(struct imx208 *imx208,
 550				   struct v4l2_subdev_state *sd_state,
 551				   struct v4l2_subdev_format *fmt)
 552{
 553	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY)
 554		fmt->format = *v4l2_subdev_state_get_format(sd_state,
 555							    fmt->pad);
 556	else
 557		imx208_mode_to_pad_format(imx208, imx208->cur_mode, fmt);
 558
 559	return 0;
 560}
 561
 562static int imx208_get_pad_format(struct v4l2_subdev *sd,
 563				 struct v4l2_subdev_state *sd_state,
 564				 struct v4l2_subdev_format *fmt)
 565{
 566	struct imx208 *imx208 = to_imx208(sd);
 567	int ret;
 568
 569	mutex_lock(&imx208->imx208_mx);
 570	ret = __imx208_get_pad_format(imx208, sd_state, fmt);
 571	mutex_unlock(&imx208->imx208_mx);
 572
 573	return ret;
 574}
 575
 576static int imx208_set_pad_format(struct v4l2_subdev *sd,
 577				 struct v4l2_subdev_state *sd_state,
 578				 struct v4l2_subdev_format *fmt)
 579{
 580	struct imx208 *imx208 = to_imx208(sd);
 581	const struct imx208_mode *mode;
 582	s32 vblank_def;
 583	s32 vblank_min;
 584	s64 h_blank;
 585	s64 pixel_rate;
 586	s64 link_freq;
 587
 588	mutex_lock(&imx208->imx208_mx);
 589
 590	fmt->format.code = imx208_get_format_code(imx208);
 591	mode = v4l2_find_nearest_size(supported_modes,
 592				      ARRAY_SIZE(supported_modes), width, height,
 593				      fmt->format.width, fmt->format.height);
 594	imx208_mode_to_pad_format(imx208, mode, fmt);
 595	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
 596		*v4l2_subdev_state_get_format(sd_state, fmt->pad) = fmt->format;
 597	} else {
 598		imx208->cur_mode = mode;
 599		__v4l2_ctrl_s_ctrl(imx208->link_freq, mode->link_freq_index);
 600		link_freq = link_freq_menu_items[mode->link_freq_index];
 601		pixel_rate = link_freq_to_pixel_rate(link_freq);
 602		__v4l2_ctrl_s_ctrl_int64(imx208->pixel_rate, pixel_rate);
 603		/* Update limits and set FPS to default */
 604		vblank_def = imx208->cur_mode->vts_def -
 605			     imx208->cur_mode->height;
 606		vblank_min = imx208->cur_mode->vts_min -
 607			     imx208->cur_mode->height;
 608		__v4l2_ctrl_modify_range(imx208->vblank, vblank_min,
 609					 IMX208_VTS_MAX - imx208->cur_mode->height,
 610					 1, vblank_def);
 611		__v4l2_ctrl_s_ctrl(imx208->vblank, vblank_def);
 612		h_blank =
 613			link_freq_configs[mode->link_freq_index].pixels_per_line
 614			 - imx208->cur_mode->width;
 615		__v4l2_ctrl_modify_range(imx208->hblank, h_blank,
 616					 h_blank, 1, h_blank);
 617	}
 618
 619	mutex_unlock(&imx208->imx208_mx);
 620
 621	return 0;
 622}
 623
 624static int imx208_identify_module(struct imx208 *imx208)
 625{
 626	int ret;
 627	u32 val;
 628
 629	if (imx208->identified)
 630		return 0;
 631
 632	ret = imx208_read_reg(imx208, IMX208_REG_CHIP_ID,
 633			      2, &val);
 634	if (ret) {
 635		dev_err(imx208->dev, "failed to read chip id %x\n",
 636			IMX208_CHIP_ID);
 637		return ret;
 638	}
 639
 640	if (val != IMX208_CHIP_ID) {
 641		dev_err(imx208->dev, "chip id mismatch: %x!=%x\n",
 642			IMX208_CHIP_ID, val);
 643		return -EIO;
 644	}
 645
 646	imx208->identified = true;
 647
 648	return 0;
 649}
 650
 651/* Start streaming */
 652static int imx208_start_streaming(struct imx208 *imx208)
 653{
 654	const struct imx208_reg_list *reg_list;
 655	int ret, link_freq_index;
 656
 657	ret = imx208_identify_module(imx208);
 658	if (ret)
 659		return ret;
 660
 661	/* Setup PLL */
 662	link_freq_index = imx208->cur_mode->link_freq_index;
 663	reg_list = &link_freq_configs[link_freq_index].reg_list;
 664	ret = imx208_write_regs(imx208, reg_list->regs, reg_list->num_of_regs);
 665	if (ret) {
 666		dev_err(imx208->dev, "%s failed to set plls\n", __func__);
 667		return ret;
 668	}
 669
 670	/* Apply default values of current mode */
 671	reg_list = &imx208->cur_mode->reg_list;
 672	ret = imx208_write_regs(imx208, reg_list->regs, reg_list->num_of_regs);
 673	if (ret) {
 674		dev_err(imx208->dev, "%s failed to set mode\n", __func__);
 675		return ret;
 676	}
 677
 678	/* Apply customized values from user */
 679	ret =  __v4l2_ctrl_handler_setup(imx208->sd.ctrl_handler);
 680	if (ret)
 681		return ret;
 682
 683	/* set stream on register */
 684	return imx208_write_reg(imx208, IMX208_REG_MODE_SELECT,
 685				1, IMX208_MODE_STREAMING);
 686}
 687
 688/* Stop streaming */
 689static int imx208_stop_streaming(struct imx208 *imx208)
 690{
 691	int ret;
 692
 693	/* set stream off register */
 694	ret = imx208_write_reg(imx208, IMX208_REG_MODE_SELECT,
 695			       1, IMX208_MODE_STANDBY);
 696	if (ret)
 697		dev_err(imx208->dev, "%s failed to set stream\n", __func__);
 698
 699	/*
 700	 * Return success even if it was an error, as there is nothing the
 701	 * caller can do about it.
 702	 */
 703	return 0;
 704}
 705
 706static int imx208_set_stream(struct v4l2_subdev *sd, int enable)
 707{
 708	struct imx208 *imx208 = to_imx208(sd);
 709	int ret = 0;
 710
 711	mutex_lock(&imx208->imx208_mx);
 712
 713	if (enable) {
 714		ret = pm_runtime_resume_and_get(imx208->dev);
 715		if (ret) {
 716			mutex_unlock(&imx208->imx208_mx);
 717			return ret;
 718		}
 719
 720		/*
 721		 * Apply default & customized values
 722		 * and then start streaming.
 723		 */
 724		ret = imx208_start_streaming(imx208);
 725		if (ret)
 726			goto err_rpm_put;
 727	} else {
 728		imx208_stop_streaming(imx208);
 729		pm_runtime_put(imx208->dev);
 730	}
 731
 732	mutex_unlock(&imx208->imx208_mx);
 733
 734	/* vflip and hflip cannot change during streaming */
 735	v4l2_ctrl_grab(imx208->vflip, enable);
 736	v4l2_ctrl_grab(imx208->hflip, enable);
 737
 738	return ret;
 739
 740err_rpm_put:
 741	pm_runtime_put(imx208->dev);
 742	mutex_unlock(&imx208->imx208_mx);
 743
 744	return ret;
 745}
 746
 747/* Verify chip ID */
 748static const struct v4l2_subdev_video_ops imx208_video_ops = {
 749	.s_stream = imx208_set_stream,
 750};
 751
 752static const struct v4l2_subdev_pad_ops imx208_pad_ops = {
 753	.enum_mbus_code = imx208_enum_mbus_code,
 754	.get_fmt = imx208_get_pad_format,
 755	.set_fmt = imx208_set_pad_format,
 756	.enum_frame_size = imx208_enum_frame_size,
 757};
 758
 759static const struct v4l2_subdev_ops imx208_subdev_ops = {
 760	.video = &imx208_video_ops,
 761	.pad = &imx208_pad_ops,
 762};
 763
 764static const struct v4l2_subdev_internal_ops imx208_internal_ops = {
 765	.open = imx208_open,
 766};
 767
 768static int imx208_read_otp(struct imx208 *imx208)
 769{
 770	struct i2c_client *client = v4l2_get_subdevdata(&imx208->sd);
 771	struct i2c_msg msgs[2];
 772	u8 addr_buf[2] = { IMX208_OTP_BASE >> 8, IMX208_OTP_BASE & 0xff };
 773	int ret = 0;
 774
 775	mutex_lock(&imx208->imx208_mx);
 776
 777	if (imx208->otp_read)
 778		goto out_unlock;
 779
 780	ret = pm_runtime_resume_and_get(imx208->dev);
 781	if (ret)
 782		goto out_unlock;
 783
 784	ret = imx208_identify_module(imx208);
 785	if (ret)
 786		goto out_pm_put;
 787
 788	/* Write register address */
 789	msgs[0].addr = client->addr;
 790	msgs[0].flags = 0;
 791	msgs[0].len = ARRAY_SIZE(addr_buf);
 792	msgs[0].buf = addr_buf;
 793
 794	/* Read data from registers */
 795	msgs[1].addr = client->addr;
 796	msgs[1].flags = I2C_M_RD;
 797	msgs[1].len = sizeof(imx208->otp_data);
 798	msgs[1].buf = imx208->otp_data;
 799
 800	ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
 801	if (ret == ARRAY_SIZE(msgs)) {
 802		imx208->otp_read = true;
 803		ret = 0;
 804	}
 805
 806out_pm_put:
 807	pm_runtime_put(imx208->dev);
 808
 809out_unlock:
 810	mutex_unlock(&imx208->imx208_mx);
 811
 812	return ret;
 813}
 814
 815static ssize_t otp_read(struct file *filp, struct kobject *kobj,
 816			const struct bin_attribute *bin_attr,
 817			char *buf, loff_t off, size_t count)
 818{
 819	struct i2c_client *client = to_i2c_client(kobj_to_dev(kobj));
 820	struct v4l2_subdev *sd = i2c_get_clientdata(client);
 821	struct imx208 *imx208 = to_imx208(sd);
 822	int ret;
 823
 824	ret = imx208_read_otp(imx208);
 825	if (ret)
 826		return ret;
 827
 828	memcpy(buf, &imx208->otp_data[off], count);
 829	return count;
 830}
 831
 832static const BIN_ATTR_RO(otp, IMX208_OTP_SIZE);
 833
 834/* Initialize control handlers */
 835static int imx208_init_controls(struct imx208 *imx208)
 836{
 837	struct v4l2_ctrl_handler *ctrl_hdlr = &imx208->ctrl_handler;
 838	s64 exposure_max;
 839	s64 vblank_def;
 840	s64 vblank_min;
 841	s64 pixel_rate_min;
 842	s64 pixel_rate_max;
 843	int ret;
 844
 845	ret = v4l2_ctrl_handler_init(ctrl_hdlr, 8);
 846	if (ret)
 847		return ret;
 848
 849	mutex_init(&imx208->imx208_mx);
 850	ctrl_hdlr->lock = &imx208->imx208_mx;
 851	imx208->link_freq =
 852		v4l2_ctrl_new_int_menu(ctrl_hdlr,
 853				       &imx208_ctrl_ops,
 854				       V4L2_CID_LINK_FREQ,
 855				       ARRAY_SIZE(link_freq_menu_items) - 1,
 856				       0, link_freq_menu_items);
 857
 858	if (imx208->link_freq)
 859		imx208->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
 860
 861	pixel_rate_max = link_freq_to_pixel_rate(link_freq_menu_items[0]);
 862	pixel_rate_min =
 863		link_freq_to_pixel_rate(link_freq_menu_items[ARRAY_SIZE(link_freq_menu_items) - 1]);
 864	/* By default, PIXEL_RATE is read only */
 865	imx208->pixel_rate = v4l2_ctrl_new_std(ctrl_hdlr, &imx208_ctrl_ops,
 866					       V4L2_CID_PIXEL_RATE,
 867					       pixel_rate_min, pixel_rate_max,
 868					       1, pixel_rate_max);
 869
 870	vblank_def = imx208->cur_mode->vts_def - imx208->cur_mode->height;
 871	vblank_min = imx208->cur_mode->vts_min - imx208->cur_mode->height;
 872	imx208->vblank =
 873		v4l2_ctrl_new_std(ctrl_hdlr, &imx208_ctrl_ops, V4L2_CID_VBLANK,
 874				  vblank_min,
 875				  IMX208_VTS_MAX - imx208->cur_mode->height, 1,
 876				  vblank_def);
 877
 878	imx208->hblank =
 879		v4l2_ctrl_new_std(ctrl_hdlr, &imx208_ctrl_ops, V4L2_CID_HBLANK,
 880				  IMX208_PPL_384MHZ - imx208->cur_mode->width,
 881				  IMX208_PPL_384MHZ - imx208->cur_mode->width,
 882				  1,
 883				  IMX208_PPL_384MHZ - imx208->cur_mode->width);
 884
 885	if (imx208->hblank)
 886		imx208->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
 887
 888	exposure_max = imx208->cur_mode->vts_def - 8;
 889	v4l2_ctrl_new_std(ctrl_hdlr, &imx208_ctrl_ops, V4L2_CID_EXPOSURE,
 890			  IMX208_EXPOSURE_MIN, exposure_max,
 891			  IMX208_EXPOSURE_STEP, IMX208_EXPOSURE_DEFAULT);
 892
 893	imx208->hflip = v4l2_ctrl_new_std(ctrl_hdlr, &imx208_ctrl_ops,
 894					  V4L2_CID_HFLIP, 0, 1, 1, 0);
 895	if (imx208->hflip)
 896		imx208->hflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT;
 897	imx208->vflip = v4l2_ctrl_new_std(ctrl_hdlr, &imx208_ctrl_ops,
 898					  V4L2_CID_VFLIP, 0, 1, 1, 0);
 899	if (imx208->vflip)
 900		imx208->vflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT;
 901
 902	v4l2_ctrl_new_std(ctrl_hdlr, &imx208_ctrl_ops, V4L2_CID_ANALOGUE_GAIN,
 903			  IMX208_ANA_GAIN_MIN, IMX208_ANA_GAIN_MAX,
 904			  IMX208_ANA_GAIN_STEP, IMX208_ANA_GAIN_DEFAULT);
 905
 906	v4l2_ctrl_new_custom(ctrl_hdlr, &imx208_digital_gain_control, NULL);
 907
 908	v4l2_ctrl_new_std_menu_items(ctrl_hdlr, &imx208_ctrl_ops,
 909				     V4L2_CID_TEST_PATTERN,
 910				     ARRAY_SIZE(imx208_test_pattern_menu) - 1,
 911				     0, 0, imx208_test_pattern_menu);
 912
 913	if (ctrl_hdlr->error) {
 914		ret = ctrl_hdlr->error;
 915		dev_err(imx208->dev, "%s control init failed (%d)\n",
 916			__func__, ret);
 917		goto error;
 918	}
 919
 920	imx208->sd.ctrl_handler = ctrl_hdlr;
 921
 922	return 0;
 923
 924error:
 925	v4l2_ctrl_handler_free(ctrl_hdlr);
 926	mutex_destroy(&imx208->imx208_mx);
 927
 928	return ret;
 929}
 930
 931static void imx208_free_controls(struct imx208 *imx208)
 932{
 933	v4l2_ctrl_handler_free(imx208->sd.ctrl_handler);
 934}
 935
 936static int imx208_probe(struct i2c_client *client)
 937{
 938	struct imx208 *imx208;
 939	unsigned long freq;
 940	int ret;
 941	bool full_power;
 942
 943	imx208 = devm_kzalloc(&client->dev, sizeof(*imx208), GFP_KERNEL);
 944	if (!imx208)
 945		return -ENOMEM;
 946
 947	imx208->dev = &client->dev;
 948
 949	imx208->clk = devm_v4l2_sensor_clk_get(imx208->dev, NULL);
 950	if (IS_ERR(imx208->clk))
 951		return dev_err_probe(imx208->dev, PTR_ERR(imx208->clk),
 952				     "failed to get clock\n");
 953
 954	freq = clk_get_rate(imx208->clk);
 955	if (freq != 19200000)
 956		return dev_err_probe(imx208->dev, -EINVAL,
 957				     "external clock %lu is not supported\n",
 958				     freq);
 959
 960	/* Initialize subdev */
 961	v4l2_i2c_subdev_init(&imx208->sd, client, &imx208_subdev_ops);
 962
 963	full_power = acpi_dev_state_d0(imx208->dev);
 964	if (full_power) {
 965		/* Check module identity */
 966		ret = imx208_identify_module(imx208);
 967		if (ret) {
 968			dev_err(imx208->dev, "failed to find sensor: %d", ret);
 969			goto error_probe;
 970		}
 971	}
 972
 973	/* Set default mode to max resolution */
 974	imx208->cur_mode = &supported_modes[0];
 975
 976	ret = imx208_init_controls(imx208);
 977	if (ret) {
 978		dev_err(imx208->dev, "failed to init controls: %d", ret);
 979		goto error_probe;
 980	}
 981
 982	/* Initialize subdev */
 983	imx208->sd.internal_ops = &imx208_internal_ops;
 984	imx208->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
 985	imx208->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
 986
 987	/* Initialize source pad */
 988	imx208->pad.flags = MEDIA_PAD_FL_SOURCE;
 989	ret = media_entity_pads_init(&imx208->sd.entity, 1, &imx208->pad);
 990	if (ret) {
 991		dev_err(imx208->dev, "%s failed:%d\n", __func__, ret);
 992		goto error_handler_free;
 993	}
 994
 995	ret = v4l2_async_register_subdev_sensor(&imx208->sd);
 996	if (ret < 0)
 997		goto error_media_entity;
 998
 999	ret = device_create_bin_file(imx208->dev, &bin_attr_otp);
1000	if (ret) {
1001		dev_err(imx208->dev, "sysfs otp creation failed\n");
1002		goto error_async_subdev;
1003	}
1004
1005	/* Set the device's state to active if it's in D0 state. */
1006	if (full_power)
1007		pm_runtime_set_active(imx208->dev);
1008	pm_runtime_enable(imx208->dev);
1009	pm_runtime_idle(imx208->dev);
1010
1011	return 0;
1012
1013error_async_subdev:
1014	v4l2_async_unregister_subdev(&imx208->sd);
1015
1016error_media_entity:
1017	media_entity_cleanup(&imx208->sd.entity);
1018
1019error_handler_free:
1020	imx208_free_controls(imx208);
1021
1022error_probe:
1023	mutex_destroy(&imx208->imx208_mx);
1024
1025	return ret;
1026}
1027
1028static void imx208_remove(struct i2c_client *client)
1029{
1030	struct v4l2_subdev *sd = i2c_get_clientdata(client);
1031	struct imx208 *imx208 = to_imx208(sd);
1032
1033	device_remove_bin_file(imx208->dev, &bin_attr_otp);
1034	v4l2_async_unregister_subdev(sd);
1035	media_entity_cleanup(&sd->entity);
1036	imx208_free_controls(imx208);
1037
1038	pm_runtime_disable(imx208->dev);
1039	pm_runtime_set_suspended(imx208->dev);
1040
1041	mutex_destroy(&imx208->imx208_mx);
1042}
1043
1044#ifdef CONFIG_ACPI
1045static const struct acpi_device_id imx208_acpi_ids[] = {
1046	{ "INT3478" },
1047	{ /* sentinel */ }
1048};
1049
1050MODULE_DEVICE_TABLE(acpi, imx208_acpi_ids);
1051#endif
1052
1053static struct i2c_driver imx208_i2c_driver = {
1054	.driver = {
1055		.name = "imx208",
1056		.acpi_match_table = ACPI_PTR(imx208_acpi_ids),
1057	},
1058	.probe = imx208_probe,
1059	.remove = imx208_remove,
1060	.flags = I2C_DRV_ACPI_WAIVE_D0_PROBE,
1061};
1062
1063module_i2c_driver(imx208_i2c_driver);
1064
1065MODULE_AUTHOR("Yeh, Andy <andy.yeh@intel.com>");
1066MODULE_AUTHOR("Chen, Ping-chung <ping-chung.chen@intel.com>");
1067MODULE_AUTHOR("Shawn Tu");
1068MODULE_DESCRIPTION("Sony IMX208 sensor driver");
1069MODULE_LICENSE("GPL v2");
~/ Read-only file preview.