File Index
Files and directories
Sign in
FILE

ov01a10.c

File preview with syntax highlighting.

linux-6.19.14/drivers/media/i2c/ov01a10.c C
  1// SPDX-License-Identifier: GPL-2.0-only
  2/*
  3 * Copyright (c) 2023 Intel Corporation.
  4 */
  5
  6#include <linux/unaligned.h>
  7
  8#include <linux/acpi.h>
  9#include <linux/bitfield.h>
 10#include <linux/i2c.h>
 11#include <linux/module.h>
 12#include <linux/pm_runtime.h>
 13
 14#include <media/v4l2-ctrls.h>
 15#include <media/v4l2-device.h>
 16#include <media/v4l2-fwnode.h>
 17
 18#define OV01A10_LINK_FREQ_400MHZ	400000000ULL
 19#define OV01A10_SCLK			80000000LL
 20#define OV01A10_DATA_LANES		1
 21
 22#define OV01A10_REG_CHIP_ID		0x300a
 23#define OV01A10_CHIP_ID			0x560141
 24
 25#define OV01A10_REG_MODE_SELECT		0x0100
 26#define OV01A10_MODE_STANDBY		0x00
 27#define OV01A10_MODE_STREAMING		0x01
 28
 29/* pixel array */
 30#define OV01A10_PIXEL_ARRAY_WIDTH	1296
 31#define OV01A10_PIXEL_ARRAY_HEIGHT	816
 32#define OV01A10_ACITVE_WIDTH		1280
 33#define OV01A10_ACITVE_HEIGHT		800
 34
 35/* vertical and horizontal timings */
 36#define OV01A10_REG_VTS			0x380e
 37#define OV01A10_VTS_DEF			0x0380
 38#define OV01A10_VTS_MIN			0x0380
 39#define OV01A10_VTS_MAX			0xffff
 40#define OV01A10_HTS_DEF			1488
 41
 42/* exposure controls */
 43#define OV01A10_REG_EXPOSURE		0x3501
 44#define OV01A10_EXPOSURE_MIN		4
 45#define OV01A10_EXPOSURE_MAX_MARGIN	8
 46#define OV01A10_EXPOSURE_STEP		1
 47
 48/* analog gain controls */
 49#define OV01A10_REG_ANALOG_GAIN		0x3508
 50#define OV01A10_ANAL_GAIN_MIN		0x100
 51#define OV01A10_ANAL_GAIN_MAX		0x3fff
 52#define OV01A10_ANAL_GAIN_STEP		1
 53
 54/* digital gain controls */
 55#define OV01A10_REG_DIGITAL_GAIN_B	0x350a
 56#define OV01A10_REG_DIGITAL_GAIN_GB	0x3510
 57#define OV01A10_REG_DIGITAL_GAIN_GR	0x3513
 58#define OV01A10_REG_DIGITAL_GAIN_R	0x3516
 59#define OV01A10_DGTL_GAIN_MIN		0
 60#define OV01A10_DGTL_GAIN_MAX		0x3fff
 61#define OV01A10_DGTL_GAIN_STEP		1
 62#define OV01A10_DGTL_GAIN_DEFAULT	1024
 63
 64/* test pattern control */
 65#define OV01A10_REG_TEST_PATTERN	0x4503
 66#define OV01A10_TEST_PATTERN_ENABLE	BIT(7)
 67#define OV01A10_LINK_FREQ_400MHZ_INDEX	0
 68
 69/* flip and mirror control */
 70#define OV01A10_REG_FORMAT1		0x3820
 71#define OV01A10_VFLIP_MASK		BIT(4)
 72#define OV01A10_HFLIP_MASK		BIT(3)
 73
 74/* window offset */
 75#define OV01A10_REG_X_WIN		0x3811
 76#define OV01A10_REG_Y_WIN		0x3813
 77
 78/*
 79 * The native ov01a10 bayer-pattern is GBRG, but there was a driver bug enabling
 80 * hflip/mirroring by default resulting in BGGR. Because of this bug Intel's
 81 * proprietary IPU6 userspace stack expects BGGR. So we report BGGR to not break
 82 * userspace and fix things up by shifting the crop window-x coordinate by 1
 83 * when hflip is *disabled*.
 84 */
 85#define OV01A10_MEDIA_BUS_FMT		MEDIA_BUS_FMT_SBGGR10_1X10
 86
 87struct ov01a10_reg {
 88	u16 address;
 89	u8 val;
 90};
 91
 92struct ov01a10_reg_list {
 93	u32 num_of_regs;
 94	const struct ov01a10_reg *regs;
 95};
 96
 97struct ov01a10_link_freq_config {
 98	const struct ov01a10_reg_list reg_list;
 99};
100
101struct ov01a10_mode {
102	u32 width;
103	u32 height;
104	u32 hts;
105	u32 vts_def;
106	u32 vts_min;
107	u32 link_freq_index;
108
109	const struct ov01a10_reg_list reg_list;
110};
111
112static const struct ov01a10_reg mipi_data_rate_720mbps[] = {
113	{0x0103, 0x01},
114	{0x0302, 0x00},
115	{0x0303, 0x06},
116	{0x0304, 0x01},
117	{0x0305, 0xe0},
118	{0x0306, 0x00},
119	{0x0308, 0x01},
120	{0x0309, 0x00},
121	{0x030c, 0x01},
122	{0x0322, 0x01},
123	{0x0323, 0x06},
124	{0x0324, 0x01},
125	{0x0325, 0x68},
126};
127
128static const struct ov01a10_reg sensor_1280x800_setting[] = {
129	{0x3002, 0xa1},
130	{0x301e, 0xf0},
131	{0x3022, 0x01},
132	{0x3501, 0x03},
133	{0x3502, 0x78},
134	{0x3504, 0x0c},
135	{0x3508, 0x01},
136	{0x3509, 0x00},
137	{0x3601, 0xc0},
138	{0x3603, 0x71},
139	{0x3610, 0x68},
140	{0x3611, 0x86},
141	{0x3640, 0x10},
142	{0x3641, 0x80},
143	{0x3642, 0xdc},
144	{0x3646, 0x55},
145	{0x3647, 0x57},
146	{0x364b, 0x00},
147	{0x3653, 0x10},
148	{0x3655, 0x00},
149	{0x3656, 0x00},
150	{0x365f, 0x0f},
151	{0x3661, 0x45},
152	{0x3662, 0x24},
153	{0x3663, 0x11},
154	{0x3664, 0x07},
155	{0x3709, 0x34},
156	{0x370b, 0x6f},
157	{0x3714, 0x22},
158	{0x371b, 0x27},
159	{0x371c, 0x67},
160	{0x371d, 0xa7},
161	{0x371e, 0xe7},
162	{0x3730, 0x81},
163	{0x3733, 0x10},
164	{0x3734, 0x40},
165	{0x3737, 0x04},
166	{0x3739, 0x1c},
167	{0x3767, 0x00},
168	{0x376c, 0x81},
169	{0x3772, 0x14},
170	{0x37c2, 0x04},
171	{0x37d8, 0x03},
172	{0x37d9, 0x0c},
173	{0x37e0, 0x00},
174	{0x37e1, 0x08},
175	{0x37e2, 0x10},
176	{0x37e3, 0x04},
177	{0x37e4, 0x04},
178	{0x37e5, 0x03},
179	{0x37e6, 0x04},
180	{0x3800, 0x00},
181	{0x3801, 0x00},
182	{0x3802, 0x00},
183	{0x3803, 0x00},
184	{0x3804, 0x05},
185	{0x3805, 0x0f},
186	{0x3806, 0x03},
187	{0x3807, 0x2f},
188	{0x3808, 0x05},
189	{0x3809, 0x00},
190	{0x380a, 0x03},
191	{0x380b, 0x20},
192	{0x380c, 0x02},
193	{0x380d, 0xe8},
194	{0x380e, 0x03},
195	{0x380f, 0x80},
196	{0x3810, 0x00},
197	{0x3811, 0x09},
198	{0x3812, 0x00},
199	{0x3813, 0x08},
200	{0x3814, 0x01},
201	{0x3815, 0x01},
202	{0x3816, 0x01},
203	{0x3817, 0x01},
204	{0x3820, 0xa8},
205	{0x3822, 0x13},
206	{0x3832, 0x28},
207	{0x3833, 0x10},
208	{0x3b00, 0x00},
209	{0x3c80, 0x00},
210	{0x3c88, 0x02},
211	{0x3c8c, 0x07},
212	{0x3c8d, 0x40},
213	{0x3cc7, 0x80},
214	{0x4000, 0xc3},
215	{0x4001, 0xe0},
216	{0x4003, 0x40},
217	{0x4008, 0x02},
218	{0x4009, 0x19},
219	{0x400a, 0x01},
220	{0x400b, 0x6c},
221	{0x4011, 0x00},
222	{0x4041, 0x00},
223	{0x4300, 0xff},
224	{0x4301, 0x00},
225	{0x4302, 0x0f},
226	{0x4503, 0x00},
227	{0x4601, 0x50},
228	{0x4800, 0x64},
229	{0x481f, 0x34},
230	{0x4825, 0x33},
231	{0x4837, 0x11},
232	{0x4881, 0x40},
233	{0x4883, 0x01},
234	{0x4890, 0x00},
235	{0x4901, 0x00},
236	{0x4902, 0x00},
237	{0x4b00, 0x2a},
238	{0x4b0d, 0x00},
239	{0x450a, 0x04},
240	{0x450b, 0x00},
241	{0x5000, 0x65},
242	{0x5200, 0x18},
243	{0x5004, 0x00},
244	{0x5080, 0x40},
245	{0x0305, 0xf4},
246	{0x0325, 0xc2},
247};
248
249static const char * const ov01a10_test_pattern_menu[] = {
250	"Disabled",
251	"Color Bar",
252	"Left-Right Darker Color Bar",
253	"Bottom-Top Darker Color Bar",
254};
255
256static const s64 link_freq_menu_items[] = {
257	OV01A10_LINK_FREQ_400MHZ,
258};
259
260static const struct ov01a10_link_freq_config link_freq_configs[] = {
261	[OV01A10_LINK_FREQ_400MHZ_INDEX] = {
262		.reg_list = {
263			.num_of_regs = ARRAY_SIZE(mipi_data_rate_720mbps),
264			.regs = mipi_data_rate_720mbps,
265		}
266	},
267};
268
269static const struct ov01a10_mode supported_modes[] = {
270	{
271		.width = OV01A10_ACITVE_WIDTH,
272		.height = OV01A10_ACITVE_HEIGHT,
273		.hts = OV01A10_HTS_DEF,
274		.vts_def = OV01A10_VTS_DEF,
275		.vts_min = OV01A10_VTS_MIN,
276		.reg_list = {
277			.num_of_regs = ARRAY_SIZE(sensor_1280x800_setting),
278			.regs = sensor_1280x800_setting,
279		},
280		.link_freq_index = OV01A10_LINK_FREQ_400MHZ_INDEX,
281	},
282};
283
284struct ov01a10 {
285	struct v4l2_subdev sd;
286	struct media_pad pad;
287	struct v4l2_ctrl_handler ctrl_handler;
288
289	/* v4l2 controls */
290	struct v4l2_ctrl *link_freq;
291	struct v4l2_ctrl *pixel_rate;
292	struct v4l2_ctrl *vblank;
293	struct v4l2_ctrl *hblank;
294	struct v4l2_ctrl *exposure;
295
296	const struct ov01a10_mode *cur_mode;
297};
298
299static inline struct ov01a10 *to_ov01a10(struct v4l2_subdev *subdev)
300{
301	return container_of(subdev, struct ov01a10, sd);
302}
303
304static int ov01a10_read_reg(struct ov01a10 *ov01a10, u16 reg, u16 len, u32 *val)
305{
306	struct i2c_client *client = v4l2_get_subdevdata(&ov01a10->sd);
307	struct i2c_msg msgs[2];
308	u8 addr_buf[2];
309	u8 data_buf[4] = {0};
310	int ret = 0;
311
312	if (len > sizeof(data_buf))
313		return -EINVAL;
314
315	put_unaligned_be16(reg, addr_buf);
316	msgs[0].addr = client->addr;
317	msgs[0].flags = 0;
318	msgs[0].len = sizeof(addr_buf);
319	msgs[0].buf = addr_buf;
320	msgs[1].addr = client->addr;
321	msgs[1].flags = I2C_M_RD;
322	msgs[1].len = len;
323	msgs[1].buf = &data_buf[sizeof(data_buf) - len];
324
325	ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
326
327	if (ret != ARRAY_SIZE(msgs))
328		return ret < 0 ? ret : -EIO;
329
330	*val = get_unaligned_be32(data_buf);
331
332	return 0;
333}
334
335static int ov01a10_write_reg(struct ov01a10 *ov01a10, u16 reg, u16 len, u32 val)
336{
337	struct i2c_client *client = v4l2_get_subdevdata(&ov01a10->sd);
338	u8 buf[6];
339	int ret = 0;
340
341	if (len > 4)
342		return -EINVAL;
343
344	put_unaligned_be16(reg, buf);
345	put_unaligned_be32(val << 8 * (4 - len), buf + 2);
346
347	ret = i2c_master_send(client, buf, len + 2);
348	if (ret != len + 2)
349		return ret < 0 ? ret : -EIO;
350
351	return 0;
352}
353
354static int ov01a10_write_reg_list(struct ov01a10 *ov01a10,
355				  const struct ov01a10_reg_list *r_list)
356{
357	struct i2c_client *client = v4l2_get_subdevdata(&ov01a10->sd);
358	unsigned int i;
359	int ret = 0;
360
361	for (i = 0; i < r_list->num_of_regs; i++) {
362		ret = ov01a10_write_reg(ov01a10, r_list->regs[i].address, 1,
363					r_list->regs[i].val);
364		if (ret) {
365			dev_err_ratelimited(&client->dev,
366					    "write reg 0x%4.4x err = %d\n",
367					    r_list->regs[i].address, ret);
368			return ret;
369		}
370	}
371
372	return 0;
373}
374
375static int ov01a10_update_digital_gain(struct ov01a10 *ov01a10, u32 d_gain)
376{
377	struct i2c_client *client = v4l2_get_subdevdata(&ov01a10->sd);
378	u32 real = d_gain << 6;
379	int ret = 0;
380
381	ret = ov01a10_write_reg(ov01a10, OV01A10_REG_DIGITAL_GAIN_B, 3, real);
382	if (ret) {
383		dev_err(&client->dev, "failed to set DIGITAL_GAIN_B\n");
384		return ret;
385	}
386
387	ret = ov01a10_write_reg(ov01a10, OV01A10_REG_DIGITAL_GAIN_GB, 3, real);
388	if (ret) {
389		dev_err(&client->dev, "failed to set DIGITAL_GAIN_GB\n");
390		return ret;
391	}
392
393	ret = ov01a10_write_reg(ov01a10, OV01A10_REG_DIGITAL_GAIN_GR, 3, real);
394	if (ret) {
395		dev_err(&client->dev, "failed to set DIGITAL_GAIN_GR\n");
396		return ret;
397	}
398
399	ret = ov01a10_write_reg(ov01a10, OV01A10_REG_DIGITAL_GAIN_R, 3, real);
400	if (ret)
401		dev_err(&client->dev, "failed to set DIGITAL_GAIN_R\n");
402
403	return ret;
404}
405
406static int ov01a10_test_pattern(struct ov01a10 *ov01a10, u32 pattern)
407{
408	if (pattern)
409		pattern |= OV01A10_TEST_PATTERN_ENABLE;
410
411	return ov01a10_write_reg(ov01a10, OV01A10_REG_TEST_PATTERN, 1, pattern);
412}
413
414/* for vflip and hflip, use 0x9 as window offset to keep the bayer */
415static int ov01a10_set_hflip(struct ov01a10 *ov01a10, u32 hflip)
416{
417	int ret;
418	u32 val, offset;
419
420	offset = hflip ? 0x8 : 0x9;
421	ret = ov01a10_write_reg(ov01a10, OV01A10_REG_X_WIN, 1, offset);
422	if (ret)
423		return ret;
424
425	ret = ov01a10_read_reg(ov01a10, OV01A10_REG_FORMAT1, 1, &val);
426	if (ret)
427		return ret;
428
429	val = hflip ? val & ~OV01A10_HFLIP_MASK :
430		      val | FIELD_PREP(OV01A10_HFLIP_MASK, 0x1);
431
432	return ov01a10_write_reg(ov01a10, OV01A10_REG_FORMAT1, 1, val);
433}
434
435static int ov01a10_set_vflip(struct ov01a10 *ov01a10, u32 vflip)
436{
437	int ret;
438	u32 val, offset;
439
440	offset = vflip ? 0x9 : 0x8;
441	ret = ov01a10_write_reg(ov01a10, OV01A10_REG_Y_WIN, 1, offset);
442	if (ret)
443		return ret;
444
445	ret = ov01a10_read_reg(ov01a10, OV01A10_REG_FORMAT1, 1, &val);
446	if (ret)
447		return ret;
448
449	val = vflip ? val | FIELD_PREP(OV01A10_VFLIP_MASK, 0x1) :
450		val & ~OV01A10_VFLIP_MASK;
451
452	return ov01a10_write_reg(ov01a10, OV01A10_REG_FORMAT1, 1, val);
453}
454
455static int ov01a10_set_ctrl(struct v4l2_ctrl *ctrl)
456{
457	struct ov01a10 *ov01a10 = container_of(ctrl->handler,
458					       struct ov01a10, ctrl_handler);
459	struct i2c_client *client = v4l2_get_subdevdata(&ov01a10->sd);
460	s64 exposure_max;
461	int ret = 0;
462
463	if (ctrl->id == V4L2_CID_VBLANK) {
464		exposure_max = ov01a10->cur_mode->height + ctrl->val -
465			OV01A10_EXPOSURE_MAX_MARGIN;
466		__v4l2_ctrl_modify_range(ov01a10->exposure,
467					 ov01a10->exposure->minimum,
468					 exposure_max, ov01a10->exposure->step,
469					 exposure_max);
470	}
471
472	if (!pm_runtime_get_if_in_use(&client->dev))
473		return 0;
474
475	switch (ctrl->id) {
476	case V4L2_CID_ANALOGUE_GAIN:
477		ret = ov01a10_write_reg(ov01a10, OV01A10_REG_ANALOG_GAIN, 2,
478					ctrl->val);
479		break;
480
481	case V4L2_CID_DIGITAL_GAIN:
482		ret = ov01a10_update_digital_gain(ov01a10, ctrl->val);
483		break;
484
485	case V4L2_CID_EXPOSURE:
486		ret = ov01a10_write_reg(ov01a10, OV01A10_REG_EXPOSURE, 2,
487					ctrl->val);
488		break;
489
490	case V4L2_CID_VBLANK:
491		ret = ov01a10_write_reg(ov01a10, OV01A10_REG_VTS, 2,
492					ov01a10->cur_mode->height + ctrl->val);
493		break;
494
495	case V4L2_CID_TEST_PATTERN:
496		ret = ov01a10_test_pattern(ov01a10, ctrl->val);
497		break;
498
499	case V4L2_CID_HFLIP:
500		ov01a10_set_hflip(ov01a10, ctrl->val);
501		break;
502
503	case V4L2_CID_VFLIP:
504		ov01a10_set_vflip(ov01a10, ctrl->val);
505		break;
506
507	default:
508		ret = -EINVAL;
509		break;
510	}
511
512	pm_runtime_put(&client->dev);
513
514	return ret;
515}
516
517static const struct v4l2_ctrl_ops ov01a10_ctrl_ops = {
518	.s_ctrl = ov01a10_set_ctrl,
519};
520
521static int ov01a10_init_controls(struct ov01a10 *ov01a10)
522{
523	struct i2c_client *client = v4l2_get_subdevdata(&ov01a10->sd);
524	struct v4l2_fwnode_device_properties props;
525	u32 vblank_min, vblank_max, vblank_default;
526	struct v4l2_ctrl_handler *ctrl_hdlr;
527	const struct ov01a10_mode *cur_mode;
528	s64 exposure_max, h_blank;
529	int ret = 0;
530	int size;
531
532	ret = v4l2_fwnode_device_parse(&client->dev, &props);
533	if (ret)
534		return ret;
535
536	ctrl_hdlr = &ov01a10->ctrl_handler;
537	ret = v4l2_ctrl_handler_init(ctrl_hdlr, 12);
538	if (ret)
539		return ret;
540
541	cur_mode = ov01a10->cur_mode;
542	size = ARRAY_SIZE(link_freq_menu_items);
543
544	ov01a10->link_freq = v4l2_ctrl_new_int_menu(ctrl_hdlr,
545						    &ov01a10_ctrl_ops,
546						    V4L2_CID_LINK_FREQ,
547						    size - 1, 0,
548						    link_freq_menu_items);
549	if (ov01a10->link_freq)
550		ov01a10->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
551
552	ov01a10->pixel_rate = v4l2_ctrl_new_std(ctrl_hdlr, &ov01a10_ctrl_ops,
553						V4L2_CID_PIXEL_RATE, 0,
554						OV01A10_SCLK, 1, OV01A10_SCLK);
555
556	vblank_min = cur_mode->vts_min - cur_mode->height;
557	vblank_max = OV01A10_VTS_MAX - cur_mode->height;
558	vblank_default = cur_mode->vts_def - cur_mode->height;
559	ov01a10->vblank = v4l2_ctrl_new_std(ctrl_hdlr, &ov01a10_ctrl_ops,
560					    V4L2_CID_VBLANK, vblank_min,
561					    vblank_max, 1, vblank_default);
562
563	h_blank = cur_mode->hts - cur_mode->width;
564	ov01a10->hblank = v4l2_ctrl_new_std(ctrl_hdlr, &ov01a10_ctrl_ops,
565					    V4L2_CID_HBLANK, h_blank, h_blank,
566					    1, h_blank);
567	if (ov01a10->hblank)
568		ov01a10->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
569
570	v4l2_ctrl_new_std(ctrl_hdlr, &ov01a10_ctrl_ops, V4L2_CID_ANALOGUE_GAIN,
571			  OV01A10_ANAL_GAIN_MIN, OV01A10_ANAL_GAIN_MAX,
572			  OV01A10_ANAL_GAIN_STEP, OV01A10_ANAL_GAIN_MIN);
573	v4l2_ctrl_new_std(ctrl_hdlr, &ov01a10_ctrl_ops, V4L2_CID_DIGITAL_GAIN,
574			  OV01A10_DGTL_GAIN_MIN, OV01A10_DGTL_GAIN_MAX,
575			  OV01A10_DGTL_GAIN_STEP, OV01A10_DGTL_GAIN_DEFAULT);
576
577	exposure_max = cur_mode->vts_def - OV01A10_EXPOSURE_MAX_MARGIN;
578	ov01a10->exposure = v4l2_ctrl_new_std(ctrl_hdlr, &ov01a10_ctrl_ops,
579					      V4L2_CID_EXPOSURE,
580					      OV01A10_EXPOSURE_MIN,
581					      exposure_max,
582					      OV01A10_EXPOSURE_STEP,
583					      exposure_max);
584
585	v4l2_ctrl_new_std_menu_items(ctrl_hdlr, &ov01a10_ctrl_ops,
586				     V4L2_CID_TEST_PATTERN,
587				     ARRAY_SIZE(ov01a10_test_pattern_menu) - 1,
588				     0, 0, ov01a10_test_pattern_menu);
589
590	v4l2_ctrl_new_std(ctrl_hdlr, &ov01a10_ctrl_ops, V4L2_CID_HFLIP,
591			  0, 1, 1, 0);
592	v4l2_ctrl_new_std(ctrl_hdlr, &ov01a10_ctrl_ops, V4L2_CID_VFLIP,
593			  0, 1, 1, 0);
594
595	ret = v4l2_ctrl_new_fwnode_properties(ctrl_hdlr, &ov01a10_ctrl_ops,
596					      &props);
597	if (ret)
598		goto fail;
599
600	if (ctrl_hdlr->error) {
601		ret = ctrl_hdlr->error;
602		goto fail;
603	}
604
605	ov01a10->sd.ctrl_handler = ctrl_hdlr;
606
607	return 0;
608fail:
609	v4l2_ctrl_handler_free(ctrl_hdlr);
610
611	return ret;
612}
613
614static void ov01a10_update_pad_format(const struct ov01a10_mode *mode,
615				      struct v4l2_mbus_framefmt *fmt)
616{
617	fmt->width = mode->width;
618	fmt->height = mode->height;
619	fmt->code = OV01A10_MEDIA_BUS_FMT;
620	fmt->field = V4L2_FIELD_NONE;
621	fmt->colorspace = V4L2_COLORSPACE_RAW;
622}
623
624static int ov01a10_start_streaming(struct ov01a10 *ov01a10)
625{
626	struct i2c_client *client = v4l2_get_subdevdata(&ov01a10->sd);
627	const struct ov01a10_reg_list *reg_list;
628	int link_freq_index;
629	int ret = 0;
630
631	link_freq_index = ov01a10->cur_mode->link_freq_index;
632	reg_list = &link_freq_configs[link_freq_index].reg_list;
633	ret = ov01a10_write_reg_list(ov01a10, reg_list);
634	if (ret) {
635		dev_err(&client->dev, "failed to set plls\n");
636		return ret;
637	}
638
639	reg_list = &ov01a10->cur_mode->reg_list;
640	ret = ov01a10_write_reg_list(ov01a10, reg_list);
641	if (ret) {
642		dev_err(&client->dev, "failed to set mode\n");
643		return ret;
644	}
645
646	ret = __v4l2_ctrl_handler_setup(ov01a10->sd.ctrl_handler);
647	if (ret)
648		return ret;
649
650	ret = ov01a10_write_reg(ov01a10, OV01A10_REG_MODE_SELECT, 1,
651				OV01A10_MODE_STREAMING);
652	if (ret)
653		dev_err(&client->dev, "failed to start streaming\n");
654
655	return ret;
656}
657
658static void ov01a10_stop_streaming(struct ov01a10 *ov01a10)
659{
660	struct i2c_client *client = v4l2_get_subdevdata(&ov01a10->sd);
661	int ret = 0;
662
663	ret = ov01a10_write_reg(ov01a10, OV01A10_REG_MODE_SELECT, 1,
664				OV01A10_MODE_STANDBY);
665	if (ret)
666		dev_err(&client->dev, "failed to stop streaming\n");
667}
668
669static int ov01a10_set_stream(struct v4l2_subdev *sd, int enable)
670{
671	struct ov01a10 *ov01a10 = to_ov01a10(sd);
672	struct i2c_client *client = v4l2_get_subdevdata(sd);
673	struct v4l2_subdev_state *state;
674	int ret = 0;
675
676	state = v4l2_subdev_lock_and_get_active_state(sd);
677
678	if (enable) {
679		ret = pm_runtime_resume_and_get(&client->dev);
680		if (ret < 0)
681			goto unlock;
682
683		ret = ov01a10_start_streaming(ov01a10);
684		if (ret) {
685			pm_runtime_put(&client->dev);
686			goto unlock;
687		}
688	} else {
689		ov01a10_stop_streaming(ov01a10);
690		pm_runtime_put(&client->dev);
691	}
692
693unlock:
694	v4l2_subdev_unlock_state(state);
695
696	return ret;
697}
698
699static int ov01a10_set_format(struct v4l2_subdev *sd,
700			      struct v4l2_subdev_state *sd_state,
701			      struct v4l2_subdev_format *fmt)
702{
703	struct ov01a10 *ov01a10 = to_ov01a10(sd);
704	const struct ov01a10_mode *mode;
705	struct v4l2_mbus_framefmt *format;
706	s32 vblank_def, h_blank;
707
708	mode = v4l2_find_nearest_size(supported_modes,
709				      ARRAY_SIZE(supported_modes), width,
710				      height, fmt->format.width,
711				      fmt->format.height);
712
713	ov01a10_update_pad_format(mode, &fmt->format);
714
715	if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
716		ov01a10->cur_mode = mode;
717		__v4l2_ctrl_s_ctrl(ov01a10->link_freq, mode->link_freq_index);
718		__v4l2_ctrl_s_ctrl_int64(ov01a10->pixel_rate, OV01A10_SCLK);
719
720		vblank_def = mode->vts_def - mode->height;
721		__v4l2_ctrl_modify_range(ov01a10->vblank,
722					 mode->vts_min - mode->height,
723					 OV01A10_VTS_MAX - mode->height, 1,
724					 vblank_def);
725		__v4l2_ctrl_s_ctrl(ov01a10->vblank, vblank_def);
726		h_blank = mode->hts - mode->width;
727		__v4l2_ctrl_modify_range(ov01a10->hblank, h_blank, h_blank, 1,
728					 h_blank);
729	}
730
731	format = v4l2_subdev_state_get_format(sd_state, fmt->pad);
732	*format = fmt->format;
733
734	return 0;
735}
736
737static int ov01a10_init_state(struct v4l2_subdev *sd,
738			      struct v4l2_subdev_state *state)
739{
740	struct v4l2_subdev_format fmt = {
741		.which = V4L2_SUBDEV_FORMAT_TRY,
742		.format = {
743			.width = OV01A10_ACITVE_WIDTH,
744			.height = OV01A10_ACITVE_HEIGHT,
745		},
746	};
747
748	ov01a10_set_format(sd, state, &fmt);
749
750	return 0;
751}
752
753static int ov01a10_enum_mbus_code(struct v4l2_subdev *sd,
754				  struct v4l2_subdev_state *sd_state,
755				  struct v4l2_subdev_mbus_code_enum *code)
756{
757	if (code->index > 0)
758		return -EINVAL;
759
760	code->code = OV01A10_MEDIA_BUS_FMT;
761
762	return 0;
763}
764
765static int ov01a10_enum_frame_size(struct v4l2_subdev *sd,
766				   struct v4l2_subdev_state *sd_state,
767				   struct v4l2_subdev_frame_size_enum *fse)
768{
769	if (fse->index >= ARRAY_SIZE(supported_modes) ||
770	    fse->code != OV01A10_MEDIA_BUS_FMT)
771		return -EINVAL;
772
773	fse->min_width = supported_modes[fse->index].width;
774	fse->max_width = fse->min_width;
775	fse->min_height = supported_modes[fse->index].height;
776	fse->max_height = fse->min_height;
777
778	return 0;
779}
780
781static int ov01a10_get_selection(struct v4l2_subdev *sd,
782				 struct v4l2_subdev_state *state,
783				 struct v4l2_subdev_selection *sel)
784{
785	if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
786		return -EINVAL;
787
788	switch (sel->target) {
789	case V4L2_SEL_TGT_NATIVE_SIZE:
790	case V4L2_SEL_TGT_CROP_BOUNDS:
791		sel->r.top = 0;
792		sel->r.left = 0;
793		sel->r.width = OV01A10_PIXEL_ARRAY_WIDTH;
794		sel->r.height = OV01A10_PIXEL_ARRAY_HEIGHT;
795		return 0;
796	case V4L2_SEL_TGT_CROP:
797	case V4L2_SEL_TGT_CROP_DEFAULT:
798		sel->r.top = (OV01A10_PIXEL_ARRAY_HEIGHT -
799			      OV01A10_ACITVE_HEIGHT) / 2;
800		sel->r.left = (OV01A10_PIXEL_ARRAY_WIDTH -
801			       OV01A10_ACITVE_WIDTH) / 2;
802		sel->r.width = OV01A10_ACITVE_WIDTH;
803		sel->r.height = OV01A10_ACITVE_HEIGHT;
804		return 0;
805	}
806
807	return -EINVAL;
808}
809
810static const struct v4l2_subdev_core_ops ov01a10_core_ops = {
811	.log_status = v4l2_ctrl_subdev_log_status,
812};
813
814static const struct v4l2_subdev_video_ops ov01a10_video_ops = {
815	.s_stream = ov01a10_set_stream,
816};
817
818static const struct v4l2_subdev_pad_ops ov01a10_pad_ops = {
819	.set_fmt = ov01a10_set_format,
820	.get_fmt = v4l2_subdev_get_fmt,
821	.get_selection = ov01a10_get_selection,
822	.enum_mbus_code = ov01a10_enum_mbus_code,
823	.enum_frame_size = ov01a10_enum_frame_size,
824};
825
826static const struct v4l2_subdev_ops ov01a10_subdev_ops = {
827	.core = &ov01a10_core_ops,
828	.video = &ov01a10_video_ops,
829	.pad = &ov01a10_pad_ops,
830};
831
832static const struct v4l2_subdev_internal_ops ov01a10_internal_ops = {
833	.init_state = ov01a10_init_state,
834};
835
836static const struct media_entity_operations ov01a10_subdev_entity_ops = {
837	.link_validate = v4l2_subdev_link_validate,
838};
839
840static int ov01a10_identify_module(struct ov01a10 *ov01a10)
841{
842	struct i2c_client *client = v4l2_get_subdevdata(&ov01a10->sd);
843	int ret;
844	u32 val;
845
846	ret = ov01a10_read_reg(ov01a10, OV01A10_REG_CHIP_ID, 3, &val);
847	if (ret)
848		return ret;
849
850	if (val != OV01A10_CHIP_ID) {
851		dev_err(&client->dev, "chip id mismatch: %x!=%x\n",
852			OV01A10_CHIP_ID, val);
853		return -EIO;
854	}
855
856	return 0;
857}
858
859static void ov01a10_remove(struct i2c_client *client)
860{
861	struct v4l2_subdev *sd = i2c_get_clientdata(client);
862
863	v4l2_async_unregister_subdev(sd);
864	v4l2_subdev_cleanup(sd);
865	media_entity_cleanup(&sd->entity);
866	v4l2_ctrl_handler_free(sd->ctrl_handler);
867
868	pm_runtime_disable(&client->dev);
869	pm_runtime_set_suspended(&client->dev);
870}
871
872static int ov01a10_probe(struct i2c_client *client)
873{
874	struct device *dev = &client->dev;
875	struct ov01a10 *ov01a10;
876	int ret = 0;
877
878	ov01a10 = devm_kzalloc(dev, sizeof(*ov01a10), GFP_KERNEL);
879	if (!ov01a10)
880		return -ENOMEM;
881
882	v4l2_i2c_subdev_init(&ov01a10->sd, client, &ov01a10_subdev_ops);
883	ov01a10->sd.internal_ops = &ov01a10_internal_ops;
884
885	ret = ov01a10_identify_module(ov01a10);
886	if (ret)
887		return dev_err_probe(dev, ret,
888				     "failed to find sensor\n");
889
890	ov01a10->cur_mode = &supported_modes[0];
891
892	ret = ov01a10_init_controls(ov01a10);
893	if (ret) {
894		dev_err(dev, "failed to init controls: %d\n", ret);
895		return ret;
896	}
897
898	ov01a10->sd.state_lock = ov01a10->ctrl_handler.lock;
899	ov01a10->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
900	ov01a10->sd.entity.ops = &ov01a10_subdev_entity_ops;
901	ov01a10->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
902	ov01a10->pad.flags = MEDIA_PAD_FL_SOURCE;
903
904	ret = media_entity_pads_init(&ov01a10->sd.entity, 1, &ov01a10->pad);
905	if (ret) {
906		dev_err(dev, "Failed to init entity pads: %d\n", ret);
907		goto err_handler_free;
908	}
909
910	ret = v4l2_subdev_init_finalize(&ov01a10->sd);
911	if (ret) {
912		dev_err(dev, "Failed to allocate subdev state: %d\n", ret);
913		goto err_media_entity_cleanup;
914	}
915
916	/*
917	 * Device is already turned on by i2c-core with ACPI domain PM.
918	 * Enable runtime PM and turn off the device.
919	 */
920	pm_runtime_set_active(&client->dev);
921	pm_runtime_enable(dev);
922	pm_runtime_idle(dev);
923
924	ret = v4l2_async_register_subdev_sensor(&ov01a10->sd);
925	if (ret < 0) {
926		dev_err(dev, "Failed to register subdev: %d\n", ret);
927		goto err_pm_disable;
928	}
929
930	return 0;
931
932err_pm_disable:
933	pm_runtime_disable(dev);
934	pm_runtime_set_suspended(&client->dev);
935	v4l2_subdev_cleanup(&ov01a10->sd);
936
937err_media_entity_cleanup:
938	media_entity_cleanup(&ov01a10->sd.entity);
939
940err_handler_free:
941	v4l2_ctrl_handler_free(ov01a10->sd.ctrl_handler);
942
943	return ret;
944}
945
946#ifdef CONFIG_ACPI
947static const struct acpi_device_id ov01a10_acpi_ids[] = {
948	{ "OVTI01A0" },
949	{ }
950};
951
952MODULE_DEVICE_TABLE(acpi, ov01a10_acpi_ids);
953#endif
954
955static struct i2c_driver ov01a10_i2c_driver = {
956	.driver = {
957		.name = "ov01a10",
958		.acpi_match_table = ACPI_PTR(ov01a10_acpi_ids),
959	},
960	.probe = ov01a10_probe,
961	.remove = ov01a10_remove,
962};
963
964module_i2c_driver(ov01a10_i2c_driver);
965
966MODULE_AUTHOR("Bingbu Cao <bingbu.cao@intel.com>");
967MODULE_AUTHOR("Wang Yating <yating.wang@intel.com>");
968MODULE_DESCRIPTION("OmniVision OV01A10 sensor driver");
969MODULE_LICENSE("GPL");
~/ Read-only file preview.